diff options
-rw-r--r-- | sys/kern/kern_sysctl.c | 185 | ||||
-rw-r--r-- | sys/kern/kern_xxx.c | 46 |
2 files changed, 137 insertions, 94 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 2c4217e..e4737ef 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 - * $Id: kern_sysctl.c,v 1.31 1995/11/06 16:18:52 phk Exp $ + * $Id: kern_sysctl.c,v 1.32 1995/11/08 08:46:01 phk Exp $ */ /* @@ -183,7 +183,7 @@ sysctl_order_cmp(void *a, void *b) static void sysctl_order(void *arg) { - int j,k; + int j; struct linker_set *l = (struct linker_set *) arg; struct sysctl_oid **oidpp; @@ -223,7 +223,7 @@ sysctl_sysctl_debug_dump_node(struct linker_set *l,int i) printf(" "); if ((*oidpp)->oid_number > 100) { - printf("Junk! %p nm %x # %x k %x a1 %x a2 %x h %x\n", + printf("Junk! %p # %d %s k %x a1 %p a2 %x h %p\n", *oidpp, (*oidpp)->oid_number, (*oidpp)->oid_name, (*oidpp)->oid_kind, (*oidpp)->oid_arg1, @@ -371,15 +371,6 @@ static struct sysctl_lock { int sl_locked; } memlock; -struct sysctl_args { - int *name; - u_int namelen; - void *old; - size_t *oldlenp; - void *new; - size_t newlen; -}; - /* @@ -444,25 +435,22 @@ found: return (i); } +struct sysctl_args { + int *name; + u_int namelen; + void *old; + size_t *oldlenp; + void *new; + size_t newlen; +}; + int __sysctl(p, uap, retval) struct proc *p; register struct sysctl_args *uap; int *retval; { - int error, dolock = 1, i; - u_int savelen = 0, oldlen = 0; - sysctlfn *fn; - int name[CTL_MAXNAME]; - void *oldp = 0; - void *newp = 0; - - if (uap->new != NULL && (error = suser(p->p_ucred, &p->p_acflag))) - return (error); - - /* - * all top-level sysctl names are non-terminal - */ + int error, name[CTL_MAXNAME]; if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) return (EINVAL); @@ -471,16 +459,43 @@ __sysctl(p, uap, retval) if (error) return (error); - if (uap->oldlenp && - (error = copyin(uap->oldlenp, &oldlen, sizeof(oldlen)))) + return (userland_sysctl(p, name, uap->namelen, + uap->old, uap->oldlenp, 0, + uap->new, uap->newlen, retval)); +} + +/* + * This is used from various compatibility syscalls too. That's why name + * must be in kernel space. + */ +int +userland_sysctl(struct proc *p, int *name, u_int namelen, void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen, int *retval) +{ + int error = 0, dolock = 1, i; + u_int savelen = 0, oldlen = 0; + sysctlfn *fn; + void *oldp = 0; + void *newp = 0; + + if (new != NULL && (error = suser(p->p_ucred, &p->p_acflag))) return (error); - if (uap->old) + if (oldlenp) { + if (inkernel) { + oldlen = *oldlenp; + } else { + error = copyin(oldlenp, &oldlen, sizeof(oldlen)); + if (error) + return (error); + } + } + + if (old) oldp = malloc(oldlen, M_TEMP, M_WAITOK); - if (uap->newlen) { - newp = malloc(uap->newlen, M_TEMP, M_WAITOK); - error = copyin(uap->new, newp, uap->newlen); + if (newlen) { + newp = malloc(newlen, M_TEMP, M_WAITOK); + error = copyin(new, newp, newlen); } if (error) { if (oldp) @@ -490,17 +505,21 @@ __sysctl(p, uap, retval) return error; } - error = sysctl_root(0, name, uap->namelen, oldp, &oldlen, - newp, uap->newlen); + error = sysctl_root(0, name, namelen, oldp, &oldlen, + newp, newlen); if (!error || error == ENOMEM) { - if (uap->oldlenp) { - i = copyout(&oldlen, uap->oldlenp, sizeof(oldlen)); - if (i) - error = i; + if (oldlenp) { + if (inkernel) { + *oldlenp = oldlen; + } else { + i = copyout(&oldlen, oldlenp, sizeof(oldlen)); + if (i) + error = i; + } } if ((error == ENOMEM || !error ) && oldp) { - i = copyout(oldp, uap->old, oldlen); + i = copyout(oldp, old, oldlen); if (i) error = i; free(oldp, M_TEMP); @@ -544,8 +563,8 @@ __sysctl(p, uap, retval) default: return (EOPNOTSUPP); } - if (uap->old != NULL) { - if (!useracc(uap->old, oldlen, B_WRITE)) + if (old != NULL) { + if (!useracc(old, oldlen, B_WRITE)) return (EFAULT); while (memlock.sl_lock) { memlock.sl_want = 1; @@ -554,18 +573,18 @@ __sysctl(p, uap, retval) } memlock.sl_lock = 1; if (dolock) - vslock(uap->old, oldlen); + vslock(old, oldlen); savelen = oldlen; } - error = (*fn)(name + 1, uap->namelen - 1, uap->old, &oldlen, - uap->new, uap->newlen, p); + error = (*fn)(name + 1, namelen - 1, old, &oldlen, + new, newlen, p); - if (uap->old != NULL) { + if (old != NULL) { if (dolock) - vsunlock(uap->old, savelen, B_WRITE); + vsunlock(old, savelen, B_WRITE); memlock.sl_lock = 0; if (memlock.sl_want) { memlock.sl_want = 0; @@ -575,17 +594,23 @@ __sysctl(p, uap, retval) #if 0 if (error) { printf("SYSCTL_ERROR: "); - for(i=0;i<uap->namelen;i++) + for(i=0;i<namelen;i++) printf("%d ", name[i]); printf("= %d\n", error); } #endif if (error) return (error); - if (uap->oldlenp) - error = copyout(&oldlen, uap->oldlenp, sizeof(oldlen)); - *retval = oldlen; - return (0); + if (retval) + *retval = oldlen; + if (oldlenp) { + if (inkernel) { + *oldlenp = oldlen; + } else { + error = copyout(&oldlen, oldlenp, sizeof(oldlen)); + } + } + return (error); } /* @@ -1170,54 +1195,64 @@ ogetkerninfo(p, uap, retval) register struct getkerninfo_args *uap; int *retval; { - int error, name[5]; + int error, name[6]; u_int size; - if (uap->size && - (error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size)))) - return (error); - switch (uap->op & 0xff00) { case KINFO_RT: - name[0] = PF_ROUTE; - name[1] = 0; - name[2] = (uap->op & 0xff0000) >> 16; - name[3] = uap->op & 0xff; - name[4] = uap->arg; - error = net_sysctl(name, 5, uap->where, &size, NULL, 0, p); + name[0] = CTL_NET; + name[1] = PF_ROUTE; + name[2] = 0; + name[3] = (uap->op & 0xff0000) >> 16; + name[4] = uap->op & 0xff; + name[5] = uap->arg; + error = userland_sysctl(p, name, 6, uap->where, uap->size, + 0, 0, 0, 0); break; case KINFO_VNODE: - name[0] = KERN_VNODE; - error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); + name[0] = CTL_KERN; + name[1] = KERN_VNODE; + error = userland_sysctl(p, name, 2, uap->where, uap->size, + 0, 0, 0, 0); break; case KINFO_PROC: - name[0] = KERN_PROC; - name[1] = uap->op & 0xff; - name[2] = uap->arg; - error = kern_sysctl(name, 3, uap->where, &size, NULL, 0, p); + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = uap->op & 0xff; + name[3] = uap->arg; + error = userland_sysctl(p, name, 4, uap->where, uap->size, + 0, 0, 0, 0); break; case KINFO_FILE: - name[0] = KERN_FILE; - error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); + name[0] = CTL_KERN; + name[1] = KERN_FILE; + error = userland_sysctl(p, name, 2, uap->where, uap->size, + 0, 0, 0, 0); break; case KINFO_METER: - name[0] = VM_METER; - error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); + name[0] = CTL_VM; + name[1] = VM_METER; + error = userland_sysctl(p, name, 2, uap->where, uap->size, + 0, 0, 0, 0); break; case KINFO_LOADAVG: - name[0] = VM_LOADAVG; - error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p); + name[0] = CTL_VM; + name[1] = VM_LOADAVG; + error = userland_sysctl(p, name, 2, uap->where, uap->size, + 0, 0, 0, 0); break; case KINFO_CLOCKRATE: - name[0] = KERN_CLOCKRATE; - error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p); + name[0] = CTL_KERN; + name[1] = KERN_CLOCKRATE; + error = userland_sysctl(p, name, 2, uap->where, uap->size, + 0, 0, 0, 0); break; case KINFO_BSDI_SYSINFO: { diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index b83ab62..83d8d5a 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)kern_xxx.c 8.2 (Berkeley) 11/14/93 - * $Id: kern_xxx.c,v 1.13 1995/08/20 04:42:25 davidg Exp $ + * $Id: kern_xxx.c,v 1.14 1995/09/06 15:23:20 nate Exp $ */ #include <sys/param.h> @@ -94,10 +94,12 @@ ogethostname(p, uap, retval) struct gethostname_args *uap; int *retval; { - int name; + int name[2]; - name = KERN_HOSTNAME; - return (kern_sysctl(&name, 1, uap->hostname, &uap->len, 0, 0, p)); + name[0] = CTL_KERN; + name[1] = KERN_HOSTNAME; + return (userland_sysctl(p, name, 2, uap->hostname, &uap->len, + 1, 0, 0, 0)); } struct sethostname_args { @@ -111,13 +113,15 @@ osethostname(p, uap, retval) register struct sethostname_args *uap; int *retval; { - int name; + int name[2]; int error; + name[0] = CTL_KERN; + name[1] = KERN_HOSTNAME; if ((error = suser(p->p_ucred, &p->p_acflag))) return (error); - name = KERN_HOSTNAME; - return (kern_sysctl(&name, 1, 0, 0, uap->hostname, uap->len, p)); + return (userland_sysctl(p, name, 2, 0, 0, 0, + uap->hostname, uap->len, 0)); } struct gethostid_args { @@ -188,33 +192,36 @@ uname(p, uap, retval) struct uname_args *uap; int *retval; { - int name; - int len; - int rtval; + int name[2], len, rtval, junk; char *s, *us; - name = KERN_OSTYPE; + name[0] = CTL_KERN; + name[1] = KERN_OSTYPE; len = sizeof uap->name->sysname; - rtval = kern_sysctl(&name, 1, uap->name->sysname, &len, 0, 0, p); + rtval = userland_sysctl(p, name, 2, uap->name->sysname, &len, + 1, 0, 0, 0); if( rtval) return rtval; subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0); - name = KERN_HOSTNAME; + name[1] = KERN_HOSTNAME; len = sizeof uap->name->nodename; - rtval = kern_sysctl(&name, 1, uap->name->nodename, &len, 0, 0, p); + rtval = userland_sysctl(p, name, 2, uap->name->nodename, &len, + 1, 0, 0, 0); if( rtval) return rtval; subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0); - name = KERN_OSRELEASE; + name[1] = KERN_OSRELEASE; len = sizeof uap->name->release; - rtval = kern_sysctl(&name, 1, uap->name->release, &len, 0, 0, p); + rtval = userland_sysctl(p, name, 2, uap->name->release, &len, + 1, 0, 0, 0); if( rtval) return rtval; subyte( uap->name->release + sizeof(uap->name->release) - 1, 0); /* name = KERN_VERSION; len = sizeof uap->name->version; - rtval = kern_sysctl(&name, 1, uap->name->version, &len, 0, 0, p); + rtval = userland_sysctl(p, name, 2, uap->name->version, &len, + 1, 0, 0, 0); if( rtval) return rtval; subyte( uap->name->version + sizeof(uap->name->version) - 1, 0); */ @@ -233,9 +240,10 @@ uname(p, uap, retval) if( rtval) return rtval; - name = HW_MACHINE; + name[1] = HW_MACHINE; len = sizeof uap->name->machine; - rtval = hw_sysctl(&name, 1, uap->name->machine, &len, 0, 0, p); + rtval = userland_sysctl(p, name, 2, uap->name->machine, &len, + 1, 0, 0, 0); if( rtval) return rtval; subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0); |