diff -Nru ntp-4.2.6.p3+dfsg/debian/changelog ntp-4.2.6.p3+dfsg/debian/changelog --- ntp-4.2.6.p3+dfsg/debian/changelog 2015-10-23 15:58:22.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/changelog 2016-06-01 17:41:00.000000000 +0000 @@ -1,3 +1,80 @@ +ntp (1:4.2.6.p3+dfsg-1ubuntu3.10) precise-security; urgency=medium + + * SECURITY UPDATE: Deja Vu replay attack on authenticated broadcast mode + - debian/patches/CVE-2015-7973.patch: improve timestamp verification in + include/ntp.h, ntpd/ntp_proto.c. + - CVE-2015-7973 + * SECURITY UPDATE: impersonation between authenticated peers + - debian/patches/CVE-2015-7974.patch: check key ID in ntpd/ntp_proto.c. + - CVE-2015-7974 + * SECURITY UPDATE: ntpq saveconfig command allows dangerous characters in + filenames + - debian/patches/CVE-2015-7976.patch: check filename in + ntpd/ntp_control.c. + - CVE-2015-7976 + * SECURITY UPDATE: restrict list denial of service + - debian/patches/CVE-2015-7977-7978.patch: improve restrict list + processing in ntpd/ntp_request.c. + - CVE-2015-7977 + - CVE-2015-7978 + * SECURITY UPDATE: authenticated broadcast mode off-path denial of + service + - debian/patches/CVE-2015-7979.patch: add more checks to + ntpd/ntp_proto.c. + - CVE-2015-7979 + - CVE-2016-1547 + * SECURITY UPDATE: Zero Origin Timestamp Bypass + - debian/patches/CVE-2015-8138.patch: check p_org in ntpd/ntp_proto.c. + - CVE-2015-8138 + * SECURITY UPDATE: potential infinite loop in ntpq + - debian/patches/CVE-2015-8158.patch: add time checks to ntpdc/ntpdc.c, + ntpq/ntpq.c. + - CVE-2015-8158 + * SECURITY UPDATE: NTP statsdir cleanup cronjob insecure (LP: #1528050) + - debian/ntp.cron.daily: fix security issues, patch thanks to halfdog! + - CVE-2016-0727 + * SECURITY UPDATE: time spoofing via interleaved symmetric mode + - debian/patches/CVE-2016-1548.patch: check for bogus packets in + ntpd/ntp_proto.c. + - CVE-2016-1548 + * SECURITY UPDATE: buffer comparison timing attacks + - debian/patches/CVE-2016-1550.patch: use CRYPTO_memcmp in + libntp/a_md5encrypt.c, sntp/crypto.c. + - CVE-2016-1550 + * SECURITY UPDATE: DoS via duplicate IPs on unconfig directives + - debian/patches/CVE-2016-2516.patch: improve logic in + ntpd/ntp_request.c. + - CVE-2016-2516 + * SECURITY UPDATE: denial of service via crafted addpeer + - debian/patches/CVE-2016-2518.patch: check mode value in + ntpd/ntp_request.c. + - CVE-2016-2518 + + -- Marc Deslauriers Wed, 01 Jun 2016 12:28:17 -0400 + +ntp (1:4.2.6.p3+dfsg-1ubuntu3.9) precise; urgency=medium + + * ntpd rejects source UDP ports less than 123 as bogus (closes: #691412) + - d/p/reject-UDP-ports-less-than-123-as-bogus.patch (LP: #1479652) + + -- Eric Desrochers Mon, 25 Jan 2016 12:28:25 -0500 + +ntp (1:4.2.6.p3+dfsg-1ubuntu3.8) precise; urgency=medium + + * Use a single lockfile again - instead unlock the file before starting the + init script. The lock sho uld be shared - both services can't run at the + same time. (LP: #1125726) + + -- Cam Cope Tue, 19 Jan 2016 10:20:07 +0000 + +ntp (1:4.2.6.p3+dfsg-1ubuntu3.7) precise; urgency=medium + + * Fix use-after-free in routing socket code (closes: #795315) + - debian/patches/use-after-free-in-routing-socket.patch: + fix logic in ntpd/ntp_io.c (LP: #1481388) + + -- Eric Desrochers Thu, 29 Oct 2015 09:47:20 -0400 + ntp (1:4.2.6.p3+dfsg-1ubuntu3.6) precise-security; urgency=medium * SECURITY UPDATE: denial of service via crafted NUL-byte in diff -Nru ntp-4.2.6.p3+dfsg/debian/ntp.cron.daily ntp-4.2.6.p3+dfsg/debian/ntp.cron.daily --- ntp-4.2.6.p3+dfsg/debian/ntp.cron.daily 2006-12-18 14:33:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/ntp.cron.daily 2016-06-01 16:26:13.000000000 +0000 @@ -9,19 +9,23 @@ statsdir=$(cat /etc/ntp.conf | grep -v '^#' | sed -n 's/statsdir \([^ ][^ ]*\)/\1/p') if [ -n "$statsdir" ] && [ -d "$statsdir" ]; then - # only keep a week's depth of these - find "$statsdir" -type f -mtime +7 -exec rm {} \; + # only keep a week's depth of these. Delete only files exactly + # within the directory and do not descend into subdirectories + # to avoid security risks on platforms where find is not using + # fts-library. + find "$statsdir" -maxdepth 1 -type f -mtime +7 -delete - # compress whatever is left to save space - cd "$statsdir" - ls loopstats.???????? peerstats.???????? > /dev/null 2>&1 + # compress whatever is left to save space but make sure to really + # do it only in the expected directory. + cd "$statsdir" || exit 1 + ls -d -- *stats.???????? > /dev/null 2>&1 if [ $? -eq 0 ]; then # Note that gzip won't compress the file names that # are hard links to the live/current files, so this # compresses yesterday and previous, leaving the live # log alone. We supress the warnings gzip issues # about not compressing the linked file. - gzip --best --quiet loopstats.???????? peerstats.???????? + gzip --best --quiet -- *stats.???????? return=$? case $return in 2) diff -Nru ntp-4.2.6.p3+dfsg/debian/ntpdate.if-up ntp-4.2.6.p3+dfsg/debian/ntpdate.if-up --- ntp-4.2.6.p3+dfsg/debian/ntpdate.if-up 2011-10-26 14:14:37.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/ntpdate.if-up 2016-01-19 10:18:05.000000000 +0000 @@ -30,7 +30,7 @@ wait_for_file /usr/sbin/ntpdate-debian fi -LOCKFILE=/var/lock/ntpdate-ifup +LOCKFILE=/var/lock/ntpdate # Avoid running more than one at a time if [ -x /usr/bin/lockfile-create ]; then @@ -49,11 +49,11 @@ /usr/sbin/ntpdate-debian -s $OPTS 2>/dev/null || : -invoke-rc.d --quiet $service start >/dev/null 2>&1 || true - if [ -x /usr/bin/lockfile-create ] ; then kill $LOCKTOUCHPID lockfile-remove $LOCKFILE fi +invoke-rc.d --quiet $service start >/dev/null 2>&1 || true + ) & diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7973.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7973.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7973.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7973.patch 2016-06-01 16:26:53.000000000 +0000 @@ -0,0 +1,129 @@ +Description: fix Deja Vu replay attack on authenticated broadcast mode +Origin: backport, https://github.com/ntp-project/ntp/commit/f6a0225a9fc6ba82268d0d69a8a4eab788889262 +Origin: backport, https://github.com/ntp-project/ntp/commit/c801a6a5f84d7f385a42e0073c94b2e0664f8ad2 +Origin: backport, https://github.com/ntp-project/ntp/commit/50ef2f62dc326bc9edac166b2b4ba5b5d8b4f7d4 +Bug: http://support.ntp.org/bin/view/Main/NtpBug2935 + +Index: ntp-4.2.6.p3+dfsg/include/ntp.h +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/include/ntp.h 2016-06-01 12:26:51.694818823 -0400 ++++ ntp-4.2.6.p3+dfsg/include/ntp.h 2016-06-01 12:26:51.690818771 -0400 +@@ -350,6 +350,7 @@ + l_fp dst; /* destination timestamp */ + l_fp aorg; /* origin timestamp */ + l_fp borg; /* alternate origin timestamp */ ++ l_fp bxmt; /* most recent broadcast transmit timestamp */ + double offset; /* peer clock offset */ + double delay; /* peer roundtrip delay */ + double jitter; /* peer jitter (squares) */ +@@ -384,7 +385,8 @@ + * Statistic counters + */ + u_long timereset; /* time stat counters were reset */ +- u_long timereceived; /* last packet received time */ ++ u_long timelastrec; /* last packet received time */ ++ u_long timereceived; /* last (clean) packet received time */ + u_long timereachable; /* last reachable/unreachable time */ + + u_long sent; /* packets sent */ +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_proto.c 2016-06-01 12:26:51.694818823 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c 2016-06-01 12:26:51.690818771 -0400 +@@ -882,6 +882,7 @@ + } else { + peer->delay = sys_bdelay; + peer->bias = -sys_bdelay / 2.; ++ peer->bxmt = p_xmt; + } + break; + } +@@ -901,6 +902,7 @@ + sys_restricted++; + return; /* ignore duplicate */ + } ++ peer->bxmt = p_xmt; + #ifdef OPENSSL + if (skeyid > NTP_MAXKEY) + crypto_recv(peer, rbufp); +@@ -988,6 +990,72 @@ + * Process regular packet. Nothing special. + */ + case AM_PROCPKT: ++ if (MODE_BROADCAST == hismode) { ++ u_char poll; ++ int bail = 0; ++ l_fp tdiff; ++ ++ DPRINTF(2, ("receive: PROCPKT/BROADCAST: prev pkt %ld seconds ago, ppoll: %d, %d secs\n", ++ (current_time - peer->timelastrec), ++ peer->ppoll, (1 << peer->ppoll) ++ )); ++ /* Things we can check: ++ * ++ * Did the poll interval change? ++ * Is the poll interval in the packet in-range? ++ * Did this packet arrive too soon? ++ * Is the timestamp in this packet monotonic ++ * with respect to the previous packet? ++ */ ++ ++ /* This is noteworthy, not error-worthy */ ++ if (pkt->ppoll != peer->ppoll) { ++ msyslog(LOG_INFO, "receive: broadcast poll from %s changed from %ud to %ud", ++ stoa(&rbufp->recv_srcadr), ++ peer->ppoll, pkt->ppoll); ++ } ++ ++ poll = min(peer->maxpoll, ++ max(peer->minpoll, pkt->ppoll)); ++ ++ /* This is error-worthy */ ++ if (pkt->ppoll != poll) { ++ msyslog(LOG_INFO, "receive: broadcast poll of %ud from %s is out-of-range (%d to %d)!", ++ pkt->ppoll, stoa(&rbufp->recv_srcadr), ++ peer->minpoll, peer->maxpoll); ++ ++bail; ++ } ++ ++ if ( (current_time - peer->timelastrec) ++ < (1 << pkt->ppoll)) { ++ msyslog(LOG_INFO, "receive: broadcast packet from %s arrived after %ld, not %d seconds!", ++ stoa(&rbufp->recv_srcadr), ++ (current_time - peer->timelastrec), ++ (1 << pkt->ppoll) ++ ); ++ ++bail; ++ } ++ ++ tdiff = p_xmt; ++ L_SUB(&tdiff, &peer->bxmt); ++ if (tdiff.l_i < 0) { ++ msyslog(LOG_INFO, "receive: broadcast packet from %s contains non-monotonic timestamp: %#010x.%08x -> %#010x.%08x", ++ stoa(&rbufp->recv_srcadr), ++ peer->bxmt.l_ui, peer->bxmt.l_uf, ++ p_xmt.l_ui, p_xmt.l_uf ++ ); ++ ++bail; ++ } ++ ++ peer->bxmt = p_xmt; ++ ++ if (bail) { ++ peer->timelastrec = current_time; ++ sys_declined++; ++ return; ++ } ++ } ++ + break; + + /* +@@ -1179,6 +1247,7 @@ + * clean. Get on with real work. + */ + peer->timereceived = current_time; ++ peer->timelastrec = current_time; + if (is_authentic == AUTH_OK) + peer->flags |= FLAG_AUTHENTIC; + else diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7974.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7974.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7974.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7974.patch 2016-06-01 16:27:00.000000000 +0000 @@ -0,0 +1,25 @@ +Description: fix impersonation between authenticated peers +Origin: vendor, http://pkgs.fedoraproject.org/cgit/rpms/ntp.git/tree/ntp-4.2.6p5-cve-2015-7974.patch +Bug: http://support.ntp.org/bin/view/Main/NtpBug2936 + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_proto.c 2016-06-01 12:26:57.486893359 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c 2016-06-01 12:26:57.486893359 -0400 +@@ -669,10 +669,13 @@ + * succeed in bloating the key cache. If an autokey, + * purge it immediately, since we won't be needing it + * again. If the packet is authentic, it can mobilize an +- * association. Note that there is no key zero. ++ * association. If it's a persistent association using a ++ * symmetric key, the key ID has to match the configured ++ * value. Note that there is no key zero. + */ +- if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, +- has_mac)) ++ if ((peer && !(peer->flags & FLAG_PREEMPT) && ++ peer->keyid <= NTP_MAXKEY && skeyid != peer->keyid) || ++ !authdecrypt(skeyid, (u_int32 *)pkt, authlen, has_mac)) + is_authentic = AUTH_ERROR; + else + is_authentic = AUTH_OK; diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7976.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7976.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7976.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7976.patch 2016-06-01 16:27:06.000000000 +0000 @@ -0,0 +1,331 @@ +Description: fix ntpq saveconfig command allows dangerous characters in filenames +Origin: backport, https://github.com/ntp-project/ntp/commit/7fe04606062ed674db3b9553d32dedad29504d61 +Origin: backport, https://github.com/ntp-project/ntp/commit/3680c2e4d5f88905ce062c7b43305d610a2c9796 +Bug: http://support.ntp.org/bin/view/Main/NtpBug2938 + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_control.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_control.c 2016-06-01 12:27:03.386969286 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_control.c 2016-06-01 12:27:03.386969286 -0400 +@@ -64,6 +64,7 @@ + static void ctl_putsys (int); + static void ctl_putpeer (int, struct peer *); + static void ctl_putfs (const char *, tstamp_t); ++static void ctl_printf (const char *, ...) __attribute__((__format__(__printf__, 1, 2))); + #ifdef REFCLOCK + static void ctl_putclock (int, struct refclockstat *, int); + #endif /* REFCLOCK */ +@@ -82,6 +83,8 @@ + static struct ctl_trap *ctlfindtrap (sockaddr_u *, + struct interface *); + ++int/*BOOL*/ is_safe_filename(const char * name); ++ + static struct ctl_proc control_codes[] = { + { CTL_OP_UNSPEC, NOAUTH, control_unspec }, + { CTL_OP_READSTAT, NOAUTH, read_status }, +@@ -550,10 +553,65 @@ + numctlerrors++; + } + ++int/*BOOL*/ ++is_safe_filename(const char * name) ++{ ++ /* We need a strict validation of filenames we should write: The ++ * daemon might run with special permissions and is remote ++ * controllable, so we better take care what we allow as file ++ * name! ++ * ++ * The first character must be digit or a letter from the ASCII ++ * base plane or a '_' ([_A-Za-z0-9]), the following characters ++ * must be from [-._+A-Za-z0-9]. ++ * ++ * We do not trust the character classification much here: Since ++ * the NTP protocol makes no provisions for UTF-8 or local code ++ * pages, we strictly require the 7bit ASCII code page. ++ * ++ * The following table is a packed bit field of 128 two-bit ++ * groups. The LSB in each group tells us if a character is ++ * acceptable at the first position, the MSB if the character is ++ * accepted at any other position. ++ * ++ * This does not ensure that the file name is syntactically ++ * correct (multiple dots will not work with VMS...) but it will ++ * exclude potential globbing bombs and directory traversal. It ++ * also rules out drive selection. (For systems that have this ++ * notion, like Windows or VMS.) ++ */ ++ static const uint32_t chclass[8] = { ++ 0x00000000, 0x00000000, ++ 0x28800000, 0x000FFFFF, ++ 0xFFFFFFFC, 0xC03FFFFF, ++ 0xFFFFFFFC, 0x003FFFFF ++ }; ++ ++ u_int widx, bidx, mask; ++ if (!*name) ++ return FALSE; ++ ++ mask = 1u; ++ while (0 != (widx = (u_char)*name++)) { ++ bidx = (widx & 15) << 1; ++ widx = widx >> 4; ++ if (widx >= sizeof(chclass)) ++ return FALSE; ++ if (0 == ((chclass[widx] >> bidx) & mask)) ++ return FALSE; ++ mask |= 2u; ++ } ++ return TRUE; ++} ++ + /* + * save_config - Implements ntpq -c "saveconfig " + * Writes current configuration including any runtime + * changes by ntpq's :config or config-from-file ++ * ++ * Note: There should be no buffer overflow or truncation in the ++ * processing of file names -- both cause security problems. This is bit ++ * painful to code but essential here. + */ + void + save_config( +@@ -561,22 +619,37 @@ + int restrict_mask + ) + { +- char reply[128]; + #ifdef SAVECONFIG ++ static const char savedconfig_eq[] = "savedconfig="; ++ ++ /* Build a safe open mode from the available mode flags. We want ++ * to create a new file and write it in text mode (when ++ * applicable -- only Windows does this...) ++ */ ++ static const int openmode = O_CREAT | O_TRUNC | O_WRONLY ++# if defined(O_EXCL) /* posix, vms */ ++ | O_EXCL ++# elif defined(_O_EXCL) /* windows is alway very special... */ ++ | _O_EXCL ++# endif ++# if defined(_O_TEXT) /* windows, again */ ++ | _O_TEXT ++#endif ++ ; ++ + char filespec[128]; + char filename[128]; + char fullpath[512]; +- const char savedconfig_eq[] = "savedconfig="; + char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)]; + time_t now; + int fd; + FILE *fptr; ++ int prc; ++ size_t reqlen; + #endif + + if (restrict_mask & RES_NOMODIFY) { +- snprintf(reply, sizeof(reply), +- "saveconfig prohibited by restrict ... nomodify"); +- ctl_putdata(reply, strlen(reply), 0); ++ ctl_printf("%s", "saveconfig prohibited by restrict ... nomodify"); + ctl_flushpkt(0); + msyslog(LOG_NOTICE, + "saveconfig from %s rejected due to nomodify restriction", +@@ -586,9 +659,7 @@ + + #ifdef SAVECONFIG + if (NULL == saveconfigdir) { +- snprintf(reply, sizeof(reply), +- "saveconfig prohibited, no saveconfigdir configured"); +- ctl_putdata(reply, strlen(reply), 0); ++ ctl_printf("%s", "saveconfig prohibited, no saveconfigdir configured"); + ctl_flushpkt(0); + msyslog(LOG_NOTICE, + "saveconfig from %s rejected, no saveconfigdir", +@@ -596,63 +667,115 @@ + return; + } + +- if (0 == reqend - reqpt) ++ /* The length checking stuff gets serious. Do not assume a NUL ++ * byte can be found, but if so, use it to calculate the needed ++ * buffer size. If the available buffer is too short, bail out; ++ * likewise if there is no file spec. (The latter will not ++ * happen when using NTPQ, but there are other ways to craft a ++ * network packet!) ++ */ ++ reqlen = (size_t)(reqend - reqpt); ++ if (0 != reqlen) { ++ char * nulpos = (char*)memchr(reqpt, 0, reqlen); ++ if (NULL != nulpos) ++ reqlen = (size_t)(nulpos - reqpt); ++ } ++ if (0 == reqlen) + return; ++ if (reqlen >= sizeof(filespec)) { ++ ctl_printf("saveconfig exceeded maximum raw name length (%u)", ++ (u_int)sizeof(filespec)); ++ ctl_flushpkt(0); ++ msyslog(LOG_NOTICE, ++ "saveconfig exceeded maximum raw name length from %s", ++ stoa(&rbufp->recv_srcadr)); ++ return; ++ } + +- strncpy(filespec, reqpt, sizeof(filespec)); +- filespec[sizeof(filespec) - 1] = '\0'; +- +- time(&now); +- ++ /* copy data directly as we exactly know the size */ ++ memcpy(filespec, reqpt, reqlen); ++ filespec[reqlen] = '\0'; ++ + /* + * allow timestamping of the saved config filename with + * strftime() format such as: + * ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf" ++ * XXX: Nice feature, but not too safe. ++ * YYY: The check for permitted characters in file names should ++ * weed out the worst. Let's hope 'strftime()' does not ++ * develop pathological problems. + */ ++ time(&now); + if (0 == strftime(filename, sizeof(filename), filespec, +- localtime(&now))) ++ localtime(&now))) ++ { ++ /* ++ * If we arrive here, 'strftime()' balked; most likely ++ * the buffer was too short. (Or it encounterd an empty ++ * format, or just a format that expands to an empty ++ * string.) We try to use the original name, though this ++ * is very likely to fail later if there are format ++ * specs in the string. Note that truncation cannot ++ * happen here as long as both buffers have the same ++ * size! ++ */ + strncpy(filename, filespec, sizeof(filename)); ++ filename[sizeof(filename) - 1] = '\0'; ++ } + +- filename[sizeof(filename) - 1] = '\0'; +- +- if (strchr(filename, '\\') || strchr(filename, '/')) { +- snprintf(reply, sizeof(reply), +- "saveconfig does not allow directory in filename"); +- ctl_putdata(reply, strlen(reply), 0); ++ /* ++ * Check the file name for sanity. This migth/will rule out file ++ * names that would be legal but problematic, and it blocks ++ * directory traversal. ++ */ ++ if (!is_safe_filename(filename)) { ++ ctl_printf("saveconfig rejects unsafe file name '%s'", ++ filename); + ctl_flushpkt(0); + msyslog(LOG_NOTICE, +- "saveconfig with path from %s rejected", ++ "saveconfig rejects unsafe file name from %s", + stoa(&rbufp->recv_srcadr)); + return; + } + +- snprintf(fullpath, sizeof(fullpath), "%s%s", +- saveconfigdir, filename); ++ /* concatenation of directory and path can cause another ++ * truncation... ++ */ ++ prc = snprintf(fullpath, sizeof(fullpath), "%s%s", ++ saveconfigdir, filename); ++ if (prc < 0 || prc >= sizeof(fullpath)) { ++ ctl_printf("saveconfig exceeded maximum path length (%u)", ++ (u_int)sizeof(fullpath)); ++ ctl_flushpkt(0); ++ msyslog(LOG_NOTICE, ++ "saveconfig exceeded maximum path length from %s", ++ stoa(&rbufp->recv_srcadr)); ++ return; ++ } + +- fd = open(fullpath, O_CREAT | O_TRUNC | O_WRONLY, +- S_IRUSR | S_IWUSR); ++ fd = open(fullpath, openmode, S_IRUSR | S_IWUSR); + if (-1 == fd) + fptr = NULL; + else + fptr = fdopen(fd, "w"); + + if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) { +- snprintf(reply, sizeof(reply), +- "Unable to save configuration to file %s", +- filename); ++ ctl_printf("Unable to save configuration to file '%s': %m", ++ filename); + msyslog(LOG_ERR, + "saveconfig %s from %s failed", filename, + stoa(&rbufp->recv_srcadr)); + } else { +- snprintf(reply, sizeof(reply), +- "Configuration saved to %s", filename); ++ ctl_printf("Configuration saved to '%s'", filename); + msyslog(LOG_NOTICE, +- "Configuration saved to %s (requested by %s)", ++ "Configuration saved to '%s' (requested by %s)", + fullpath, stoa(&rbufp->recv_srcadr)); + /* + * save the output filename in system variable + * savedconfig, retrieved with: + * ntpq -c "rv 0 savedconfig" ++ * Note: the way 'savedconfig' is defined makes overflow ++ * checks unnecessary here. + */ + snprintf(savedconfig, sizeof(savedconfig), "%s%s", + savedconfig_eq, filename); +@@ -662,11 +785,9 @@ + if (NULL != fptr) + fclose(fptr); + #else /* !SAVECONFIG follows */ +- snprintf(reply, sizeof(reply), +- "saveconfig unavailable, configured with --disable-saveconfig"); +-#endif +- +- ctl_putdata(reply, strlen(reply), 0); ++ ctl_printf("%s", ++ "saveconfig unavailable, configured with --disable-saveconfig"); ++#endif + ctl_flushpkt(0); + } + +@@ -1326,6 +1447,29 @@ + ctl_putdata(buffer, (unsigned)(cp - buffer), 0); + } + ++/* ++ * ctl_printf - put a formatted string into the data buffer ++ */ ++static void ++ctl_printf( ++ const char * fmt, ++ ... ++ ) ++{ ++ static const char * ellipsis = "[...]"; ++ va_list va; ++ char fmtbuf[128]; ++ int rc; ++ ++ va_start(va, fmt); ++ rc = vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, va); ++ va_end(va); ++ if (rc < 0 || rc >= sizeof(fmtbuf)) ++ strcpy(fmtbuf + sizeof(fmtbuf) - strlen(ellipsis) - 1, ++ ellipsis); ++ ctl_putdata(fmtbuf, strlen(fmtbuf), 0); ++} ++ + + /* + * ctl_putsys - output a system variable diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7977-7978.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7977-7978.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7977-7978.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7977-7978.patch 2016-06-01 16:27:14.000000000 +0000 @@ -0,0 +1,257 @@ +Backport of: + +From 8a0c765f3c47633fa262356b0818788d1cf249b1 Mon Sep 17 00:00:00 2001 +From: +Date: Sun, 11 Oct 2015 14:12:31 +0200 +Subject: [PATCH] [Bug 2939] reslist NULL pointer dereference [Bug 2940] Stack + exhaustion in recursive traversal of restriction list -- these two where + fixed together -- + +--- + ChangeLog | 4 ++ + ntpd/ntp_request.c | 166 ++++++++++++++++++++++++++++++++++++++++------------- + 2 files changed, 131 insertions(+), 39 deletions(-) + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_request.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_request.c 2016-06-01 12:27:12.139081919 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_request.c 2016-06-01 12:27:12.135081867 -0400 +@@ -1733,56 +1733,143 @@ + loop_config(LOOP_DRIFTCOMP, drift_comp); + } + ++/* There have been some issues with the restrict list processing, ++ * ranging from problems with deep recursion (resulting in stack ++ * overflows) and overfull reply buffers. ++ * ++ * To avoid this trouble the list reversal is done iteratively using a ++ * scratch pad. ++ */ ++typedef struct RestrictStack RestrictStackT; ++struct RestrictStack { ++ RestrictStackT *link; ++ size_t fcnt; ++ const restrict_u *pres[63]; ++}; ++ ++static size_t ++getStackSheetSize( ++ RestrictStackT *sp ++ ) ++{ ++ if (sp) ++ return sizeof(sp->pres)/sizeof(sp->pres[0]); ++ return 0u; ++} ++ ++static int/*BOOL*/ ++pushRestriction( ++ RestrictStackT **spp, ++ const restrict_u *ptr ++ ) ++{ ++ RestrictStackT *sp; ++ ++ if (NULL == (sp = *spp) || 0 == sp->fcnt) { ++ /* need another sheet in the scratch pad */ ++ sp = emalloc(sizeof(*sp)); ++ sp->link = *spp; ++ sp->fcnt = getStackSheetSize(sp); ++ *spp = sp; ++ } ++ sp->pres[--sp->fcnt] = ptr; ++ return TRUE; ++} ++ ++static int/*BOOL*/ ++popRestriction( ++ RestrictStackT **spp, ++ const restrict_u **opp ++ ) ++{ ++ RestrictStackT *sp; ++ ++ if (NULL == (sp = *spp) || sp->fcnt >= getStackSheetSize(sp)) ++ return FALSE; ++ ++ *opp = sp->pres[sp->fcnt++]; ++ if (sp->fcnt >= getStackSheetSize(sp)) { ++ /* discard sheet from scratch pad */ ++ *spp = sp->link; ++ free(sp); ++ } ++ return TRUE; ++} ++ ++static void ++flushRestrictionStack( ++ RestrictStackT **spp ++ ) ++{ ++ RestrictStackT *sp; ++ ++ while (NULL != (sp = *spp)) { ++ *spp = sp->link; ++ free(sp); ++ } ++} ++ + /* +- * list_restrict4 - recursive helper for list_restrict dumps IPv4 ++ * list_restrict4 - iterative helper for list_restrict dumps IPv4 + * restriction list in reverse order. + */ + static void + list_restrict4( +- restrict_u * res, ++ const restrict_u * res, + struct info_restrict ** ppir + ) + { ++ RestrictStackT * rpad; + struct info_restrict * pir; + +- if (res->link != NULL) +- list_restrict4(res->link, ppir); +- + pir = *ppir; +- pir->addr = htonl(res->u.v4.addr); +- if (client_v6_capable) +- pir->v6_flag = 0; +- pir->mask = htonl(res->u.v4.mask); +- pir->count = htonl(res->count); +- pir->flags = htons(res->flags); +- pir->mflags = htons(res->mflags); +- *ppir = (struct info_restrict *)more_pkt(); ++ for (rpad = NULL; res; res = res->link) ++ if (!pushRestriction(&rpad, res)) ++ break; ++ ++ while (pir && popRestriction(&rpad, &res)) { ++ pir->addr = htonl(res->u.v4.addr); ++ if (client_v6_capable) ++ pir->v6_flag = 0; ++ pir->mask = htonl(res->u.v4.mask); ++ pir->count = htonl(res->count); ++ pir->flags = htons(res->flags); ++ pir->mflags = htons(res->mflags); ++ pir = (struct info_restrict *)more_pkt(); ++ } ++ flushRestrictionStack(&rpad); ++ *ppir = pir; + } + +- + /* +- * list_restrict6 - recursive helper for list_restrict dumps IPv6 ++ * list_restrict6 - iterative helper for list_restrict dumps IPv6 + * restriction list in reverse order. + */ + static void + list_restrict6( +- restrict_u * res, ++ const restrict_u * res, + struct info_restrict ** ppir + ) + { ++ RestrictStackT * rpad; + struct info_restrict * pir; + +- if (res->link != NULL) +- list_restrict6(res->link, ppir); +- + pir = *ppir; +- pir->addr6 = res->u.v6.addr; +- pir->mask6 = res->u.v6.mask; +- pir->v6_flag = 1; +- pir->count = htonl(res->count); +- pir->flags = htons(res->flags); +- pir->mflags = htons(res->mflags); +- *ppir = (struct info_restrict *)more_pkt(); ++ for (rpad = NULL; res; res = res->link) ++ if (!pushRestriction(&rpad, res)) ++ break; ++ ++ while (pir && popRestriction(&rpad, &res)) { ++ pir->addr6 = res->u.v6.addr; ++ pir->mask6 = res->u.v6.mask; ++ pir->v6_flag = 1; ++ pir->count = htonl(res->count); ++ pir->flags = htons(res->flags); ++ pir->mflags = htons(res->mflags); ++ pir = (struct info_restrict *)more_pkt(); ++ } ++ flushRestrictionStack(&rpad); ++ *ppir = pir; + } + + +@@ -1806,8 +1893,7 @@ + /* + * The restriction lists are kept sorted in the reverse order + * than they were originally. To preserve the output semantics, +- * dump each list in reverse order. A recursive helper function +- * achieves that. ++ * dump each list in reverse order. The workers take care of that. + */ + list_restrict4(restrictlist4, &ir); + if (client_v6_capable) +@@ -2238,11 +2324,11 @@ + u_long trust + ) + { +- register u_long *kp; ++ register uint32_t *kp; + register int items; + + items = INFO_NITEMS(inpkt->err_nitems); +- kp = (u_long *)inpkt->data; ++ kp = (uint32_t *)inpkt->data; + while (items-- > 0) { + authtrust(*kp, trust); + kp++; +@@ -2348,7 +2434,7 @@ + it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt, + v6sizeof(struct info_trap)); + +- for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) { ++ for (i = 0, tr = ctl_trap; it && i < CTL_MAXTRAPS; i++, tr++) { + if (tr->tr_flags & TRAP_INUSE) { + if (IS_IPV4(&tr->tr_addr)) { + if (tr->tr_localaddr == any_interface) +@@ -2684,7 +2770,7 @@ + ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt, + sizeof(struct info_clock)); + +- while (items-- > 0) { ++ while (items-- > 0 && ic) { + NSRCADR(&addr) = *clkaddr++; + if (!ISREFCLOCKADR(&addr) || + findexistingpeer(&addr, NULL, -1) == NULL) { +@@ -2823,7 +2909,7 @@ + ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt, + sizeof(struct info_clkbug)); + +- while (items-- > 0) { ++ while (items-- > 0 && ic) { + NSRCADR(&addr) = *clkaddr++; + if (!ISREFCLOCKADR(&addr) || + findexistingpeer(&addr, NULL, -1) == 0) { +@@ -2871,13 +2957,15 @@ + struct info_if_stats **ifsp = (struct info_if_stats **)data; + struct info_if_stats *ifs = *ifsp; + endpt *ep = interface_info->ep; ++ ++ if (NULL == ifs) ++ return; + + memset(ifs, 0, sizeof(*ifs)); + + if (IS_IPV6(&ep->sin)) { +- if (!client_v6_capable) { ++ if (!client_v6_capable) + return; +- } + ifs->v6_flag = 1; + ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin); + ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast); diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7979.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7979.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7979.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-7979.patch 2016-06-01 16:27:21.000000000 +0000 @@ -0,0 +1,28 @@ +Description: fix authenticated broadcast mode off-path denial of service +Origin: vendor, http://pkgs.fedoraproject.org/cgit/rpms/ntp.git/tree/ntp-4.2.6p5-cve-2015-7979.patch +Bug: http://support.ntp.org/bin/view/Main/NtpBug2942 + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_proto.c 2016-06-01 12:27:19.571177566 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c 2016-06-01 12:27:19.571177566 -0400 +@@ -1178,7 +1178,8 @@ + report_event(PEVNT_AUTH, peer, "crypto_NAK"); + peer->flash |= TEST5; /* bad auth */ + peer->badauth++; +- if (peer->flags & FLAG_PREEMPT) { ++ if (peer->flags & FLAG_PREEMPT && hismode != MODE_BROADCAST && ++ !(peer->flash & (TEST2 | TEST3))) { + unpeer(peer); + return; + } +@@ -1204,7 +1205,8 @@ + if (has_mac && + (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE)) + fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask); +- if (peer->flags & FLAG_PREEMPT) { ++ if (peer->flags & FLAG_PREEMPT && hismode != MODE_BROADCAST && ++ !(peer->flash & (TEST2 | TEST3))) { + unpeer(peer); + return; + } diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8138.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8138.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8138.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8138.patch 2016-06-01 16:27:31.000000000 +0000 @@ -0,0 +1,18 @@ +Description: fix Zero Origin Timestamp Bypass +Origin: vendor, http://pkgs.fedoraproject.org/cgit/rpms/ntp.git/tree/ntp-4.2.6p5-cve-2015-8138.patch +Bug: http://support.ntp.org/bin/view/Main/NtpBug2945 +Bug: http://support.ntp.org/bin/view/Main/NtpBug2901 + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_proto.c 2016-06-01 12:27:28.707295147 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c 2016-06-01 12:27:28.707295147 -0400 +@@ -1138,7 +1138,7 @@ + * the packet is not bogus in symmetric interleaved mode. + */ + } else if (peer->flip == 0) { +- if (!L_ISEQU(&p_org, &peer->aorg)) { ++ if (L_ISZERO(&p_org) || !L_ISEQU(&p_org, &peer->aorg)) { + peer->bogusorg++; + peer->flash |= TEST2; /* bogus */ + if (!L_ISZERO(&peer->dst) && L_ISEQU(&p_org, diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8158.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8158.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8158.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2015-8158.patch 2016-06-01 16:27:37.000000000 +0000 @@ -0,0 +1,138 @@ +Backport of: + +From 7ae776fa4db933a17598875fc5917aaea531e4cf Mon Sep 17 00:00:00 2001 +From: +Date: Sat, 17 Oct 2015 21:15:39 +0200 +Subject: [PATCH] [Bug 2948] Potential Infinite Loop in ntpq and ntpdc + +--- + ChangeLog | 2 ++ + ntpdc/ntpdc.c | 21 ++++++++++++++++++++- + ntpq/ntpq.c | 24 ++++++++++++++++++++++-- + 3 files changed, 44 insertions(+), 3 deletions(-) + +Index: ntp-4.2.6.p3+dfsg/ntpdc/ntpdc.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpdc/ntpdc.c 2016-06-01 12:27:34.815373760 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpdc/ntpdc.c 2016-06-01 12:27:34.811373708 -0400 +@@ -657,6 +657,10 @@ + 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 @@ + 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 @@ + 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 @@ + } + + /* +- * 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(); +Index: ntp-4.2.6.p3+dfsg/ntpq/ntpq.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpq/ntpq.c 2016-06-01 12:27:34.815373760 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpq/ntpq.c 2016-06-01 12:27:34.811373708 -0400 +@@ -834,6 +834,10 @@ + 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 +@@ -850,6 +854,8 @@ + numfrags = 0; + seenlastfrag = 0; + ++ tobase = (uint32_t)time(NULL); ++ + FD_ZERO(&fds); + + /* +@@ -862,6 +868,7 @@ + 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); +@@ -870,6 +877,17 @@ + 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 +@@ -1164,10 +1182,12 @@ + } + + /* +- * 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. diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1548.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1548.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1548.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1548.patch 2016-06-01 16:27:46.000000000 +0000 @@ -0,0 +1,69 @@ +Description: fix time spoofing via interleaved symmetric mode +Origin: vendor, http://pkgs.fedoraproject.org/cgit/rpms/ntp.git/tree/ntp-4.2.6p5-cve-2016-1548.patch +Bug: http://support.ntp.org/bin/view/Main/NtpBug2978 + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_proto.c 2016-06-01 12:27:44.535498863 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_proto.c 2016-06-01 12:27:44.535498863 -0400 +@@ -305,6 +305,7 @@ + int authlen; /* offset of MAC field */ + int is_authentic = 0; /* cryptosum ok */ + int retcode = AM_NOMATCH; /* match code */ ++ int xleave_mismatch = 0; /* mismatch in xleave mode */ + keyid_t skeyid = 0; /* key IDs */ + u_int32 opcode = 0; /* extension field opcode */ + sockaddr_u *dstadr_sin; /* active runway */ +@@ -1133,9 +1134,8 @@ + } + + /* +- * Check for bogus packet in basic mode. If found, switch to +- * interleaved mode and resynchronize, but only after confirming +- * the packet is not bogus in symmetric interleaved mode. ++ * Check for bogus packet in basic mode. If found, check if it's not ++ * a valid packet in symmetric interleaved mode. + */ + } else if (peer->flip == 0) { + if (L_ISZERO(&p_org) || !L_ISEQU(&p_org, &peer->aorg)) { +@@ -1143,8 +1143,7 @@ + peer->flash |= TEST2; /* bogus */ + if (!L_ISZERO(&peer->dst) && L_ISEQU(&p_org, + &peer->dst)) { +- peer->flip = 1; +- report_event(PEVNT_XLEAVE, peer, NULL); ++ xleave_mismatch = 1; + } + } else { + L_CLR(&peer->aorg); +@@ -1218,6 +1217,16 @@ + } + + /* ++ * If the packet is bogus in basic mode but not in symmetric ++ * interleaved mode and it passed the authentication check, ++ * enable the mode and resynchronize. ++ */ ++ if (xleave_mismatch && hismode == MODE_ACTIVE) { ++ peer->flip = 1; ++ report_event(PEVNT_XLEAVE, peer, NULL); ++ } ++ ++ /* + * Update the state variables. + */ + if (peer->flip == 0) { +@@ -1754,6 +1763,13 @@ + sys_rootdisp = dtemp + peer->rootdisp; + sys_rootdelay = peer->delay + peer->rootdelay; + sys_reftime = peer->dst; ++ ++ /* Randomize the fraction part of the reference time to not reveal ++ peer->dst to NTP clients as it could be used in a DoS attack ++ enabling the symmetric interleaved mode with spoofed packets */ ++ ntp_crypto_random_buf(&sys_reftime.l_uf, sizeof (sys_reftime.l_uf)); ++ if (L_ISHIS(&sys_reftime, &peer->dst)) ++ sys_reftime.l_ui--; + + #ifdef DEBUG + if (debug) diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1550.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1550.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1550.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-1550.patch 2016-06-01 15:19:00.000000000 +0000 @@ -0,0 +1,30 @@ +Description: fix buffer comparison timing attacks +Origin: vendor, http://pkgs.fedoraproject.org/cgit/rpms/ntp.git/tree/ntp-4.2.6p5-cve-2016-1550.patch +Bug: http://support.ntp.org/bin/view/Main/NtpBug2879 + +Index: ntp-4.2.6.p5+dfsg/libntp/a_md5encrypt.c +=================================================================== +--- ntp-4.2.6.p5+dfsg.orig/libntp/a_md5encrypt.c 2016-06-01 11:18:22.702295683 -0400 ++++ ntp-4.2.6.p5+dfsg/libntp/a_md5encrypt.c 2016-06-01 11:18:46.446620254 -0400 +@@ -80,7 +80,7 @@ + "MAC decrypt: MAC length error"); + return (0); + } +- return (!memcmp(digest, (char *)pkt + length + 4, len)); ++ return (!CRYPTO_memcmp(digest, (char *)pkt + length + 4, len)); + } + + /* +Index: ntp-4.2.6.p5+dfsg/sntp/crypto.c +=================================================================== +--- ntp-4.2.6.p5+dfsg.orig/sntp/crypto.c 2016-06-01 11:18:22.702295683 -0400 ++++ ntp-4.2.6.p5+dfsg/sntp/crypto.c 2016-06-01 11:18:22.702295683 -0400 +@@ -58,7 +58,7 @@ + if (!hash_len) + authentic = FALSE; + else +- authentic = !memcmp(digest, pkt_data + pkt_size + 4, ++ authentic = !CRYPTO_memcmp(digest, pkt_data + pkt_size + 4, + hash_len); + return authentic; + } diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2516.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2516.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2516.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2516.patch 2016-06-01 16:27:59.000000000 +0000 @@ -0,0 +1,25 @@ +Description: fix DoS via duplicate IPs on unconfig directives +Origin: backport, http://pkgs.fedoraproject.org/cgit/rpms/ntp.git/tree/ntp-4.2.6p5-cve-2016-2516.patch +Bug: http://support.ntp.org/bin/view/Main/NtpBug3011 + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_request.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_request.c 2016-06-01 12:27:58.191674630 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_request.c 2016-06-01 12:27:58.191674630 -0400 +@@ -1629,11 +1629,12 @@ + if (peer->flags & FLAG_CONFIG) + found = 1; + } +- NTP_INSIST(found); +- NTP_INSIST(peer); ++ if (found) { ++ NTP_INSIST(peer); + +- peer_clear(peer, "GONE"); +- unpeer(peer); ++ peer_clear(peer, "GONE"); ++ unpeer(peer); ++ } + + cp = (struct conf_unpeer *) + ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2518.patch ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2518.patch --- ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2518.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/CVE-2016-2518.patch 2016-06-01 16:28:05.000000000 +0000 @@ -0,0 +1,49 @@ +Description: fix denial of service via crafted addpeer +Origin: upstream, http://bk1.ntp.org/ntp-stable/?PAGE=patch&REV=56c9c5218oFfAM2Htz-Zz0kGVqWFow +Bug: http://support.ntp.org/bin/view/Main/NtpBug3009 + +Index: ntp-4.2.6.p3+dfsg/ntpd/ntp_request.c +=================================================================== +--- ntp-4.2.6.p3+dfsg.orig/ntpd/ntp_request.c 2016-06-01 12:28:04.327753610 -0400 ++++ ntp-4.2.6.p3+dfsg/ntpd/ntp_request.c 2016-06-01 12:28:04.323753559 -0400 +@@ -1411,11 +1411,38 @@ + peeraddr.sa.sa_len = SOCKLEN(&peeraddr); + #endif + +- /* XXX W2DO? minpoll/maxpoll arguments ??? */ ++ /* check mode value: 0 <= hmode <= 6 ++ * ++ * There's no good global define for that limit, and ++ * using a magic define is as good (or bad, actually) as ++ * a magic number. So we use the highest possible peer ++ * mode, and that is MODE_BCLIENT. ++ * ++ * [Bug 3009] claims that a problem occurs for hmode > 7, ++ * but the code in ntp_peer.c indicates trouble for any ++ * hmode > 6 ( --> MODE_BCLIENT). ++ */ ++ if (temp_cp.hmode > MODE_BCLIENT) { ++ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); ++ return; ++ } ++ ++ /* Any more checks on the values? Unchecked at this ++ * point: ++ * - version ++ * - ttl ++ * - keyid ++ * ++ * - minpoll/maxpoll, but they are treated properly ++ * for all cases internally. Checking not necessary. ++ */ ++ ++ /* finally create the peer */ + if (peer_config(&peeraddr, (struct interface *)0, + temp_cp.hmode, temp_cp.version, temp_cp.minpoll, + temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid, +- NULL) == 0) { ++ NULL) == 0) ++ { + req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); + return; + } diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/reject-UDP-ports-less-than-123-as-bogus.patch ntp-4.2.6.p3+dfsg/debian/patches/reject-UDP-ports-less-than-123-as-bogus.patch --- ntp-4.2.6.p3+dfsg/debian/patches/reject-UDP-ports-less-than-123-as-bogus.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/reject-UDP-ports-less-than-123-as-bogus.patch 2016-02-11 17:10:40.000000000 +0000 @@ -0,0 +1,34 @@ +Description: [Bug 2174] ntpd rejects source UDP ports less than 123 as bogus. + +If an NTP client sends a request with a source port less than 123, the packet +is silently ignored by ntpd. This is occurring in our environment due to NAT. + +Author: davehart@dlh-7551.ad.hartbrothers.com +Bug: http://bugs.ntp.org/show_bug.cgi?id=2174 +Bug-Ubuntu: https://launchpad.net/bugs/1479652 +Origin: backport, http://bk.ntp.org/ntp-dev/?PAGE=patch&REV=4f977538lZC_iBKp-J-Xg1LFrR9foQ + +--- a/ntpd/ntp_proto.c ++++ b/ntpd/ntp_proto.c +@@ -332,18 +332,15 @@ + * reveals a clogging attack. + */ + sys_received++; +- if (SRCPORT(&rbufp->recv_srcadr) < NTP_PORT) { ++ if (0 == SRCPORT(&rbufp->recv_srcadr)) { + sys_badlength++; + return; /* bogus port */ + } + restrict_mask = restrictions(&rbufp->recv_srcadr); +-#ifdef DEBUG +- if (debug > 1) +- printf("receive: at %ld %s<-%s flags %x restrict %03x\n", ++ DPRINTF(2, ("receive: at %ld %s<-%s flags %x restrict %03x\n", + current_time, stoa(&rbufp->dstadr->sin), + stoa(&rbufp->recv_srcadr), +- rbufp->dstadr->flags, restrict_mask); +-#endif ++ rbufp->dstadr->flags, restrict_mask)); + pkt = &rbufp->recv_pkt; + hisversion = PKT_VERSION(pkt->li_vn_mode); + hisleap = PKT_LEAP(pkt->li_vn_mode); diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/series ntp-4.2.6.p3+dfsg/debian/patches/series --- ntp-4.2.6.p3+dfsg/debian/patches/series 2015-10-23 15:56:40.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/series 2016-06-01 16:26:22.000000000 +0000 @@ -31,3 +31,16 @@ CVE-2015-7853.patch CVE-2015-7855.patch CVE-2015-7871.patch +use-after-free-in-routing-socket.patch +reject-UDP-ports-less-than-123-as-bogus.patch +CVE-2015-7973.patch +CVE-2015-7974.patch +CVE-2015-7976.patch +CVE-2015-7977-7978.patch +CVE-2015-7979.patch +CVE-2015-8138.patch +CVE-2015-8158.patch +CVE-2016-1548.patch +CVE-2016-1550.patch +CVE-2016-2516.patch +CVE-2016-2518.patch diff -Nru ntp-4.2.6.p3+dfsg/debian/patches/use-after-free-in-routing-socket.patch ntp-4.2.6.p3+dfsg/debian/patches/use-after-free-in-routing-socket.patch --- ntp-4.2.6.p3+dfsg/debian/patches/use-after-free-in-routing-socket.patch 1970-01-01 00:00:00.000000000 +0000 +++ ntp-4.2.6.p3+dfsg/debian/patches/use-after-free-in-routing-socket.patch 2015-11-10 16:50:28.000000000 +0000 @@ -0,0 +1,31 @@ +Description: Fix use-after-free in routing socket code. +Origin: backport, https://bugs.ntp.org/attachment.cgi?id=883 +Bug: http://bugs.ntp.org/2224 +--- a/ntpd/ntp_io.c ++++ b/ntpd/ntp_io.c +@@ -3534,7 +3534,8 @@ + int select_count = 0; + endpt *ep; + #if defined(HAS_ROUTING_SOCKET) +- struct asyncio_reader *asyncio_reader; ++ struct asyncio_reader * asyncio_reader; ++ struct asyncio_reader * next_asyncio_reader; + #endif + + handler_calls++; +@@ -3637,11 +3638,13 @@ + asyncio_reader = asyncio_reader_list; + + while (asyncio_reader != NULL) { ++ /* callback may unlink and free asyncio_reader */ ++ next_asyncio_reader = asyncio_reader->link; + if (FD_ISSET(asyncio_reader->fd, &fds)) { + ++select_count; +- (asyncio_reader->receiver)(asyncio_reader); ++ (*asyncio_reader->receiver)(asyncio_reader); + } +- asyncio_reader = asyncio_reader->link; ++ asyncio_reader = next_asyncio_reader; + } + #endif /* HAS_ROUTING_SOCKET */ +