diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-02-04 16:44:25 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-02-04 17:07:20 +0000 |
commit | 9f9c1ede3abcde796fabcebd33bd7b8e5c00fba7 (patch) | |
tree | 751ec6df7d867cbb0d539f9f40f2968a0d361858 | |
parent | 598bcc5f585ffc20abd925ff8587c2ef5de23805 (diff) | |
download | illumos-joyent-release-20160204.tar.gz |
OS-5142 pselect brokenrelease-20160204
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
-rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_poll.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_poll.c b/usr/src/uts/common/brand/lx/syscall/lx_poll.c index a2d768206f..fd50f18a68 100644 --- a/usr/src/uts/common/brand/lx/syscall/lx_poll.c +++ b/usr/src/uts/common/brand/lx/syscall/lx_poll.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2015 Joyent, Inc. + * Copyright 2016 Joyent, Inc. */ #include <sys/types.h> @@ -677,7 +677,7 @@ lx_select(int nfds, long *rfds, long *wfds, long *efds, long lx_pselect(int nfds, long *rfds, long *wfds, long *efds, - timespec_t *timeoutp, lx_sigset_t *setp) + timespec_t *timeoutp, uintptr_t setp) { timespec_t ts, *tsp = NULL; k_sigset_t kset, *ksetp = NULL; @@ -702,12 +702,30 @@ lx_pselect(int nfds, long *rfds, long *wfds, long *efds, tsp = &ts; } if (setp != NULL) { + struct { + lx_sigset_t *addr; + size_t size; + } ps_lx_sigset; lx_sigset_t lset; - if (copyin(setp, &lset, sizeof (lset))) + if (copyin((void *)setp, &ps_lx_sigset, sizeof (ps_lx_sigset))) return (set_errno(EFAULT)); - lx_ltos_sigset(&lset, &kset); - ksetp = &kset; + + /* + * Yes, that's right: Linux forces a size to be passed only + * so it can check that it's the size of a sigset_t. + */ + if (ps_lx_sigset.size != sizeof (lx_sigset_t)) + return (set_errno(EINVAL)); + + /* This is where we check if the sigset is *really* NULL. */ + if (ps_lx_sigset.addr != NULL) { + if (copyin(ps_lx_sigset.addr, &lset, sizeof (lset))) + return (set_errno(EFAULT)); + + lx_ltos_sigset(&lset, &kset); + ksetp = &kset; + } } return (lx_select_common(nfds, rfds, wfds, efds, tsp, ksetp)); |