[netstack] Update raw socket and hostinet control message parsing.

There are surprisingly few syscall tests that run with hostinet. For example
running the following command only returns two results:
`bazel query test/syscalls:all | grep hostnet`

I think as a result, as our control messages evolved, hostinet was left
behind. Update it to support all control messages netstack supports.

This change also updates sentry's control message parsing logic to make it up to
date with all the control messages we support.

PiperOrigin-RevId: 347508892
This commit is contained in:
Ayush Ranjan
2020-12-14 18:00:55 -08:00
committed by gVisor bot
parent 2e191cb3f7
commit a1c56bc227
4 changed files with 129 additions and 12 deletions
+26
View File
@@ -503,6 +503,14 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte) (socket.Con
cmsgs.Unix.Credentials = scmCreds
i += binary.AlignUp(length, width)
case linux.SO_TIMESTAMP:
if length < linux.SizeOfTimeval {
return socket.ControlMessages{}, syserror.EINVAL
}
cmsgs.IP.HasTimestamp = true
binary.Unmarshal(buf[i:i+linux.SizeOfTimeval], usermem.ByteOrder, &cmsgs.IP.Timestamp)
i += binary.AlignUp(length, width)
default:
// Unknown message type.
return socket.ControlMessages{}, syserror.EINVAL
@@ -529,6 +537,15 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte) (socket.Con
cmsgs.IP.PacketInfo = packetInfo
i += binary.AlignUp(length, width)
case linux.IP_RECVORIGDSTADDR:
var addr linux.SockAddrInet
if length < addr.SizeBytes() {
return socket.ControlMessages{}, syserror.EINVAL
}
binary.Unmarshal(buf[i:i+addr.SizeBytes()], usermem.ByteOrder, &addr)
cmsgs.IP.OriginalDstAddress = &addr
i += binary.AlignUp(length, width)
default:
return socket.ControlMessages{}, syserror.EINVAL
}
@@ -542,6 +559,15 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte) (socket.Con
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageTClass], usermem.ByteOrder, &cmsgs.IP.TClass)
i += binary.AlignUp(length, width)
case linux.IPV6_RECVORIGDSTADDR:
var addr linux.SockAddrInet6
if length < addr.SizeBytes() {
return socket.ControlMessages{}, syserror.EINVAL
}
binary.Unmarshal(buf[i:i+addr.SizeBytes()], usermem.ByteOrder, &addr)
cmsgs.IP.OriginalDstAddress = &addr
i += binary.AlignUp(length, width)
default:
return socket.ControlMessages{}, syserror.EINVAL
}
+36 -12
View File
@@ -331,17 +331,17 @@ func (s *socketOpsCommon) GetSockOpt(t *kernel.Task, level int, name int, outPtr
switch level {
case linux.SOL_IP:
switch name {
case linux.IP_TOS, linux.IP_RECVTOS, linux.IP_PKTINFO:
case linux.IP_TOS, linux.IP_RECVTOS, linux.IP_PKTINFO, linux.IP_RECVORIGDSTADDR:
optlen = sizeofInt32
}
case linux.SOL_IPV6:
switch name {
case linux.IPV6_TCLASS, linux.IPV6_RECVTCLASS, linux.IPV6_V6ONLY:
case linux.IPV6_TCLASS, linux.IPV6_RECVTCLASS, linux.IPV6_V6ONLY, linux.IPV6_RECVORIGDSTADDR:
optlen = sizeofInt32
}
case linux.SOL_SOCKET:
switch name {
case linux.SO_ERROR, linux.SO_KEEPALIVE, linux.SO_SNDBUF, linux.SO_RCVBUF, linux.SO_REUSEADDR:
case linux.SO_ERROR, linux.SO_KEEPALIVE, linux.SO_SNDBUF, linux.SO_RCVBUF, linux.SO_REUSEADDR, linux.SO_TIMESTAMP:
optlen = sizeofInt32
case linux.SO_LINGER:
optlen = syscall.SizeofLinger
@@ -377,24 +377,24 @@ func (s *socketOpsCommon) SetSockOpt(t *kernel.Task, level int, name int, opt []
switch level {
case linux.SOL_IP:
switch name {
case linux.IP_TOS, linux.IP_RECVTOS:
case linux.IP_TOS, linux.IP_RECVTOS, linux.IP_RECVORIGDSTADDR:
optlen = sizeofInt32
case linux.IP_PKTINFO:
optlen = linux.SizeOfControlMessageIPPacketInfo
}
case linux.SOL_IPV6:
switch name {
case linux.IPV6_TCLASS, linux.IPV6_RECVTCLASS, linux.IPV6_V6ONLY:
case linux.IPV6_TCLASS, linux.IPV6_RECVTCLASS, linux.IPV6_V6ONLY, linux.IPV6_RECVORIGDSTADDR:
optlen = sizeofInt32
}
case linux.SOL_SOCKET:
switch name {
case linux.SO_SNDBUF, linux.SO_RCVBUF, linux.SO_REUSEADDR:
case linux.SO_SNDBUF, linux.SO_RCVBUF, linux.SO_REUSEADDR, linux.SO_TIMESTAMP:
optlen = sizeofInt32
}
case linux.SOL_TCP:
switch name {
case linux.TCP_NODELAY:
case linux.TCP_NODELAY, linux.TCP_INQ:
optlen = sizeofInt32
}
}
@@ -513,24 +513,48 @@ func (s *socketOpsCommon) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags
controlMessages := socket.ControlMessages{}
for _, unixCmsg := range unixControlMessages {
switch unixCmsg.Header.Level {
case syscall.SOL_IP:
case linux.SOL_SOCKET:
switch unixCmsg.Header.Type {
case syscall.IP_TOS:
case linux.SO_TIMESTAMP:
controlMessages.IP.HasTimestamp = true
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfTimeval], usermem.ByteOrder, &controlMessages.IP.Timestamp)
}
case linux.SOL_IP:
switch unixCmsg.Header.Type {
case linux.IP_TOS:
controlMessages.IP.HasTOS = true
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageTOS], usermem.ByteOrder, &controlMessages.IP.TOS)
case syscall.IP_PKTINFO:
case linux.IP_PKTINFO:
controlMessages.IP.HasIPPacketInfo = true
var packetInfo linux.ControlMessageIPPacketInfo
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageIPPacketInfo], usermem.ByteOrder, &packetInfo)
controlMessages.IP.PacketInfo = packetInfo
case linux.IP_RECVORIGDSTADDR:
var addr linux.SockAddrInet
binary.Unmarshal(unixCmsg.Data[:addr.SizeBytes()], usermem.ByteOrder, &addr)
controlMessages.IP.OriginalDstAddress = &addr
}
case syscall.SOL_IPV6:
case linux.SOL_IPV6:
switch unixCmsg.Header.Type {
case syscall.IPV6_TCLASS:
case linux.IPV6_TCLASS:
controlMessages.IP.HasTClass = true
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageTClass], usermem.ByteOrder, &controlMessages.IP.TClass)
case linux.IPV6_RECVORIGDSTADDR:
var addr linux.SockAddrInet6
binary.Unmarshal(unixCmsg.Data[:addr.SizeBytes()], usermem.ByteOrder, &addr)
controlMessages.IP.OriginalDstAddress = &addr
}
case linux.SOL_TCP:
switch unixCmsg.Header.Type {
case linux.TCP_INQ:
controlMessages.IP.HasInq = true
binary.Unmarshal(unixCmsg.Data[:linux.SizeOfControlMessageInq], usermem.ByteOrder, &controlMessages.IP.Inq)
}
}
}
+60
View File
@@ -341,6 +341,16 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.EqualTo(syscall.SOL_IP),
seccomp.EqualTo(syscall.IP_RECVTOS),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IP),
seccomp.EqualTo(syscall.IP_PKTINFO),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IP),
seccomp.EqualTo(syscall.IP_RECVORIGDSTADDR),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IPV6),
@@ -356,6 +366,11 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.EqualTo(syscall.SOL_IPV6),
seccomp.EqualTo(syscall.IPV6_V6ONLY),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IPV6),
seccomp.EqualTo(linux.IPV6_RECVORIGDSTADDR),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_SOCKET),
@@ -391,6 +406,11 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.EqualTo(syscall.SOL_SOCKET),
seccomp.EqualTo(syscall.SO_LINGER),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_SOCKET),
seccomp.EqualTo(syscall.SO_TIMESTAMP),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_TCP),
@@ -401,6 +421,11 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.EqualTo(syscall.SOL_TCP),
seccomp.EqualTo(syscall.TCP_INFO),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_TCP),
seccomp.EqualTo(linux.TCP_INQ),
},
},
syscall.SYS_IOCTL: []seccomp.Rule{
{
@@ -447,6 +472,13 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_SOCKET),
seccomp.EqualTo(syscall.SO_TIMESTAMP),
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_TCP),
@@ -454,6 +486,13 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_TCP),
seccomp.EqualTo(linux.TCP_INQ),
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IP),
@@ -468,6 +507,20 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IP),
seccomp.EqualTo(syscall.IP_PKTINFO),
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IP),
seccomp.EqualTo(syscall.IP_RECVORIGDSTADDR),
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IPV6),
@@ -482,6 +535,13 @@ func hostInetFilters() seccomp.SyscallRules {
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
{
seccomp.MatchAny{},
seccomp.EqualTo(syscall.SOL_IPV6),
seccomp.EqualTo(linux.IPV6_RECVORIGDSTADDR),
seccomp.MatchAny{},
seccomp.EqualTo(4),
},
},
syscall.SYS_SHUTDOWN: []seccomp.Rule{
{
+7
View File
@@ -647,6 +647,7 @@ syscall_test(
syscall_test(
size = "medium",
add_hostinet = True,
test = "//test/syscalls/linux:socket_ip_tcp_loopback_non_blocking_test",
)
@@ -658,12 +659,14 @@ syscall_test(
syscall_test(
size = "medium",
add_hostinet = True,
shard_count = most_shards,
test = "//test/syscalls/linux:socket_ip_tcp_udp_generic_loopback_test",
)
syscall_test(
size = "medium",
add_hostinet = True,
test = "//test/syscalls/linux:socket_ip_udp_loopback_non_blocking_test",
)
@@ -680,6 +683,7 @@ syscall_test(
syscall_test(
size = "medium",
add_hostinet = True,
shard_count = more_shards,
# Takes too long under gotsan to run.
tags = ["nogotsan"],
@@ -728,6 +732,7 @@ syscall_test(
)
syscall_test(
add_hostinet = True,
test = "//test/syscalls/linux:socket_non_stream_blocking_local_test",
)
@@ -903,6 +908,7 @@ syscall_test(
)
syscall_test(
add_hostinet = True,
test = "//test/syscalls/linux:udp_bind_test",
)
@@ -967,6 +973,7 @@ syscall_test(
)
syscall_test(
add_hostinet = True,
test = "//test/syscalls/linux:proc_net_tcp_test",
)