From 05541825553524e2ac353eb6c62c8b5ad049de24 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 7 Aug 2018 11:31:14 +0200 Subject: setarch: make optional Let's allow to change personality flags without execution domain modification. Old way: setarch `arch` --addr-no-randomize myprog New way: setarch --addr-no-randomize myprog Addresses: https://github.com/karelzak/util-linux/issues/668 Signed-off-by: Karel Zak --- sys-utils/setarch.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'sys-utils/setarch.c') diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c index fc5764f82..a733f7b3c 100644 --- a/sys-utils/setarch.c +++ b/sys-utils/setarch.c @@ -94,7 +94,7 @@ static void __attribute__((__noreturn__)) usage(int archwrapper) { fputs(USAGE_HEADER, stdout); if (!archwrapper) - printf(_(" %s [options] [ [...]]\n"), program_invocation_short_name); + printf(_(" %s [] [options] [ [...]]\n"), program_invocation_short_name); else printf(_(" %s [options] [ [...]]\n"), program_invocation_short_name); @@ -385,19 +385,26 @@ int main(int argc, char *argv[]) } } - if (!arch) - errx(EXIT_FAILURE, _("no architecture argument specified")); + if (!arch && !options) + errx(EXIT_FAILURE, _("no architecture argument or personality flags specified")); argc -= optind; argv += optind; - doms = init_arch_domains(); + /* get execution domain (architecture) */ + if (arch) { + doms = init_arch_domains(); + target = get_arch_domain(doms, arch); - target = get_arch_domain(doms, arch); - if (!target) - errx(EXIT_FAILURE, _("%s: Unrecognized architecture"), arch); + if (!target) + errx(EXIT_FAILURE, _("%s: Unrecognized architecture"), arch); + pers_value = target->perval; + } + + /* add personality flags */ + pers_value |= options; - pers_value = target->perval | options; + /* call kernel */ if (personality(pers_value) < 0) { /* * Depending on architecture and kernel version, personality @@ -411,7 +418,9 @@ int main(int argc, char *argv[]) err(EXIT_FAILURE, _("failed to set personality to %s"), arch); } - verify_arch_domain(target, arch); + /* make sure architecture is set as expected */ + if (arch) + verify_arch_domain(target, arch); if (verbose) { printf(_("Execute command `%s'.\n"), argc ? argv[0] : "/bin/sh"); -- cgit v1.2.3-55-g7522