From 7c2210190a26e9dee80aac76fa7f06adf1c21701 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sun, 26 Jul 2015 11:06:53 +0000 Subject: [PATCH] Implement execveat syscall decoding * execve.c (decode_execve): New function. (sys_execve): Use it. (sys_execveat): New function. * linux/dummy.h (sys_execveat): Remove. * tests/execveat.c: New file. * tests/execveat.expected: Likewise. * tests/execveat-v.expected: Likewise. * tests/execveat.test: New test. * tests/Makefile.am (check_PROGRAMS): Add execveat. (TESTS): Add execveat.test. (EXTRA_DIST): Add execveat.expected and execveat-v.expected. * tests/.gitignore: Add execveat. --- execve.c | 34 +++++++++++++++++++++++++--------- linux/dummy.h | 1 - tests/.gitignore | 1 + tests/Makefile.am | 4 ++++ tests/execveat-v.expected | 1 + tests/execveat.c | 31 +++++++++++++++++++++++++++++++ tests/execveat.expected | 1 + tests/execveat.test | 13 +++++++++++++ 8 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 tests/execveat-v.expected create mode 100644 tests/execveat.c create mode 100644 tests/execveat.expected create mode 100755 tests/execveat.test diff --git a/execve.c b/execve.c index 3f49e20f..a8f53f60 100644 --- a/execve.c +++ b/execve.c @@ -40,29 +40,45 @@ printargc(const char *fmt, struct tcb *tcp, long addr) tprintf(fmt, count, count == 1 ? "" : "s"); } -SYS_FUNC(execve) +static void +decode_execve(struct tcb *tcp, const unsigned int index) { - printpath(tcp, tcp->u_arg[0]); + printpath(tcp, tcp->u_arg[index + 0]); tprints(", "); - if (!tcp->u_arg[1] || !verbose(tcp)) - printaddr(tcp->u_arg[1]); + if (!tcp->u_arg[index + 1] || !verbose(tcp)) + printaddr(tcp->u_arg[index + 1]); else { tprints("["); - printargv(tcp, tcp->u_arg[1]); + printargv(tcp, tcp->u_arg[index + 1]); tprints("]"); } tprints(", "); - if (!tcp->u_arg[2] || !verbose(tcp)) - printaddr(tcp->u_arg[2]); + if (!tcp->u_arg[index + 2] || !verbose(tcp)) + printaddr(tcp->u_arg[index + 2]); else if (abbrev(tcp)) - printargc("[/* %d var%s */]", tcp, tcp->u_arg[2]); + printargc("[/* %d var%s */]", tcp, tcp->u_arg[index + 2]); else { tprints("["); - printargv(tcp, tcp->u_arg[2]); + printargv(tcp, tcp->u_arg[index + 2]); tprints("]"); } +} + +SYS_FUNC(execve) +{ + decode_execve(tcp, 0); + + return RVAL_DECODED; +} + +SYS_FUNC(execveat) +{ + print_dirfd(tcp, tcp->u_arg[0]); + decode_execve(tcp, 1); + tprints(", "); + printflags(at_flags, tcp->u_arg[4], "AT_???"); return RVAL_DECODED; } diff --git a/linux/dummy.h b/linux/dummy.h index 0a3db913..4e9db9e5 100644 --- a/linux/dummy.h +++ b/linux/dummy.h @@ -32,7 +32,6 @@ #endif /* still unfinished */ -#define sys_execveat printargs #define sys_ioperm printargs #define sys_iopl printargs #define sys_kcmp printargs diff --git a/tests/.gitignore b/tests/.gitignore index 495a7375..3ea70db1 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,6 +1,7 @@ bpf caps execve +execveat fanotify_mark filter-unavailable getrandom diff --git a/tests/Makefile.am b/tests/Makefile.am index 3da24bf4..bd3f5cfc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -12,6 +12,7 @@ check_PROGRAMS = \ bpf \ caps \ execve \ + execveat \ fanotify_mark \ filter-unavailable \ getrandom \ @@ -67,6 +68,7 @@ TESTS = \ caps.test \ dumpio.test \ execve.test \ + execveat.test \ fanotify_mark.test \ filter-unavailable.test \ getdents.test \ @@ -121,6 +123,8 @@ EXTRA_DIST = init.sh run.sh match.awk \ dumpio.expected \ execve.expected \ execve-v.expected \ + execveat.expected \ + execveat-v.expected \ fanotify_mark.expected \ filter-unavailable.expected \ getdents.awk \ diff --git a/tests/execveat-v.expected b/tests/execveat-v.expected new file mode 100644 index 00000000..ebac879e --- /dev/null +++ b/tests/execveat-v.expected @@ -0,0 +1 @@ +execveat\(AT_FDCWD, "execveat\\nfilename", \["execveat\\nfilename", "first", "second"\], \["foobar=1", "foo\\nbar=2"\], AT_SYMLINK_NOFOLLOW\|AT_EMPTY_PATH\) += -1 .* diff --git a/tests/execveat.c b/tests/execveat.c new file mode 100644 index 00000000..4363c946 --- /dev/null +++ b/tests/execveat.c @@ -0,0 +1,31 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#ifdef __NR_execveat + +#define FILENAME "execveat\nfilename" +static const char * const argv[] = + { FILENAME, "first", "second", NULL, NULL, NULL }; +static const char * const envp[] = + { "foobar=1", "foo\nbar=2", NULL , "", NULL , "", NULL, NULL}; + +int +main(void) +{ + syscall(__NR_execveat, -100, FILENAME, argv, envp, 0x1100); + return 0; +} + +#else + +int +main(void) +{ + return 77; +} + +#endif diff --git a/tests/execveat.expected b/tests/execveat.expected new file mode 100644 index 00000000..7383ed23 --- /dev/null +++ b/tests/execveat.expected @@ -0,0 +1 @@ +execveat\(AT_FDCWD, "execveat\\nfilename", \["execveat\\nfilename", "first", "second"\], \[/\* 2 vars \*/\], AT_SYMLINK_NOFOLLOW\|AT_EMPTY_PATH\) += -1 .* diff --git a/tests/execveat.test b/tests/execveat.test new file mode 100755 index 00000000..b371b079 --- /dev/null +++ b/tests/execveat.test @@ -0,0 +1,13 @@ +#!/bin/sh + +# Check execveat syscall decoding. + +. "${srcdir=.}/init.sh" + +run_prog +run_strace $args +match_grep +run_strace -v $args +match_grep "$LOG" "$srcdir/${ME_%.test}-v.expected" + +exit 0 -- 2.40.0