From 3fa06e049012218d883d0e1251df86bafbc446bf Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 22 Nov 2018 11:03:35 +0100 Subject: [PATCH] setarch: fix obscure sparc32bash use-case Reported-by: Carlos Santos Signed-off-by: Karel Zak Signed-off-by: Carlos Santos --- sys-utils/setarch.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c index a733f7b3c..7c0a63fbb 100644 --- a/sys-utils/setarch.c +++ b/sys-utils/setarch.c @@ -268,6 +268,7 @@ int main(int argc, char *argv[]) int c; struct arch_domain *doms, *target; unsigned long pers_value = 0; + char *shell = NULL, *shell_arg = NULL; /* Options without equivalent short options */ enum { @@ -310,14 +311,14 @@ int main(int argc, char *argv[]) archwrapper = strcmp(program_invocation_short_name, "setarch") != 0; if (archwrapper) { arch = program_invocation_short_name; /* symlinks to setarch */ -#if defined(__sparc64__) || defined(__sparc__) + + /* Don't use ifdef sparc here, we get "Unrecognized architecture" + * error message later if necessary */ if (strcmp(arch, "sparc32bash") == 0) { - if (set_arch(arch, 0L, 0)) - err(EXIT_FAILURE, _("Failed to set personality to %s"), arch); - execl("/bin/bash", "", NULL); - errexec("/bin/bash"); + shell = "/bin/bash"; + shell_arg = ""; + goto set_arch; } -#endif } else { if (1 < argc && *argv[1] != '-') { arch = argv[1]; @@ -391,6 +392,7 @@ int main(int argc, char *argv[]) argc -= optind; argv += optind; +set_arch: /* get execution domain (architecture) */ if (arch) { doms = init_arch_domains(); @@ -422,17 +424,23 @@ int main(int argc, char *argv[]) if (arch) verify_arch_domain(target, arch); + if (!argc) { + shell = "/bin/sh"; + shell_arg = "-sh"; + } if (verbose) { - printf(_("Execute command `%s'.\n"), argc ? argv[0] : "/bin/sh"); + printf(_("Execute command `%s'.\n"), shell ? shell : argv[0]); /* flush all output streams before exec */ fflush(NULL); } - if (!argc) { - execl("/bin/sh", "-sh", NULL); - errexec("/bin/sh"); + /* Execute shell */ + if (shell) { + execl(shell, shell_arg, NULL); + errexec(shell); } + /* Execute on command line specified command */ execvp(argv[0], argv); errexec(argv[0]); } -- 2.14.5