mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix slice bounds out of range panic in parsing socket control message.
Panic found by syzakller. PiperOrigin-RevId: 288799046
This commit is contained in:
@@ -471,6 +471,9 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte) (socket.Con
|
||||
case linux.SOL_IP:
|
||||
switch h.Type {
|
||||
case linux.IP_TOS:
|
||||
if length < linux.SizeOfControlMessageTOS {
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
}
|
||||
cmsgs.IP.HasTOS = true
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageTOS], usermem.ByteOrder, &cmsgs.IP.TOS)
|
||||
i += AlignUp(length, width)
|
||||
@@ -481,6 +484,9 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte) (socket.Con
|
||||
case linux.SOL_IPV6:
|
||||
switch h.Type {
|
||||
case linux.IPV6_TCLASS:
|
||||
if length < linux.SizeOfControlMessageTClass {
|
||||
return socket.ControlMessages{}, syserror.EINVAL
|
||||
}
|
||||
cmsgs.IP.HasTClass = true
|
||||
binary.Unmarshal(buf[i:i+linux.SizeOfControlMessageTClass], usermem.ByteOrder, &cmsgs.IP.TClass)
|
||||
i += AlignUp(length, width)
|
||||
|
||||
@@ -129,6 +129,7 @@ TEST_P(IPUnboundSocketTest, InvalidNegativeTtl) {
|
||||
struct TOSOption {
|
||||
int level;
|
||||
int option;
|
||||
int cmsg_level;
|
||||
};
|
||||
|
||||
constexpr int INET_ECN_MASK = 3;
|
||||
@@ -139,10 +140,12 @@ static TOSOption GetTOSOption(int domain) {
|
||||
case AF_INET:
|
||||
opt.level = IPPROTO_IP;
|
||||
opt.option = IP_TOS;
|
||||
opt.cmsg_level = SOL_IP;
|
||||
break;
|
||||
case AF_INET6:
|
||||
opt.level = IPPROTO_IPV6;
|
||||
opt.option = IPV6_TCLASS;
|
||||
opt.cmsg_level = SOL_IPV6;
|
||||
break;
|
||||
}
|
||||
return opt;
|
||||
@@ -386,6 +389,36 @@ TEST_P(IPUnboundSocketTest, NullTOS) {
|
||||
SyscallFailsWithErrno(EFAULT));
|
||||
}
|
||||
|
||||
TEST_P(IPUnboundSocketTest, InsufficientBufferTOS) {
|
||||
SKIP_IF(GetParam().protocol == IPPROTO_TCP);
|
||||
|
||||
auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket());
|
||||
TOSOption t = GetTOSOption(GetParam().domain);
|
||||
|
||||
in_addr addr4;
|
||||
in6_addr addr6;
|
||||
ASSERT_THAT(inet_pton(AF_INET, "127.0.0.1", &addr4), ::testing::Eq(1));
|
||||
ASSERT_THAT(inet_pton(AF_INET6, "fe80::", &addr6), ::testing::Eq(1));
|
||||
|
||||
cmsghdr cmsg = {};
|
||||
cmsg.cmsg_len = sizeof(cmsg);
|
||||
cmsg.cmsg_level = t.cmsg_level;
|
||||
cmsg.cmsg_type = t.option;
|
||||
|
||||
msghdr msg = {};
|
||||
msg.msg_control = &cmsg;
|
||||
msg.msg_controllen = sizeof(cmsg);
|
||||
if (GetParam().domain == AF_INET) {
|
||||
msg.msg_name = &addr4;
|
||||
msg.msg_namelen = sizeof(addr4);
|
||||
} else {
|
||||
msg.msg_name = &addr6;
|
||||
msg.msg_namelen = sizeof(addr6);
|
||||
}
|
||||
|
||||
EXPECT_THAT(sendmsg(socket->get(), &msg, 0), SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
IPUnboundSockets, IPUnboundSocketTest,
|
||||
::testing::ValuesIn(VecCat<SocketKind>(VecCat<SocketKind>(
|
||||
|
||||
Reference in New Issue
Block a user