diff options
author | tmm <tmm@FreeBSD.org> | 2001-03-08 01:20:43 +0000 |
---|---|---|
committer | tmm <tmm@FreeBSD.org> | 2001-03-08 01:20:43 +0000 |
commit | 400bee78994fb8c07571d1ee5d5dda2eb75f2f5a (patch) | |
tree | a81b50122172d3f5771f3222e089afa255d0c76a /sys/kern/kern_sysctl.c | |
parent | aa2af82f77a2bb5105a384b806e6ba2cf75a0ad4 (diff) | |
download | FreeBSD-src-400bee78994fb8c07571d1ee5d5dda2eb75f2f5a.zip FreeBSD-src-400bee78994fb8c07571d1ee5d5dda2eb75f2f5a.tar.gz |
Make the SYSCTL_OUT handlers sysctl_old_user() and sysctl_old_kernel()
more robust. They would correctly return ENOMEM for the first time when
the buffer was exhausted, but subsequent calls in this case could cause
writes ouside of the buffer bounds.
Approved by: rwatson
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r-- | sys/kern/kern_sysctl.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index dd361d7..206322c 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -817,8 +817,11 @@ sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l) if (req->oldptr) { i = l; - if (i > req->oldlen - req->oldidx) - i = req->oldlen - req->oldidx; + if (req->oldlen <= req->oldidx) + i = 0; + else + if (i > req->oldlen - req->oldidx) + i = req->oldlen - req->oldidx; if (i > 0) bcopy(p, (char *)req->oldptr + req->oldidx, i); } @@ -914,8 +917,11 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) } if (req->oldptr) { i = l; - if (i > req->oldlen - req->oldidx) - i = req->oldlen - req->oldidx; + if (req->oldlen <= req->oldidx) + i = 0; + else + if (i > req->oldlen - req->oldidx) + i = req->oldlen - req->oldidx; if (i > 0) error = copyout(p, (char *)req->oldptr + req->oldidx, i); |