summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2019-11-29 00:08:41 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2019-12-03 18:28:38 +0000
commite63ea1f970505bef26ee06b3cef54076ad25b94e (patch)
treec0e9805405f13cf867a28fe08a5ef82e9c791746 /usr/src
parentb8dc1b43d204b714c2fda8dd4efd67de0c671db6 (diff)
downloadillumos-gate-e63ea1f970505bef26ee06b3cef54076ad25b94e.tar.gz
12043 Streams ioctl for _I_CMD within kernel causes EFAULT
Reviewed by: John Levon <john.levon@joyent.com> Reviewed by: Jason King <jason.king@joyent.com> Approved by: Robert Mustacchi <rm@fingolfin.org>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/os/streamio.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c
index d81bfbb202..9abbf03fe8 100644
--- a/usr/src/uts/common/os/streamio.c
+++ b/usr/src/uts/common/os/streamio.c
@@ -3575,29 +3575,39 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
if (stp->sd_flag & STRHUP)
return (ENXIO);
- if ((scp = kmem_alloc(sizeof (strcmd_t), KM_NOSLEEP)) == NULL)
- return (ENOMEM);
+ if (copyflag == U_TO_K) {
+ if ((scp = kmem_alloc(sizeof (strcmd_t),
+ KM_NOSLEEP)) == NULL) {
+ return (ENOMEM);
+ }
- if (copyin((void *)arg, scp, sizeof (strcmd_t))) {
- kmem_free(scp, sizeof (strcmd_t));
- return (EFAULT);
+ if (copyin((void *)arg, scp, sizeof (strcmd_t))) {
+ kmem_free(scp, sizeof (strcmd_t));
+ return (EFAULT);
+ }
+ } else {
+ scp = (strcmd_t *)arg;
}
access = job_control_type(scp->sc_cmd);
mutex_enter(&stp->sd_lock);
if (access != -1 && (error = i_straccess(stp, access)) != 0) {
mutex_exit(&stp->sd_lock);
- kmem_free(scp, sizeof (strcmd_t));
+ if (copyflag == U_TO_K)
+ kmem_free(scp, sizeof (strcmd_t));
return (error);
}
mutex_exit(&stp->sd_lock);
*rvalp = 0;
if ((error = strdocmd(stp, scp, crp)) == 0) {
- if (copyout(scp, (void *)arg, sizeof (strcmd_t)))
+ if (copyflag == U_TO_K &&
+ copyout(scp, (void *)arg, sizeof (strcmd_t))) {
error = EFAULT;
+ }
}
- kmem_free(scp, sizeof (strcmd_t));
+ if (copyflag == U_TO_K)
+ kmem_free(scp, sizeof (strcmd_t));
return (error);
case I_NREAD: