<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>