diff options
author | Eugene Syromyatnikov <evgsyr@gmail.com> | 2022-08-03 14:56:53 +0200 |
---|---|---|
committer | Eugene Syromyatnikov <evgsyr@gmail.com> | 2022-08-09 10:34:31 +0200 |
commit | 8ad09429b7d27e85c0fdc1e043ed16ab10746240 (patch) | |
tree | e267439b86494bf1fba720739d87f098691a5596 | |
parent | 8495c8b757c5ff66500fe09326a5ee1fc1aea26c (diff) | |
download | strace-8ad09429b7d27e85c0fdc1e043ed16ab10746240.tar.gz |
printsiginfo: print si_lower/si_upper for SEGV_BNDERR signals
* configure.ac (AC_CHECK_MEMBERS): Add siginfo_t.si_lower
and siginfo_t.si_upper checks.
* src/printsiginfo.c (print_si_info): [!SEGV_STACKFLOW
&& HAVE_SIGINFO_T_SI_LOWER] <case SIGSEGV>: Print si_lower
and si_upper fields if si_code is SEGV_BNDERR.
* tests/ptrace.c: Add checks.
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/printsiginfo.c | 16 | ||||
-rw-r--r-- | tests/ptrace.c | 99 |
3 files changed, 107 insertions, 12 deletions
diff --git a/configure.ac b/configure.ac index 30dab8eea..4dd35adad 100644 --- a/configure.ac +++ b/configure.ac @@ -425,7 +425,9 @@ AC_CHECK_MEMBERS(m4_normalize([ siginfo_t.si_timerid, siginfo_t.si_overrun, siginfo_t.si_pkey, - siginfo_t.si_addr_lsb + siginfo_t.si_addr_lsb, + siginfo_t.si_lower, + siginfo_t.si_upper ]),,, [#include <signal.h>]) AC_CHECK_HEADERS(m4_normalize([ diff --git a/src/printsiginfo.c b/src/printsiginfo.c index c49bf0163..f9990d219 100644 --- a/src/printsiginfo.c +++ b/src/printsiginfo.c @@ -179,14 +179,26 @@ print_si_info(struct tcb *tcp, const siginfo_t *sip) case SIGSEGV: tprint_struct_next(); PRINT_FIELD_PTR(*sip, si_addr); -#ifdef HAVE_SIGINFO_T_SI_PKEY +#if (!defined(SEGV_STACKFLOW) && defined(HAVE_SIGINFO_T_SI_LOWER)) \ + || (!defined(__SEGV_PSTKOVF) && defined(HAVE_SIGINFO_T_SI_PKEY)) switch (sip->si_code) { +# if !defined(SEGV_STACKFLOW) && defined(HAVE_SIGINFO_T_SI_LOWER) + case SEGV_BNDERR: + tprint_struct_next(); + PRINT_FIELD_PTR(*sip, si_lower); + tprint_struct_next(); + PRINT_FIELD_PTR(*sip, si_upper); + break; +# endif /* !SEGV_STACKFLOW && HAVE_SIGINFO_T_SI_LOWER */ +# if !defined(__SEGV_PSTKOVF) && defined(HAVE_SIGINFO_T_SI_PKEY) case SEGV_PKUERR: tprint_struct_next(); PRINT_FIELD_U(*sip, si_pkey); break; +# endif /* !__SEGV_PSTKOVF && HAVE_SIGINFO_T_SI_PKEY */ } -#endif +#endif /* !SEGV_STACKFLOW && HAVE_SIGINFO_T_SI_LOWER + * || !__SEGV_PSTKOVF && HAVE_SIGINFO_T_SI_PKEY */ break; case SIGPOLL: switch (sip->si_code) { diff --git a/tests/ptrace.c b/tests/ptrace.c index c22403ec9..c60cdea97 100644 --- a/tests/ptrace.c +++ b/tests/ptrace.c @@ -33,6 +33,12 @@ #undef XLAT_MACROS_ONLY #include "xlat/audit_arch.h" +#if SIZEOF_LONG > 4 +# define UP64BIT(a_) a_ +#else +# define UP64BIT(a_) +#endif + struct valstraux { int val; const char *str; @@ -1890,21 +1896,96 @@ main(void) XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request, XLAT_ARGS(SIGPROF), sip->si_code, sip->si_errno, errstr); -#if defined HAVE_SIGINFO_T_SI_PKEY && defined SEGV_PKUERR + /* SIGSEGV */ + struct valstraux segv_codes[] = { + { ARG_XLAT_KNOWN(0x1, "SEGV_MAPERR") }, + { ARG_XLAT_KNOWN(0x2, "SEGV_ACCERR") }, +#ifdef SEGV_STACKFLOW + { ARG_XLAT_KNOWN(0x3, "SEGV_STACKFLOW") }, +#else + { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"), "" +# ifdef HAVE_SIGINFO_T_SI_LOWER + ", si_lower=NULL, si_upper=NULL" + }, + { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"), + ", si_lower=NULL" + ", si_upper=0x" UP64BIT("deadc0de") "beadfeed" }, + { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"), + ", si_lower=0x" UP64BIT("facecafe") "befeeded" + ", si_upper=NULL" }, + { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"), + ", si_lower=0x" UP64BIT("beefface") "cafedead" + ", si_upper=0x" UP64BIT("badc0ded") "dadfaced", +#endif /* HAVE_SIGINFO_T_SI_LOWER */ + }, +#endif /* SEGV_STACKFLOW */ +#ifdef __SEGV_PSTKOVF + { ARG_XLAT_KNOWN(0x4, "__SEGV_PSTKOVF") }, +#else + { ARG_XLAT_KNOWN(0x4, "SEGV_PKUERR"), "" +# ifdef HAVE_SIGINFO_T_SI_PKEY + ", si_pkey=0" + }, + { ARG_XLAT_KNOWN(0x4, "SEGV_PKUERR"), ", si_pkey=1234567890" }, + { ARG_XLAT_KNOWN(0x4, "SEGV_PKUERR"), ", si_pkey=3141592653" +# endif /* HAVE_SIGINFO_T_SI_PKEY */ + }, +#endif /* __SEGV_PSTKOVF */ + { ARG_XLAT_KNOWN(0x5, "SEGV_ACCADI") }, + { ARG_XLAT_KNOWN(0x6, "SEGV_ADIDERR") }, + { ARG_XLAT_KNOWN(0x7, "SEGV_ADIPERR") }, + { ARG_XLAT_KNOWN(0x8, "SEGV_MTEAERR") }, + { ARG_XLAT_KNOWN(0x9, "SEGV_MTESERR") }, + { ARG_STR(0xa) }, + { ARG_STR(0x499602d2) }, + }; + uint32_t segv_pkey_vecs[] = { 0, 1234567890, 3141592653U }; + struct { + void *lower; + void *upper; + } segv_bnd_vecs[] = { + { 0, 0 }, + { 0, (void *) (uintptr_t) 0xdeadc0debeadfeedULL }, + { (void *) (uintptr_t) 0xfacecafebefeededULL, 0 }, + { (void *) (uintptr_t) 0xbeeffacecafedeadULL, + (void *) (uintptr_t) 0xbadc0deddadfacedULL }, + }; + size_t segv_pkey_pos = 0; + size_t segv_bnd_pos = 0; + memset(sip, -1, sizeof(*sip)); sip->si_signo = SIGSEGV; - sip->si_code = SEGV_PKUERR; sip->si_errno = 0; sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL; - sip->si_pkey = 0xbadc0ded; - do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip); - printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U - ", si_code=" XLAT_FMT ", si_addr=%p, si_pkey=%u}) = %s\n", - XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request, - XLAT_ARGS(SIGSEGV), XLAT_ARGS(SEGV_PKUERR), - sip->si_addr, sip->si_pkey, errstr); + for (size_t i = 0; i < ARRAY_SIZE(segv_codes); i++) { + sip->si_code = segv_codes[i].val; + + switch (sip->si_code) { + case 3: /* SEGV_BNDERR */ +#ifdef HAVE_SIGINFO_T_SI_LOWER + sip->si_lower = segv_bnd_vecs[segv_bnd_pos].lower; + sip->si_upper = segv_bnd_vecs[segv_bnd_pos].upper; +#endif + segv_bnd_pos = (segv_bnd_pos + 1) + % ARRAY_SIZE(segv_bnd_vecs); + break; + case 4: /* SEGV_PKUERR */ +#ifdef HAVE_SIGINFO_T_SI_PKEY + sip->si_pkey = segv_pkey_vecs[segv_pkey_pos]; #endif + segv_pkey_pos = (segv_pkey_pos + 1) + % ARRAY_SIZE(segv_pkey_vecs); + break; + }; + + do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip); + printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U + ", si_code=%s, si_addr=%p%s}) = %s\n", + XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request, + XLAT_ARGS(SIGSEGV), segv_codes[i].str, + sip->si_addr, segv_codes[i].aux ?: "", errstr); + } #ifdef HAVE_SIGINFO_T_SI_SYSCALL memset(sip, -1, sizeof(*sip)); |