<html lang='en'>
<head>
<meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
<title>
GitLab
</title>
</meta>
</head>
<style>
  img {
    max-width: 100%;
    height: auto;
  }
  p.details {
    font-style:italic;
    color:#777
  }
  .footer p {
    font-size:small;
    color:#777
  }
  pre.commit-message {
    white-space: pre-wrap;
  }
  .file-stats a {
    text-decoration: none;
  }
  .file-stats .new-file {
    color: #090;
  }
  .file-stats .deleted-file {
    color: #B00;
  }
</style>
<body>
<div class='content'>
<h3>
Daniel Fox Franke pushed to branch master
at <a href="https://gitlab.com/NTPsec/ntpsec">NTPsec / ntpsec</a>
</h3>
<h4>
Commits:
</h4>
<ul>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/9bd05b082c87b79a157c2382955302e9f8c70a27">9bd05b08</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T11:37:31-05:00</i>
</div>
<pre class='commit-message'>CVE-2015-7975: Add missing length check to nextvar()</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/e31cdda32bc52aff047b4bd7e9b885aa56b51e15">e31cdda3</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T11:37:59-05:00</i>
</div>
<pre class='commit-message'>CVE-2015-8139: Don't allow rv of expected origin timestamp</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/bd103818b1f0a8b96a9dee2a347f16e29d16d971">bd103818</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T11:38:06-05:00</i>
</div>
<pre class='commit-message'>CVE-2015-8138: fix logic error accepting zero origin timestamps</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/16277376571651732902f7df93870d4877c8b2d8">16277376</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T11:38:16-05:00</i>
</div>
<pre class='commit-message'>CVE-2015-8158: Avoid infinite loop processing responses in ntpq</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/1b14fb93ae88b56dfacbb15bea65382603e178a4">1b14fb93</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T11:40:16-05:00</i>
</div>
<pre class='commit-message'>CVE-2015-7979: Don't demobilize in response to unauthenticated packet</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/1eb96e5e90be819b4a57e6246b2fd8357452772f">1eb96e5e</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T14:28:23-05:00</i>
</div>
<pre class='commit-message'>Make MAC verification run in constant time</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/5b4aac162f4b79ecf764e7b7b8a7dd92cec3fd99">5b4aac16</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T14:38:40-05:00</i>
</div>
<pre class='commit-message'>CVE-2015-7973: prevent replay in authenticated broadcast mode</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/576d06e9a7d40741d9f09a105ca29b134dac77c2">576d06e9</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T14:57:11-05:00</i>
</div>
<pre class='commit-message'>Make sure saveconfig doesn't get re-enabled by accident

This is dangerous functionality. Make sure it doesn't get re-enabled
by accident while we're deciding whether to repair or remove it.</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/36ec80633e2da1423d4c9b683a78e110670d16a5">36ec8063</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T15:24:08-05:00</i>
</div>
<pre class='commit-message'>Add missing length checks to decodearr and outputarr

These function are awful! This commit should make them non-vulnerable,
but they desperately want to be rewritten.</pre>
</li>
<li>
<strong><a href="https://gitlab.com/NTPsec/ntpsec/commit/74bd2defce5844b89bd80d962ba0294cc3356f35">74bd2def</a></strong>
<div>
<span>by Daniel Fox Franke</span>
<i>at 2016-01-20T15:31:31-05:00</i>
</div>
<pre class='commit-message'>Draft release notes for 0.9.1</pre>
</li>
</ul>
<h4>6 changed files:</h4>
<ul>
<li class='file-stats'>
<a href='#diff-0'>
NEWS
</a>
</li>
<li class='file-stats'>
<a href='#diff-1'>
libntp/a_md5encrypt.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-2'>
ntpd/ntp_control.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-3'>
ntpd/ntp_proto.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-4'>
ntpq/ntpq.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-5'>
pylib/configure.py
</a>
</li>
</ul>
<h4>Changes:</h4>
<li id='diff-0'>
<a href='https://gitlab.com/NTPsec/ntpsec/compare/bdacafa9bb2adaa14e3738fa24cae631e947c750...74bd2defce5844b89bd80d962ba0294cc3356f35#diff-0'>
<strong>
NEWS
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/NEWS
</span><span style="color: #000000;background-color: #ddffdd">+++ b/NEWS
</span><span style="color: #aaaaaa">@@ -6,8 +6,69 @@ Much of the traditional function of a news file is now better addressed
</span> by browsing the comments in the revision history.  This file will focus
 on user-visible changes.
 
