selftests/seccomp: Record syscall during ptrace entry

In preparation for performing actions during ptrace syscall exit, save
the syscall number during ptrace syscall entry. Some architectures do
no have the syscall number available during ptrace syscall exit.

Suggested-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Link: https://lore.kernel.org/linux-kselftest/20200911181012.171027-1-cascardo@canonical.com/
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
Link: https://lore.kernel.org/lkml/20200921074354.6shkt2e5yhzhj3sn@wittgenstein/
Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
Kees Cook 2020-09-19 00:14:31 -07:00
parent 46138329fa
commit 71c87fbe72
1 changed files with 27 additions and 13 deletions

View File

@ -1949,12 +1949,19 @@ void tracer_seccomp(struct __test_metadata *_metadata, pid_t tracee,
}
FIXTURE(TRACE_syscall) {
struct sock_fprog prog;
pid_t tracer, mytid, mypid, parent;
long syscall_nr;
};
void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
int status, void *args)
{
int ret, nr;
int ret;
unsigned long msg;
static bool entry;
FIXTURE_DATA(TRACE_syscall) *self = args;
/*
* The traditional way to tell PTRACE_SYSCALL entry/exit
@ -1968,23 +1975,30 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY
: PTRACE_EVENTMSG_SYSCALL_EXIT, msg);
if (!entry)
/*
* Some architectures only support setting return values during
* syscall exit under ptrace, and on exit the syscall number may
* no longer be available. Therefore, save the initial sycall
* number here, so it can be examined during both entry and exit
* phases.
*/
if (entry)
self->syscall_nr = get_syscall(_metadata, tracee);
else
return;
nr = get_syscall(_metadata, tracee);
if (nr == __NR_getpid)
switch (self->syscall_nr) {
case __NR_getpid:
change_syscall(_metadata, tracee, __NR_getppid, 0);
if (nr == __NR_gettid)
break;
case __NR_gettid:
change_syscall(_metadata, tracee, -1, 45000);
if (nr == __NR_openat)
break;
case __NR_openat:
change_syscall(_metadata, tracee, -1, -ESRCH);
break;
}
}
FIXTURE(TRACE_syscall) {
struct sock_fprog prog;
pid_t tracer, mytid, mypid, parent;
};
FIXTURE_VARIANT(TRACE_syscall) {
/*
@ -2044,7 +2058,7 @@ FIXTURE_SETUP(TRACE_syscall)
self->tracer = setup_trace_fixture(_metadata,
variant->use_ptrace ? tracer_ptrace
: tracer_seccomp,
NULL, variant->use_ptrace);
self, variant->use_ptrace);
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
ASSERT_EQ(0, ret);