Skip to content

Commit f436315

Browse files
Nicolas Pitrenashif
authored andcommitted
lib/os/heap: guard against arithmetic overflows
Let's do it upfront only once for each entry point and dispense with overflow checks later to keep the code simple. Signed-off-by: Nicolas Pitre <[email protected]>
1 parent c92ad60 commit f436315

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

lib/os/heap.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,12 @@ static chunkid_t alloc_chunk(struct z_heap *h, size_t sz)
223223

224224
void *sys_heap_alloc(struct sys_heap *heap, size_t bytes)
225225
{
226-
if (bytes == 0U) {
226+
struct z_heap *h = heap->heap;
227+
228+
if (bytes == 0U || size_too_big(h, bytes)) {
227229
return NULL;
228230
}
229231

230-
struct z_heap *h = heap->heap;
231232
size_t chunk_sz = bytes_to_chunksz(h, bytes);
232233
chunkid_t c = alloc_chunk(h, chunk_sz);
233234
if (c == 0U) {
@@ -253,7 +254,7 @@ void *sys_heap_aligned_alloc(struct sys_heap *heap, size_t align, size_t bytes)
253254
if (align <= chunk_header_bytes(h)) {
254255
return sys_heap_alloc(heap, bytes);
255256
}
256-
if (bytes == 0) {
257+
if (bytes == 0 || size_too_big(h, bytes)) {
257258
return NULL;
258259
}
259260

@@ -297,6 +298,8 @@ void *sys_heap_aligned_alloc(struct sys_heap *heap, size_t align, size_t bytes)
297298

298299
void *sys_heap_realloc(struct sys_heap *heap, void *ptr, size_t bytes)
299300
{
301+
struct z_heap *h = heap->heap;
302+
300303
/* special realloc semantics */
301304
if (ptr == NULL) {
302305
return sys_heap_alloc(heap, bytes);
@@ -306,7 +309,10 @@ void *sys_heap_realloc(struct sys_heap *heap, void *ptr, size_t bytes)
306309
return NULL;
307310
}
308311

309-
struct z_heap *h = heap->heap;
312+
if (size_too_big(h, bytes)) {
313+
return NULL;
314+
}
315+
310316
chunkid_t c = mem_to_chunkid(h, ptr);
311317
chunkid_t rc = right_chunk(h, c);
312318
size_t chunks_need = bytes_to_chunksz(h, bytes);

lib/os/heap.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,16 @@ static inline int bucket_idx(struct z_heap *h, size_t sz)
229229
return 31 - __builtin_clz(usable_sz);
230230
}
231231

232+
static inline bool size_too_big(struct z_heap *h, size_t bytes)
233+
{
234+
/*
235+
* Quick check to bail out early if size is too big.
236+
* Also guards against potential arithmetic overflows elsewhere.
237+
* There is a minimum of one chunk always in use by the heap header.
238+
*/
239+
return (bytes / CHUNK_UNIT) >= h->len;
240+
}
241+
232242
/* For debugging */
233243
void heap_dump(struct z_heap *h);
234244

0 commit comments

Comments
 (0)