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.
diff --git a/execve.c b/execve.c
index 3f49e20..a8f53f6 100644
--- a/execve.c
+++ b/execve.c
@@ -40,29 +40,45 @@
tprintf(fmt, count, count == 1 ? "" : "s");
}
+static void
+decode_execve(struct tcb *tcp, const unsigned int index)
+{
+ printpath(tcp, tcp->u_arg[index + 0]);
+ tprints(", ");
+
+ if (!tcp->u_arg[index + 1] || !verbose(tcp))
+ printaddr(tcp->u_arg[index + 1]);
+ else {
+ tprints("[");
+ printargv(tcp, tcp->u_arg[index + 1]);
+ tprints("]");
+ }
+ tprints(", ");
+
+ 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[index + 2]);
+ else {
+ tprints("[");
+ printargv(tcp, tcp->u_arg[index + 2]);
+ tprints("]");
+ }
+}
+
SYS_FUNC(execve)
{
- printpath(tcp, tcp->u_arg[0]);
- tprints(", ");
+ decode_execve(tcp, 0);
- if (!tcp->u_arg[1] || !verbose(tcp))
- printaddr(tcp->u_arg[1]);
- else {
- tprints("[");
- printargv(tcp, tcp->u_arg[1]);
- tprints("]");
- }
- tprints(", ");
+ return RVAL_DECODED;
+}
- if (!tcp->u_arg[2] || !verbose(tcp))
- printaddr(tcp->u_arg[2]);
- else if (abbrev(tcp))
- printargc("[/* %d var%s */]", tcp, tcp->u_arg[2]);
- else {
- tprints("[");
- printargv(tcp, tcp->u_arg[2]);
- tprints("]");
- }
+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 0a3db91..4e9db9e 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 495a737..3ea70db 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 3da24bf..bd3f5cf 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,6 +12,7 @@
bpf \
caps \
execve \
+ execveat \
fanotify_mark \
filter-unavailable \
getrandom \
@@ -67,6 +68,7 @@
caps.test \
dumpio.test \
execve.test \
+ execveat.test \
fanotify_mark.test \
filter-unavailable.test \
getdents.test \
@@ -121,6 +123,8 @@
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 0000000..ebac879
--- /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 0000000..4363c94
--- /dev/null
+++ b/tests/execveat.c
@@ -0,0 +1,31 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#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 0000000..7383ed2
--- /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 0000000..b371b07
--- /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