Tighten up the string->integer conversion in sysctl(8):
(1) Reject zero-length strings for CTLTYPE_INT, _UINT, _LONG, _ULONG. Do not silently convert to 0. (2) When converting CTLTYPE_INT, _UINT, _LONG, and _ULONG, check the end pointer generated by strtol() and strtoul() rather than discarding it. Reject the string if either none of the string was useful for conversion to an integer, or if there was trailing garbage. I.e., we will not allow you to set a numeric sysctl to a value unless we can completely convert the string argument to a numeric value. I tripped over this when I put the following in /etc/sysctl.conf: kern.maxfiles="4000" Ouch.
This commit is contained in:
parent
47030ceaf2
commit
a78d3eaffc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=116383
@ -163,7 +163,7 @@ parse(char *string)
|
|||||||
size_t newsize = 0;
|
size_t newsize = 0;
|
||||||
quad_t quadval;
|
quad_t quadval;
|
||||||
int mib[CTL_MAXNAME];
|
int mib[CTL_MAXNAME];
|
||||||
char *cp, *bufp, buf[BUFSIZ], fmt[BUFSIZ];
|
char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ];
|
||||||
u_int kind;
|
u_int kind;
|
||||||
|
|
||||||
bufp = buf;
|
bufp = buf;
|
||||||
@ -198,25 +198,45 @@ parse(char *string)
|
|||||||
|
|
||||||
if (!(kind&CTLFLAG_WR))
|
if (!(kind&CTLFLAG_WR))
|
||||||
errx(1, "oid '%s' is read only", bufp);
|
errx(1, "oid '%s' is read only", bufp);
|
||||||
|
|
||||||
|
if ((kind & CTLTYPE) == CTLTYPE_INT ||
|
||||||
|
(kind & CTLTYPE) == CTLTYPE_UINT ||
|
||||||
|
(kind & CTLTYPE) == CTLTYPE_LONG ||
|
||||||
|
(kind & CTLTYPE) == CTLTYPE_ULONG) {
|
||||||
|
if (strlen(newval) == 0)
|
||||||
|
errx(1, "empty numeric value");
|
||||||
|
}
|
||||||
|
|
||||||
switch (kind & CTLTYPE) {
|
switch (kind & CTLTYPE) {
|
||||||
case CTLTYPE_INT:
|
case CTLTYPE_INT:
|
||||||
intval = (int) strtol(newval, NULL, 0);
|
intval = (int) strtol(newval, &endptr, 0);
|
||||||
|
if (endptr == newval || *endptr != '\0')
|
||||||
|
errx(1, "invalid integer '%s'",
|
||||||
|
newval);
|
||||||
newval = &intval;
|
newval = &intval;
|
||||||
newsize = sizeof(intval);
|
newsize = sizeof(intval);
|
||||||
break;
|
break;
|
||||||
case CTLTYPE_UINT:
|
case CTLTYPE_UINT:
|
||||||
uintval = (int) strtoul(newval, NULL, 0);
|
uintval = (int) strtoul(newval, &endptr, 0);
|
||||||
|
if (endptr == newval || *endptr != '\0')
|
||||||
|
errx(1, "invalid unsigned integer '%s'",
|
||||||
|
newval);
|
||||||
newval = &uintval;
|
newval = &uintval;
|
||||||
newsize = sizeof uintval;
|
newsize = sizeof uintval;
|
||||||
break;
|
break;
|
||||||
case CTLTYPE_LONG:
|
case CTLTYPE_LONG:
|
||||||
longval = strtol(newval, NULL, 0);
|
longval = strtol(newval, &endptr, 0);
|
||||||
|
if (endptr == newval || *endptr != '\0')
|
||||||
|
errx(1, "invalid long integer '%s'",
|
||||||
|
newval);
|
||||||
newval = &longval;
|
newval = &longval;
|
||||||
newsize = sizeof longval;
|
newsize = sizeof longval;
|
||||||
break;
|
break;
|
||||||
case CTLTYPE_ULONG:
|
case CTLTYPE_ULONG:
|
||||||
ulongval = strtoul(newval, NULL, 0);
|
ulongval = strtoul(newval, &endptr, 0);
|
||||||
|
if (endptr == newval || *endptr != '\0')
|
||||||
|
errx(1, "invalid unsigned long integer"
|
||||||
|
" '%s'", newval);
|
||||||
newval = &ulongval;
|
newval = &ulongval;
|
||||||
newsize = sizeof ulongval;
|
newsize = sizeof ulongval;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user