mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Make the old compat functions use the sysctl front door, rather than
crashing through the walls. This should save Peters blood pressure and netscapes uname call.
This commit is contained in:
parent
a4cc272814
commit
b8da239623
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=12171
@ -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 @@ sysctl_root SYSCTL_HANDLER_ARGS
|
||||
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: {
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user