Message ID | 20200919080637.259478-2-keescook@chromium.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | selftests/seccomp: Refactor change_syscall() | expand |
On Sat, Sep 19, 2020 at 01:06:34AM -0700, Kees Cook wrote: > 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/ > Signed-off-by: Kees Cook <keescook@chromium.org> > --- > tools/testing/selftests/seccomp/seccomp_bpf.c | 40 +++++++++++++------ > 1 file changed, 27 insertions(+), 13 deletions(-) > > diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c > index bc0fb463c709..c0311b4c736b 100644 > --- a/tools/testing/selftests/seccomp/seccomp_bpf.c > +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c > @@ -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,24 +1975,31 @@ 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 s/sycall/syscall/ Otherwise looks good. Thanks! Acked-by: Christian Brauner <christian.brauner@ubuntu.com> > + * 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) { > /* > * All of the SECCOMP_RET_TRACE behaviors can be tested with either > @@ -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); > -- > 2.25.1 >
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index bc0fb463c709..c0311b4c736b 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -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,24 +1975,31 @@ 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) { /* * All of the SECCOMP_RET_TRACE behaviors can be tested with either @@ -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);
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/ Signed-off-by: Kees Cook <keescook@chromium.org> --- tools/testing/selftests/seccomp/seccomp_bpf.c | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-)