mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
buflib: fix bug in handle_table_shrink
The way it iterated over the handle table is unsafe if *every* handle is free, leading to an out of bounds access. This is a contrived example, but the bug can be triggered by making several allocations, freeing them out of order so that the handle table remains uncompacted, and then triggering a compaction using buflib_alloc_maximum(). Change-Id: I879e2f0b223e6ca596769610ac46f4edf1107f5c
This commit is contained in:
parent
4d3bf1c446
commit
c8365b2bdd
1 changed files with 9 additions and 7 deletions
|
|
@ -247,18 +247,20 @@ union buflib_data* handle_to_block(struct buflib_context* ctx, int handle)
|
|||
/* Shrink the handle table, returning true if its size was reduced, false if
|
||||
* not
|
||||
*/
|
||||
static inline
|
||||
bool
|
||||
handle_table_shrink(struct buflib_context *ctx)
|
||||
static inline bool handle_table_shrink(struct buflib_context *ctx)
|
||||
{
|
||||
bool rv;
|
||||
union buflib_data *handle;
|
||||
for (handle = ctx->last_handle; !(handle->alloc); handle++);
|
||||
union buflib_data *old_last = ctx->last_handle;
|
||||
|
||||
for (handle = ctx->last_handle; handle != ctx->handle_table; ++handle)
|
||||
if (handle->alloc)
|
||||
break;
|
||||
|
||||
if (handle > ctx->first_free_handle)
|
||||
ctx->first_free_handle = handle - 1;
|
||||
rv = handle != ctx->last_handle;
|
||||
|
||||
ctx->last_handle = handle;
|
||||
return rv;
|
||||
return handle != old_last;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue