From ef9c1eaf7a388d0ba97f128defae3a546117b125 Mon Sep 17 00:00:00 2001 From: niklascfw Date: Fri, 13 Feb 2026 21:16:58 +0100 Subject: [PATCH] Fix data abort crash in Mac special files removal (listdir) The listdir function had three memory corruption bugs causing a data abort (Err:19) on the Switch: 1. Heap buffer overflow: CpyStr("sd:/") allocated only 5 bytes but listdir appends full subdirectory paths in-place via memcpy. Fixed by using a 1024-byte stack buffer instead. 2. Use-after-free: _DeleteFileSimple(path) freed the shared traversal buffer, but the loop continued using it. Fixed by inlining f_unlink without freeing. 3. Recursive free + missing else: free(path) at the end of listdir freed the buffer shared across all recursive frames, and a missing else caused recursion into directories that were just deleted. Removed the free and added an else guard. Co-authored-by: Cursor --- source/apl/apl.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/source/apl/apl.c b/source/apl/apl.c index ff3ba4e..a9488b0 100644 --- a/source/apl/apl.c +++ b/source/apl/apl.c @@ -100,11 +100,10 @@ int listdir(char *path, u32 hos_folder, int *deleted_count) if (!hos_folder && !strcmp(fno.fname, "Nintendo")) continue; - // // Set new directory or file. + // Set new directory or file. memcpy(&path[dirLength], "/", 1); memcpy(&path[dirLength + 1], fno.fname, strlen(fno.fname) + 1); - // gfx_printf("THING: %s\n", fno.fname); - // gfx_printf("Pfad: %s\n", dir); + // Is it a directory? if (fno.fattrib & AM_DIR) { @@ -121,9 +120,10 @@ int listdir(char *path, u32 hos_folder, int *deleted_count) _FolderDelete(path); if (deleted_count) (*deleted_count)++; } - - // Enter the directory. - listdir(path, 0, deleted_count); + else { + // Only recurse into directories that were not deleted. + listdir(path, 0, deleted_count); + } if (res != FR_OK) break; } else { @@ -136,13 +136,14 @@ int listdir(char *path, u32 hos_folder, int *deleted_count) strcmp(fno.fname, ".TemporaryItems") == 0 || _StartsWith(fno.fname, "._") ) { - _DeleteFileSimple(path); + res = f_unlink(path); + if (res) + DrawError(newErrCode(res)); if (deleted_count) (*deleted_count)++; } } } f_closedir(&dir); - free(path); return res; } @@ -362,7 +363,8 @@ void m_entry_fixMacSpecialFolders(){ gfx_clearscreen(); gfx_printf("\n\n-- Mac-Ordner reparieren (dies kann ein wenig dauern, bitte warten.)\n\n"); int deleted = 0; - char *path = CpyStr("sd:/"); + char path[1024]; + strcpy(path, "sd:/"); listdir(path, 0, &deleted); if (deleted > 0) gfx_printf("\n%d Mac-Datei(en)/Ordner entfernt.\n", deleted);