summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/syscalls
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@google.com>2019-12-19 17:25:18 -0800
committergVisor bot <gvisor-bot@google.com>2019-12-19 17:26:44 -0800
commit29955a4797e8264f75886a989dbc81b2b5443f4c (patch)
treec030fd27dd08c2ebc08f02315b3546a2a492f112 /pkg/sentry/syscalls
parent7419e0e5d74621b2be60e9b18e4e2d7bb2a65cc3 (diff)
futex: wake one waiter if futex_wake is called with a non-positive value
This change is needed to be compatible with the Linux kernel. There is no glibc wrapper for the futex system call, so it is easy to make a mistake and call syscall(__NR_futex, FUTEX_WAKE, addr) without the fourth argument. This works on Linux, because it wakes one waiter even if val is nonpositive. PiperOrigin-RevId: 286494396
Diffstat (limited to 'pkg/sentry/syscalls')
-rw-r--r--pkg/sentry/syscalls/linux/sys_futex.go10
1 files changed, 10 insertions, 0 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go
index b9bd25464..bde17a767 100644
--- a/pkg/sentry/syscalls/linux/sys_futex.go
+++ b/pkg/sentry/syscalls/linux/sys_futex.go
@@ -226,6 +226,11 @@ func Futex(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
if mask == 0 {
return 0, nil, syserror.EINVAL
}
+ if val <= 0 {
+ // The Linux kernel wakes one waiter even if val is
+ // non-positive.
+ val = 1
+ }
n, err := t.Futex().Wake(t, addr, private, mask, val)
return uintptr(n), nil, err
@@ -242,6 +247,11 @@ func Futex(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
case linux.FUTEX_WAKE_OP:
op := uint32(val3)
+ if val <= 0 {
+ // The Linux kernel wakes one waiter even if val is
+ // non-positive.
+ val = 1
+ }
n, err := t.Futex().WakeOp(t, addr, naddr, private, val, nreq, op)
return uintptr(n), nil, err