Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+27 -13
+27 -13
tools/testing/selftests/seccomp/seccomp_bpf.c
··· 1949 1949 1950 1950 } 1951 1951 1952 + FIXTURE(TRACE_syscall) { 1953 + struct sock_fprog prog; 1954 + pid_t tracer, mytid, mypid, parent; 1955 + long syscall_nr; 1956 + }; 1957 + 1952 1958 void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee, 1953 1959 int status, void *args) 1954 1960 { 1955 - int ret, nr; 1961 + int ret; 1956 1962 unsigned long msg; 1957 1963 static bool entry; 1964 + FIXTURE_DATA(TRACE_syscall) *self = args; 1958 1965 1959 1966 /* 1960 1967 * The traditional way to tell PTRACE_SYSCALL entry/exit ··· 1975 1968 EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY 1976 1969 : PTRACE_EVENTMSG_SYSCALL_EXIT, msg); 1977 1970 1978 - if (!entry) 1971 + /* 1972 + * Some architectures only support setting return values during 1973 + * syscall exit under ptrace, and on exit the syscall number may 1974 + * no longer be available. Therefore, save the initial sycall 1975 + * number here, so it can be examined during both entry and exit 1976 + * phases. 1977 + */ 1978 + if (entry) 1979 + self->syscall_nr = get_syscall(_metadata, tracee); 1980 + else 1979 1981 return; 1980 1982 1981 - nr = get_syscall(_metadata, tracee); 1982 - 1983 - if (nr == __NR_getpid) 1983 + switch (self->syscall_nr) { 1984 + case __NR_getpid: 1984 1985 change_syscall(_metadata, tracee, __NR_getppid, 0); 1985 - if (nr == __NR_gettid) 1986 + break; 1987 + case __NR_gettid: 1986 1988 change_syscall(_metadata, tracee, -1, 45000); 1987 - if (nr == __NR_openat) 1989 + break; 1990 + case __NR_openat: 1988 1991 change_syscall(_metadata, tracee, -1, -ESRCH); 1992 + break; 1993 + } 1989 1994 } 1990 - 1991 - FIXTURE(TRACE_syscall) { 1992 - struct sock_fprog prog; 1993 - pid_t tracer, mytid, mypid, parent; 1994 - }; 1995 1995 1996 1996 FIXTURE_VARIANT(TRACE_syscall) { 1997 1997 /* ··· 2058 2044 self->tracer = setup_trace_fixture(_metadata, 2059 2045 variant->use_ptrace ? tracer_ptrace 2060 2046 : tracer_seccomp, 2061 - NULL, variant->use_ptrace); 2047 + self, variant->use_ptrace); 2062 2048 2063 2049 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); 2064 2050 ASSERT_EQ(0, ret);