* 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.
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;
}
#endif
/* still unfinished */
-#define sys_execveat printargs
#define sys_ioperm printargs
#define sys_iopl printargs
#define sys_kcmp printargs
bpf
caps
execve
+execveat
fanotify_mark
filter-unavailable
getrandom
bpf \
caps \
execve \
+ execveat \
fanotify_mark \
filter-unavailable \
getrandom \
caps.test \
dumpio.test \
execve.test \
+ execveat.test \
fanotify_mark.test \
filter-unavailable.test \
getdents.test \
dumpio.expected \
execve.expected \
execve-v.expected \
+ execveat.expected \
+ execveat-v.expected \
fanotify_mark.expected \
filter-unavailable.expected \
getdents.awk \
--- /dev/null
+execveat\(AT_FDCWD, "execveat\\nfilename", \["execveat\\nfilename", "first", "second"\], \["foobar=1", "foo\\nbar=2"\], AT_SYMLINK_NOFOLLOW\|AT_EMPTY_PATH\) += -1 .*
--- /dev/null
+#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
--- /dev/null
+execveat\(AT_FDCWD, "execveat\\nfilename", \["execveat\\nfilename", "first", "second"\], \[/\* 2 vars \*/\], AT_SYMLINK_NOFOLLOW\|AT_EMPTY_PATH\) += -1 .*
--- /dev/null
+#!/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