]> granicus.if.org Git - strace/commitdiff
signal: SIGSYS: decode si_syscall & si_arch fields
authorMike Frysinger <vapier@gentoo.org>
Tue, 18 Aug 2015 07:24:59 +0000 (03:24 -0400)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 18 Aug 2015 07:51:54 +0000 (07:51 +0000)
When receiving SIGSYS, the si_syscall & si_arch fields are set to known
values, so make sure we decode their values into the symbol settings.
This makes stracing seccomp failures much easier.

* defs.h (syscall_name): New prototype.
* printsiginfo.c: Include linux/audit.h and xlat/audit_arch.h.
(print_si_info): Decode si_syscall & si_arch for SIGSYS.
* syscall.c (undefined_scno_name): Delete.
(syscall_name): New function.
(trace_syscall_entering): Change undefined_scno_name to syscall_name.
(trace_syscall_exiting): Likewise.
* xlat/audit_arch.in: New file.

defs.h
printsiginfo.c
syscall.c
xlat/audit_arch.in [new file with mode: 0644]

diff --git a/defs.h b/defs.h
index 74c8d608c82e7192566c44abe53181907faa3ac3..29c2131e21606c978046d9cab162c8fe644c797f 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -465,6 +465,7 @@ extern void call_summary(FILE *);
 extern void clear_regs(void);
 extern void get_regs(pid_t pid);
 extern int get_scno(struct tcb *tcp);
+extern const char *syscall_name(long scno);
 
 extern int umoven(struct tcb *, long, unsigned int, void *);
 #define umove(pid, addr, objp) \
index e592854c5e55b25ef9da415ed42b73715b1938d4..ce8cf54066362a0c18fb38574bf7e64601248fa6 100644 (file)
@@ -1,9 +1,11 @@
 #include "defs.h"
 
 #include <signal.h>
+#include <linux/audit.h>
 
 #include "printsiginfo.h"
 
+#include "xlat/audit_arch.h"
 #include "xlat/sigbus_codes.h"
 #include "xlat/sigchld_codes.h"
 #include "xlat/sigfpe_codes.h"
@@ -154,9 +156,10 @@ print_si_info(const siginfo_t *sip, bool verbose)
                        break;
 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
                case SIGSYS:
-                       tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u",
+                       tprintf(", si_call_addr=%#lx, si_syscall=__NR_%s, si_arch=",
                                (unsigned long) sip->si_call_addr,
-                               sip->si_syscall, sip->si_arch);
+                               syscall_name(sip->si_syscall));
+                       printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???");
                        break;
 #endif
                default:
index 6aa1cd2d17c00f801b8208dc7b8ab68e6d823fd5..396a7dd7d992d5f23f05040983143d43805b8912 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -745,13 +745,17 @@ shuffle_scno(unsigned long scno)
 # define shuffle_scno(scno) ((long)(scno))
 #endif
 
-static char*
-undefined_scno_name(struct tcb *tcp)
+const char *
+syscall_name(long scno)
 {
        static char buf[sizeof("syscall_%lu") + sizeof(long)*3];
 
-       sprintf(buf, "syscall_%lu", shuffle_scno(tcp->scno));
-       return buf;
+       if (SCNO_IS_VALID(scno))
+               return sysent[scno].sys_name;
+       else {
+               sprintf(buf, "syscall_%lu", shuffle_scno(scno));
+               return buf;
+       }
 }
 
 static long get_regs_error;
@@ -781,7 +785,7 @@ trace_syscall_entering(struct tcb *tcp)
                if (scno_good != 1)
                        tprints("????" /* anti-trigraph gap */ "(");
                else if (tcp->qual_flg & UNDEFINED_SCNO)
-                       tprintf("%s(", undefined_scno_name(tcp));
+                       tprintf("%s(", syscall_name(tcp->scno));
                else
                        tprintf("%s(", tcp->s_ent->sys_name);
                /*
@@ -843,7 +847,7 @@ trace_syscall_entering(struct tcb *tcp)
 
        printleader(tcp);
        if (tcp->qual_flg & UNDEFINED_SCNO)
-               tprintf("%s(", undefined_scno_name(tcp));
+               tprintf("%s(", syscall_name(tcp->scno));
        else
                tprintf("%s(", tcp->s_ent->sys_name);
        if ((tcp->qual_flg & QUAL_RAW) && SEN_exit != tcp->s_ent->sen)
@@ -907,7 +911,7 @@ trace_syscall_exiting(struct tcb *tcp)
                tcp->flags &= ~TCB_REPRINT;
                printleader(tcp);
                if (tcp->qual_flg & UNDEFINED_SCNO)
-                       tprintf("<... %s resumed> ", undefined_scno_name(tcp));
+                       tprintf("<... %s resumed> ", syscall_name(tcp->scno));
                else
                        tprintf("<... %s resumed> ", tcp->s_ent->sys_name);
        }
diff --git a/xlat/audit_arch.in b/xlat/audit_arch.in
new file mode 100644 (file)
index 0000000..aa9ccdb
--- /dev/null
@@ -0,0 +1,35 @@
+AUDIT_ARCH_AARCH64
+AUDIT_ARCH_ALPHA
+AUDIT_ARCH_ARM
+AUDIT_ARCH_ARMEB
+AUDIT_ARCH_CRIS
+AUDIT_ARCH_FRV
+AUDIT_ARCH_I386
+AUDIT_ARCH_IA64
+AUDIT_ARCH_M32R
+AUDIT_ARCH_M68K
+/* Linux had broken linux/elf-em.h for a while.  */
+#ifdef EM_MICROBLAZE
+AUDIT_ARCH_MICROBLAZE
+#endif
+AUDIT_ARCH_MIPS
+AUDIT_ARCH_MIPS64
+AUDIT_ARCH_MIPS64N32
+AUDIT_ARCH_MIPSEL
+AUDIT_ARCH_MIPSEL64
+AUDIT_ARCH_MIPSEL64N32
+AUDIT_ARCH_OPENRISC
+AUDIT_ARCH_PARISC
+AUDIT_ARCH_PARISC64
+AUDIT_ARCH_PPC
+AUDIT_ARCH_PPC64
+AUDIT_ARCH_PPC64LE
+AUDIT_ARCH_S390
+AUDIT_ARCH_S390X
+AUDIT_ARCH_SH
+AUDIT_ARCH_SH64
+AUDIT_ARCH_SHEL
+AUDIT_ARCH_SHEL64
+AUDIT_ARCH_SPARC
+AUDIT_ARCH_SPARC64
+AUDIT_ARCH_X86_64