mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 08:10:30 -10:00
menu: re-fetch the menu handle after menu_entry_action()
generic_menu_iterate()'s ITERATE_TYPE_DEFAULT case runs the selected entry's action handler and then writes BIT64_SET(menu->state, MENU_STATE_POST_ITERATE) through the menu handle it was passed. menu_entry_action() can tear down and recreate that handle - a menu driver change, or any CMD_EVENT_REINIT dispatched from an action - leaving the parameter and the cached entries list stale; the tail of the function then reads and writes menu->state through freed memory. Observed as a Play Console SIGSEGV at menu_driver_iterate+4088 on a 32-bit Android 11 TV (1.22.2 / 2026-08-26, armeabi-v7a, BuildId d75406ff); the faulting instructions are the read-modify-write of the POST_ITERATE bit through the stale pointer. On 64-bit heaps the same write usually lands in still-mapped freed memory, so this has been corrupting quietly rather than crashing. Re-fetch the handle and the entries list after the action returns; if the menu is gone, there is nothing to post-iterate.
This commit is contained in:
1 parent
f61012ad1a
commit
38234ab96d
1 file changed
+12
@@ -7816,6 +7816,18 @@ static int generic_menu_iterate(
|
||||
selection, (enum menu_action)action)))
|
||||
return -1;
|
||||
|
||||
/* menu_entry_action() can tear down and recreate the menu
|
||||
* (a menu driver change, or any CMD_EVENT_REINIT dispatched
|
||||
* from an entry's action handler): the handle and the
|
||||
* entries list cached above are stale once it returns.
|
||||
* Re-fetch both before writing through them - on 64-bit
|
||||
* heaps the stale menu->state write lands in freed memory
|
||||
* silently instead of faulting, so this corrupts quietly
|
||||
* everywhere the fault does not reproduce. */
|
||||
if (!(menu = menu_st->driver_data))
|
||||
return 0;
|
||||
menu_list = menu_st->entries.list;
|
||||
|
||||
BIT64_SET(menu->state, MENU_STATE_POST_ITERATE);
|
||||
|
||||
/* Have to defer it so we let settings refresh. */
|
||||
|
||||
Reference in new issue
Block a user