Blame SOURCES/ntp-4.2.6p5-cve-2017-6464.patch

edcb74
2017-02-12 09:49:29+01:00, perlinger@ntp.org
edcb74
  [Sec 3389] NTP-01-016: Denial of Service via Malformed Config
edcb74
edcb74
diff -up ntp-4.2.6p5/ntpd/ntp_config.c.cve-2017-6464 ntp-4.2.6p5/ntpd/ntp_config.c
edcb74
--- ntp-4.2.6p5/ntpd/ntp_config.c.cve-2017-6464	2017-03-22 12:54:11.257454635 +0100
edcb74
+++ ntp-4.2.6p5/ntpd/ntp_config.c	2017-03-22 12:57:06.919024166 +0100
edcb74
@@ -311,6 +311,9 @@ void ntpd_set_tod_using(const char *);
edcb74
 static u_int32 get_pfxmatch(const char **, struct masks *);
edcb74
 static u_int32 get_match(const char *, struct masks *);
edcb74
 static u_int32 get_logmask(const char *);
edcb74
+static int/*BOOL*/ is_refclk_addr(const struct address_node * addr);
edcb74
+
edcb74
+
edcb74
 static int getnetnum(const char *num,sockaddr_u *addr, int complain,
edcb74
 		     enum gnn_type a_type);
edcb74
 static int get_multiple_netnums(const char *num, sockaddr_u *addr,
edcb74
@@ -1342,7 +1344,10 @@ create_peer_node(
edcb74
 			break;
edcb74
 
edcb74
 		case T_Ttl:
edcb74
-			if (my_node->ttl >= MAX_TTL) {
edcb74
+			if (is_refclk_addr(addr)) {
edcb74
+				msyslog(LOG_ERR, "'ttl' does not apply for refclocks");
edcb74
+				errflag = 1;
edcb74
+			} else if (option->value.i < 0 || option->value.i >= MAX_TTL) {
edcb74
 				msyslog(LOG_ERR, "ttl: invalid argument");
edcb74
 				errflag = 1;
edcb74
 			}
edcb74
@@ -1351,7 +1355,12 @@ create_peer_node(
edcb74
 			break;
edcb74
 
edcb74
 		case T_Mode:
edcb74
-			my_node->ttl = option->value.i;
edcb74
+			if (is_refclk_addr(addr)) {
edcb74
+				my_node->ttl = option->value.i;
edcb74
+			} else {
edcb74
+				msyslog(LOG_ERR, "'mode' does not apply for network peers");
edcb74
+				errflag = 1;
edcb74
+			}
edcb74
 			break;
edcb74
 
edcb74
		case T_Key:
edcb74
@@ -2674,6 +2685,16 @@ apply_enable_disable(
edcb74
 	}
edcb74
 }
edcb74
 
edcb74
+/* Hack to disambiguate 'server' statements for refclocks and network peers.
edcb74
+ * Please note the qualification 'hack'. It's just that.
edcb74
+ */
edcb74
+static int/*BOOL*/
edcb74
+is_refclk_addr(
edcb74
+	const struct address_node * addr
edcb74
+	)
edcb74
+{
edcb74
+	return addr && addr->address && !strncmp(addr->address, "127.127.", 8);
edcb74
+}
edcb74
 
edcb74
 static void
edcb74
 config_system_opts(
9e87e2
@@ -2920,7 +2941,9 @@ config_ttl(
9e87e2
 
9e87e2
 		curr_ttl = next_node(curr_ttl);
9e87e2
 	}
9e87e2
-	sys_ttlmax = i - 1;
9e87e2
+
9e87e2
+	if (i)
9e87e2
+		sys_ttlmax = i - 1;
9e87e2
 }
9e87e2
 
9e87e2
 
edcb74
diff -up ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2017-6464 ntp-4.2.6p5/ntpd/ntp_proto.c
edcb74
--- ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2017-6464	2017-03-22 12:54:11.270454677 +0100
edcb74
+++ ntp-4.2.6p5/ntpd/ntp_proto.c	2017-03-22 12:54:11.279454706 +0100
edcb74
@@ -3017,8 +3017,9 @@ peer_xmit(
edcb74
 			}
edcb74
 		}
edcb74
 		peer->t21_bytes = sendlen;
edcb74
-		sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl],
edcb74
-		    &xpkt, sendlen);
edcb74
+		sendpkt(&peer->srcadr, peer->dstadr,
edcb74
+			sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl],
edcb74
+			&xpkt, sendlen);
edcb74
 		peer->sent++;
edcb74
 		peer->throttle += (1 << peer->minpoll) - 2;
edcb74
 
edcb74
@@ -3330,8 +3331,9 @@ peer_xmit(
edcb74
 		exit (-1);
edcb74
 	}
edcb74
 	peer->t21_bytes = sendlen;
edcb74
-	sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt,
edcb74
-	    sendlen);
edcb74
+	sendpkt(&peer->srcadr, peer->dstadr,
edcb74
+		sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl],
edcb74
+		&xpkt, sendlen);
edcb74
 	peer->sent++;
edcb74
 	peer->throttle += (1 << peer->minpoll) - 2;
edcb74