Skip to content

Commit 7130231

Browse files
committed
selftests/landlock: Test inherited restriction of abstract UNIX socket
JIRA: https://issues.redhat.com/browse/RHEL-94688 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 <[email protected]> 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 <[email protected]> (cherry picked from commit 644a728) Signed-off-by: Ryan Sullivan <[email protected]>
1 parent c8d20f4 commit 7130231

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

tools/testing/selftests/landlock/scoped_abstract_unix_test.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,4 +974,68 @@ TEST(datagram_sockets)
974974
_metadata->exit_code = KSFT_FAIL;
975975
}
976976

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+
9771041
TEST_HARNESS_MAIN

0 commit comments

Comments
 (0)