@@ -1470,6 +1470,7 @@ pid_t setup_trace_fixture(struct __test_metadata *_metadata,
1470
1470
1471
1471
return tracer_pid ;
1472
1472
}
1473
+
1473
1474
void teardown_trace_fixture (struct __test_metadata * _metadata ,
1474
1475
pid_t tracer )
1475
1476
{
@@ -1750,7 +1751,7 @@ void change_syscall(struct __test_metadata *_metadata,
1750
1751
EXPECT_EQ (0 , ret );
1751
1752
}
1752
1753
1753
- void tracer_syscall (struct __test_metadata * _metadata , pid_t tracee ,
1754
+ void tracer_seccomp (struct __test_metadata * _metadata , pid_t tracee ,
1754
1755
int status , void * args )
1755
1756
{
1756
1757
int ret ;
@@ -1827,6 +1828,24 @@ FIXTURE(TRACE_syscall) {
1827
1828
pid_t tracer , mytid , mypid , parent ;
1828
1829
};
1829
1830
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
+
1830
1849
FIXTURE_SETUP (TRACE_syscall )
1831
1850
{
1832
1851
struct sock_filter filter [] = {
@@ -1842,12 +1861,11 @@ FIXTURE_SETUP(TRACE_syscall)
1842
1861
BPF_STMT (BPF_RET |BPF_K , SECCOMP_RET_TRACE | 0x1005 ),
1843
1862
BPF_STMT (BPF_RET |BPF_K , SECCOMP_RET_ALLOW ),
1844
1863
};
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 ;
1851
1869
1852
1870
/* Prepare some testable syscall results. */
1853
1871
self -> mytid = syscall (__NR_gettid );
@@ -1865,109 +1883,53 @@ FIXTURE_SETUP(TRACE_syscall)
1865
1883
ASSERT_NE (self -> parent , self -> mypid );
1866
1884
1867
1885
/* 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 );
1878
1890
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 );
1889
1893
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 ;
1896
1896
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 );
1899
1899
}
1900
1900
1901
- TEST_F (TRACE_syscall , ptrace_syscall_faked )
1901
+ FIXTURE_TEARDOWN (TRACE_syscall )
1902
1902
{
1903
- /* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
1904
1903
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 ));
1910
1904
}
1911
1905
1912
1906
TEST_F (TRACE_syscall , syscall_allowed )
1913
1907
{
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
-
1922
1908
/* getppid works as expected (no changes). */
1923
1909
EXPECT_EQ (self -> parent , syscall (__NR_getppid ));
1924
1910
EXPECT_NE (self -> mypid , syscall (__NR_getppid ));
1925
1911
}
1926
1912
1927
1913
TEST_F (TRACE_syscall , syscall_redirected )
1928
1914
{
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
-
1937
1915
/* getpid has been redirected to getppid as expected. */
1938
1916
EXPECT_EQ (self -> parent , syscall (__NR_getpid ));
1939
1917
EXPECT_NE (self -> mypid , syscall (__NR_getpid ));
1940
1918
}
1941
1919
1942
1920
TEST_F (TRACE_syscall , syscall_errno )
1943
1921
{
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. */
1953
1923
EXPECT_SYSCALL_RETURN (- ESRCH , syscall (__NR_openat ));
1954
1924
}
1955
1925
1956
1926
TEST_F (TRACE_syscall , syscall_faked )
1957
1927
{
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. */
1967
1929
EXPECT_SYSCALL_RETURN (45000 , syscall (__NR_gettid ));
1968
1930
}
1969
1931
1970
- TEST_F (TRACE_syscall , skip_after_RET_TRACE )
1932
+ TEST_F (TRACE_syscall , skip_after )
1971
1933
{
1972
1934
struct sock_filter filter [] = {
1973
1935
BPF_STMT (BPF_LD |BPF_W |BPF_ABS ,
@@ -1982,14 +1944,7 @@ TEST_F(TRACE_syscall, skip_after_RET_TRACE)
1982
1944
};
1983
1945
long ret ;
1984
1946
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. */
1993
1948
ret = prctl (PR_SET_SECCOMP , SECCOMP_MODE_FILTER , & prog , 0 , 0 );
1994
1949
ASSERT_EQ (0 , ret );
1995
1950
@@ -1999,7 +1954,7 @@ TEST_F(TRACE_syscall, skip_after_RET_TRACE)
1999
1954
EXPECT_EQ (EPERM , errno );
2000
1955
}
2001
1956
2002
- TEST_F_SIGNAL (TRACE_syscall , kill_after_RET_TRACE , SIGSYS )
1957
+ TEST_F_SIGNAL (TRACE_syscall , kill_after , SIGSYS )
2003
1958
{
2004
1959
struct sock_filter filter [] = {
2005
1960
BPF_STMT (BPF_LD |BPF_W |BPF_ABS ,
@@ -2014,77 +1969,7 @@ TEST_F_SIGNAL(TRACE_syscall, kill_after_RET_TRACE, SIGSYS)
2014
1969
};
2015
1970
long ret ;
2016
1971
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. */
2088
1973
ret = prctl (PR_SET_SECCOMP , SECCOMP_MODE_FILTER , & prog , 0 , 0 );
2089
1974
ASSERT_EQ (0 , ret );
2090
1975
0 commit comments