summaryrefslogtreecommitdiff
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2005-07-31 04:36:52 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2005-07-31 04:36:52 +0000
commit62d84ae7dbf17f958fadaf54eb348d051a02c678 (patch)
treebcc5021083f044d84180313f67e9af096b0ab56a /sys/kern/kern_sysctl.c
parent7f5924101ef06c4d3997b6942f55f0c64af1abaa (diff)
do not allocate huge kinfo_proc2 and eproc structures on the stack.
allocate them on startup if needed, and free them when done. discussion with pascoe, tested by dlg
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r--sys/kern/kern_sysctl.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index ac0e8d7dad5..f60cc100d65 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.127 2005/06/08 22:33:27 millert Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.128 2005/07/31 04:36:51 deraadt Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -1018,8 +1018,8 @@ sysctl_doproc(name, namelen, where, sizep)
char *where;
size_t *sizep;
{
- struct kinfo_proc2 kproc2;
- struct eproc eproc;
+ struct kinfo_proc2 *kproc2 = NULL;
+ struct eproc *eproc = NULL;
struct proc *p;
char *dp;
int arg, buflen, doingzomb, elem_size, elem_count;
@@ -1037,6 +1037,7 @@ sysctl_doproc(name, namelen, where, sizep)
op = name[1];
arg = op == KERN_PROC_ALL ? 0 : name[2];
elem_size = elem_count = 0;
+ eproc = malloc(sizeof(struct eproc), M_TEMP, M_WAITOK);
} else /* if (type == KERN_PROC2) */ {
if (namelen != 5 || name[3] < 0 || name[4] < 0)
return (EINVAL);
@@ -1044,6 +1045,7 @@ sysctl_doproc(name, namelen, where, sizep)
arg = name[2];
elem_size = name[3];
elem_count = name[4];
+ kproc2 = malloc(sizeof(struct kinfo_proc2), M_TEMP, M_WAITOK);
}
p = LIST_FIRST(&allproc);
doingzomb = 0;
@@ -1102,36 +1104,37 @@ again:
/* no filtering */
break;
default:
- return (EINVAL);
+ error = EINVAL;
+ goto err;
}
if (type == KERN_PROC) {
if (buflen >= sizeof(struct kinfo_proc)) {
- fill_eproc(p, &eproc);
+ fill_eproc(p, eproc);
error = copyout((caddr_t)p,
&((struct kinfo_proc *)dp)->kp_proc,
sizeof(struct proc));
if (error)
- return (error);
- error = copyout((caddr_t)&eproc,
+ goto err;
+ error = copyout((caddr_t)eproc,
&((struct kinfo_proc *)dp)->kp_eproc,
- sizeof(eproc));
+ sizeof(*eproc));
if (error)
- return (error);
+ goto err;
dp += sizeof(struct kinfo_proc);
buflen -= sizeof(struct kinfo_proc);
}
needed += sizeof(struct kinfo_proc);
} else /* if (type == KERN_PROC2) */ {
if (buflen >= elem_size && elem_count > 0) {
- fill_kproc2(p, &kproc2);
+ fill_kproc2(p, kproc2);
/*
* Copy out elem_size, but not larger than
* the size of a struct kinfo_proc2.
*/
- error = copyout(&kproc2, dp,
- min(sizeof(kproc2), elem_size));
+ error = copyout(kproc2, dp,
+ min(sizeof(*kproc2), elem_size));
if (error)
- return (error);
+ goto err;
dp += elem_size;
buflen -= elem_size;
elem_count--;
@@ -1146,13 +1149,20 @@ again:
}
if (where != NULL) {
*sizep = dp - where;
- if (needed > *sizep)
- return (ENOMEM);
+ if (needed > *sizep) {
+ error = ENOMEM;
+ goto err;
+ }
} else {
needed += KERN_PROCSLOP;
*sizep = needed;
}
- return (0);
+err:
+ if (eproc)
+ free(eproc, M_TEMP);
+ if (kproc2)
+ free(kproc2, M_TEMP);
+ return (error);
}
#endif /* SMALL_KERNEL */