On 08/03/2017 11:58 AM, Kees Cook wrote: > On Fri, Jul 28, 2017 at 1:55 PM, Tyler Hicks <tyhicks@xxxxxxxxxxxxx> wrote: >> 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@xxxxxxxxxxxxx> >> --- >> >> * Changes since v4: >> - This is a new patch >> >> tools/testing/selftests/seccomp/seccomp_bpf.c | 58 +++++++++++++++++++++++++++ >> 1 file changed, 58 insertions(+) >> >> diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c >> index 040e875..d221437 100644 >> --- a/tools/testing/selftests/seccomp/seccomp_bpf.c >> +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c >> @@ -1885,6 +1885,64 @@ TEST(seccomp_syscall_mode_lock) >> } >> } >> >> +/* Test detection of known and unknown filter flags. Userspace needs to be able >> + * to check if a filter flag is support by the current kernel and a good way of >> + * doing that is by attempting to enter filter mode, with the flag bit in >> + * question set, and a NULL pointer for the _args_ parameter. EFAULT indicates >> + * that the flag is valid and EINVAL indicates that the flag is invalid. >> + */ >> +TEST(detect_seccomp_filter_flags) >> +{ >> + unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC, >> + SECCOMP_FILTER_FLAG_LOG }; >> + unsigned int flag, all_flags; >> + int i; >> + long ret; >> + >> + /* Test detection of known-good filter flags */ >> + for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) { >> + flag = flags[i]; >> + ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); >> + ASSERT_NE(ENOSYS, errno) { >> + TH_LOG("Kernel does not support seccomp syscall!"); >> + } >> + EXPECT_EQ(-1, ret); >> + EXPECT_EQ(EFAULT, errno) { >> + TH_LOG("Failed to detect that a known-good filter flag (0x%X) is supported!", >> + flag); >> + } >> + >> + all_flags |= flag; >> + } >> + >> + /* Test detection of all known-good filter flags */ >> + ret = seccomp(SECCOMP_SET_MODE_FILTER, all_flags, NULL); >> + EXPECT_EQ(-1, ret); >> + EXPECT_EQ(EFAULT, errno) { >> + TH_LOG("Failed to detect that all known-good filter flags (0x%X) are supported!", >> + all_flags); >> + } >> + >> + /* Test detection of an unknown filter flag */ >> + flag = -1; >> + ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); >> + EXPECT_EQ(-1, ret); >> + EXPECT_EQ(EINVAL, errno) { >> + TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported!", >> + flag); >> + } >> + >> + /* Test detection of an unknown filter flag that may simply need to be >> + * added to this test */ >> + flag = flags[ARRAY_SIZE(flags) - 1] << 1; >> + ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); >> + EXPECT_EQ(-1, ret); >> + EXPECT_EQ(EINVAL, errno) { >> + 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?", >> + flag); >> + } >> +} >> + >> TEST(TSYNC_first) >> { >> struct sock_filter filter[] = { >> -- >> 2.7.4 >> > > This is good, yes. Can you actually move it earlier in the series, so > it will pass before adding ..._FLAG_LOG, and then the patch adding > ..._FLAG_LOG will add it to this test too? Yeah, that's the correct way to order it. Tyler > > Thanks! > > -Kees >
Attachment:
signature.asc
Description: OpenPGP digital signature