From 2739cf46284f2786ad33b545d55b8178bc46f7de Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Thu, 22 Apr 2021 16:31:11 -0700 Subject: Fix AF_UNIX listen() w/ zero backlog. In https://github.com/google/gvisor/commit/f075522849fa a check to increase zero to a minimum backlog length was removed from sys_socket.go to bring it in parity with linux and then in tcp/endpoint.go we bump backlog by 1. But this broke calling listen on a AF_UNIX socket w/ a zero backlog as in linux it does allow 1 connection even with a zero backlog. This was caught by a php runtime test socket_abstract_path.phpt. PiperOrigin-RevId: 369974744 --- pkg/sentry/syscalls/linux/sys_socket.go | 13 ++++++++++--- pkg/sentry/syscalls/linux/vfs2/socket.go | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'pkg/sentry/syscalls') diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go index eff251cec..5e9e940df 100644 --- a/pkg/sentry/syscalls/linux/sys_socket.go +++ b/pkg/sentry/syscalls/linux/sys_socket.go @@ -383,12 +383,19 @@ func Listen(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal // Linux treats incoming backlog as uint with a limit defined by // sysctl_somaxconn. // https://github.com/torvalds/linux/blob/7acac4b3196/net/socket.c#L1666 - // - // We use the backlog to allocate a channel of that size, hence enforce - // a hard limit for the backlog. backlog = maxListenBacklog } + // Accept one more than the configured listen backlog to keep in parity with + // Linux. Ref, because of missing equality check here: + // https://github.com/torvalds/linux/blob/7acac4b3196/include/net/sock.h#L937 + // + // In case of unix domain sockets, the following check + // https://github.com/torvalds/linux/blob/7d6beb71da3/net/unix/af_unix.c#L1293 + // will allow 1 connect through since it checks for a receive queue len > + // backlog and not >=. + backlog++ + return 0, nil, s.Listen(t, int(backlog)).ToError() } diff --git a/pkg/sentry/syscalls/linux/vfs2/socket.go b/pkg/sentry/syscalls/linux/vfs2/socket.go index 936614eab..6edde0ed1 100644 --- a/pkg/sentry/syscalls/linux/vfs2/socket.go +++ b/pkg/sentry/syscalls/linux/vfs2/socket.go @@ -387,12 +387,19 @@ func Listen(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal // Linux treats incoming backlog as uint with a limit defined by // sysctl_somaxconn. // https://github.com/torvalds/linux/blob/7acac4b3196/net/socket.c#L1666 - // - // We use the backlog to allocate a channel of that size, hence enforce - // a hard limit for the backlog. backlog = maxListenBacklog } + // Accept one more than the configured listen backlog to keep in parity with + // Linux. Ref, because of missing equality check here: + // https://github.com/torvalds/linux/blob/7acac4b3196/include/net/sock.h#L937 + // + // In case of unix domain sockets, the following check + // https://github.com/torvalds/linux/blob/7d6beb71da3/net/unix/af_unix.c#L1293 + // will allow 1 connect through since it checks for a receive queue len > + // backlog and not >=. + backlog++ + return 0, nil, s.Listen(t, int(backlog)).ToError() } -- cgit v1.2.3