selftests/landlock: Check IOCTL restrictions for named UNIX domain sockets
authorGünther Noack <gnoack@google.com>
Fri, 19 Apr 2024 16:11:17 +0000 (16:11 +0000)
committerMickaël Salaün <mic@digikod.net>
Mon, 13 May 2024 04:58:32 +0000 (06:58 +0200)
The LANDLOCK_ACCESS_FS_IOCTL_DEV right should have no effect on the use of
named UNIX domain sockets.

Suggested-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://lore.kernel.org/r/20240419161122.2023765-7-gnoack@google.com
[mic: Add missing stddef.h for offsetof()]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
tools/testing/selftests/landlock/fs_test.c

index b133020c7761c7e0276b031f6c838aaa7a54d2a7..8443f329ac7cc5ad5eda52afde1d6469c6d2dc92 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/landlock.h>
 #include <linux/magic.h>
 #include <sched.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/capability.h>
 #include <sys/mount.h>
 #include <sys/prctl.h>
 #include <sys/sendfile.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
+#include <sys/un.h>
 #include <sys/vfs.h>
 #include <unistd.h>
 
@@ -3985,6 +3988,56 @@ TEST_F_FORK(layout1, named_pipe_ioctl)
        ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0));
 }
 
+/* For named UNIX domain sockets, no IOCTL restrictions apply. */
+TEST_F_FORK(layout1, named_unix_domain_socket_ioctl)
+{
+       const char *const path = file1_s1d1;
+       int srv_fd, cli_fd, ruleset_fd;
+       socklen_t size;
+       struct sockaddr_un srv_un, cli_un;
+       const struct landlock_ruleset_attr attr = {
+               .handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV,
+       };
+
+       /* Sets up a server */
+       srv_un.sun_family = AF_UNIX;
+       strncpy(srv_un.sun_path, path, sizeof(srv_un.sun_path));
+
+       ASSERT_EQ(0, unlink(path));
+       srv_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       ASSERT_LE(0, srv_fd);
+
+       size = offsetof(struct sockaddr_un, sun_path) + strlen(srv_un.sun_path);
+       ASSERT_EQ(0, bind(srv_fd, (struct sockaddr *)&srv_un, size));
+       ASSERT_EQ(0, listen(srv_fd, 10 /* qlen */));
+
+       /* Enables Landlock. */
+       ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
+       ASSERT_LE(0, ruleset_fd);
+       enforce_ruleset(_metadata, ruleset_fd);
+       ASSERT_EQ(0, close(ruleset_fd));
+
+       /* Sets up a client connection to it */
+       cli_un.sun_family = AF_UNIX;
+       cli_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       ASSERT_LE(0, cli_fd);
+
+       size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path);
+       ASSERT_EQ(0, bind(cli_fd, (struct sockaddr *)&cli_un, size));
+
+       bzero(&cli_un, sizeof(cli_un));
+       cli_un.sun_family = AF_UNIX;
+       strncpy(cli_un.sun_path, path, sizeof(cli_un.sun_path));
+       size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path);
+
+       ASSERT_EQ(0, connect(cli_fd, (struct sockaddr *)&cli_un, size));
+
+       /* FIONREAD and other IOCTLs should not be forbidden. */
+       EXPECT_EQ(0, test_fionread_ioctl(cli_fd));
+
+       ASSERT_EQ(0, close(cli_fd));
+}
+
 /* clang-format off */
 FIXTURE(ioctl) {};