<span style="color: #000000;background-color: #ffdddd">-== 2016-01-19: 0.9.1 (pending) ==
-
</span><span style="color: #000000;background-color: #ddffdd">+== 2016-01-20: 0.9.1 (pending) ==
+
+Point release for security. Fixes:
+
+* CVE-2015-7973: Replay attack on authenticated broadcast mode
+  (Aanchal Malhotra)
+* CVE-2015-7975: nextvar() missing length check (Jonathan Gardner)
+* CVE-2015-7979: Off-path Denial of Service (DoS) attack on
+  authenticated broadcast and other preemptable modes (Aanchal
+  Malhotra)
+* CVE-2015-8138: Zero Origin Timestamp Bypass (Matthew van Gundy &
+  Jonathan Gardner)
+* CVE-2015-8139: Origin Leak: ntpq and ntpdc Disclose Origin Timestamp
+  to Unauthenticated Clients (Matthew van Gundy)
+* CVE-2015-8158: Potential Infinite Loop in ntpq (Jonathan Gardner)
+* Timing attack on MAC verification (Daniel Franke)
+* Missing length checks in decodearr() and outputarr() (Daniel Franke)
+
+Two additional security issues hve been reported to us for which we
+are not implementing code changes, but the user should be aware of
+their impact.
+
+The first (CVE-2015-8140) pertains to NTP's dynamic reconfiguration
+feature, which permits on-the-fly modification of NTP's configuration
+via ntpq. This feature is rarely used, typically disabled, and can
+only be enabled when authentication is configured. Ntpd has no means
+of detecting that a request to change its configuration is a replay of
+an old packet. Therefore, if an administrator sets ntpd to
+configuration A and then to configuration B, an attacker who captures
+the packets commanding these changes can replay the first one and
+restore ntpd's state to configuration A. This is only a concern when
+the configuration commands are sent over an untrusted
+network. Configuration changes made via localhost are not susceptible.
+
+This is an inherent design flaw in NTP cryptography and in the remote
+reconfiguration protocol, and can be fixed only with a considerable
+reworking and by changing the protocol in a way that is neither
+forward nor backward compatible. This cryptographic rework is on the
+horizon in the form of Network Time Security (currently a draft in the
+IETF network time working group). Given that this vulnerability
+impacts few if any real users, we have chosen to defer fixing it until
+we have tools more suitable to the task. For the mean time, if you
+rely on NTP's reconfiguration support, we recommend either restricting
+its use to localhost or trusted networks, or tunneling through SSH or
+a VPN. The 'nomodify' option to the 'restrict' directive may be used
+to enforce this policy.
+
+The second (CVE-2015-7974) pertains to the fact that when multiple
+trusted keys are configured, no mechanism exists to associate
+particular keys with particular peers or assign particular privileges.
+This is not a bug, per se, but rather a lack of expressiveness in
+NTP's configuration language. We intend to address in a future release
+as part of a larger redesign aimed at giving clearer semantics to the
+configuration language and making it easier to write safe
+configurations.
+
+Note that NTPsec is not impacted by CVE-2015-7976, CVE-2015-7977, or
+CVE-2015-7978. CVE-2015-7977 and CVE-2015-7978 both pertain to mode 7
+packets, support for which was completely removed before NTPsec's
+first beta. CVE-2015-7976 is a feature request to restrict the format
+of filenames used in saveconfig commands. Saveconfig support is
+disabled at compile time in NTPsec and will not be re-enabled without
+much more extensive hardening.
</span> 
 == 2015-11-16: 0.9.0 ==
 
</code></pre>

<br>
</li>
<li id='diff-1'>
<a href='https://gitlab.com/NTPsec/ntpsec/compare/bdacafa9bb2adaa14e3738fa24cae631e947c750...74bd2defce5844b89bd80d962ba0294cc3356f35#diff-1'>
<strong>
libntp/a_md5encrypt.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/libntp/a_md5encrypt.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/libntp/a_md5encrypt.c
</span><span style="color: #aaaaaa">@@ -4,12 +4,38 @@
</span> #include <config.h>
 
 #include <string.h>
