Fix socket_ip_tcp_generic_loopback_test_runsc_ptrace_hostnet

This was mostly a matter of allowing more get/setsockopts. Also had to support
getsockopt with a null option, because apparantly Linux allows that.

PiperOrigin-RevId: 508460614
This commit is contained in:
Nicolas Lacasse
2023-02-09 13:32:17 -08:00
committed by gVisor bot
parent 89cc675c29
commit c0a18ec43b
5 changed files with 26 additions and 6 deletions
+5 -1
View File
@@ -222,7 +222,11 @@ func accept4(fd int, addr *byte, addrlen *uint32, flags int) (int, error) {
func getsockopt(fd int, level, name int, opt []byte) ([]byte, error) {
optlen32 := int32(len(opt))
_, _, errno := unix.Syscall6(unix.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(firstBytePtr(opt)), uintptr(unsafe.Pointer(&optlen32)), 0)
var optPtr uintptr
if optlen32 > 0 {
optPtr = uintptr(firstBytePtr(opt))
}
_, _, errno := unix.Syscall6(unix.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), optPtr, uintptr(unsafe.Pointer(&optlen32)), 0)
if errno != 0 {
return nil, errno
}
+17 -2
View File
@@ -50,6 +50,8 @@ type SockOpt struct {
// SockOpts are the socket options supported by hostinet.
var SockOpts = []SockOpt{
{linux.SOL_IP, linux.IP_MULTICAST_LOOP, sizeofInt32, true, true},
{linux.SOL_IP, linux.IP_MULTICAST_TTL, sizeofInt32, true, true},
{linux.SOL_IP, linux.IP_PKTINFO, sizeofInt32, true, true},
{linux.SOL_IP, linux.IP_RECVERR, sizeofInt32, true, true},
{linux.SOL_IP, linux.IP_RECVORIGDSTADDR, sizeofInt32, true, true},
@@ -70,21 +72,28 @@ var SockOpts = []SockOpt{
{linux.SOL_SOCKET, linux.SO_ACCEPTCONN, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_BROADCAST, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_ERROR, sizeofInt32, false, true},
{linux.SOL_SOCKET, linux.SO_ERROR, sizeofInt32, true, false},
{linux.SOL_SOCKET, linux.SO_KEEPALIVE, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_LINGER, linux.SizeOfLinger, true, true},
{linux.SOL_SOCKET, linux.SO_OOBINLINE, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_RCVBUF, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_REUSEADDR, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_SNDBUF, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_TIMESTAMP, sizeofInt32, true, true},
{linux.SOL_SOCKET, linux.SO_TYPE, sizeofInt32, false, true},
{linux.SOL_SOCKET, linux.SO_TYPE, sizeofInt32, true, false},
{linux.SOL_TCP, linux.TCP_CONGESTION, 0 /* string */, true, true},
{linux.SOL_TCP, linux.TCP_CORK, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_DEFER_ACCEPT, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_INFO, uint64(linux.SizeOfTCPInfo), true, false},
{linux.SOL_TCP, linux.TCP_INQ, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_KEEPCNT, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_KEEPIDLE, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_KEEPINTVL, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_LINGER2, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_MAXSEG, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_NODELAY, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_QUICKACK, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_SYNCNT, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_USER_TIMEOUT, sizeofInt32, true, true},
{linux.SOL_TCP, linux.TCP_WINDOW_CLAMP, sizeofInt32, true, true},
@@ -139,6 +148,9 @@ func (s *Socket) GetSockOpt(t *kernel.Task, level, name int, optValAddr hostarch
if !ok {
return nil, syserr.ErrProtocolNotAvailable
}
if !sockOpt.AllowGet {
return nil, syserr.ErrInvalidArgument
}
var opt []byte
if sockOpt.Size > 0 {
// Validate size of input buffer.
@@ -206,6 +218,9 @@ func (s *Socket) SetSockOpt(t *kernel.Task, level, name int, opt []byte) *syserr
// seems dangerous, but it's what netstack does...
return nil
}
if !sockOpt.AllowSet {
return syserr.ErrInvalidArgument
}
if sockOpt.Size > 0 {
if uint64(len(opt)) < sockOpt.Size {
return syserr.ErrInvalidArgument
+1
View File
@@ -734,6 +734,7 @@ syscall_test(
syscall_test(
size = "large",
add_hostinet = True,
shard_count = most_shards,
test = "//test/syscalls/linux:socket_ip_tcp_generic_loopback_test",
)
@@ -958,7 +958,7 @@ TEST_P(AllSocketPairTest, GetSocketRcvbufOption) {
SyscallSucceeds());
ASSERT_EQ(opt_len, sizeof(opt));
if (IsRunningOnGvisor()) {
if (IsRunningOnGvisor() && !IsRunningWithHostinet()) {
// Minimum buffer size in gVisor is 4KiB.
const int minRcvBufSizeGvisor = 4096;
EXPECT_EQ(opt, minRcvBufSizeGvisor);
@@ -991,7 +991,7 @@ TEST_P(AllSocketPairTest, GetSetSocketRcvlowatOption) {
SyscallSucceeds());
ASSERT_EQ(opt_len, sizeof(opt));
if (IsRunningOnGvisor()) {
if (IsRunningOnGvisor() && !IsRunningWithHostinet()) {
// TODO(b/226603727): Add support for setting SO_RCVLOWAT option in gVisor.
EXPECT_EQ(opt, defaultSz);
} else {
+1 -1
View File
@@ -1273,7 +1273,7 @@ TEST_P(TCPSocketPairTest, SetAndGetLingerOption) {
// Linux returns a different value as it uses HZ to convert the seconds to
// jiffies which overflows for negative values. We want to be compatible with
// linux for getsockopt return value.
if (IsRunningOnGvisor()) {
if (IsRunningOnGvisor() && !IsRunningWithHostinet()) {
EXPECT_EQ(sl.l_linger, got_linger.l_linger);
}