Commit b36e9f4
committed
menu: fix OOM NULL-derefs in ozone list cloning and menu_list constructor
Three unchecked allocation sites across two menu files, all on
hot paths (menu navigation and menu init).
=== menu/drivers/ozone.c: ozone_copy_node ===
ozone_node_t *new_node = (ozone_node_t*)malloc(sizeof(*new_node));
*new_node = *old_node; /* NULL-deref on OOM */
new_node->fullpath = old_node->fullpath
? strdup(old_node->fullpath)
: NULL;
return new_node;
Unchecked malloc; the immediate '*new_node = *old_node' struct
copy NULL-derefs on OOM. This function is called by
ozone_list_deep_copy on every node that has an attached
ozone_node_t userdata, which is every entry in ozone's scrolling
content lists during navigation-induced list copies (scroll,
filter, submenu entry/exit).
Fix: NULL-check and return NULL. The single caller
(ozone_list_deep_copy) already handles a NULL return cleanly -
it writes the result directly into dst->list[j].userdata, and
downstream code (ozone_free_list_nodes, ozone's draw paths)
already tolerates NULL userdata entries (represents
'non-ozone-specific' list items like folder entries).
=== menu/drivers/ozone.c: ozone_list_deep_copy actiondata branch ===
if (src_adata)
{
void *data = malloc(sizeof(menu_file_list_cbs_t));
memcpy(data, src_adata, sizeof(menu_file_list_cbs_t));
dst->list[j].actiondata = data;
}
Same pattern: unchecked malloc, immediate memcpy NULL-derefs on
OOM. Hit for every list entry that has an actiondata callback
block (which is most of them - menu cbs get attached during
setting construction).
Fix: NULL-check the malloc; on failure leave
dst->list[j].actiondata = NULL. The surrounding code already
handles NULL actiondata (matches the 'no src_adata' branch
directly above - entries without cbs just skip action dispatch).
=== menu/menu_driver.c: menu_list_new inner mallocs ===
for (i = 0; i < list->menu_stack_size; i++)
{
list->menu_stack[i] = (file_list_t*)
malloc(sizeof(*list->menu_stack[i]));
list->menu_stack[i]->list = NULL; /* NULL-deref */
list->menu_stack[i]->capacity = 0;
list->menu_stack[i]->size = 0;
}
for (i = 0; i < list->selection_buf_size; i++)
{
list->selection_buf[i] = (file_list_t*)
malloc(sizeof(*list->selection_buf[i]));
list->selection_buf[i]->list = NULL; /* NULL-deref */
list->selection_buf[i]->capacity = 0;
list->selection_buf[i]->size = 0;
}
Two sibling-drift sites. Each malloc is unchecked and the
immediate field writes NULL-deref on OOM. Both loops init the
menu's double-buffered navigation stacks; menu_list_new runs
once per menu-driver init, so this crashes RetroArch startup if
OOM hits at exactly the wrong moment.
Fix: NULL-check each malloc, goto error on failure.
menu_list_free already handles partially-populated menu_stack /
selection_buf arrays correctly (has 'if (!menu_list->menu_stack[i])
continue' guards, and the outer arrays are calloc'd so
unallocated slots past the failure point are already NULL).
=== Thread-safety ===
ozone_list_deep_copy runs on the main/menu thread during list
refresh; menu_list_new runs during menu-driver init before any
worker threads are started. No lock discipline changes.
=== Reachability ===
* ozone_copy_node: every ozone list refresh with non-empty
content (scrolling, filtering, submenu nav).
* ozone_list_deep_copy actiondata: every ozone list entry with
attached cbs (which is most).
* menu_list_new: RetroArch startup menu-driver init. Typically
only succeeds or fails once at boot, but the size-2 initial
lists are small so this fails only on catastrophic memory
pressure.
=== Not a bug, verified clean ===
Also audited but found properly NULL-checked or gracefully
degrading:
* menu/drivers/materialui.c:2365, 9092 - use the
'if (!(x = alloc(...)))' idiom.
* menu/drivers/rgui.c:6829 - 'if (!(x = calloc(...)))'.
* menu/menu_setting.c:714 (SETTINGS_LIST_APPEND_internal)
realloc-to-tmp with NULL check; caller gates config_* on
its return.
* menu/menu_setting.c:25854, 25915 - NULL-checked with proper
unwind.
* menu/menu_driver.c:4161, 4254 - NULL-checked.
* menu/menu_screensaver.c:309 - NULL-checked.
* menu/cbs/ and menu/widgets/ - no raw alloc sites found.1 parent 5874334 commit b36e9f4
2 files changed
Lines changed: 29 additions & 2 deletions
File tree
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4623 | 4623 | | |
4624 | 4624 | | |
4625 | 4625 | | |
| 4626 | + | |
| 4627 | + | |
| 4628 | + | |
| 4629 | + | |
| 4630 | + | |
| 4631 | + | |
| 4632 | + | |
| 4633 | + | |
4626 | 4634 | | |
4627 | 4635 | | |
4628 | 4636 | | |
| |||
4662 | 4670 | | |
4663 | 4671 | | |
4664 | 4672 | | |
4665 | | - | |
4666 | | - | |
| 4673 | + | |
| 4674 | + | |
| 4675 | + | |
| 4676 | + | |
| 4677 | + | |
| 4678 | + | |
| 4679 | + | |
| 4680 | + | |
| 4681 | + | |
| 4682 | + | |
| 4683 | + | |
4667 | 4684 | | |
4668 | 4685 | | |
4669 | 4686 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1422 | 1422 | | |
1423 | 1423 | | |
1424 | 1424 | | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
1425 | 1432 | | |
1426 | 1433 | | |
1427 | 1434 | | |
| |||
1431 | 1438 | | |
1432 | 1439 | | |
1433 | 1440 | | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
1434 | 1444 | | |
1435 | 1445 | | |
1436 | 1446 | | |
| |||
0 commit comments