diff options
-rw-r--r-- | include/linux/poison.h | 3 | ||||
-rw-r--r-- | lib/flex_array.c | 15 |
2 files changed, 10 insertions, 8 deletions
diff --git a/include/linux/poison.h b/include/linux/poison.h index 6729f7dcd60e..7fc194aef8c2 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h | |||
@@ -65,6 +65,9 @@ | |||
65 | #define MUTEX_DEBUG_INIT 0x11 | 65 | #define MUTEX_DEBUG_INIT 0x11 |
66 | #define MUTEX_DEBUG_FREE 0x22 | 66 | #define MUTEX_DEBUG_FREE 0x22 |
67 | 67 | ||
68 | /********** lib/flex_array.c **********/ | ||
69 | #define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ | ||
70 | |||
68 | /********** security/ **********/ | 71 | /********** security/ **********/ |
69 | #define KEY_DESTROY 0xbd | 72 | #define KEY_DESTROY 0xbd |
70 | 73 | ||
diff --git a/lib/flex_array.c b/lib/flex_array.c index b68f99be4080..e22d0e9776aa 100644 --- a/lib/flex_array.c +++ b/lib/flex_array.c | |||
@@ -113,6 +113,8 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total, | |||
113 | return NULL; | 113 | return NULL; |
114 | ret->element_size = element_size; | 114 | ret->element_size = element_size; |
115 | ret->total_nr_elements = total; | 115 | ret->total_nr_elements = total; |
116 | if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO)) | ||
117 | memset(ret->parts[0], FLEX_ARRAY_FREE, bytes_left_in_base()); | ||
116 | return ret; | 118 | return ret; |
117 | } | 119 | } |
118 | 120 | ||
@@ -159,15 +161,12 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags) | |||
159 | { | 161 | { |
160 | struct flex_array_part *part = fa->parts[part_nr]; | 162 | struct flex_array_part *part = fa->parts[part_nr]; |
161 | if (!part) { | 163 | if (!part) { |
162 | /* | 164 | part = kmalloc(sizeof(struct flex_array_part), flags); |
163 | * This leaves the part pages uninitialized | ||
164 | * and with potentially random data, just | ||
165 | * as if the user had kmalloc()'d the whole. | ||
166 | * __GFP_ZERO can be used to zero it. | ||
167 | */ | ||
168 | part = kmalloc(FLEX_ARRAY_PART_SIZE, flags); | ||
169 | if (!part) | 165 | if (!part) |
170 | return NULL; | 166 | return NULL; |
167 | if (!(flags & __GFP_ZERO)) | ||
168 | memset(part, FLEX_ARRAY_FREE, | ||
169 | sizeof(struct flex_array_part)); | ||
171 | fa->parts[part_nr] = part; | 170 | fa->parts[part_nr] = part; |
172 | } | 171 | } |
173 | return part; | 172 | return part; |
@@ -228,7 +227,7 @@ int flex_array_clear(struct flex_array *fa, unsigned int element_nr) | |||
228 | return -EINVAL; | 227 | return -EINVAL; |
229 | } | 228 | } |
230 | dst = &part->elements[index_inside_part(fa, element_nr)]; | 229 | dst = &part->elements[index_inside_part(fa, element_nr)]; |
231 | memset(dst, 0, fa->element_size); | 230 | memset(dst, FLEX_ARRAY_FREE, fa->element_size); |
232 | return 0; | 231 | return 0; |
233 | } | 232 | } |
234 | 233 | ||