<span style="color: #000000;background-color: #ddffdd">+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
</span> 
 #include "ntp_fp.h"
 #include "ntp_stdlib.h"
 #include "ntp.h"
 #include "ntp_md5.h" /* provides OpenSSL digest API */
 
<span style="color: #000000;background-color: #ddffdd">+/* ctmemeq - test two blocks memory for equality without leaking
+ * timing information.
+ *
+ * Return value: true if the two blocks of memory are equal, false
+ * otherwise.
+ *
+ * TODO: find out if this is useful elsewhere and if so move
+ * it to a more appropriate place and give it a prototype in a
+ * header file.
+ */
+static bool ctmemeq(const void *s1, const void *s2, size_t n) {
+       const uint8_t *a = s1;
+       const uint8_t *b = s2;
+       uint8_t accum = 0;
+        ptrdiff_t i;
+
+       for(i=0; i<n; i++) {
+               accum |= a[i] ^ b[i];
+       }
+
+       return accum == 0;
+}
+
</span> /*
  * MD5authencrypt - generate message digest
  *
<span style="color: #aaaaaa">@@ -93,7 +119,7 @@ MD5authdecrypt(
</span>               "MAC decrypt: MAC length error");
                return (0);
        }
<span style="color: #000000;background-color: #ffdddd">-        return !memcmp(digest, (char *)pkt + length + 4, len);
</span><span style="color: #000000;background-color: #ddffdd">+   return (int)ctmemeq(digest, (char *)pkt + length + 4, len);
</span> }
 
 /*
</code></pre>

<br>
</li>
<li id='diff-2'>
<a href='https://gitlab.com/NTPsec/ntpsec/compare/bdacafa9bb2adaa14e3738fa24cae631e947c750...74bd2defce5844b89bd80d962ba0294cc3356f35#diff-2'>
<strong>
ntpd/ntp_control.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/ntpd/ntp_control.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/ntpd/ntp_control.c
</span><span style="color: #aaaaaa">@@ -251,7 +251,7 @@ static const struct ctl_proc control_codes[] = {
</span> #define   CP_ROOTDISPERSION       15
 #define        CP_REFID                16
 #define        CP_REFTIME              17
<span style="color: #000000;background-color: #ffdddd">-#define CP_ORG                  18
</span><span style="color: #000000;background-color: #ddffdd">+/* #define CP_ORG                  18 */
</span> #define   CP_REC                  19
 #define        CP_XMT                  20
 #define        CP_REACH                21
