Blob Blame History Raw
diff -U0 ntp-4.2.6p5/ChangeLog.cve-2015-8158 ntp-4.2.6p5/ChangeLog
diff -up ntp-4.2.6p5/ntpdc/ntpdc.c.cve-2015-8158 ntp-4.2.6p5/ntpdc/ntpdc.c
--- ntp-4.2.6p5/ntpdc/ntpdc.c.cve-2015-8158	2016-01-20 14:06:21.035659659 +0100
+++ ntp-4.2.6p5/ntpdc/ntpdc.c	2016-01-20 14:25:39.734622168 +0100
@@ -657,6 +657,10 @@ getresponse(
 	fd_set fds;
 	int n;
 	int pad;
+	/* absolute timeout checks. Not 'time_t' by intention! */
+	uint32_t tobase;	/* base value for timeout */
+	uint32_t tospan;	/* timeout span (max delay) */
+	uint32_t todiff;	/* current delay */
 
 	/*
 	 * This is pretty tricky.  We may get between 1 and many packets
@@ -673,12 +677,14 @@ getresponse(
 	lastseq = 999;	/* too big to be a sequence number */
 	memset(haveseq, 0, sizeof(haveseq));
 	FD_ZERO(&fds);
+	tobase = (uint32_t)time(NULL);
 
     again:
 	if (firstpkt)
 		tvo = tvout;
 	else
 		tvo = tvsout;
+	tospan = (uint32_t)tvo.tv_sec + (tvo.tv_usec != 0);
 	
 	FD_SET(sockfd, &fds);
 	n = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvo);
@@ -687,6 +693,17 @@ getresponse(
 		warning("select fails", "", "");
 		return -1;
 	}
+	
+	/*
+	 * Check if this is already too late. Trash the data and fake a
+	 * timeout if this is so.
+	 */
+	todiff = (((uint32_t)time(NULL)) - tobase) & 0x7FFFFFFFu;
+	if ((n > 0) && (todiff > tospan)) {
+		n = recv(sockfd, (char *)&rpkt, sizeof(rpkt), 0);
+		n = 0; /* faked timeout return from 'select()'*/
+	}
+	
 	if (n == 0) {
 		/*
 		 * Timed out.  Return what we have
@@ -831,8 +848,10 @@ getresponse(
 	}
 
 	/*
-	 * So far, so good.  Copy this data into the output array.
+	 * So far, so good.  Copy this data into the output array. Bump
+	 * the timeout base, in case we expect more data.
 	 */
+	tobase = (uint32_t)time(NULL);
 	if ((datap + datasize + (pad * items)) > (pktdata + pktdatasize)) {
 		int offset = datap - pktdata;
 		growpktdata();
diff -up ntp-4.2.6p5/ntpq/ntpq.c.cve-2015-8158 ntp-4.2.6p5/ntpq/ntpq.c
--- ntp-4.2.6p5/ntpq/ntpq.c.cve-2015-8158	2016-01-20 14:06:21.493660755 +0100
+++ ntp-4.2.6p5/ntpq/ntpq.c	2016-01-20 14:13:56.132819820 +0100
@@ -836,6 +836,10 @@ getresponse(
 	int len;
 	int first;
 	char *data;
+	/* absolute timeout checks. Not 'time_t' by intention! */
+	uint32_t tobase;	/* base value for timeout */
+	uint32_t tospan;	/* timeout span (max delay) */
+	uint32_t todiff;	/* current delay */
 
 	/*
 	 * This is pretty tricky.  We may get between 1 and MAXFRAG packets
@@ -852,6 +856,8 @@ getresponse(
 	numfrags = 0;
 	seenlastfrag = 0;
 
+	tobase = (uint32_t)time(NULL);
+	
 	FD_ZERO(&fds);
 
 	/*
@@ -864,7 +870,8 @@ getresponse(
 			tvo = tvout;
 		else
 			tvo = tvsout;
-		
+		tospan = (uint32_t)tvo.tv_sec + (tvo.tv_usec != 0);
+
 		FD_SET(sockfd, &fds);
 		n = select(sockfd + 1, &fds, NULL, NULL, &tvo);
 
@@ -872,6 +879,17 @@ getresponse(
 			warning("select fails", "", "");
 			return -1;
 		}
+
+		/*
+		 * Check if this is already too late. Trash the data and
+		 * fake a timeout if this is so.
+		 */
+		todiff = (((uint32_t)time(NULL)) - tobase) & 0x7FFFFFFFu;
+		if ((n > 0) && (todiff > tospan)) {
+			n = recv(sockfd, (char *)&rpkt, sizeof(rpkt), 0);
+			n = 0; /* faked timeout return from 'select()'*/
+		}
+
 		if (n == 0) {
 			/*
 			 * Timed out.  Return what we have
@@ -1166,10 +1184,13 @@ getresponse(
 		}
 
 		/*
-		 * Copy the data into the data buffer.
+		 * Copy the data into the data buffer, and bump the
+		 * timout base in case we need more.
 		 */
 		memcpy((char *)pktdata + offset, rpkt.data, count);
 
+		tobase = (uint32_t)time(NULL);
+		
 		/*
 		 * If we've seen the last fragment, look for holes in the sequence.
 		 * If there aren't any, we're done.