From 079be2f30f50748bac6089d23e17ee4a7d071d09 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Wed, 25 Jun 2025 15:10:59 +0800 Subject: [PATCH] Enable syscall tests for UNIX sockets --- kernel/src/net/socket/unix/stream/socket.rs | 19 ++++++++++++- test/apps/network/unix_err.c | 10 +++++++ test/syscall_test/gvisor/Makefile | 2 ++ .../gvisor/blocklists/socket_unix_pair_test | 27 +++++++++++++++++++ .../gvisor/blocklists/socket_unix_stream_test | 5 ++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 test/syscall_test/gvisor/blocklists/socket_unix_pair_test create mode 100644 test/syscall_test/gvisor/blocklists/socket_unix_stream_test diff --git a/kernel/src/net/socket/unix/stream/socket.rs b/kernel/src/net/socket/unix/stream/socket.rs index c5dd1deb1..6ed269fad 100644 --- a/kernel/src/net/socket/unix/stream/socket.rs +++ b/kernel/src/net/socket/unix/stream/socket.rs @@ -371,9 +371,26 @@ impl Socket for UnixStreamSocket { } let MessageHeader { - control_message, .. + control_message, + addr, } = message_header; + // According to the Linux man pages, `EISCONN` _may_ be returned when the destination + // address is specified for a connection-mode socket. In practice, `sendmsg` on UNIX stream + // sockets will fail due to that. We follow the same behavior as the Linux implementation. + if addr.is_some() { + match self.state.read().as_ref() { + State::Init(_) | State::Listen(_) => return_errno_with_message!( + Errno::EOPNOTSUPP, + "sending to a specific address is not allowed on UNIX stream sockets" + ), + State::Connected(_) => return_errno_with_message!( + Errno::EISCONN, + "sending to a specific address is not allowed on UNIX stream sockets" + ), + } + } + if control_message.is_some() { // TODO: Support sending control message warn!("sending control message is not supported"); diff --git a/test/apps/network/unix_err.c b/test/apps/network/unix_err.c index a0acfdcb9..3ab9e41cf 100644 --- a/test/apps/network/unix_err.c +++ b/test/apps/network/unix_err.c @@ -340,6 +340,16 @@ FN_TEST(send) TEST_ERRNO(send(sk_listen, buf, 0, 0), ENOTCONN); TEST_ERRNO(write(sk_listen, buf, 1), ENOTCONN); TEST_ERRNO(write(sk_listen, buf, 0), ENOTCONN); + + TEST_ERRNO(sendto(sk_unbound, buf, 1, 0, &LISTEN_ADDR, LISTEN_ADDRLEN), + EOPNOTSUPP); + TEST_ERRNO(sendto(sk_bound, buf, 1, 0, &LISTEN_ADDR2, LISTEN_ADDRLEN2), + EOPNOTSUPP); + TEST_ERRNO(sendto(sk_listen, buf, 1, 0, &BOUND_ADDR, BOUND_ADDRLEN), + EOPNOTSUPP); + TEST_ERRNO(sendto(sk_accepted, buf, 1, 0, &UNNAMED_ADDR, + UNNAMED_ADDRLEN), + EISCONN); } END_TEST() diff --git a/test/syscall_test/gvisor/Makefile b/test/syscall_test/gvisor/Makefile index 8d63bc1b9..acb80992b 100644 --- a/test/syscall_test/gvisor/Makefile +++ b/test/syscall_test/gvisor/Makefile @@ -50,6 +50,8 @@ TESTS ?= \ sigaltstack_test \ signalfd_test \ socket_netlink_route_test \ + socket_unix_pair_test \ + socket_unix_stream_test \ stat_test \ stat_times_test \ statfs_test \ diff --git a/test/syscall_test/gvisor/blocklists/socket_unix_pair_test b/test/syscall_test/gvisor/blocklists/socket_unix_pair_test new file mode 100644 index 000000000..228ad2bff --- /dev/null +++ b/test/syscall_test/gvisor/blocklists/socket_unix_pair_test @@ -0,0 +1,27 @@ +# TODO: Support `SOCK_SEQPACKET` sockets +AllUnixDomainSockets/UnixSocketPairTest.BindToBadName/* +AllUnixDomainSockets/UnixSocketPairTest.BindToBadFamily/* +AllUnixDomainSockets/*/4 +AllUnixDomainSockets/*/5 +AllUnixDomainSockets/*/10 +AllUnixDomainSockets/*/11 + +# TODO: Support `SOCK_DGRAM` sockets +AllUnixDomainSockets/*/2 +AllUnixDomainSockets/*/3 +AllUnixDomainSockets/*/8 +AllUnixDomainSockets/*/9 + +# TODO: Support the `recvmmsg` system call +AllUnixDomainSockets/UnixSocketPairTest.RecvmmsgTimeoutAfterRecv/* + +# TODO: Support `ioctl` operations on sockets +AllUnixDomainSockets/UnixSocketPairTest.TIOCINQSucceeds/* +AllUnixDomainSockets/UnixSocketPairTest.TIOCOUTQSucceeds/* +AllUnixDomainSockets/UnixSocketPairTest.NetdeviceIoctlsSucceed/* + +# TODO: Fix operations on `/proc/*/fd/*` +AllUnixDomainSockets/UnixSocketPairTest.SocketReopenFromProcfs/* + +# TODO: Support control messages +AllUnixDomainSockets/UnixSocketPairCmsgTest.* diff --git a/test/syscall_test/gvisor/blocklists/socket_unix_stream_test b/test/syscall_test/gvisor/blocklists/socket_unix_stream_test new file mode 100644 index 000000000..d86d2aaba --- /dev/null +++ b/test/syscall_test/gvisor/blocklists/socket_unix_stream_test @@ -0,0 +1,5 @@ +# TODO: Support the `SO_RCVTIMEO` socket option +AllUnixDomainSockets/StreamUnixSocketPairTest.RecvmsgOneSideClosed/* + +# TODO: Support `ECONNRESET` errors on UNIX sockets +AllUnixDomainSockets/StreamUnixSocketPairTest.ReadOneSideClosedWithUnreadData/*