<span style="color: #aaaaaa">@@ -491,7 +491,9 @@ static const struct ctl_var peer_var[] = {
</span>   { CP_ROOTDISPERSION, RO, "rootdisp" },        /* 15 */
        { CP_REFID,     RO, "refid" },                /* 16 */
        { CP_REFTIME,   RO, "reftime" },      /* 17 */
<span style="color: #000000;background-color: #ffdddd">-        { CP_ORG,       RO, "org" },          /* 18 */
</span><span style="color: #000000;background-color: #ddffdd">+        /* This variable is disabled because leaking it creates a
+           vulnerability */
+        /*     { CP_ORG,       RO, "org" }, */       /* 18 */
</span>   { CP_REC,       RO, "rec" },          /* 19 */
        { CP_XMT,       RO, "xleave" },               /* 20 */
        { CP_REACH,     RO, "reach" },                /* 21 */
<span style="color: #aaaaaa">@@ -2447,10 +2449,6 @@ ctl_putpeer(
</span>           ctl_putts(peer_var[id].text, &p->reftime);
                break;
 
<span style="color: #000000;background-color: #ffdddd">-        case CP_ORG:
-               ctl_putts(peer_var[id].text, &p->aorg);
-               break;
-
</span>   case CP_REC:
                ctl_putts(peer_var[id].text, &p->dst);
                break;
</code></pre>

<br>
</li>
<li id='diff-3'>
<a href='https://gitlab.com/NTPsec/ntpsec/compare/bdacafa9bb2adaa14e3738fa24cae631e947c750...74bd2defce5844b89bd80d962ba0294cc3356f35#diff-3'>
<strong>
ntpd/ntp_proto.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/ntpd/ntp_proto.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/ntpd/ntp_proto.c
</span><span style="color: #aaaaaa">@@ -1249,9 +1249,8 @@ receive(
</span>           peer->flash |= BOGON3;                       /* unsynch */
 
        /*
<span style="color: #000000;background-color: #ffdddd">-         * If the transmit timestamp duplicates a previous one, the
-        * packet is a replay. This prevents the bad guys from replaying
-        * the most recent packet, authenticated or not.
</span><span style="color: #000000;background-color: #ddffdd">+    * If the transmit timestamp duplicates the previous one, the
+        * packet is a duplicate.
</span>    */
        } else if (L_ISEQU(&peer->xmt, &p_xmt)) {
                peer->flash |= BOGON1;                       /* duplicate */
<span style="color: #aaaaaa">@@ -1273,13 +1272,33 @@ receive(
</span>                   return;
                }
 
<span style="color: #000000;background-color: #ddffdd">+                /* In basic (non-interleaved) broadcast mode, origin
+                * timestamps are zero. This is problematic because,
+                * when authentication is not enabled, origin timestamp
+                * checking is our only real line of defense to prevent
+                * spoofing by off-path attackers. Enabling
+                * authentication helps, but then we need some means
+                * of replay detection. Our solution is to reject
+                * packets whose transmit timestamp is earlier than
+                * one which was previously seen. This should be enforced
+                * *only* if authentication is enabled, because otherwise
+                * it results in an easy DoS by sending a spoofed packet
+                * with the transmit timestamp far in the future.
+                */
+               
+               if((restrict_mask & RES_DONTTRUST) &&
+                  L_ISGEQ(&peer->xmt, &p_xmt)) {
+                       peer->flash |= BOGON1;
+                       peer->oldpkt++;
+                       return;
+               }
</span>   /*
         * 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.
         */
        } else if (peer->flip == 0) {
<span style="color: #000000;background-color: #ffdddd">-                if (!L_ISEQU(&p_org, &peer->aorg)) {
</span><span style="color: #000000;background-color: #ddffdd">+           if (!L_ISEQU(&p_org, &peer->aorg) || L_ISZERO(&p_org)) {
</span>                   peer->bogusorg++;
                        peer->flash |= BOGON2;       /* bogus */
                        if (!L_ISZERO(&peer->dst) && L_ISEQU(&p_org,
<span style="color: #aaaaaa">@@ -1319,14 +1338,6 @@ receive(
</span>           report_event(PEVNT_AUTH, peer, "crypto_NAK");
                peer->flash |= BOGON5;               /* bad auth */
                peer->badauth++;
<span style="color: #000000;background-color: #ffdddd">-                if (peer->flags & FLAG_PREEMPT) {
-                       unpeer(peer);
-                       return;
-               }
-#ifdef ENABLE_AUTOKEY
-               if (peer->crypto)
-                       peer_clear(peer, "AUTH");
-#endif /* ENABLE_AUTOKEY */
</span>           return;
 
        /*
<span style="color: #aaaaaa">@@ -1345,10 +1356,6 @@ receive(
</span>           if (has_mac &&
                    (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE))
                        fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask);
<span style="color: #000000;background-color: #ffdddd">-                if (peer->flags & FLAG_PREEMPT) {
-                       unpeer(peer);
-                       return;
-               }
</span> #ifdef ENABLE_AUTOKEY
                if (peer->crypto)
                        peer_clear(peer, "AUTH");
</code></pre>

<br>
</li>
<li id='diff-4'>
<a href='https://gitlab.com/NTPsec/ntpsec/compare/bdacafa9bb2adaa14e3738fa24cae631e947c750...74bd2defce5844b89bd80d962ba0294cc3356f35#diff-4'>
<strong>
ntpq/ntpq.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/ntpq/ntpq.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/ntpq/ntpq.c
</span><span style="color: #aaaaaa">@@ -877,6 +877,7 @@ getresponse(
</span>   fd_set fds;
        int n;
        int errcode;
<span style="color: #000000;background-color: #ddffdd">+        int bail = 0;
</span> 
        /*
         * This is pretty tricky.  We may get between 1 and MAXFRAG packets
<span style="color: #aaaaaa">@@ -901,6 +902,14 @@ getresponse(
</span>    */
        for (;;) {
 
<span style="color: #000000;background-color: #ddffdd">+                /* Discarding various invalid packets can cause us to
+                   loop more than MAXFRAGS times, but enforce a sane bound
+                   on how long we're willing to spend here. */
+               if(bail++ >= (2*MAXFRAGS)) {
+                        warning("too many packets in response; bailing out");
+                       return ERR_TOOMUCH;
+                }
+
</span>           if (numfrags == 0)
                        tvo = tvout;
                else
<span style="color: #aaaaaa">@@ -2066,8 +2075,12 @@ decodearr(
</span>               break;
 
                bp = buf;
<span style="color: #000000;background-color: #ffdddd">-                while (!isspace((int)*cp) && *cp != '\0')
</span><span style="color: #000000;background-color: #ddffdd">+           while (!isspace((int)*cp) && *cp != '\0') {
</span>               *bp++ = *cp++;
<span style="color: #000000;background-color: #ddffdd">+                    if(bp >= buf + sizeof buf)
+                       return false;
+               }
+
</span>           *bp++ = '\0';
 
                if (!decodetime(buf, lfp))
<span style="color: #aaaaaa">@@ -2861,6 +2874,8 @@ nextvar(
</span>   len = srclen;
        while (len > 0 && isspace((unsigned char)cp[len - 1]))
                len--;
<span style="color: #000000;background-color: #ddffdd">+        if(len >= sizeof name)
+                return 0;
</span>   if (len > 0)
                memcpy(name, cp, len);
        name[len] = '\0';
<span style="color: #aaaaaa">@@ -3077,7 +3092,11 @@ outputarr(
</span>   register char *cp;
        register int i;
        register int len;
<span style="color: #000000;background-color: #ffdddd">-        char buf[256];
</span><span style="color: #000000;background-color: #ddffdd">+   char *buf;
+
+       REQUIRE(narr >= 0 && narr <= MAXVALLEN);
+       buf = malloc(16 + 8*narr);
+       ENSURE(buf != NULL);
</span> 
        bp = buf;
        /*
<span style="color: #aaaaaa">@@ -3105,6 +3124,7 @@ outputarr(
</span>   }
        *bp = '\0';
        output(fp, name, buf);
<span style="color: #000000;background-color: #ddffdd">+        free(buf);
</span> }
 
 static char *
</code></pre>

<br>
</li>
<li id='diff-5'>
<a href='https://gitlab.com/NTPsec/ntpsec/compare/bdacafa9bb2adaa14e3738fa24cae631e947c750...74bd2defce5844b89bd80d962ba0294cc3356f35#diff-5'>
<strong>
pylib/configure.py
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/pylib/configure.py
</span><span style="color: #000000;background-color: #ddffdd">+++ b/pylib/configure.py
</span><span style="color: #aaaaaa">@@ -76,9 +76,6 @@ def cmd_configure(ctx):
</span>   if ctx.options.enable_debug_gdb:
                ctx.env.CFLAGS += ["-g"]
 
<span style="color: #000000;background-color: #ffdddd">-        if ctx.options.enable_saveconfig:
-               ctx.define("SAVECONFIG", 1)
-
</span>   if not ctx.options.disable_debug:
                ctx.define("DEBUG", 1)
                ctx.env.BISONFLAGS += ["--debug"]
</code></pre>

<br>
</li>

</div>
<div class='footer' style='margin-top: 10px;'>
<p>

<br>
<a href="https://gitlab.com/NTPsec/ntpsec/compare/bdacafa9bb2adaa14e3738fa24cae631e947c750...74bd2defce5844b89bd80d962ba0294cc3356f35">View it on GitLab</a>.
<br>
You're receiving this email because of your account on gitlab.com.
If you'd like to receive fewer emails, you can
adjust your notification settings.

</p>
</div>
</body>
</html>