]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
setarch: show current personality
authorThomas Weißschuh <thomas@t-8ch.de>
Wed, 21 Dec 2022 15:50:46 +0000 (15:50 +0000)
committerThomas Weißschuh <thomas@t-8ch.de>
Thu, 5 Jan 2023 15:19:32 +0000 (15:19 +0000)
sys-utils/setarch.8.adoc
sys-utils/setarch.c
tests/expected/misc/setarch-show [new file with mode: 0644]
tests/ts/misc/setarch

index d204028f4fab049e8adac53073efb5c5b2c35b39..c0521c3ab25b5f3adade7bf8a5d3736bd8f06823 100644 (file)
@@ -31,6 +31,11 @@ Since version 2.33 the _arch_ command line argument is optional and *setarch* ma
 *--list*::
 List the architectures that *setarch* knows about. Whether *setarch* can actually set each of these architectures depends on the running kernel.
 
+*--show[=personality]*::
+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 numbers with values was described in *sys/personality.h*.
+
 *--uname-2.6*::
 Causes the _program_ to see a kernel version number beginning with 2.6. Turns on *UNAME26*.
 
index d6789d05e86f555853d4b4d5fc842ac58377d6a7..8c6eecf522bf8a22b5c94937e9cb3c5fe9d0d809 100644 (file)
@@ -36,6 +36,7 @@
 #include "c.h"
 #include "closestream.h"
 #include "sysfs.h"
+#include "strutils.h"
 
 #ifndef HAVE_PERSONALITY
 # include <syscall.h>
 # define ADDR_LIMIT_3GB          0x8000000
 #endif
 
