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) + } + +}