diff options
author | truckman <truckman@FreeBSD.org> | 2004-03-16 01:28:45 +0000 |
---|---|---|
committer | truckman <truckman@FreeBSD.org> | 2004-03-16 01:28:45 +0000 |
commit | 2b0bda9870e0b9d139131c9bd58ebed9f9c3086b (patch) | |
tree | 466c3e72a795f8ea117699c43985d036dedb0f87 /sys/kern | |
parent | 12adb9e4a7a3722da6282caae8bab77c1170d4fd (diff) | |
download | FreeBSD-src-2b0bda9870e0b9d139131c9bd58ebed9f9c3086b.zip FreeBSD-src-2b0bda9870e0b9d139131c9bd58ebed9f9c3086b.tar.gz |
Don't bother calling vslock() and vsunlock() if oldlen is zero.
If vslock() returns ENOMEM, sysctl_wire_old_buffer() should set
wiredlen to zero and return zero (success) so that the handler will
operate according to sysctl(3):
The size of the buffer is given by the location specified by
oldlenp before the call, and that location gives the amount
of data copied after a successful call and after a call that
returns with the error code ENOMEM.
The handler will return an ENOMEM error because the zero length
buffer will overflow.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_sysctl.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 912eb00..de5152e 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -999,7 +999,7 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old, error = sysctl_root(0, name, namelen, &req); - if (req.lock == REQ_WIRED) + if (req.lock == REQ_WIRED && req.wiredlen > 0) vsunlock(req.oldptr, req.wiredlen); SYSCTL_UNLOCK(); @@ -1102,13 +1102,15 @@ sysctl_wire_old_buffer(struct sysctl_req *req, size_t len) ret = 0; if (req->lock == REQ_LOCKED && req->oldptr && req->oldfunc == sysctl_old_user) { - ret = vslock(req->oldptr, wiredlen); - if (ret == 0) { - req->lock = REQ_WIRED; - req->wiredlen = wiredlen; + if (wiredlen != 0) { + ret = vslock(req->oldptr, wiredlen); + if (ret != 0 && ret != ENOMEM) + return (ret); } + req->lock = REQ_WIRED; + req->wiredlen = wiredlen; } - return (ret); + return (0); } int @@ -1317,7 +1319,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, } while (error == EAGAIN); req = req2; - if (req.lock == REQ_WIRED) + if (req.lock == REQ_WIRED && req.wiredlen > 0) vsunlock(req.oldptr, req.wiredlen); SYSCTL_UNLOCK(); |