Skip to content

Commit 0bf18a0

Browse files
keesshuahkh
authored andcommitted
selftests/seccomp: Refactor to use fixture variants
Now that the selftest harness has variants, use them to eliminate a bunch of copy/paste duplication. Cc: Andy Lutomirski <[email protected]> Cc: Will Drewry <[email protected]> Cc: Jakub Kicinski <[email protected]> Signed-off-by: Kees Cook <[email protected]> Acked-by: Jakub Kicinski <[email protected]> Signed-off-by: Shuah Khan <[email protected]>
1 parent 3e4cd8e commit 0bf18a0

File tree

1 file changed

+42
-157
lines changed

1 file changed

+42
-157
lines changed

tools/testing/selftests/seccomp/seccomp_bpf.c

Lines changed: 42 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,7 @@ pid_t setup_trace_fixture(struct __test_metadata *_metadata,
14701470

14711471
return tracer_pid;
14721472
}
1473+
14731474
void teardown_trace_fixture(struct __test_metadata *_metadata,
14741475
pid_t tracer)
14751476
{
@@ -1750,7 +1751,7 @@ void change_syscall(struct __test_metadata *_metadata,
17501751
EXPECT_EQ(0, ret);
17511752
}
17521753

1753-
void tracer_syscall(struct __test_metadata *_metadata, pid_t tracee,
1754+
void tracer_seccomp(struct __test_metadata *_metadata, pid_t tracee,
17541755
int status, void *args)
17551756
{
17561757
int ret;
@@ -1827,6 +1828,24 @@ FIXTURE(TRACE_syscall) {
18271828
pid_t tracer, mytid, mypid, parent;
18281829
};
18291830

1831+
FIXTURE_VARIANT(TRACE_syscall) {
1832+
/*
1833+
* All of the SECCOMP_RET_TRACE behaviors can be tested with either
1834+
* SECCOMP_RET_TRACE+PTRACE_CONT or plain ptrace()+PTRACE_SYSCALL.
1835+
* This indicates if we should use SECCOMP_RET_TRACE (false), or
1836+
* ptrace (true).
1837+
*/
1838+
bool use_ptrace;
1839+
};
1840+
1841+
FIXTURE_VARIANT_ADD(TRACE_syscall, ptrace) {
1842+
.use_ptrace = true,
1843+
};
1844+
1845+
FIXTURE_VARIANT_ADD(TRACE_syscall, seccomp) {
1846+
.use_ptrace = false,
1847+
};
1848+
18301849
FIXTURE_SETUP(TRACE_syscall)
18311850
{
18321851
struct sock_filter filter[] = {
@@ -1842,12 +1861,11 @@ FIXTURE_SETUP(TRACE_syscall)
18421861
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1005),
18431862
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
18441863
};
1845-
1846-
memset(&self->prog, 0, sizeof(self->prog));
1847-
self->prog.filter = malloc(sizeof(filter));
1848-
ASSERT_NE(NULL, self->prog.filter);
1849-
memcpy(self->prog.filter, filter, sizeof(filter));
1850-
self->prog.len = (unsigned short)ARRAY_SIZE(filter);
1864+
struct sock_fprog prog = {
1865+
.len = (unsigned short)ARRAY_SIZE(filter),
1866+
.filter = filter,
1867+
};
1868+
long ret;
18511869

18521870
/* Prepare some testable syscall results. */
18531871
self->mytid = syscall(__NR_gettid);
@@ -1865,109 +1883,53 @@ FIXTURE_SETUP(TRACE_syscall)
18651883
ASSERT_NE(self->parent, self->mypid);
18661884

18671885
/* Launch tracer. */
1868-
self->tracer = setup_trace_fixture(_metadata, tracer_syscall, NULL,
1869-
false);
1870-
}
1871-
1872-
FIXTURE_TEARDOWN(TRACE_syscall)
1873-
{
1874-
teardown_trace_fixture(_metadata, self->tracer);
1875-
if (self->prog.filter)
1876-
free(self->prog.filter);
1877-
}
1886+
self->tracer = setup_trace_fixture(_metadata,
1887+
variant->use_ptrace ? tracer_ptrace
1888+
: tracer_seccomp,
1889+
NULL, variant->use_ptrace);
18781890

1879-
TEST_F(TRACE_syscall, ptrace_syscall_redirected)
1880-
{
1881-
/* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
1882-
teardown_trace_fixture(_metadata, self->tracer);
1883-
self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
1884-
true);
1885-
1886-
/* Tracer will redirect getpid to getppid. */
1887-
EXPECT_NE(self->mypid, syscall(__NR_getpid));
1888-
}
1891+
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1892+
ASSERT_EQ(0, ret);
18891893

1890-
TEST_F(TRACE_syscall, ptrace_syscall_errno)
1891-
{
1892-
/* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
1893-
teardown_trace_fixture(_metadata, self->tracer);
1894-
self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
1895-
true);
1894+
if (variant->use_ptrace)
1895+
return;
18961896

1897-
/* Tracer should skip the open syscall, resulting in ESRCH. */
1898-
EXPECT_SYSCALL_RETURN(-ESRCH, syscall(__NR_openat));
1897+
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1898+
ASSERT_EQ(0, ret);
18991899
}
19001900

1901-
TEST_F(TRACE_syscall, ptrace_syscall_faked)
1901+
FIXTURE_TEARDOWN(TRACE_syscall)
19021902
{
1903-
/* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
19041903
teardown_trace_fixture(_metadata, self->tracer);
1905-
self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
1906-
true);
1907-
1908-
/* Tracer should skip the gettid syscall, resulting fake pid. */
1909-
EXPECT_SYSCALL_RETURN(45000, syscall(__NR_gettid));
19101904
}
19111905

19121906
TEST_F(TRACE_syscall, syscall_allowed)
19131907
{
1914-
long ret;
1915-
1916-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1917-
ASSERT_EQ(0, ret);
1918-
1919-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1920-
ASSERT_EQ(0, ret);
1921-
19221908
/* getppid works as expected (no changes). */
19231909
EXPECT_EQ(self->parent, syscall(__NR_getppid));
19241910
EXPECT_NE(self->mypid, syscall(__NR_getppid));
19251911
}
19261912

19271913
TEST_F(TRACE_syscall, syscall_redirected)
19281914
{
1929-
long ret;
1930-
1931-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1932-
ASSERT_EQ(0, ret);
1933-
1934-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1935-
ASSERT_EQ(0, ret);
1936-
19371915
/* getpid has been redirected to getppid as expected. */
19381916
EXPECT_EQ(self->parent, syscall(__NR_getpid));
19391917
EXPECT_NE(self->mypid, syscall(__NR_getpid));
19401918
}
19411919

19421920
TEST_F(TRACE_syscall, syscall_errno)
19431921
{
1944-
long ret;
1945-
1946-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1947-
ASSERT_EQ(0, ret);
1948-
1949-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1950-
ASSERT_EQ(0, ret);
1951-
1952-
/* openat has been skipped and an errno return. */
1922+
/* Tracer should skip the open syscall, resulting in ESRCH. */
19531923
EXPECT_SYSCALL_RETURN(-ESRCH, syscall(__NR_openat));
19541924
}
19551925

19561926
TEST_F(TRACE_syscall, syscall_faked)
19571927
{
1958-
long ret;
1959-
1960-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1961-
ASSERT_EQ(0, ret);
1962-
1963-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1964-
ASSERT_EQ(0, ret);
1965-
1966-
/* gettid has been skipped and an altered return value stored. */
1928+
/* Tracer skips the gettid syscall and store altered return value. */
19671929
EXPECT_SYSCALL_RETURN(45000, syscall(__NR_gettid));
19681930
}
19691931

1970-
TEST_F(TRACE_syscall, skip_after_RET_TRACE)
1932+
TEST_F(TRACE_syscall, skip_after)
19711933
{
19721934
struct sock_filter filter[] = {
19731935
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
@@ -1982,14 +1944,7 @@ TEST_F(TRACE_syscall, skip_after_RET_TRACE)
19821944
};
19831945
long ret;
19841946

1985-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1986-
ASSERT_EQ(0, ret);
1987-
1988-
/* Install fixture filter. */
1989-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1990-
ASSERT_EQ(0, ret);
1991-
1992-
/* Install "errno on getppid" filter. */
1947+
/* Install additional "errno on getppid" filter. */
19931948
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
19941949
ASSERT_EQ(0, ret);
19951950

@@ -1999,7 +1954,7 @@ TEST_F(TRACE_syscall, skip_after_RET_TRACE)
19991954
EXPECT_EQ(EPERM, errno);
20001955
}
20011956

2002-
TEST_F_SIGNAL(TRACE_syscall, kill_after_RET_TRACE, SIGSYS)
1957+
TEST_F_SIGNAL(TRACE_syscall, kill_after, SIGSYS)
20031958
{
20041959
struct sock_filter filter[] = {
20051960
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
@@ -2014,77 +1969,7 @@ TEST_F_SIGNAL(TRACE_syscall, kill_after_RET_TRACE, SIGSYS)
20141969
};
20151970
long ret;
20161971

2017-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
2018-
ASSERT_EQ(0, ret);
2019-
2020-
/* Install fixture filter. */
2021-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
2022-
ASSERT_EQ(0, ret);
2023-
2024-
/* Install "death on getppid" filter. */
2025-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
2026-
ASSERT_EQ(0, ret);
2027-
2028-
/* Tracer will redirect getpid to getppid, and we should die. */
2029-
EXPECT_NE(self->mypid, syscall(__NR_getpid));
2030-
}
2031-
2032-
TEST_F(TRACE_syscall, skip_after_ptrace)
2033-
{
2034-
struct sock_filter filter[] = {
2035-
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
2036-
offsetof(struct seccomp_data, nr)),
2037-
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
2038-
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EPERM),
2039-
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
2040-
};
2041-
struct sock_fprog prog = {
2042-
.len = (unsigned short)ARRAY_SIZE(filter),
2043-
.filter = filter,
2044-
};
2045-
long ret;
2046-
2047-
/* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
2048-
teardown_trace_fixture(_metadata, self->tracer);
2049-
self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
2050-
true);
2051-
2052-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
2053-
ASSERT_EQ(0, ret);
2054-
2055-
/* Install "errno on getppid" filter. */
2056-
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
2057-
ASSERT_EQ(0, ret);
2058-
2059-
/* Tracer will redirect getpid to getppid, and we should see EPERM. */
2060-
EXPECT_EQ(-1, syscall(__NR_getpid));
2061-
EXPECT_EQ(EPERM, errno);
2062-
}
2063-
2064-
TEST_F_SIGNAL(TRACE_syscall, kill_after_ptrace, SIGSYS)
2065-
{
2066-
struct sock_filter filter[] = {
2067-
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
2068-
offsetof(struct seccomp_data, nr)),
2069-
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
2070-
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
2071-
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
2072-
};
2073-
struct sock_fprog prog = {
2074-
.len = (unsigned short)ARRAY_SIZE(filter),
2075-
.filter = filter,
2076-
};
2077-
long ret;
2078-
2079-
/* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
2080-
teardown_trace_fixture(_metadata, self->tracer);
2081-
self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
2082-
true);
2083-
2084-
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
2085-
ASSERT_EQ(0, ret);
2086-
2087-
/* Install "death on getppid" filter. */
1972+
/* Install additional "death on getppid" filter. */
20881973
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
20891974
ASSERT_EQ(0, ret);
20901975

0 commit comments

Comments
 (0)