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 <cursoragent@cursor.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user