Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b7ea5b5 authored by Tyler Hicks's avatar Tyler Hicks Committed by Kees Cook
Browse files

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: default avatarTyler Hicks <tyhicks@canonical.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent 0ddec0fc
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -1835,6 +1835,66 @@ 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 supported 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 };
	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[] = {