summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjhb <jhb@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>2020-10-30 21:13:05 +0000
committerjhb <jhb@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>2020-10-30 21:13:05 +0000
commitcb5818214d7d321898de92e1652fe575011f750b (patch)
tree2b231de536c47fc9e199d5aa18709c75db171824
parent0bb770f63650db1c57f6751e804ff3abed0bdb9e (diff)
downloadfreebsd-cb5818214d7d321898de92e1652fe575011f750b.tar.gz
freebsd-cb5818214d7d321898de92e1652fe575011f750b.tar.bz2
Use a dynamic buffer for the copy of a node's new value.
This permits setting a node's value to a string longer than BUFSIZ. Reported by: Sony Arpita Das @ Chelsio Reviewed by: freqlabs MFC after: 1 week Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D27027 git-svn-id: http://svn.freebsd.org/base/head@367188 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
-rw-r--r--sbin/sysctl/sysctl.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 545030b2f10..a2b02c86fb4 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -344,13 +344,13 @@ parse_numeric(const char *newvalstr, const char *fmt, u_int kind,
static int
parse(const char *string, int lineno)
{
- int len, i, j;
+ int len, i, j, save_errno;
const void *newval;
char *newvalstr = NULL;
void *newbuf;
size_t newsize = Bflag;
int mib[CTL_MAXNAME];
- char *cp, *bufp, buf[BUFSIZ], fmt[BUFSIZ], line[BUFSIZ];
+ char *cp, *bufp, *buf, fmt[BUFSIZ], line[BUFSIZ];
u_int kind;
if (lineno)
@@ -365,11 +365,7 @@ parse(const char *string, int lineno)
* Whitespace surrounding the delimiter is trimmed.
* Quotes around the value are stripped.
*/
- cp = buf;
- if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) {
- warnx("oid too long: '%s'%s", string, line);
- return (1);
- }
+ cp = buf = strdup(string);
bufp = strsep(&cp, "=:");
if (cp != NULL) {
/* Tflag just lists tunables, do not allow assignment */
@@ -403,22 +399,24 @@ parse(const char *string, int lineno)
*/
len = name2oid(bufp, mib);
if (len < 0) {
- if (iflag)
+ if (iflag) {
+ free(buf);
return (0);
- if (qflag)
- return (1);
- else {
+ }
+ if (!qflag) {
if (errno == ENOENT) {
warnx("unknown oid '%s'%s", bufp, line);
} else {
warn("unknown oid '%s'%s", bufp, line);
}
- return (1);
}
+ free(buf);
+ return (1);
}
if (oidfmt(mib, len, fmt, &kind)) {
warn("couldn't find format of oid '%s'%s", bufp, line);
+ free(buf);
if (iflag)
return (1);
else
@@ -430,6 +428,7 @@ parse(const char *string, int lineno)
* show the node and its children. Otherwise, set the new value.
*/
if (newvalstr == NULL || dflag) {
+ free(buf);
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
if (dflag) {
i = show_var(mib, len, false);
@@ -450,6 +449,7 @@ parse(const char *string, int lineno)
*/
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
warnx("oid '%s' isn't a leaf node%s", bufp, line);
+ free(buf);
return (1);
}
@@ -459,6 +459,7 @@ parse(const char *string, int lineno)
warnx("Tunable values are set in /boot/loader.conf");
} else
warnx("oid '%s' is read only%s", bufp, line);
+ free(buf);
return (1);
}
@@ -477,6 +478,7 @@ parse(const char *string, int lineno)
case CTLTYPE_U64:
if (strlen(newvalstr) == 0) {
warnx("empty numeric value");
+ free(buf);
return (1);
}
/* FALLTHROUGH */
@@ -485,6 +487,7 @@ parse(const char *string, int lineno)
default:
warnx("oid '%s' is type %d, cannot set that%s",
bufp, kind & CTLTYPE, line);
+ free(buf);
return (1);
}
@@ -503,6 +506,7 @@ parse(const char *string, int lineno)
warnx("invalid %s '%s'%s",
ctl_typename[kind & CTLTYPE], cp, line);
free(newbuf);
+ free(buf);
return (1);
}
}
@@ -515,10 +519,12 @@ parse(const char *string, int lineno)
*/
i = show_var(mib, len, false);
if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
+ save_errno = errno;
free(newbuf);
+ free(buf);
if (!i && !bflag)
putchar('\n');
- switch (errno) {
+ switch (save_errno) {
case EOPNOTSUPP:
warnx("%s: value is not available%s",
string, line);
@@ -532,11 +538,12 @@ parse(const char *string, int lineno)
string, line);
return (1);
default:
- warn("%s%s", string, line);
+ warnc(save_errno, "%s%s", string, line);
return (1);
}
}
free(newbuf);
+ free(buf);
if (!bflag)
printf(" -> ");
i = nflag;