+#define ALL_PERSONALITIES \
+    X(PER_LINUX) \
+    X(PER_LINUX_32BIT) \
+    X(PER_LINUX_FDPIC) \
+    X(PER_SVR4) \
+    X(PER_SVR3) \
+    X(PER_SCOSVR3) \
+    X(PER_OSR5) \
+    X(PER_WYSEV386) \
+    X(PER_ISCR4) \
+    X(PER_BSD) \
+    X(PER_SUNOS) \
+    X(PER_XENIX) \
+    X(PER_LINUX32) \
+    X(PER_LINUX32_3GB) \
+    X(PER_IRIX32) \
+    X(PER_IRIXN32) \
+    X(PER_IRIX64) \
+    X(PER_RISCOS) \
+    X(PER_SOLARIS) \
+    X(PER_UW7) \
+    X(PER_OSF4) \
+    X(PER_HPUX) \
+
+
+#define ALL_OPTIONS \
+    X(UNAME26) \
+    X(ADDR_NO_RANDOMIZE) \
+    X(FDPIC_FUNCPTRS) \
+    X(MMAP_PAGE_ZERO) \
+    X(ADDR_COMPAT_LAYOUT) \
+    X(READ_IMPLIES_EXEC) \
+    X(ADDR_LIMIT_32BIT) \
+    X(SHORT_INODE) \
+    X(WHOLE_SECONDS) \
+    X(STICKY_TIMEOUTS) \
+    X(ADDR_LIMIT_3GB) \
+
 
 struct arch_domain {
        int             perval;         /* PER_* */
@@ -117,8 +156,10 @@ static void __attribute__((__noreturn__)) usage(int archwrapper)
        fputs(_("     --uname-2.6          turns on UNAME26\n"), stdout);
        fputs(_(" -v, --verbose            say what options are being switched on\n"), stdout);
 
-       if (!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(USAGE_SEPARATOR, stdout);
        printf(USAGE_HELP_OPTIONS(26));
@@ -296,6 +337,73 @@ static void verify_arch_domain(struct arch_domain *doms, struct arch_domain *tar
        errx(EXIT_FAILURE, _("Kernel cannot set architecture to %s"), wanted);
 }
 
+static const struct { int value; const char * const name; } all_personalities[] = {
+#define X(opt) { .value = opt, .name = #opt },
+       ALL_PERSONALITIES
+#undef X
+};
+
+static const struct { int value; const char * const name; } all_options[] = {
+#define X(opt) { .value = opt, .name = #opt },
+       ALL_OPTIONS
+#undef X
+};
+
+static void show_personality(int pers)
+{
+       int options;
+       size_t i;
+
+       /* Test for exact matches including options */
+       for (i = 0; i < ARRAY_SIZE(all_personalities); i++) {
+               if (pers == all_personalities[i].value) {
+                       printf("%s\n", all_personalities[i].name);
+                       return;
+               }
+       }
+
+       options = pers & ~PER_MASK;
+       pers &= PER_MASK;
+
+       /* Second test for type-only matches */
+       for (i = 0; i < ARRAY_SIZE(all_personalities); i++) {
+               if (pers == all_personalities[i].value) {
+                       printf("%s", all_personalities[i].name);
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(all_personalities))
+               printf("0x%02x", pers);
+
+       if (options) {
+               printf(" (");
+
+               for (i = 0; i < ARRAY_SIZE(all_options); i++) {
+                       if (options & all_options[i].value) {
+                               printf("%s", all_options[i].name);
+
+                               options &= ~all_options[i].value;
+                               if (options)
+                                       printf(" ");
+                       }
+               }
+               if (options)
+                       printf("0x%08x", options);
+               printf(")");
+       }
+       printf("\n");
+}
+
+static void show_current_personality(void)
+{
+       int pers = personality(0xffffffff);
+       if (pers == -1)
+               err(EXIT_FAILURE, _("Can not get current kernel personality"));
+
+       show_personality(pers);
+}
+
 int main(int argc, char *argv[])
 {
        const char *arch = NULL;
@@ -311,29 +419,31 @@ int main(int argc, char *argv[])
        enum {
                OPT_4GB = CHAR_MAX + 1,
                OPT_UNAME26,
-               OPT_LIST
+               OPT_LIST,
+               OPT_SHOW,
        };
 
        /* Options --3gb and --4gb are for compatibility with an old
         * Debian setarch implementation.  */
        static const struct option longopts[] = {
-               {"help",                no_argument,    NULL,   'h'},
-               {"version",             no_argument,    NULL,   'V'},
-               {"verbose",             no_argument,    NULL,   'v'},
-               {"addr-no-randomize",   no_argument,    NULL,   'R'},
-               {"fdpic-funcptrs",      no_argument,    NULL,   'F'},
-               {"mmap-page-zero",      no_argument,    NULL,   'Z'},
-               {"addr-compat-layout",  no_argument,    NULL,   'L'},
-               {"read-implies-exec",   no_argument,    NULL,   'X'},
-               {"32bit",               no_argument,    NULL,   'B'},
-               {"short-inode",         no_argument,    NULL,   'I'},
-               {"whole-seconds",       no_argument,    NULL,   'S'},
-               {"sticky-timeouts",     no_argument,    NULL,   'T'},
-               {"3gb",                 no_argument,    NULL,   '3'},
-               {"4gb",                 no_argument,    NULL,   OPT_4GB},
-               {"uname-2.6",           no_argument,    NULL,   OPT_UNAME26},
-               {"list",                no_argument,    NULL,   OPT_LIST},
-               {NULL,                  0,              NULL,   0}
+               {"help",                no_argument,            NULL,   'h'},
+               {"version",             no_argument,            NULL,   'V'},
+               {"verbose",             no_argument,            NULL,   'v'},
+               {"addr-no-randomize",   no_argument,            NULL,   'R'},
+               {"fdpic-funcptrs",      no_argument,            NULL,   'F'},
+               {"mmap-page-zero",      no_argument,            NULL,   'Z'},
+               {"addr-compat-layout",  no_argument,            NULL,   'L'},
+               {"read-implies-exec",   no_argument,            NULL,   'X'},
+               {"32bit",               no_argument,            NULL,   'B'},
+               {"short-inode",         no_argument,            NULL,   'I'},
+               {"whole-seconds",       no_argument,            NULL,   'S'},
+               {"sticky-timeouts",     no_argument,            NULL,   'T'},
+               {"3gb",                 no_argument,            NULL,   '3'},
+               {"4gb",                 no_argument,            NULL,   OPT_4GB},
+               {"uname-2.6",           no_argument,            NULL,   OPT_UNAME26},
+               {"list",                no_argument,            NULL,   OPT_LIST},
+               {"show",                optional_argument,      NULL,   OPT_SHOW},
+               {NULL,                  0,                      NULL,   0}
        };
 
        setlocale(LC_ALL, "");
@@ -411,8 +521,22 @@ int main(int argc, char *argv[])
                                return EXIT_SUCCESS;
                        } else
                                warnx(_("unrecognized option '--list'"));
-                       /* fallthrough */
+                       goto error_getopts;
+               case OPT_SHOW:
+                       if (!archwrapper) {
+                               if (!optarg || strcmp(optarg, "current") == 0)
+                                       show_current_personality();
+                               else
+                                       show_personality(str2num_or_err(
+                                               optarg, 16,
+                                               _("could not parse personality"),
+                                               0, INT_MAX));
+                               return EXIT_SUCCESS;
+                       } else
+                               warnx(_("unrecognized option '--show'"));
+                       goto error_getopts;
 
+error_getopts:
                default:
                        errtryhelp(EXIT_FAILURE);
                case 'h':
diff --git a/tests/expected/misc/setarch-show b/tests/expected/misc/setarch-show
new file mode 100644 (file)
index 0000000..fc919c6
--- /dev/null
@@ -0,0 +1,7 @@
+###### --show
+0x00000000: PER_LINUX
+0x00800000: PER_LINUX_32BIT
+0x00880000: PER_LINUX (FDPIC_FUNCPTRS ADDR_LIMIT_32BIT)
+0x00000008: PER_LINUX32
+0x08000008: PER_LINUX32_3GB
+0x000040ff: 0xff (0x00004000)
index aa07cb018d8ed16bf9a2af19a239a1a1409e3305..5398b3391ec1892082131996f43684bb69252710 100755 (executable)
@@ -89,4 +89,21 @@ ts_init_subtest uname26-version
 ts_finalize_subtest
 fi # conditional subtest
 
+ts_init_subtest show
+echo "###### --show" >>$TS_OUTPUT
+
+show() {
+       echo -n "$1: " >> $TS_OUTPUT
+       $TS_CMD_SETARCH --show=$1 >> $TS_OUTPUT 2> $TS_ERRLOG
+}
+
+show 0x00000000
+show 0x00800000
+show 0x00880000
+show 0x00000008
+show 0x08000008
+show 0x000040ff
+
+ts_finalize_subtest
+
 ts_finalize