From 3aef195c435771e43ccddb6226f8c98519e2b830 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 7 Mar 2024 14:34:22 +0000 Subject: su: handle restricted disk drivers Certain tools which allow disk image files and RAM disks to be mounted were found to lack a feature used to implement realpath(3). This resulted in a segfault in the 'su' applet when it was run in such a virtual filesystem. 'su' uses realpath(3) to canonicalise the current directory. This is only really required to handle network shares mapped to a drive letter. (GitHub issue #148) - If the call to realpath(3) fails for some reason fall back to using the current directory determined by calling getcwd(3). - If getcwd(3) fails simply don't pass any directory to the shell being started by 'su'. Also, ensure all allocated memory is freed, if required. (GitHub issue #389) Adds 16-32 bytes. --- loginutils/suw32.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/loginutils/suw32.c b/loginutils/suw32.c index 240a692bc..89ccec220 100644 --- a/loginutils/suw32.c +++ b/loginutils/suw32.c @@ -40,7 +40,7 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) unsigned opt; char *opt_command = NULL; SHELLEXECUTEINFO info; - char *bb_path, *cwd, *q, *args; + char *bb_path, *cwd, *realcwd, *q, *args; DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); opt = getopt32(argv, "c:NW", &opt_command); @@ -74,11 +74,16 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) * a network share it may not be available once we have elevated * privileges. */ - cwd = xmalloc_realpath(getcwd(NULL, 0)); - q = quote_arg(cwd); - args = xasprintf("--busybox ash -d %s -t \"BusyBox ash (Admin)\"", q); - free(q); - free(cwd); + args = xasprintf("--busybox ash -t \"BusyBox ash (Admin)\""); + + cwd = getcwd(NULL, 0); + realcwd = cwd ? xmalloc_realpath(cwd) : NULL; + if (realcwd || cwd) { + args = xappendword(args, "-d"); + q = quote_arg(realcwd ?: cwd); + args = xappendword(args, q); + free(q); + } if (opt & OPT_N) args = xappendword(args, "-N"); @@ -106,6 +111,13 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) if (!ShellExecuteExA(&info)) return 1; + if (ENABLE_FEATURE_CLEAN_UP) { + free(bb_path); + free(cwd); + free(realcwd); + free(args); + } + if (opt & OPT_W) { DWORD r; -- cgit v1.2.3-55-g6feb