Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/landlock: Test inherited restriction of abstract UNIX socket

A socket can be shared between multiple processes, so it can connect and
send data to them. Provide a test scenario where a sandboxed process
inherits a socket's file descriptor. The process cannot connect or send
data to the inherited socket since the process is scoped.

Test coverage for security/landlock is 92.0% of 1013 lines according to
gcc/gcov-14.

Signed-off-by: Tahera Fahimi <fahimitahera@gmail.com>
Link: https://lore.kernel.org/r/1428574deec13603b6ab2f2ed68ecbfa3b63bcb3.1725494372.git.fahimitahera@gmail.com
[mic: Remove negative ASSERT, fix potential race condition because of
closed connections, remove useless buffer, add test coverage]
Signed-off-by: Mickaël Salaün <mic@digikod.net>

authored by

Tahera Fahimi and committed by
Mickaël Salaün
644a7285 d1cc0ef8

+64
+64
tools/testing/selftests/landlock/scoped_abstract_unix_test.c
··· 974 974 _metadata->exit_code = KSFT_FAIL; 975 975 } 976 976 977 + TEST(self_connect) 978 + { 979 + struct service_fixture connected_addr, non_connected_addr; 980 + int connected_socket, non_connected_socket, status; 981 + pid_t child; 982 + 983 + drop_caps(_metadata); 984 + memset(&connected_addr, 0, sizeof(connected_addr)); 985 + set_unix_address(&connected_addr, 0); 986 + memset(&non_connected_addr, 0, sizeof(non_connected_addr)); 987 + set_unix_address(&non_connected_addr, 1); 988 + 989 + connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 990 + non_connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 991 + ASSERT_LE(0, connected_socket); 992 + ASSERT_LE(0, non_connected_socket); 993 + 994 + ASSERT_EQ(0, bind(connected_socket, &connected_addr.unix_addr, 995 + connected_addr.unix_addr_len)); 996 + ASSERT_EQ(0, bind(non_connected_socket, &non_connected_addr.unix_addr, 997 + non_connected_addr.unix_addr_len)); 998 + 999 + child = fork(); 1000 + ASSERT_LE(0, child); 1001 + if (child == 0) { 1002 + /* Child's domain is scoped. */ 1003 + create_scoped_domain(_metadata, 1004 + LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 1005 + 1006 + /* 1007 + * The child inherits the sockets, and cannot connect or 1008 + * send data to them. 1009 + */ 1010 + ASSERT_EQ(-1, 1011 + connect(connected_socket, &connected_addr.unix_addr, 1012 + connected_addr.unix_addr_len)); 1013 + ASSERT_EQ(EPERM, errno); 1014 + 1015 + ASSERT_EQ(-1, sendto(connected_socket, ".", 1, 0, 1016 + &connected_addr.unix_addr, 1017 + connected_addr.unix_addr_len)); 1018 + ASSERT_EQ(EPERM, errno); 1019 + 1020 + ASSERT_EQ(-1, sendto(non_connected_socket, ".", 1, 0, 1021 + &non_connected_addr.unix_addr, 1022 + non_connected_addr.unix_addr_len)); 1023 + ASSERT_EQ(EPERM, errno); 1024 + 1025 + EXPECT_EQ(0, close(connected_socket)); 1026 + EXPECT_EQ(0, close(non_connected_socket)); 1027 + _exit(_metadata->exit_code); 1028 + return; 1029 + } 1030 + 1031 + /* Waits for all tests to finish. */ 1032 + ASSERT_EQ(child, waitpid(child, &status, 0)); 1033 + EXPECT_EQ(0, close(connected_socket)); 1034 + EXPECT_EQ(0, close(non_connected_socket)); 1035 + 1036 + if (WIFSIGNALED(status) || !WIFEXITED(status) || 1037 + WEXITSTATUS(status) != EXIT_SUCCESS) 1038 + _metadata->exit_code = KSFT_FAIL; 1039 + } 1040 + 977 1041 TEST_HARNESS_MAIN