summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/ntp_control.c
diff options
context:
space:
mode:
authorgjb <gjb@FreeBSD.org>2016-01-04 19:19:48 +0000
committergjb <gjb@FreeBSD.org>2016-01-04 19:19:48 +0000
commitccde53b74b7bd32198439bfa247743fbf4c91a76 (patch)
tree3882b41d5bbb0e4ad065fa3392bf2eab80a3d4e3 /contrib/ntp/ntpd/ntp_control.c
parent04942f20347330d49715904f537ca62d33372684 (diff)
parentc9ef17cbe9e3b753415472a271916c098cab7780 (diff)
downloadFreeBSD-src-ccde53b74b7bd32198439bfa247743fbf4c91a76.zip
FreeBSD-src-ccde53b74b7bd32198439bfa247743fbf4c91a76.tar.gz
MFH r289384-r293170
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'contrib/ntp/ntpd/ntp_control.c')
-rw-r--r--contrib/ntp/ntpd/ntp_control.c85
1 files changed, 50 insertions, 35 deletions
diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c
index 5bd12dc..4e5b645 100644
--- a/contrib/ntp/ntpd/ntp_control.c
+++ b/contrib/ntp/ntpd/ntp_control.c
@@ -8,6 +8,7 @@
*/
#ifdef HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -32,15 +33,11 @@
#include "ntp_leapsec.h"
#include "ntp_md5.h" /* provides OpenSSL digest API */
#include "lib_strbuf.h"
+#include <rc_cmdlength.h>
#ifdef KERNEL_PLL
# include "ntp_syscall.h"
#endif
-extern size_t remoteconfig_cmdlength( const char *src_buf, const char *src_end );
-
-#ifndef MIN
-#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
-#endif
/*
* Structure to hold request procedure information
@@ -428,10 +425,10 @@ static const struct ctl_var sys_var[] = {
{ CS_TIMER_XMTS, RO, "timer_xmts" }, /* 87 */
{ CS_FUZZ, RO, "fuzz" }, /* 88 */
{ CS_WANDER_THRESH, RO, "clk_wander_threshold" }, /* 89 */
-#ifdef LEAP_SMEAR
+
{ CS_LEAPSMEARINTV, RO, "leapsmearinterval" }, /* 90 */
{ CS_LEAPSMEAROFFS, RO, "leapsmearoffset" }, /* 91 */
-#endif /* LEAP_SMEAR */
+
#ifdef AUTOKEY
{ CS_FLAGS, RO, "flags" }, /* 1 + CS_MAX_NOAUTOKEY */
{ CS_HOST, RO, "host" }, /* 2 + CS_MAX_NOAUTOKEY */
@@ -892,6 +889,28 @@ save_config(
int restrict_mask
)
{
+ /* block directory traversal by searching for characters that
+ * indicate directory components in a file path.
+ *
+ * Conceptually we should be searching for DIRSEP in filename,
+ * however Windows actually recognizes both forward and
+ * backslashes as equivalent directory separators at the API
+ * level. On POSIX systems we could allow '\\' but such
+ * filenames are tricky to manipulate from a shell, so just
+ * reject both types of slashes on all platforms.
+ */
+ /* TALOS-CAN-0062: block directory traversal for VMS, too */
+ static const char * illegal_in_filename =
+#if defined(VMS)
+ ":[]" /* do not allow drive and path components here */
+#elif defined(SYS_WINNT)
+ ":\\/" /* path and drive separators */
+#else
+ "\\/" /* separator and critical char for POSIX */
+#endif
+ ;
+
+
char reply[128];
#ifdef SAVECONFIG
char filespec[128];
@@ -946,15 +965,9 @@ save_config(
localtime(&now)))
strlcpy(filename, filespec, sizeof(filename));
- /*
- * Conceptually we should be searching for DIRSEP in filename,
- * however Windows actually recognizes both forward and
- * backslashes as equivalent directory separators at the API
- * level. On POSIX systems we could allow '\\' but such
- * filenames are tricky to manipulate from a shell, so just
- * reject both types of slashes on all platforms.
- */
- if (strchr(filename, '\\') || strchr(filename, '/')) {
+ /* block directory/drive traversal */
+ /* TALOS-CAN-0062: block directory traversal for VMS, too */
+ if (NULL != strpbrk(filename, illegal_in_filename)) {
snprintf(reply, sizeof(reply),
"saveconfig does not allow directory in filename");
ctl_putdata(reply, strlen(reply), 0);
@@ -1409,7 +1422,7 @@ ctl_putstr(
memcpy(buffer, tag, tl);
cp = buffer + tl;
if (len > 0) {
- NTP_INSIST(tl + 3 + len <= sizeof(buffer));
+ INSIST(tl + 3 + len <= sizeof(buffer));
*cp++ = '=';
*cp++ = '"';
memcpy(cp, data, len);
@@ -1444,7 +1457,7 @@ ctl_putunqstr(
memcpy(buffer, tag, tl);
cp = buffer + tl;
if (len > 0) {
- NTP_INSIST(tl + 1 + len <= sizeof(buffer));
+ INSIST(tl + 1 + len <= sizeof(buffer));
*cp++ = '=';
memcpy(cp, data, len);
cp += len;
@@ -1473,7 +1486,7 @@ ctl_putdblf(
while (*cq != '\0')
*cp++ = *cq++;
*cp++ = '=';
- NTP_INSIST((size_t)(cp - buffer) < sizeof(buffer));
+ INSIST((size_t)(cp - buffer) < sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer), use_f ? "%.*f" : "%.*g",
precision, d);
cp += strlen(cp);
@@ -1499,7 +1512,7 @@ ctl_putuint(
*cp++ = *cq++;
*cp++ = '=';
- NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
+ INSIST((cp - buffer) < (int)sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer), "%lu", uval);
cp += strlen(cp);
ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
@@ -1526,7 +1539,7 @@ ctl_putcal(
pcal->hour,
pcal->minute
);
- NTP_INSIST(numch < sizeof(buffer));
+ INSIST(numch < sizeof(buffer));
ctl_putdata(buffer, numch, 0);
return;
@@ -1557,7 +1570,7 @@ ctl_putfs(
tm = gmtime(&fstamp);
if (NULL == tm)
return;
- NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
+ INSIST((cp - buffer) < (int)sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer),
"%04d%02d%02d%02d%02d", tm->tm_year + 1900,
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
@@ -1586,7 +1599,7 @@ ctl_puthex(
*cp++ = *cq++;
*cp++ = '=';
- NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
+ INSIST((cp - buffer) < (int)sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%lx", uval);
cp += strlen(cp);
ctl_putdata(buffer,(unsigned)( cp - buffer ), 0);
@@ -1612,7 +1625,7 @@ ctl_putint(
*cp++ = *cq++;
*cp++ = '=';
- NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
+ INSIST((cp - buffer) < (int)sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer), "%ld", ival);
cp += strlen(cp);
ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
@@ -1638,7 +1651,7 @@ ctl_putts(
*cp++ = *cq++;
*cp++ = '=';
- NTP_INSIST((size_t)(cp - buffer) < sizeof(buffer));
+ INSIST((size_t)(cp - buffer) < sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%08x.%08x",
(u_int)ts->l_ui, (u_int)ts->l_uf);
cp += strlen(cp);
@@ -1670,7 +1683,7 @@ ctl_putadr(
cq = numtoa(addr32);
else
cq = stoa(addr);
- NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
+ INSIST((cp - buffer) < (int)sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer), "%s", cq);
cp += strlen(cp);
ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
@@ -1741,7 +1754,7 @@ ctl_putarray(
if (i == 0)
i = NTP_SHIFT;
i--;
- NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
+ INSIST((cp - buffer) < (int)sizeof(buffer));
snprintf(cp, sizeof(buffer) - (cp - buffer),
" %.2f", arr[i] * 1e3);
cp += strlen(cp);
@@ -2410,6 +2423,9 @@ ctl_putsys(
ntohl(hostval.tstamp));
break;
#endif /* AUTOKEY */
+
+ default:
+ break;
}
}
@@ -2933,7 +2949,6 @@ ctl_getitem(
* Look for a first character match on the tag. If we find
* one, see if it is a full match.
*/
- v = var_list;
cp = reqpt;
for (v = var_list; !(EOV & v->flags); v++) {
if (!(PADDING & v->flags) && *cp == *(v->text)) {
@@ -3115,7 +3130,7 @@ read_peervars(void)
ctl_error(CERR_UNKNOWNVAR);
return;
}
- NTP_INSIST(v->code < COUNTOF(wants));
+ INSIST(v->code < COUNTOF(wants));
wants[v->code] = 1;
gotvar = 1;
}
@@ -3158,19 +3173,19 @@ read_sysvars(void)
gotvar = 0;
while (NULL != (v = ctl_getitem(sys_var, &valuep))) {
if (!(EOV & v->flags)) {
- NTP_INSIST(v->code < wants_count);
+ INSIST(v->code < wants_count);
wants[v->code] = 1;
gotvar = 1;
} else {
v = ctl_getitem(ext_sys_var, &valuep);
- NTP_INSIST(v != NULL);
+ INSIST(v != NULL);
if (EOV & v->flags) {
ctl_error(CERR_UNKNOWNVAR);
free(wants);
return;
}
n = v->code + CS_MAXCODE + 1;
- NTP_INSIST(n < wants_count);
+ INSIST(n < wants_count);
wants[n] = 1;
gotvar = 1;
}
@@ -4404,7 +4419,7 @@ read_clockstatus(
gotvar = TRUE;
} else {
v = ctl_getitem(kv, &valuep);
- NTP_INSIST(NULL != v);
+ INSIST(NULL != v);
if (EOV & v->flags) {
ctl_error(CERR_UNKNOWNVAR);
free(wants);
@@ -4800,7 +4815,7 @@ report_event(
for (i = 1; i <= CS_VARLIST; i++)
ctl_putsys(i);
} else {
- NTP_INSIST(peer != NULL);
+ INSIST(peer != NULL);
rpkt.associd = htons(peer->associd);
rpkt.status = htons(ctlpeerstatus(peer));
@@ -4905,7 +4920,7 @@ count_var(
while (!(EOV & (k++)->flags))
c++;
- NTP_ENSURE(c <= USHRT_MAX);
+ ENSURE(c <= USHRT_MAX);
return (u_short)c;
}
OpenPOWER on IntegriCloud