From 26bb1685bd1425bcd855e721b426de108ec62e22 Mon Sep 17 00:00:00 2001 From: christos Date: Fri, 27 Oct 2006 16:49:01 +0000 Subject: [PATCH] don't allocate large buffers on the stack. --- sys/miscfs/procfs/procfs_linux.c | 93 ++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/sys/miscfs/procfs/procfs_linux.c b/sys/miscfs/procfs/procfs_linux.c index 3653b3c97865..5d052aa9980e 100644 --- a/sys/miscfs/procfs/procfs_linux.c +++ b/sys/miscfs/procfs/procfs_linux.c @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_linux.c,v 1.28 2006/10/23 18:19:14 elad Exp $ */ +/* $NetBSD: procfs_linux.c,v 1.29 2006/10/27 16:49:01 christos Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.28 2006/10/23 18:19:14 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.29 2006/10/27 16:49:01 christos Exp $"); #include #include @@ -66,6 +66,8 @@ extern int max_devsw_convs; #define PGTOB(p) ((unsigned long)(p) << PAGE_SHIFT) #define PGTOKB(p) ((unsigned long)(p) << (PAGE_SHIFT - 10)) +#define LBFSZ (8 * 1024) + /* * Linux compatible /proc/meminfo. Only active when the -o linux * mountflag is used. @@ -74,10 +76,13 @@ int procfs_domeminfo(struct lwp *curl __unused, struct proc *p __unused, struct pfsnode *pfs __unused, struct uio *uio) { - char bf[512]; + char *bf; int len; + int error = 0; - len = snprintf(bf, sizeof bf, + bf = malloc(LBFSZ, M_TEMP, M_WAITOK); + + len = snprintf(bf, LBFSZ, " total: used: free: shared: buffers: cached:\n" "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n" "Swap: %8lu %8lu %8lu\n" @@ -106,9 +111,12 @@ procfs_domeminfo(struct lwp *curl __unused, struct proc *p __unused, PGTOKB(uvmexp.swpages - uvmexp.swpginuse)); if (len == 0) - return 0; + goto out; - return (uiomove_frombuf(bf, len, uio)); + error = uiomove_frombuf(bf, len, uio); +out: + free(bf, M_TEMP); + return error; } /* @@ -119,43 +127,46 @@ int procfs_dodevices(struct lwp *curl __unused, struct proc *p __unused, struct pfsnode *pfs __unused, struct uio *uio) { - char bf[4096]; + char *bf; int offset = 0; - int i; + int i, error = ENAMETOOLONG; - offset += snprintf(&bf[offset], sizeof(bf) - offset, - "Character devices:\n"); - if (offset >= sizeof(bf)) - return ENAMETOOLONG; + bf = malloc(LBFSZ, M_TEMP, M_WAITOK); + + offset += snprintf(&bf[offset], LBFSZ - offset, "Character devices:\n"); + if (offset >= LBFSZ) + goto out; for (i = 0; i < max_devsw_convs; i++) { if ((devsw_conv[i].d_name == NULL) || (devsw_conv[i].d_cmajor == -1)) continue; - offset += snprintf(&bf[offset], sizeof(bf) - offset, + offset += snprintf(&bf[offset], LBFSZ - offset, "%3d %s\n", devsw_conv[i].d_cmajor, devsw_conv[i].d_name); - if (offset >= sizeof(bf)) - return ENAMETOOLONG; + if (offset >= LBFSZ) + goto out; } - offset += snprintf(&bf[offset], sizeof(bf) - offset, - "\nBlock devices:\n"); - if (offset >= sizeof(bf)) - return ENAMETOOLONG; + offset += snprintf(&bf[offset], LBFSZ - offset, "\nBlock devices:\n"); + if (offset >= LBFSZ) + goto out; for (i = 0; i < max_devsw_convs; i++) { if ((devsw_conv[i].d_name == NULL) || (devsw_conv[i].d_bmajor == -1)) continue; - offset += snprintf(&bf[offset], sizeof(bf) - offset, + offset += snprintf(&bf[offset], LBFSZ - offset, "%3d %s\n", devsw_conv[i].d_bmajor, devsw_conv[i].d_name); - if (offset >= sizeof(bf)) - return ENAMETOOLONG; + if (offset >= LBFSZ) + goto out; } - return (uiomove_frombuf(bf, offset, uio)); + error = uiomove_frombuf(bf, offset, uio); +out: + free(bf, M_TEMP); + return error; } /* @@ -166,7 +177,7 @@ int procfs_do_pid_stat(struct lwp *curl __unused, struct lwp *l, struct pfsnode *pfs __unused, struct uio *uio) { - char bf[512]; + char *bf; struct proc *p = l->l_proc; int len; struct tty *tty = p->p_session->s_ttyp; @@ -175,6 +186,9 @@ procfs_do_pid_stat(struct lwp *curl __unused, struct lwp *l, struct vm_map *map = &p->p_vmspace->vm_map; struct vm_map_entry *entry; unsigned long stext = 0, etext = 0, sstack = 0; + int error = 0; + + bf = malloc(LBFSZ, M_TEMP, M_WAITOK); if (map != &curproc->p_vmspace->vm_map) vm_map_lock_read(map); @@ -200,7 +214,7 @@ procfs_do_pid_stat(struct lwp *curl __unused, struct lwp *l, if (map != &curproc->p_vmspace->vm_map) vm_map_unlock_read(map); - len = snprintf(bf, sizeof(bf), + len = snprintf(bf, LBFSZ, "%d (%s) %c %d %d %d %d %d " "%u " "%lu %lu %lu %lu %lu %lu %lu %lu " @@ -259,16 +273,19 @@ procfs_do_pid_stat(struct lwp *curl __unused, struct lwp *l, 0); /* XXX: processor */ if (len == 0) - return 0; + goto out; - return (uiomove_frombuf(bf, len, uio)); + error = uiomove_frombuf(bf, len, uio); +out: + free(bf, M_TEMP); + return error; } int procfs_docpuinfo(struct lwp *curl __unused, struct proc *p __unused, struct pfsnode *pfs __unused, struct uio *uio) { - int len = 4096; + int len = LBFSZ; char *bf = malloc(len, M_TEMP, M_WAITOK); int error; @@ -292,35 +309,42 @@ int procfs_douptime(struct lwp *curl __unused, struct proc *p __unused, struct pfsnode *pfs __unused, struct uio *uio) { - char bf[512]; + char *bf; int len; struct timeval runtime; u_int64_t idle; + int error = 0; + + bf = malloc(LBFSZ, M_TEMP, M_WAITOK); timersub(&curcpu()->ci_schedstate.spc_runtime, &boottime, &runtime); idle = curcpu()->ci_schedstate.spc_cp_time[CP_IDLE]; - len = snprintf(bf, sizeof(bf), + len = snprintf(bf, LBFSZ, "%lu.%02lu %" PRIu64 ".%02" PRIu64 "\n", runtime.tv_sec, runtime.tv_usec / 10000, idle / hz, (((idle % hz) * 100) / hz) % 100); if (len == 0) - return 0; + goto out; - return (uiomove_frombuf(bf, len, uio)); + error = uiomove_frombuf(bf, len, uio); +out: + free(bf, M_TEMP); + return error; } int procfs_domounts(struct lwp *curl __unused, struct proc *p __unused, struct pfsnode *pfs __unused, struct uio *uio) { - char bf[512], *mtab = NULL; + char *bf, *mtab = NULL; const char *fsname; size_t len, mtabsz = 0; struct mount *mp, *nmp; struct statvfs *sfs; int error = 0; + bf = malloc(LBFSZ, M_TEMP, M_WAITOK); simple_lock(&mountlist_slock); for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; mp = nmp) { @@ -338,7 +362,7 @@ procfs_domounts(struct lwp *curl __unused, struct proc *p __unused, else if (strcmp(fsname, "ext2fs") == 0) fsname = "ext2"; - len = snprintf(bf, sizeof(bf), "%s %s %s %s%s%s%s%s%s 0 0\n", + len = snprintf(bf, LBFSZ, "%s %s %s %s%s%s%s%s%s 0 0\n", sfs->f_mntfromname, sfs->f_mntonname, fsname, @@ -359,6 +383,7 @@ procfs_domounts(struct lwp *curl __unused, struct proc *p __unused, vfs_unbusy(mp); } simple_unlock(&mountlist_slock); + free(bf, M_TEMP); if (mtabsz > 0) { error = uiomove_frombuf(mtab, mtabsz, uio);