From ccf259775958a38e65d78e77189f67eb0eb07672 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Wed, 6 Sep 2006 20:15:43 +0000 Subject: [PATCH] While convenient, avoid using alloca() for reasons specified in the BUGS section of the alloca(3) manpage. In particular, when the number of TCP sockets is several tens of thousand, trying to "sysctl -a" would SIGSEGV on the net.inet.tcp.pcblist entry (it would exceed the stacksize ulimit, in an undetectable manner). Reported by: Igor Sysoev --- sbin/sysctl/sysctl.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c index 3b40689ecf68..73bf68ddd928 100644 --- a/sbin/sysctl/sysctl.c +++ b/sbin/sysctl/sysctl.c @@ -541,7 +541,7 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind) static int show_var(int *oid, int nlen) { - u_char buf[BUFSIZ], *val, *p; + u_char buf[BUFSIZ], *val, *oval, *p; char name[BUFSIZ], *fmt, *sep; int qoid[CTL_MAXNAME+2]; int i; @@ -584,14 +584,21 @@ show_var(int *oid, int nlen) i = sysctl(oid, nlen, 0, &j, 0, 0); j += j; /* we want to be sure :-) */ - val = alloca(j + 1); + val = oval = malloc(j + 1); + if (val == NULL) { + warnx("malloc failed"); + return (-1); + } len = j; i = sysctl(oid, nlen, val, &len, 0, 0); - if (i || !len) + if (i || !len) { + free(oval); return (1); + } if (bflag) { fwrite(val, 1, len, stdout); + free(oval); return (0); } val[len] = '\0'; @@ -603,6 +610,7 @@ show_var(int *oid, int nlen) if (!nflag) printf("%s%s", name, sep); printf("%.*s", len, p); + free(oval); return (0); case 'I': @@ -630,6 +638,7 @@ show_var(int *oid, int nlen) len -= sizeof(int); p += sizeof(int); } + free(oval); return (0); case 'L': @@ -657,12 +666,14 @@ show_var(int *oid, int nlen) len -= sizeof(long); p += sizeof(long); } + free(oval); return (0); case 'P': if (!nflag) printf("%s%s", name, sep); printf("%p", *(void **)p); + free(oval); return (0); case 'T': @@ -683,12 +694,15 @@ show_var(int *oid, int nlen) if (func) { if (!nflag) printf("%s%s", name, sep); + free(oval); return ((*func)(len, p)); } /* FALLTHROUGH */ default: - if (!oflag && !xflag) + if (!oflag && !xflag) { + free(oval); return (1); + } if (!nflag) printf("%s%s", name, sep); printf("Format:%s Length:%d Dump:0x", fmt, len); @@ -696,8 +710,10 @@ show_var(int *oid, int nlen) printf("%02x", *p++); if (!xflag && len > 16) printf("..."); + free(oval); return (0); } + free(oval); return (1); }