From 37792ee1e6e12fbc6fb81a5913846a5a80233f0c Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Tue, 9 Nov 2021 20:56:41 -0800 Subject: [PATCH] Validate ControlMessageHeader.Length Reported-by: syzbot+fee12cabc732cf92d9e7@syzkaller.appspotmail.com PiperOrigin-RevId: 408776291 --- pkg/sentry/socket/control/BUILD | 1 + pkg/sentry/socket/control/control.go | 2 +- pkg/sentry/socket/control/control_test.go | 21 +++++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index b2fc84181..9753e733a 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -37,6 +37,7 @@ go_test( deps = [ "//pkg/abi/linux", "//pkg/binary", + "//pkg/errors/linuxerr", "//pkg/hostarch", "//pkg/sentry/socket", "@com_github_google_go_cmp//cmp:go_default_library", diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index 4b036b323..c40141a1d 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -503,7 +503,7 @@ func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte, width uint) } length := int(h.Length) - linux.SizeOfControlMessageHeader - if length > len(buf) { + if length < 0 || length > len(buf) { return socket.ControlMessages{}, linuxerr.EINVAL } diff --git a/pkg/sentry/socket/control/control_test.go b/pkg/sentry/socket/control/control_test.go index 1b04e1bbc..65c393f58 100644 --- a/pkg/sentry/socket/control/control_test.go +++ b/pkg/sentry/socket/control/control_test.go @@ -22,6 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/binary" + "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/hostarch" "gvisor.dev/gvisor/pkg/sentry/socket" ) @@ -57,3 +58,23 @@ func TestParse(t *testing.T) { t.Errorf("unexpected message parsed, (-want, +got):\n%s", diff) } } + +func TestParseRightsNegativeLength(t *testing.T) { + // Craft the control message to parse. + length := uint64(linux.SizeOfControlMessageHeader) + 128 + hdr := linux.ControlMessageHeader{ + Length: uint64(0xffffffff8f000000), + Level: linux.SOL_SOCKET, + Type: linux.SCM_RIGHTS, + } + hdrBuf := make([]byte, 0, length) + hdrBuf = binary.Marshal(hdrBuf, hostarch.ByteOrder, &hdr) + + buf := make([]byte, length) + copy(buf, hdrBuf) + cmsg, err := Parse(nil, nil, buf, 8 /* width */) + if err != linuxerr.EINVAL { + t.Fatalf("Parse(_, _, %+v, _): %v", cmsg, err) + } + +}