diff options
author | Tyler Hicks <tyhicks@canonical.com> | 2017-08-11 00:33:55 -0400 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2017-08-14 16:46:46 -0400 |
commit | 2b7ea5b5b5799f2878ed454bb48032bed6d101d3 (patch) | |
tree | 5aaae1f8f90097ea54686faa783ac0e72b851e3f /tools | |
parent | 0ddec0fc8900201c0897b87b762b7c420436662f (diff) |
seccomp: Selftest for detection of filter flag support
Userspace needs to be able to reliably detect the support of a filter
flag. A good way of doing that is by attempting to enter filter mode,
with the flag bit(s) in question set, and a NULL pointer for the args
parameter of seccomp(2). EFAULT indicates that the flag is valid and
EINVAL indicates that the flag is invalid.
This patch adds a selftest that can be used to test this method of
detection in userspace.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/seccomp/seccomp_bpf.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 1f2888f6678b..abf708e09892 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c | |||
@@ -1835,6 +1835,66 @@ TEST(seccomp_syscall_mode_lock) | |||
1835 | } | 1835 | } |
1836 | } | 1836 | } |
1837 | 1837 | ||
1838 | /* | ||
1839 | * Test detection of known and unknown filter flags. Userspace needs to be able | ||
1840 | * to check if a filter flag is supported by the current kernel and a good way | ||
1841 | * of doing that is by attempting to enter filter mode, with the flag bit in | ||
1842 | * question set, and a NULL pointer for the _args_ parameter. EFAULT indicates | ||
1843 | * that the flag is valid and EINVAL indicates that the flag is invalid. | ||
1844 | */ | ||
1845 | TEST(detect_seccomp_filter_flags) | ||
1846 | { | ||
1847 | unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC }; | ||
1848 | unsigned int flag, all_flags; | ||
1849 | int i; | ||
1850 | long ret; | ||
1851 | |||
1852 | /* Test detection of known-good filter flags */ | ||
1853 | for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) { | ||
1854 | flag = flags[i]; | ||
1855 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); | ||
1856 | ASSERT_NE(ENOSYS, errno) { | ||
1857 | TH_LOG("Kernel does not support seccomp syscall!"); | ||
1858 | } | ||
1859 | EXPECT_EQ(-1, ret); | ||
1860 | EXPECT_EQ(EFAULT, errno) { | ||
1861 | TH_LOG("Failed to detect that a known-good filter flag (0x%X) is supported!", | ||
1862 | flag); | ||
1863 | } | ||
1864 | |||
1865 | all_flags |= flag; | ||
1866 | } | ||
1867 | |||
1868 | /* Test detection of all known-good filter flags */ | ||
1869 | ret = seccomp(SECCOMP_SET_MODE_FILTER, all_flags, NULL); | ||
1870 | EXPECT_EQ(-1, ret); | ||
1871 | EXPECT_EQ(EFAULT, errno) { | ||
1872 | TH_LOG("Failed to detect that all known-good filter flags (0x%X) are supported!", | ||
1873 | all_flags); | ||
1874 | } | ||
1875 | |||
1876 | /* Test detection of an unknown filter flag */ | ||
1877 | flag = -1; | ||
1878 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); | ||
1879 | EXPECT_EQ(-1, ret); | ||
1880 | EXPECT_EQ(EINVAL, errno) { | ||
1881 | TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported!", | ||
1882 | flag); | ||
1883 | } | ||
1884 | |||
1885 | /* | ||
1886 | * Test detection of an unknown filter flag that may simply need to be | ||
1887 | * added to this test | ||
1888 | */ | ||
1889 | flag = flags[ARRAY_SIZE(flags) - 1] << 1; | ||
1890 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); | ||
1891 | EXPECT_EQ(-1, ret); | ||
1892 | EXPECT_EQ(EINVAL, errno) { | ||
1893 | TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported! Does a new flag need to be added to this test?", | ||
1894 | flag); | ||
1895 | } | ||
1896 | } | ||
1897 | |||
1838 | TEST(TSYNC_first) | 1898 | TEST(TSYNC_first) |
1839 | { | 1899 | { |
1840 | struct sock_filter filter[] = { | 1900 | struct sock_filter filter[] = { |