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
This commit is contained in:
ru 2006-09-06 20:15:43 +00:00
parent 50aef09189
commit a91c39740f

View File

@ -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);
}