summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_sysctl.c30
-rw-r--r--sys/sys/sysctl.h2
2 files changed, 17 insertions, 15 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index de5152e..59a630f 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -981,6 +981,7 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
if (oldlenp) {
req.oldlen = *oldlenp;
}
+ req.validlen = req.oldlen;
if (old) {
req.oldptr= old;
@@ -999,8 +1000,8 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
error = sysctl_root(0, name, namelen, &req);
- if (req.lock == REQ_WIRED && req.wiredlen > 0)
- vsunlock(req.oldptr, req.wiredlen);
+ if (req.lock == REQ_WIRED && req.validlen > 0)
+ vsunlock(req.oldptr, req.validlen);
SYSCTL_UNLOCK();
@@ -1008,8 +1009,8 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
return (error);
if (retval) {
- if (req.oldptr && req.oldidx > req.oldlen)
- *retval = req.oldlen;
+ if (req.oldptr && req.oldidx > req.validlen)
+ *retval = req.validlen;
else
*retval = req.oldidx;
}
@@ -1055,7 +1056,7 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l)
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"sysctl_old_user()");
i = l;
- len = (req->lock == REQ_WIRED) ? req->wiredlen : req->oldlen;
+ len = req->validlen;
if (len <= origidx)
i = 0;
else {
@@ -1108,7 +1109,7 @@ sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
return (ret);
}
req->lock = REQ_WIRED;
- req->wiredlen = wiredlen;
+ req->validlen = wiredlen;
}
return (0);
}
@@ -1278,7 +1279,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval)
{
int error = 0;
- struct sysctl_req req, req2;
+ struct sysctl_req req;
bzero(&req, sizeof req);
@@ -1293,6 +1294,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
return (error);
}
}
+ req.validlen = req.oldlen;
if (old) {
if (!useracc(old, req.oldlen, VM_PROT_WRITE))
@@ -1314,13 +1316,13 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
SYSCTL_LOCK();
do {
- req2 = req;
- error = sysctl_root(0, name, namelen, &req2);
+ req.oldidx = 0;
+ req.newidx = 0;
+ error = sysctl_root(0, name, namelen, &req);
} while (error == EAGAIN);
- req = req2;
- if (req.lock == REQ_WIRED && req.wiredlen > 0)
- vsunlock(req.oldptr, req.wiredlen);
+ if (req.lock == REQ_WIRED && req.validlen > 0)
+ vsunlock(req.oldptr, req.validlen);
SYSCTL_UNLOCK();
@@ -1328,8 +1330,8 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
return (error);
if (retval) {
- if (req.oldptr && req.oldidx > req.oldlen)
- *retval = req.oldlen;
+ if (req.oldptr && req.oldidx > req.validlen)
+ *retval = req.validlen;
else
*retval = req.oldidx;
}
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index b4b66e7..77a36cd 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -139,7 +139,7 @@ struct sysctl_req {
size_t newlen;
size_t newidx;
int (*newfunc)(struct sysctl_req *, void *, size_t);
- size_t wiredlen;
+ size_t validlen;
};
SLIST_HEAD(sysctl_oid_list, sysctl_oid);
OpenPOWER on IntegriCloud