From f3a858e16cfe0ce7c16daadd0b20c958d3efc144 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Tue, 21 Jan 2025 22:01:16 -0500 Subject: [PATCH] [bugfix] tree.c rockbox_browse dirfilter use after free, set_current_file_ex rockbox_browse() set its own *dirfilter and then may neglect to restore it set_current_file_ex() can take a unified path and file or separate path and file only issue is when you send a folder and don't have the final slash its then interpreted as a file and current file is set to it meanwhile path is split and you end up in the parent dir instead if filename is null check if path points to a directory if dir_exists(path) then we will use it as is and set filename to "" Change-Id: I6beaa91141c1a4025cdfac5d6ba426137146c212 --- apps/tree.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/tree.c b/apps/tree.c index 1c31b1e430..8e8499ba1b 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -609,7 +609,7 @@ static void set_current_file_ex(const char *path, const char *filename) return; #endif - if (!filename) /* path and filename supplied combined */ + if (!filename && !dir_exists(path)) /* path and filename supplied combined */ { /* separate directory from filename */ /* gets the directory's name and put it into tc.currdir */ @@ -628,6 +628,8 @@ static void set_current_file_ex(const char *path, const char *filename) } else /* path and filename came in separate ensure an ending '/' */ { + if (!filename) + filename = ""; char *end_p = strmemccpy(tc.currdir, path, MAX_PATH); size_t endpos = end_p - tc.currdir; if (endpos < MAX_PATH) @@ -1053,7 +1055,7 @@ int rockbox_browse(struct browse_context *browse) if (backup_count >= 0) backups[backup_count] = tc; backup_count++; - + int *prev_dirfilter = tc.dirfilter; tc.dirfilter = &dirfilter; tc.sort_dir = global_settings.sort_dir; @@ -1110,6 +1112,7 @@ int rockbox_browse(struct browse_context *browse) } tc.is_browsing = false; + tc.dirfilter = prev_dirfilter; /* Bugfix restore dirfilter*/ backup_count--; if (backup_count >= 0)