From: Masatake YAMATO Date: Tue, 25 Mar 2025 19:49:02 +0000 (+0900) Subject: setarch: add -p/--pid option showing the personality of specified process X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e6446e135b010914644821c17f401670c5c3dce6;p=thirdparty%2Futil-linux.git setarch: add -p/--pid option showing the personality of specified process Signed-off-by: Masatake YAMATO --- diff --git a/bash-completion/setarch b/bash-completion/setarch index 7d7bdb00c..9546eb292 100644 --- a/bash-completion/setarch +++ b/bash-completion/setarch @@ -4,10 +4,29 @@ _setarch_module() COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" + pprev="${COMP_WORDS[COMP_CWORD-2]}" + case $pprev in + '-p'|'--pid') + COMPREPLY=( $(compgen -W "--show" -- $cur) ) + return 0 + ;; + esac case $prev in '-h'|'--help'|'-V'|'--version') return 0 ;; + '-p'|'--pid') + COMPREPLY=( $(compgen -W "$(cd /proc && echo [0-9]*)" -- $cur) ) + return 0 + ;; + '--show') + OPTS=" + current + --pid + " + COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) + return 0 + ;; esac if [ $COMP_CWORD -eq 1 ]; then OPTS="$($1 --list)" diff --git a/sys-utils/setarch.8.adoc b/sys-utils/setarch.8.adoc index 7c64aed7c..1d8c390b3 100644 --- a/sys-utils/setarch.8.adoc +++ b/sys-utils/setarch.8.adoc @@ -35,6 +35,8 @@ List the architectures that *setarch* knows about. Whether *setarch* can actuall Show the currently active personality and flags. If the *personality* argument is provided, it is shown instead of the current one. *personality* is a hexadecimal number with values was described in *sys/personality.h*. ++ +If *--pid=pid* option is provided, show them of the specifies process. *--uname-2.6*:: Causes the _program_ to see a kernel version number beginning with 2.6. Turns on *UNAME26*. @@ -48,6 +50,9 @@ Specifies _program_ should use a maximum of 3GB of address space. Supported on x *--4gb*:: This option has no effect. It is retained for backward compatibility only, and may be removed in future releases. +*-p*, *--pid=pid*:: +With *--show* option, show the currently active personality and flags of the specifies process. + *-B*, *--32bit*:: Limit the address space to 32 bits to emulate hardware. Supported on ARM and Alpha. Turns on *ADDR_LIMIT_32BIT*. @@ -84,6 +89,9 @@ setarch --addr-no-randomize mytestprog setarch ppc32 rpmbuild --target=ppc --rebuild foo.src.rpm setarch ppc32 -v -vL3 rpmbuild --target=ppc --rebuild bar.src.rpm setarch ppc32 --32bit rpmbuild --target=ppc --rebuild foo.src.rpm +setarch --show +setarch --show=$(cat /proc/9284/personality) +setarch --show --pid 9284 .... == AUTHORS @@ -96,6 +104,7 @@ mailto:kzak@redhat.com[Karel Zak] *personality*(2), *select*(2) +*proc_pid_personality(5) include::man-common/bugreports.adoc[] diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c index 4bcb5e69e..c5a2751f6 100644 --- a/sys-utils/setarch.c +++ b/sys-utils/setarch.c @@ -37,6 +37,7 @@ #include "closestream.h" #include "sysfs.h" #include "strutils.h" +#include "procfs.h" #ifndef HAVE_PERSONALITY # include @@ -169,6 +170,7 @@ static void __attribute__((__noreturn__)) usage(int archwrapper) if (!archwrapper) { fputs(_(" --list list settable architectures, and exit\n"), stdout); fputs(_(" --show[=personality] show current or specific personality and exit\n"), stdout); + fputs(_(" -p, --pid=PID show the personality of the process using with --show\n"), stdout); } fputs(USAGE_SEPARATOR, stdout); @@ -424,6 +426,24 @@ static void show_current_personality(void) show_personality(pers); } +static void show_process_personality(pid_t pid) +{ + int pers; + char *pers_str; + + pers_str = pid_get_personality(pid); + if (pers_str == NULL) + err(EXIT_FAILURE, + _("Can not get the personality for process(%d)"), + pid); + pers = str2num_or_err(pers_str, 16, + _("could not parse personality"), + 0, INT_MAX); + free(pers_str); + + show_personality(pers); +} + int main(int argc, char *argv[]) { const char *arch = NULL; @@ -434,6 +454,8 @@ int main(int argc, char *argv[]) struct arch_domain *doms = NULL, *target = NULL; unsigned long pers_value = 0; char *shell = NULL, *shell_arg = NULL; + int do_show = 0; + pid_t target_pid = 0; /* Options without equivalent short options */ enum { @@ -463,6 +485,7 @@ int main(int argc, char *argv[]) {"uname-2.6", no_argument, NULL, OPT_UNAME26}, {"list", no_argument, NULL, OPT_LIST}, {"show", optional_argument, NULL, OPT_SHOW}, + {"pid", required_argument, NULL, 'p'}, {NULL, 0, NULL, 0} }; @@ -495,7 +518,7 @@ int main(int argc, char *argv[]) } } - while ((c = getopt_long(argc, argv, "+hVv3BFILRSTXZ", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "+hVv3BFILRSTXZp:", longopts, NULL)) != -1) { switch (c) { case 'v': verbose = 1; @@ -542,9 +565,22 @@ int main(int argc, char *argv[]) } else warnx(_("unrecognized option '--list'")); goto error_getopts; + case 'p': + if (!archwrapper) { + target_pid = strtos32_or_err(optarg, _("invalid PID argument")); + if (target_pid <= 0) + errx(EXIT_FAILURE, _("out of range value for pid specification: %d"), + target_pid); + break; + } else + warnx(_("unrecognized option '%s'"), argv[optind - 1]); + goto error_getopts; case OPT_SHOW: if (!archwrapper) { - if (!optarg || strcmp(optarg, "current") == 0) + if (!optarg) { + do_show = 1; + break; + } else if (strcmp(optarg, "current") == 0) show_current_personality(); else show_personality(str2num_or_err( @@ -566,6 +602,17 @@ error_getopts: } } + /* We could not find --pid option though we saw --show option. */ + if (do_show) { + if (target_pid) + show_process_personality(target_pid); + else + show_current_personality(); + return EXIT_SUCCESS; + } + if (target_pid) + errx(EXIT_FAILURE, _("use -p/--pid option with --show option")); + if (!arch && !options) errx(EXIT_FAILURE, _("no architecture argument or personality flags specified")); diff --git a/tests/expected/setarch/pid-without-show b/tests/expected/setarch/pid-without-show new file mode 100644 index 000000000..a9bf5a0e1 --- /dev/null +++ b/tests/expected/setarch/pid-without-show @@ -0,0 +1 @@ +exit status: 1 diff --git a/tests/expected/setarch/pid-without-show.err b/tests/expected/setarch/pid-without-show.err new file mode 100644 index 000000000..e0242f98e --- /dev/null +++ b/tests/expected/setarch/pid-without-show.err @@ -0,0 +1 @@ +setarch: use -p/--pid option with --show option diff --git a/tests/expected/setarch/show-with-pid b/tests/expected/setarch/show-with-pid new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/tests/expected/setarch/show-with-pid @@ -0,0 +1 @@ +OK diff --git a/tests/ts/setarch/pid-without-show b/tests/ts/setarch/pid-without-show new file mode 100755 index 000000000..5fbf9d0ca --- /dev/null +++ b/tests/ts/setarch/pid-without-show @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright (C) 2025 Masatake YAMATO +# +# This file is part of util-linux. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +TS_TOPDIR="${0%/*}/../.." +TS_DESC="--show --pid options" + +. "$TS_TOPDIR"/functions.sh + +ts_init "$*" + +ts_check_test_command "$TS_CMD_SETARCH" + +ts_cd "$TS_OUTDIR" + +LC_ALL=C "$TS_CMD_SETARCH" --pid=$$ 2 2> $TS_ERRLOG > $TS_OUTPUT +echo "exit status: $?" >> $TS_OUTPUT + +ts_finalize diff --git a/tests/ts/setarch/show-with-pid b/tests/ts/setarch/show-with-pid new file mode 100755 index 000000000..8f5c4391f --- /dev/null +++ b/tests/ts/setarch/show-with-pid @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Copyright (C) 2025 Masatake YAMATO +# +# This file is part of util-linux. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +TS_TOPDIR="${0%/*}/../.." +TS_DESC="--show --pid options" + +. "$TS_TOPDIR"/functions.sh + +ts_init "$*" + +ts_check_test_command "$TS_CMD_SETARCH" +ts_check_prog "cat" + +ts_cd "$TS_OUTDIR" + +if ! "$TS_CMD_SETARCH" -R bash -c 'echo $$; cat' < /dev/null 1 > /dev/null 2>&1; then + ts_skip "--addr-no-randomize doesn't work on this platform" +fi + +SKIP_REASON= +{ + PID= + coproc BASH { "$TS_CMD_SETARCH" -R bash -c 'echo $$; cat'; } + if read -u ${BASH[0]} PID; then + personality_file="/proc/$PID/personality" + if personality=$(cat "$personality_file"); then + DIRECT=$("$TS_CMD_SETARCH" --show="$personality") + INDIRECT=$("$TS_CMD_SETARCH" --show --pid="$PID") + if [[ "$DIRECT" == "$INDIRECT" ]]; then + echo OK + else + echo DIRECT: "$DIRECT" + echo INDIRECT: "$INDIRECT" + fi + else + SKIP_REASON="cannot read $personality_file on this platform" + fi + fi + exec {BASH[1]}>&- + wait ${BASH_PID} +} > $TS_OUTPUT 2>&1 + +if [[ -n "$SKIP_REASON" ]]; then + ts_skip "$SKIP_REASON" +fi + +ts_finalize