Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e5a214e

Browse filesBrowse files
authored
Fix umm_blocks() (esp8266#8429)
Extracted fix from upstream for umm_blocks() - On allocations that were too large, umm_blocks() could return an incorrectly truncated value when the result is cast to uint16_t.
1 parent b5f3d1d commit e5a214e
Copy full SHA for e5a214e

File tree

Expand file treeCollapse file tree

1 file changed

+57
-17
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+57
-17
lines changed

‎cores/esp8266/umm_malloc/umm_malloc.cpp

Copy file name to clipboardExpand all lines: cores/esp8266/umm_malloc/umm_malloc.cpp
+57-17Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -266,28 +266,68 @@ static umm_heap_context_t *umm_get_ptr_context(void *ptr) {
266266

267267
/* ------------------------------------------------------------------------ */
268268

269-
static uint16_t umm_blocks( size_t size ) {
269+
static uint16_t umm_blocks(size_t size) {
270270

271-
/*
272-
* The calculation of the block size is not too difficult, but there are
273-
* a few little things that we need to be mindful of.
274-
*
275-
* When a block removed from the free list, the space used by the free
276-
* pointers is available for data. That's what the first calculation
277-
* of size is doing.
278-
*/
271+
/*
272+
* The calculation of the block size is not too difficult, but there are
273+
* a few little things that we need to be mindful of.
274+
*
275+
* When a block removed from the free list, the space used by the free
276+
* pointers is available for data. That's what the first calculation
277+
* of size is doing.
278+
*
279+
* We don't check for the special case of (size == 0) here as this needs
280+
* special handling in the caller depending on context. For example when we
281+
* realloc() a block to size 0 it should simply be freed.
282+
*
283+
* We do NOT need to check for allocating more blocks than the heap can
284+
* possibly hold - the allocator figures this out for us.
285+
*
286+
* There are only two cases left to consider:
287+
*
288+
* 1. (size <= body) Obviously this is just one block
289+
* 2. (blocks > (2^15)) This should return ((2^15)) to force a
290+
* failure when the allocator runs
291+
*
292+
* If the requested size is greater that 32677-2 blocks (max block index
293+
* minus the overhead of the top and bottom bookkeeping blocks) then we
294+
* will return an incorrectly truncated value when the result is cast to
295+
* a uint16_t.
296+
*/
279297

280-
if( size <= (sizeof(((umm_block *)0)->body)) )
281-
return( 1 );
298+
if (size <= (sizeof(((umm_block *)0)->body))) {
299+
return 1;
300+
}
282301

283-
/*
284-
* If it's for more than that, then we need to figure out the number of
285-
* additional whole blocks the size of an umm_block are required.
286-
*/
302+
/*
303+
* If it's for more than that, then we need to figure out the number of
304+
* additional whole blocks the size of an umm_block are required, so
305+
* reduce the size request by the number of bytes in the body of the
306+
* first block.
307+
*/
308+
309+
size -= (sizeof(((umm_block *)0)->body));
287310

288-
size -= ( 1 + (sizeof(((umm_block *)0)->body)) );
311+
/* NOTE WELL that we take advantage of the fact that INT16_MAX is the
312+
* number of blocks that we can index in 15 bits :-)
313+
*
314+
* The below expression looks wierd, but it's right. Assuming body
315+
* size of 4 bytes and a block size of 8 bytes:
316+
*
317+
* BYTES (BYTES-BODY) (BYTES-BODY-1)/BLOCKSIZE BLOCKS
318+
* 1 n/a n/a 1
319+
* 5 1 0 2
320+
* 12 8 0 2
321+
* 13 9 1 3
322+
*/
323+
324+
size_t blocks = (2 + ((size - 1) / sizeof(umm_block)));
325+
326+
if (blocks > (INT16_MAX)) {
327+
blocks = INT16_MAX;
328+
}
289329

290-
return( 2 + size/(sizeof(umm_block)) );
330+
return (uint16_t)blocks;
291331
}
292332

293333
/* ------------------------------------------------------------------------ */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.