Sophie

Sophie

distrib > Mageia > 5 > i586 > by-pkgid > cd0f440b578c03b7706d19492362a305 > files > 31

ntp-4.2.6p5-24.7.mga5.src.rpm

diff -up ntp-4.2.6p5/ntpd/ntp_control.c.cve-2015-5146 ntp-4.2.6p5/ntpd/ntp_control.c
--- ntp-4.2.6p5/ntpd/ntp_control.c.cve-2015-5146	2015-07-16 15:37:02.297977248 +0200
+++ ntp-4.2.6p5/ntpd/ntp_control.c	2015-07-16 15:37:02.403977575 +0200
@@ -2471,6 +2471,35 @@ write_variables(
 	ctl_flushpkt(0);
 }
 
+/* Bug 2853 */
+/* evaluate the length of the command sequence. This breaks at the first
+ * char that is not >= SPACE and <= 127 after trimming from the right.
+ */
+static size_t
+cmdlength(
+	const char *src_buf,
+	const char *src_end
+	)
+{
+	const char *scan;
+	unsigned char ch;
+
+	/* trim whitespace & garbage from the right */
+	while (src_end != src_buf) {
+		ch = src_end[-1];
+		if (ch > ' ' && ch < 128)
+			break;
+		--src_end;
+	}
+	/* now do a forward scan */
+	for (scan = src_buf; scan != src_end; ++scan) {
+		ch = scan[0];
+		if ((ch < ' ' || ch >= 128) && ch != '\t')
+			break;
+	}
+	return (size_t)(scan - src_buf);
+}
+
 /*
  * configure() processes ntpq :config/config-from-file, allowing
  *		generic runtime reconfiguration.
@@ -2482,7 +2511,6 @@ static void configure(
 {
 	size_t data_count;
 	int retval;
-	int replace_nl;
 
 	/* I haven't yet implemented changes to an existing association.
 	 * Hence check if the association id is 0
@@ -2506,7 +2534,7 @@ static void configure(
 	}
 
 	/* Initialize the remote config buffer */
-	data_count = reqend - reqpt;
+	data_count = cmdlength(reqpt, reqend);
 
 	if (data_count > sizeof(remote_config.buffer) - 2) {
 		snprintf(remote_config.err_msg,
@@ -2520,33 +2548,41 @@ static void configure(
 			stoa(&rbufp->recv_srcadr));
 		return;
 	}
+	/* Bug 2853 -- check if all characters were acceptable */
+	if (data_count != (size_t)(reqend - reqpt)) {
+		snprintf(remote_config.err_msg,
+			 sizeof(remote_config.err_msg),
+			 "runtime configuration failed: request contains an unprintable character");
+		ctl_putdata(remote_config.err_msg,
+			    strlen(remote_config.err_msg), 0);
+		ctl_flushpkt(0);
+		msyslog(LOG_NOTICE,
+			"runtime config from %s rejected: request contains an unprintable character: %0x",
+			stoa(&rbufp->recv_srcadr),
+			reqpt[data_count]);
+		return;
+	}
 
 	memcpy(remote_config.buffer, reqpt, data_count);
-	if (data_count > 0
-	    && '\n' != remote_config.buffer[data_count - 1])
-		remote_config.buffer[data_count++] = '\n';
+	/* The buffer has no trailing linefeed or NUL right now. For
+	 * logging, we do not want a newline, so we do that first after
+	 * adding the necessary NUL byte.
+	 */
 	remote_config.buffer[data_count] = '\0';
-	remote_config.pos = 0;
-	remote_config.err_pos = 0;
-	remote_config.no_errors = 0;
-
-	/* do not include terminating newline in log */
-	if (data_count > 0
-	    && '\n' == remote_config.buffer[data_count - 1]) {
-		remote_config.buffer[data_count - 1] = '\0';
-		replace_nl = 1;
-	} else
-		replace_nl = 0;
-
 	DPRINTF(1, ("Got Remote Configuration Command: %s\n",
 		remote_config.buffer));
 	msyslog(LOG_NOTICE, "%s config: %s",
 		stoa(&rbufp->recv_srcadr),
 		remote_config.buffer);
 
-	if (replace_nl)
-		remote_config.buffer[data_count - 1] = '\n';
-
+	/* Now we have to make sure there is a NL/NUL sequence at the
+	 * end of the buffer before we parse it.
+	 */
+	remote_config.buffer[data_count++] = '\n';
+	remote_config.buffer[data_count] = '\0';
+	remote_config.pos = 0;
+	remote_config.err_pos = 0;
+	remote_config.no_errors = 0;
 	config_remotely(&rbufp->recv_srcadr);
 
 	/*