summaryrefslogtreecommitdiffstats
path: root/sbin/sysctl
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2006-09-06 20:15:43 +0000
committerru <ru@FreeBSD.org>2006-09-06 20:15:43 +0000
commita91c39740f9997269193da0d48c103338454d72d (patch)
tree571226944f09f8ee848c7b08af2e1fdded662c59 /sbin/sysctl
parent50aef091890514c5738156130ba23bdfb2592788 (diff)
downloadFreeBSD-src-a91c39740f9997269193da0d48c103338454d72d.zip
FreeBSD-src-a91c39740f9997269193da0d48c103338454d72d.tar.gz
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
Diffstat (limited to 'sbin/sysctl')
-rw-r--r--sbin/sysctl/sysctl.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 3b40689..73bf68d 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);
}
OpenPOWER on IntegriCloud