diff options
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_mmap.go | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index f8d9c43fd..145f7846c 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -308,28 +308,31 @@ func SetMempolicy(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel. nodemask := args[1].Pointer() maxnode := args[2].Uint() - if maxnode < 1 { + if nodemask != 0 && maxnode < 1 { return 0, nil, syserror.EINVAL } if modeWithFlags&linux.MPOL_MODE_FLAGS == linux.MPOL_MODE_FLAGS { - // Can't specify multiple modes simultaneously. Must also contain a - // valid mode, which we check below. + // Can't specify multiple modes simultaneously. return 0, nil, syserror.EINVAL } mode := modeWithFlags &^ linux.MPOL_MODE_FLAGS if mode < 0 || mode >= linux.MPOL_MAX { + // Must specify a valid mode. return 0, nil, syserror.EINVAL } var nodemaskVal uint32 - if _, err := t.CopyIn(nodemask, &nodemaskVal); err != nil { - return 0, nil, syserror.EFAULT + // Nodemask may be empty for some policy modes. + if nodemask != 0 && maxnode > 0 { + if _, err := t.CopyIn(nodemask, &nodemaskVal); err != nil { + return 0, nil, syserror.EFAULT + } } - // When setting MPOL_INTERLEAVE, nodemask must not be empty. - if mode == linux.MPOL_INTERLEAVE && nodemaskVal == 0 { + if (mode == linux.MPOL_INTERLEAVE || mode == linux.MPOL_BIND) && nodemaskVal == 0 { + // Mode requires a non-empty nodemask, but got an empty nodemask. return 0, nil, syserror.EINVAL } |