From 727508b0776278e9239f50d65ea3bb849e4e7803 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sat, 26 Dec 2015 01:40:50 +0000 Subject: [PATCH] Enhance personality syscall decoding * xlat/personality_options.in: Split into ... * xlat/personality_types.in: ... personality types and ... * xlat/personality_flags.in: ... personality flags. * personality.c: Include "xlat/personality_types.h" and "xlat/personality_flags.h" instead of "xlat/personality_options.h". (SYS_FUNC(personality)): Print PER_MASK part of personality as a symbolic value, and the rest of personality as a set of flags. * tests/personality.c (main): Add more test cases. * tests/personality.test: Update. --- personality.c | 60 +++++++-- tests/personality.c | 115 ++++++++++++++++-- tests/personality.test | 2 +- xlat/personality_flags.in | 12 ++ ...nality_options.in => personality_types.in} | 11 -- 5 files changed, 169 insertions(+), 31 deletions(-) create mode 100644 xlat/personality_flags.in rename xlat/{personality_options.in => personality_types.in} (60%) diff --git a/personality.c b/personality.c index 4df4cf33..02dc80f2 100644 --- a/personality.c +++ b/personality.c @@ -1,20 +1,66 @@ -#include "defs.h" +/* + * Copyright (c) 2015 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "defs.h" #include +#include "xlat/personality_types.h" +#include "xlat/personality_flags.h" -#include "xlat/personality_options.h" SYS_FUNC(personality) { + unsigned int pers; + if (entering(tcp)) { - const unsigned int pers = tcp->u_arg[0]; - if (0xffffffff == pers) + pers = tcp->u_arg[0]; + if (0xffffffff == pers) { tprints("0xffffffff"); - else - printflags(personality_options, pers, "PER_???"); + } else { + printxval(personality_types, pers & PER_MASK, "PER_???"); + pers &= ~PER_MASK; + if (pers) { + tprints("|"); + printflags(personality_flags, pers, NULL); + } + } return 0; } - tcp->auxstr = sprintflags("", personality_options, tcp->u_rval); + pers = tcp->u_rval; + const char *type = xlookup(personality_types, pers & PER_MASK); + char *p; + static char outstr[1024]; + if (type) + p = stpcpy(outstr, type); + else + p = outstr + sprintf(outstr, "%#x /* %s */", pers & PER_MASK, "PER_???"); + pers &= ~PER_MASK; + if (pers) + strcpy(p, sprintflags("|", personality_flags, pers)); + tcp->auxstr = outstr; return RVAL_HEX | RVAL_STR; } diff --git a/tests/personality.c b/tests/personality.c index 83638856..7a279a14 100644 --- a/tests/personality.c +++ b/tests/personality.c @@ -1,27 +1,118 @@ +/* + * Copyright (c) 2015 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include #include int main(void) { - const unsigned int test_pers = + const unsigned int good_type = PER_BSD; + const char *good_type_str = "PER_BSD"; + + const unsigned int bad_type = 0x1f; + const char *bad_type_str = "0x1f /\\* PER_\\?\\?\\? \\*/"; + + const unsigned int good_flags = SHORT_INODE | WHOLE_SECONDS | STICKY_TIMEOUTS; - const unsigned int saved_pers = personality(0); + const char *good_flags_str = + "SHORT_INODE\\|WHOLE_SECONDS\\|STICKY_TIMEOUTS"; - printf("personality\\(PER_LINUX\\) = %#x \\([^)]*\\)\n", saved_pers); + const unsigned int bad_flags = 0x10000; + const char *bad_flags_str = "0x10000"; - personality(test_pers); - puts("personality\\(SHORT_INODE\\|WHOLE_SECONDS\\|STICKY_TIMEOUTS\\)" - " = 0 \\(PER_LINUX\\)"); + const unsigned int saved_pers = personality(0xffffffff); + printf("personality\\(0xffffffff\\) = %#x \\([^)]*\\)\n", saved_pers); + + /* PER_LINUX */ + personality(PER_LINUX); + printf("personality\\(PER_LINUX\\) = %#x \\([^)]*\\)\n", saved_pers); personality(0xffffffff); - printf("personality\\(0xffffffff\\) = %#x" - " \\(SHORT_INODE\\|WHOLE_SECONDS\\|STICKY_TIMEOUTS\\)\n", - test_pers); + puts("personality\\(0xffffffff\\) = 0 \\(PER_LINUX\\)"); + + personality(good_flags); + printf("personality\\(PER_LINUX\\|%s\\) = 0 \\(PER_LINUX\\)\n", + good_flags_str); + + personality(bad_flags); + printf("personality\\(PER_LINUX\\|%s\\)" + " = %#x \\(PER_LINUX\\|%s\\)\n", + bad_flags_str, good_flags, good_flags_str); + + personality(good_flags | bad_flags); + printf("personality\\(PER_LINUX\\|%s\\|%s\\)" + " = %#x \\(PER_LINUX\\|%s\\)\n", + good_flags_str, bad_flags_str, bad_flags, bad_flags_str); + + /* another valid type */ + personality(good_type); + printf("personality\\(%s\\) = %#x \\(PER_LINUX\\|%s\\|%s\\)\n", + good_type_str, good_flags | bad_flags, + good_flags_str, bad_flags_str); + + personality(good_type | good_flags); + printf("personality\\(%s\\|%s\\) = %#x \\(%s\\)\n", + good_type_str, good_flags_str, good_type, good_type_str); + + personality(good_type | bad_flags); + printf("personality\\(%s\\|%s\\) = %#x \\(%s\\|%s\\)\n", + good_type_str, bad_flags_str, good_type | good_flags, + good_type_str, good_flags_str); + + personality(good_type | good_flags | bad_flags); + printf("personality\\(%s\\|%s\\|%s\\) = %#x \\(%s\\|%s\\)\n", + good_type_str, good_flags_str, bad_flags_str, + good_type | bad_flags, + good_type_str, bad_flags_str); + + /* invalid type */ + personality(bad_type); + printf("personality\\(%s\\) = %#x \\(%s\\|%s\\|%s\\)\n", + bad_type_str, good_type | good_flags | bad_flags, + good_type_str, good_flags_str, bad_flags_str); + + personality(bad_type | good_flags); + printf("personality\\(%s\\|%s\\) = %#x \\(%s\\)\n", + bad_type_str, good_flags_str, bad_type, bad_type_str); + + personality(bad_type | bad_flags); + printf("personality\\(%s\\|%s\\) = %#x \\(%s\\|%s\\)\n", + bad_type_str, bad_flags_str, bad_type | good_flags, + bad_type_str, good_flags_str); + + personality(bad_type | good_flags | bad_flags); + printf("personality\\(%s\\|%s\\|%s\\) = %#x \\(%s\\|%s\\)\n", + bad_type_str, good_flags_str, bad_flags_str, + bad_type | bad_flags, bad_type_str, bad_flags_str); personality(saved_pers); - printf("personality\\([^)]*\\) = %#x" - " \\(SHORT_INODE\\|WHOLE_SECONDS\\|STICKY_TIMEOUTS\\)\n", - test_pers); + printf("personality\\([^)]*\\) = %#x \\(%s\\|%s\\|%s\\)\n", + bad_type | good_flags | bad_flags, + bad_type_str, good_flags_str, bad_flags_str); return 0; } diff --git a/tests/personality.test b/tests/personality.test index b4329c0c..e3d6e671 100755 --- a/tests/personality.test +++ b/tests/personality.test @@ -6,7 +6,7 @@ run_prog > /dev/null OUT="$LOG.out" -run_strace -a22 -epersonality $args > "$OUT" +run_strace -a20 -epersonality $args > "$OUT" match_grep "$LOG" "$OUT" rm -f "$OUT" diff --git a/xlat/personality_flags.in b/xlat/personality_flags.in new file mode 100644 index 00000000..a8715e2f --- /dev/null +++ b/xlat/personality_flags.in @@ -0,0 +1,12 @@ +#unconditional +UNAME26 +ADDR_NO_RANDOMIZE +FDPIC_FUNCPTRS +MMAP_PAGE_ZERO +ADDR_COMPAT_LAYOUT +READ_IMPLIES_EXEC +ADDR_LIMIT_32BIT +SHORT_INODE +WHOLE_SECONDS +STICKY_TIMEOUTS +ADDR_LIMIT_3GB diff --git a/xlat/personality_options.in b/xlat/personality_types.in similarity index 60% rename from xlat/personality_options.in rename to xlat/personality_types.in index 5f81cd27..6832c65d 100644 --- a/xlat/personality_options.in +++ b/xlat/personality_types.in @@ -21,14 +21,3 @@ PER_SOLARIS PER_UW7 PER_OSF4 PER_HPUX -UNAME26 -ADDR_NO_RANDOMIZE -FDPIC_FUNCPTRS -MMAP_PAGE_ZERO -ADDR_COMPAT_LAYOUT -READ_IMPLIES_EXEC -ADDR_LIMIT_32BIT -SHORT_INODE -WHOLE_SECONDS -STICKY_TIMEOUTS -ADDR_LIMIT_3GB -- 2.40.0