From cfc4c0301b3edee77ee71569e262964e3053f919 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Tue, 20 Jan 2026 19:16:24 +0800 Subject: [PATCH] Handle the listener in `State::set_pass_cred` --- kernel/src/net/socket/unix/stream/socket.rs | 2 +- .../src/apps/network/unix_stream_err.c | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/kernel/src/net/socket/unix/stream/socket.rs b/kernel/src/net/socket/unix/stream/socket.rs index ef1af0904..ed6e1fe3e 100644 --- a/kernel/src/net/socket/unix/stream/socket.rs +++ b/kernel/src/net/socket/unix/stream/socket.rs @@ -553,7 +553,7 @@ impl SetSocketLevelOption for State { // automatically." See for // details. } - Self::Listen(_) => {} + Self::Listen(listener) => listener.set_pass_cred(pass_cred), Self::Connected(connected) => connected.set_pass_cred(pass_cred), } } diff --git a/test/initramfs/src/apps/network/unix_stream_err.c b/test/initramfs/src/apps/network/unix_stream_err.c index f6ee1c76a..8c88a0c21 100644 --- a/test/initramfs/src/apps/network/unix_stream_err.c +++ b/test/initramfs/src/apps/network/unix_stream_err.c @@ -114,4 +114,87 @@ FN_TEST(scm_rights) } END_TEST() +#define MAKE_SOCKOPTION_INHERIT_TEST(before_listen, after_listen, \ + after_connect, after_accept) \ + int sk2_listen, sk2_connected, sk2_accepted; \ + \ + sk2_listen = TEST_SUCC(socket(PF_UNIX, SOCK_STREAM, 0)); \ + TEST_SUCC(bind(sk2_listen, &UNIX_ADDR("\0abcd"), PATH_OFFSET + 5)); \ + \ + before_listen; \ + \ + TEST_SUCC(listen(sk2_listen, 0)); \ + \ + after_listen; \ + \ + sk2_connected = TEST_SUCC(socket(PF_UNIX, SOCK_STREAM, 0)); \ + TEST_SUCC(connect(sk2_connected, &UNIX_ADDR("\0abcd"), \ + PATH_OFFSET + 5)); \ + \ + after_connect; \ + \ + sk2_accepted = TEST_SUCC(accept(sk2_listen, NULL, NULL)); \ + \ + after_accept; \ + \ + TEST_SUCC(close(sk2_listen)); \ + TEST_SUCC(close(sk2_connected)); \ + TEST_SUCC(close(sk2_accepted)); + +static int val; +static socklen_t val_len = sizeof(val); +static const int one = 1; +static const int zero = 0; + +FN_TEST(passcred_in_listen_wont_inherit) +{ + MAKE_SOCKOPTION_INHERIT_TEST( + /* before_listen */ + TEST_SUCC(setsockopt(sk2_listen, SOL_SOCKET, SO_PASSCRED, &one, + sizeof(one))), + /* after_listen */ + TEST_SUCC(setsockopt(sk2_listen, SOL_SOCKET, SO_PASSCRED, &zero, + sizeof(zero))), + /* after_connect */, + /* after_accept */ + TEST_RES(getsockopt(sk2_accepted, SOL_SOCKET, SO_PASSCRED, &val, + &val_len), + val_len == sizeof(val) && val == 0)); +} +END_TEST() + +FN_TEST(passcred_in_connect_will_inherit) +{ + MAKE_SOCKOPTION_INHERIT_TEST( + /* before_listen */, + /* after_listen */ + TEST_SUCC(setsockopt(sk2_listen, SOL_SOCKET, SO_PASSCRED, &one, + sizeof(one))), + /* after_connect */ + TEST_SUCC(setsockopt(sk2_listen, SOL_SOCKET, SO_PASSCRED, &zero, + sizeof(zero))), + /* after_accept */ + TEST_RES(getsockopt(sk2_accepted, SOL_SOCKET, SO_PASSCRED, &val, + &val_len), + val_len == sizeof(val) && val == 1)); +} +END_TEST() + +FN_TEST(passcred_in_accept_wont_inherit) +{ + MAKE_SOCKOPTION_INHERIT_TEST( + /* before_listen */, + /* after_listen */, + /* after_connect */ + TEST_SUCC(setsockopt(sk2_listen, SOL_SOCKET, SO_PASSCRED, &one, + sizeof(one))), + /* after_accept */ + TEST_RES(getsockopt(sk2_accepted, SOL_SOCKET, SO_PASSCRED, &val, + &val_len), + val_len == sizeof(val) && val == 0)); +} +END_TEST() + +#undef MAKE_SOCKOPTION_INHERIT_TEST + #include "unix_streamlike_epilogue.h"