summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/ntp_control.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/ntpd/ntp_control.c')
-rw-r--r--contrib/ntp/ntpd/ntp_control.c88
1 files changed, 49 insertions, 39 deletions
diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c
index 8ad1faf..7736311 100644
--- a/contrib/ntp/ntpd/ntp_control.c
+++ b/contrib/ntp/ntpd/ntp_control.c
@@ -3,10 +3,6 @@
* traps. Provides service to ntpq and others.
*/
-/*
- * $FreeBSD: stable/10/contrib/ntp/ntpd/ntp_control.c 276072 2014-12-22 19:07:16Z delphij $
- */
-
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -32,15 +28,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 +420,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 +884,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 +960,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 +1417,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 +1452,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 +1481,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 +1507,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 +1534,7 @@ ctl_putcal(
pcal->hour,
pcal->minute
);
- NTP_INSIST(numch < sizeof(buffer));
+ INSIST(numch < sizeof(buffer));
ctl_putdata(buffer, numch, 0);
return;
@@ -1557,7 +1565,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 +1594,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 +1620,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 +1646,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 +1678,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 +1749,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 +2418,9 @@ ctl_putsys(
ntohl(hostval.tstamp));
break;
#endif /* AUTOKEY */
+
+ default:
+ break;
}
}
@@ -2933,7 +2944,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 +3125,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 +3168,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 +4414,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 +4810,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 +4915,7 @@ count_var(
while (!(EOV & (k++)->flags))
c++;
- NTP_ENSURE(c <= USHRT_MAX);
+ ENSURE(c <= USHRT_MAX);
return (u_short)c;
}
OpenPOWER on IntegriCloud