summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2016-02-04 16:44:25 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2016-02-04 17:07:20 +0000
commit9f9c1ede3abcde796fabcebd33bd7b8e5c00fba7 (patch)
tree751ec6df7d867cbb0d539f9f40f2968a0d361858
parent598bcc5f585ffc20abd925ff8587c2ef5de23805 (diff)
downloadillumos-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.c28
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));