---
+* [Bug 2948] Potential Infinite Loop in ntpq ( and ntpdc) perlinger@ntp.org
+---
(4.2.8p4-RC1) 2015/10/06 Released by Harlan Stenn <stenn@ntp.org>
* [Bug 2332] (reopened) Exercise thread cancellation once before dropping
fd_set fds;
ssize_t 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
lastseq = 999; /* too big to be a sequence number */
ZERO(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);
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
}
/*
- * 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();
fd_set fds;
int n;
int errcode;
+ /* 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
numfrags = 0;
seenlastfrag = 0;
+ tobase = (uint32_t)time(NULL);
+
FD_ZERO(&fds);
/*
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);
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
}
/*
- * 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.u, 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.