|
| 1 | +From c5532c9200d2c0d471b468b97370bb29d9d5393c Mon Sep 17 00:00:00 2001 |
| 2 | +From: Chris Chilvers <chris.chilvers@appsbroker.com> |
| 3 | +Date: Fri, 3 Feb 2023 17:10:50 +0000 |
| 4 | +Subject: [PATCH] Stop assuming 0x6000000 is an invalid memory address |
| 5 | + |
| 6 | +On 32 bit architectures, this address would often live in the kernel |
| 7 | +address space (though not all systems have this guarantee). |
| 8 | + |
| 9 | +With a 64 bit architecture however this bit pattern can appear in valid |
| 10 | +addresses allocated using calloc. This causes the decant_cull_table |
| 11 | +check to mistakenly abort the application. |
| 12 | + |
| 13 | +For now create a defined sentinel address that can be used for bug |
| 14 | +checks. The downside is that with only a single sentinel value we |
| 15 | +cannot tell how an invalid value got into cullbuild. |
| 16 | + |
| 17 | +This also does not deal with the other invalid memory patters that are |
| 18 | +created using memset. This is used to fill the memory with a repeating |
| 19 | +pattern such as 0x6b, 0x6d, or 0x6e; all of which would also match the |
| 20 | +mask 0xf0000000 == 0x60000000. |
| 21 | + |
| 22 | +For now just change memset to fill the memory with zeros. This should |
| 23 | +act like a null pointer and cause a segfault if there's an attempt to |
| 24 | +dereference one. |
| 25 | +--- |
| 26 | + cachefilesd.c | 25 +++++++++++++++---------- |
| 27 | + 1 file changed, 15 insertions(+), 10 deletions(-) |
| 28 | + |
| 29 | +diff --git a/cachefilesd.c b/cachefilesd.c |
| 30 | +index d4d236f..b59ffb9 100644 |
| 31 | +--- a/cachefilesd.c |
| 32 | ++++ b/cachefilesd.c |
| 33 | +@@ -98,6 +98,10 @@ static unsigned culltable_size = 4096; |
| 34 | + static struct object **cullbuild; |
| 35 | + static struct object **cullready; |
| 36 | + |
| 37 | ++// represents an invalid entry in the cull table |
| 38 | ++// it might be possible to just replace this with NULL |
| 39 | ++static struct object invalid = {}; |
| 40 | ++ |
| 41 | + static unsigned nr_in_build_table; |
| 42 | + static unsigned nr_in_ready_table; |
| 43 | + static int ncullable; |
| 44 | +@@ -1092,7 +1096,7 @@ static void put_object(struct object *object) |
| 45 | + |
| 46 | + parent = object->parent; |
| 47 | + |
| 48 | +- memset(object, 0x6d, sizeof(struct object)); |
| 49 | ++ memset(object, 0, sizeof(struct object)); |
| 50 | + free(object); |
| 51 | + |
| 52 | + if (parent) |
| 53 | +@@ -1213,7 +1217,7 @@ static void insert_into_cull_table(struct object *object) |
| 54 | + |
| 55 | + /* newest object in table will be displaced by this one */ |
| 56 | + put_object(cullbuild[0]); |
| 57 | +- cullbuild[0] = (void *)(0x6b000000 | __LINE__); |
| 58 | ++ cullbuild[0] = &invalid; |
| 59 | + object->usage++; |
| 60 | + |
| 61 | + /* place directly in first slot if second is older */ |
| 62 | +@@ -1391,7 +1395,7 @@ next: |
| 63 | + |
| 64 | + if (loop == nr_in_ready_table - 1) { |
| 65 | + /* child was oldest object */ |
| 66 | +- cullready[--nr_in_ready_table] = (void *)(0x6b000000 | __LINE__); |
| 67 | ++ cullready[--nr_in_ready_table] = &invalid; |
| 68 | + put_object(child); |
| 69 | + goto removed; |
| 70 | + } |
| 71 | +@@ -1400,7 +1404,7 @@ next: |
| 72 | + memmove(&cullready[loop], |
| 73 | + &cullready[loop + 1], |
| 74 | + (nr_in_ready_table - (loop + 1)) * sizeof(cullready[0])); |
| 75 | +- cullready[--nr_in_ready_table] = (void *)(0x6b000000 | __LINE__); |
| 76 | ++ cullready[--nr_in_ready_table] = &invalid; |
| 77 | + put_object(child); |
| 78 | + goto removed; |
| 79 | + } |
| 80 | +@@ -1411,7 +1415,7 @@ next: |
| 81 | + |
| 82 | + if (loop == nr_in_build_table - 1) { |
| 83 | + /* child was oldest object */ |
| 84 | +- cullbuild[--nr_in_build_table] = (void *)(0x6b000000 | __LINE__); |
| 85 | ++ cullbuild[--nr_in_build_table] = &invalid; |
| 86 | + put_object(child); |
| 87 | + } |
| 88 | + else if (loop < nr_in_build_table - 1) { |
| 89 | +@@ -1419,7 +1423,7 @@ next: |
| 90 | + memmove(&cullbuild[loop], |
| 91 | + &cullbuild[loop + 1], |
| 92 | + (nr_in_build_table - (loop + 1)) * sizeof(cullbuild[0])); |
| 93 | +- cullbuild[--nr_in_build_table] = (void *)(0x6b000000 | __LINE__); |
| 94 | ++ cullbuild[--nr_in_build_table] = &invalid; |
| 95 | + put_object(child); |
| 96 | + } |
| 97 | + |
| 98 | +@@ -1531,7 +1535,7 @@ static void decant_cull_table(void) |
| 99 | + |
| 100 | + n = copy * sizeof(cullready[0]); |
| 101 | + memcpy(cullready, cullbuild, n); |
| 102 | +- memset(cullbuild, 0x6e, n); |
| 103 | ++ memset(cullbuild, 0, n); |
| 104 | + nr_in_ready_table = nr_in_build_table; |
| 105 | + nr_in_build_table = 0; |
| 106 | + goto check; |
| 107 | +@@ -1559,7 +1563,7 @@ static void decant_cull_table(void) |
| 108 | + nr_in_ready_table += copy; |
| 109 | + |
| 110 | + memcpy(&cullready[0], &cullbuild[leave], copy * sizeof(cullready[0])); |
| 111 | +- memset(&cullbuild[leave], 0x6b, copy * sizeof(cullbuild[0])); |
| 112 | ++ memset(&cullbuild[leave], 0, copy * sizeof(cullbuild[0])); |
| 113 | + nr_in_build_table = leave; |
| 114 | + |
| 115 | + if (copy + leave > culltable_size) |
| 116 | +@@ -1567,7 +1571,8 @@ static void decant_cull_table(void) |
| 117 | + |
| 118 | + check: |
| 119 | + for (loop = 0; loop < nr_in_ready_table; loop++) |
| 120 | +- if (((long)cullready[loop] & 0xf0000000) == 0x60000000) |
| 121 | ++ // check for invalid sentiel value, or 0 from memset |
| 122 | ++ if (cullready[loop] == &invalid || ((long)cullready[loop] == 0)) |
| 123 | + abort(); |
| 124 | + } |
| 125 | + |
| 126 | +@@ -1645,6 +1650,6 @@ static void cull_objects(void) |
| 127 | + |
| 128 | + if (cullready[nr_in_ready_table - 1]->cullable) { |
| 129 | + cull_object(cullready[nr_in_ready_table - 1]); |
| 130 | +- cullready[--nr_in_ready_table] = (void *)(0x6b000000 | __LINE__); |
| 131 | ++ cullready[--nr_in_ready_table] = &invalid; |
| 132 | + } |
| 133 | + } |
| 134 | +-- |
| 135 | +2.34.1 |
| 136 | + |
0 commit comments