[PATCH v4 4/6] selftest/landlock: Test file_send_sigiotask by sending out-of-bound message

Tahera Fahimi fahimitahera at gmail.com
Fri Sep 6 21:30:06 UTC 2024


This patch adds a test to verify handling the signal scoping mechanism
in file_send_sigiotask by triggering SIGURG through receiving an
out-of-bound message in UNIX sockets.

Signed-off-by: Tahera Fahimi <fahimitahera at gmail.com>
---
V4:
* Using pipe instead of Poll for synchronization.
---
 .../selftests/landlock/scoped_signal_test.c   | 99 +++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/tools/testing/selftests/landlock/scoped_signal_test.c b/tools/testing/selftests/landlock/scoped_signal_test.c
index c71fb83b7147..630f3a515731 100644
--- a/tools/testing/selftests/landlock/scoped_signal_test.c
+++ b/tools/testing/selftests/landlock/scoped_signal_test.c
@@ -269,4 +269,103 @@ TEST(signal_scoping_threads)
 	EXPECT_EQ(0, close(thread_pipe[1]));
 }
 
+#define SOCKET_PATH "/tmp/unix_sock_test"
+
+const short backlog = 10;
+
+static volatile sig_atomic_t signal_received;
+
+static void handle_sigurg(int sig)
+{
+	if (sig == SIGURG)
+		signal_received = 1;
+	else
+		signal_received = -1;
+}
+
+static int setup_signal_handler(int signal)
+{
+	struct sigaction sa;
+
+	sa.sa_handler = handle_sigurg;
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = SA_SIGINFO | SA_RESTART;
+	return sigaction(SIGURG, &sa, NULL);
+}
+
+/*
+ * Sending an out of bound message will trigger the SIGURG signal
+ * through file_send_sigiotask.
+ */
+TEST(test_sigurg_socket)
+{
+	int sock_fd, recv_sock;
+	struct sockaddr_un addr, paddr;
+	socklen_t size;
+	char oob_buf, buffer;
+	int status;
+	int pipe_parent[2], pipe_child[2];
+	pid_t child;
+
+	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
+	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", SOCKET_PATH);
+	unlink(SOCKET_PATH);
+	size = sizeof(addr);
+
+	child = fork();
+	ASSERT_LE(0, child);
+	if (child == 0) {
+		oob_buf = '.';
+
+		ASSERT_EQ(0, close(pipe_parent[1]));
+		ASSERT_EQ(0, close(pipe_child[0]));
+
+		sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+		ASSERT_NE(-1, sock_fd);
+
+		ASSERT_EQ(1, read(pipe_parent[0], &buffer, 1));
+		ASSERT_EQ(0, connect(sock_fd, &addr, sizeof(addr)));
+
+		ASSERT_EQ(1, read(pipe_parent[0], &buffer, 1));
+		ASSERT_NE(-1, send(sock_fd, &oob_buf, 1, MSG_OOB));
+		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
+
+		EXPECT_EQ(0, close(sock_fd));
+
+		_exit(_metadata->exit_code);
+		return;
+	}
+	ASSERT_EQ(0, close(pipe_parent[0]));
+	ASSERT_EQ(0, close(pipe_child[1]));
+
+	sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	ASSERT_NE(-1, sock_fd);
+	ASSERT_EQ(0, bind(sock_fd, &addr, size));
+	ASSERT_EQ(0, listen(sock_fd, backlog));
+
+	ASSERT_NE(-1, setup_signal_handler(SIGURG));
+	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
+	recv_sock = accept(sock_fd, &paddr, &size);
+	ASSERT_NE(-1, recv_sock);
+
+	create_scoped_domain(_metadata, LANDLOCK_SCOPED_SIGNAL);
+
+	ASSERT_NE(-1, fcntl(recv_sock, F_SETOWN, getpid()));
+	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
+	ASSERT_EQ(1, read(pipe_child[0], &buffer, 1));
+	ASSERT_EQ(1, recv(recv_sock, &oob_buf, 1, MSG_OOB));
+
+	ASSERT_EQ(1, signal_received);
+	EXPECT_EQ(0, close(sock_fd));
+	EXPECT_EQ(0, close(recv_sock));
+	ASSERT_EQ(child, waitpid(child, &status, 0));
+	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
+	    WEXITSTATUS(status) != EXIT_SUCCESS)
+		_metadata->exit_code = KSFT_FAIL;
+}
+
 TEST_HARNESS_MAIN
-- 
2.34.1




More information about the Linux-security-module-archive mailing list