|
|
2b78f7 |
http://bk.ntp.org/ntp-stable/?PAGE=patch&REV=54abb266In81wLNAqIaovtP8f2UmUw
|
|
|
2b78f7 |
http://bk.ntp.org/ntp-stable/?PAGE=patch&REV=54a7c595jlwS3KmAxBML75HFGLR_pQ
|
|
|
2b78f7 |
http://bk.ntp.org/ntp-stable/?PAGE=patch&REV=5492d353ncauuWt_PONxaDhC5Qv_SA
|
|
|
2b78f7 |
|
|
|
2b78f7 |
diff -up ntp-4.2.6p5/ntpd/ntp_crypto.c.cve-2014-9297 ntp-4.2.6p5/ntpd/ntp_crypto.c
|
|
|
2b78f7 |
--- ntp-4.2.6p5/ntpd/ntp_crypto.c.cve-2014-9297 2015-02-04 11:37:44.488673076 +0100
|
|
|
2b78f7 |
+++ ntp-4.2.6p5/ntpd/ntp_crypto.c 2015-02-04 11:37:44.491673082 +0100
|
|
|
2b78f7 |
@@ -109,6 +109,7 @@
|
|
|
2b78f7 |
#define TAI_1972 10 /* initial TAI offset (s) */
|
|
|
2b78f7 |
#define MAX_LEAP 100 /* max UTC leapseconds (s) */
|
|
|
2b78f7 |
#define VALUE_LEN (6 * 4) /* min response field length */
|
|
|
2b78f7 |
+#define MAX_VALLEN (65535 - VALUE_LEN)
|
|
|
2b78f7 |
#define YEAR (60 * 60 * 24 * 365) /* seconds in year */
|
|
|
2b78f7 |
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
@@ -147,8 +148,8 @@ static char *rand_file = NULL; /* random
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
static int crypto_verify (struct exten *, struct value *,
|
|
|
2b78f7 |
struct peer *);
|
|
|
2b78f7 |
-static int crypto_encrypt (struct exten *, struct value *,
|
|
|
2b78f7 |
- keyid_t *);
|
|
|
2b78f7 |
+static int crypto_encrypt (const u_char *, u_int, keyid_t *,
|
|
|
2b78f7 |
+ struct value *);
|
|
|
2b78f7 |
static int crypto_alice (struct peer *, struct value *);
|
|
|
2b78f7 |
static int crypto_alice2 (struct peer *, struct value *);
|
|
|
2b78f7 |
static int crypto_alice3 (struct peer *, struct value *);
|
|
|
2b78f7 |
@@ -444,6 +445,12 @@ crypto_recv(
|
|
|
2b78f7 |
tstamp = ntohl(ep->tstamp);
|
|
|
2b78f7 |
fstamp = ntohl(ep->fstamp);
|
|
|
2b78f7 |
vallen = ntohl(ep->vallen);
|
|
|
2b78f7 |
+ /*
|
|
|
2b78f7 |
+ * Bug 2761: I hope this isn't too early...
|
|
|
2b78f7 |
+ */
|
|
|
2b78f7 |
+ if ( vallen == 0
|
|
|
2b78f7 |
+ || len - VALUE_LEN < vallen)
|
|
|
2b78f7 |
+ return XEVNT_LEN;
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
switch (code) {
|
|
|
2b78f7 |
|
|
|
2b78f7 |
@@ -494,8 +501,9 @@ crypto_recv(
|
|
|
2b78f7 |
rval = XEVNT_ERR;
|
|
|
2b78f7 |
break;
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
+ INSIST(len >= VALUE_LEN);
|
|
|
2b78f7 |
if (vallen == 0 || vallen > MAXHOSTNAME ||
|
|
|
2b78f7 |
- len < VALUE_LEN + vallen) {
|
|
|
2b78f7 |
+ len - VALUE_LEN < vallen) {
|
|
|
2b78f7 |
rval = XEVNT_LEN;
|
|
|
2b78f7 |
break;
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
@@ -1162,11 +1170,11 @@ crypto_xmit(
|
|
|
2b78f7 |
* choice.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
case CRYPTO_CERT | CRYPTO_RESP:
|
|
|
2b78f7 |
- vallen = ntohl(ep->vallen);
|
|
|
2b78f7 |
- if (vallen == 0 || vallen > MAXHOSTNAME) {
|
|
|
2b78f7 |
+ vallen = ntohl(ep->vallen); /* Must be <64k */
|
|
|
2b78f7 |
+ if (vallen == 0 || vallen > MAXHOSTNAME ||
|
|
|
2b78f7 |
+ len - VALUE_LEN < vallen) {
|
|
|
2b78f7 |
rval = XEVNT_LEN;
|
|
|
2b78f7 |
break;
|
|
|
2b78f7 |
-
|
|
|
2b78f7 |
} else {
|
|
|
2b78f7 |
memcpy(certname, ep->pkt, vallen);
|
|
|
2b78f7 |
certname[vallen] = '\0';
|
|
|
2b78f7 |
@@ -1315,7 +1323,10 @@ crypto_xmit(
|
|
|
2b78f7 |
* anything goes wrong.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
case CRYPTO_COOK | CRYPTO_RESP:
|
|
|
2b78f7 |
- if ((opcode & 0xffff) < VALUE_LEN) {
|
|
|
2b78f7 |
+ vallen = ntohl(ep->vallen); /* Must be <64k */
|
|
|
2b78f7 |
+ if ( vallen == 0
|
|
|
2b78f7 |
+ || (vallen >= MAX_VALLEN)
|
|
|
2b78f7 |
+ || (opcode & 0x0000ffff) < VALUE_LEN + vallen) {
|
|
|
2b78f7 |
rval = XEVNT_LEN;
|
|
|
2b78f7 |
break;
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
@@ -1323,8 +1334,8 @@ crypto_xmit(
|
|
|
2b78f7 |
tcookie = cookie;
|
|
|
2b78f7 |
else
|
|
|
2b78f7 |
tcookie = peer->hcookie;
|
|
|
2b78f7 |
- if ((rval = crypto_encrypt(ep, &vtemp, &tcookie)) ==
|
|
|
2b78f7 |
- XEVNT_OK) {
|
|
|
2b78f7 |
+ if ((rval = crypto_encrypt((const u_char *)ep->pkt, vallen, &tcookie, &vtemp))
|
|
|
2b78f7 |
+ == XEVNT_OK) {
|
|
|
2b78f7 |
len = crypto_send(fp, &vtemp, start);
|
|
|
2b78f7 |
value_free(&vtemp);
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
@@ -1464,13 +1475,16 @@ crypto_verify(
|
|
|
2b78f7 |
* up to the next word (4 octets).
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
vallen = ntohl(ep->vallen);
|
|
|
2b78f7 |
- if (vallen == 0)
|
|
|
2b78f7 |
+ if ( vallen == 0
|
|
|
2b78f7 |
+ || vallen > MAX_VALLEN)
|
|
|
2b78f7 |
return (XEVNT_LEN);
|
|
|
2b78f7 |
|
|
|
2b78f7 |
i = (vallen + 3) / 4;
|
|
|
2b78f7 |
siglen = ntohl(ep->pkt[i++]);
|
|
|
2b78f7 |
- if (len < VALUE_LEN + ((vallen + 3) / 4) * 4 + ((siglen + 3) /
|
|
|
2b78f7 |
- 4) * 4)
|
|
|
2b78f7 |
+ if ( siglen > MAX_VALLEN
|
|
|
2b78f7 |
+ || len - VALUE_LEN < ((vallen + 3) / 4) * 4
|
|
|
2b78f7 |
+ || len - VALUE_LEN - ((vallen + 3) / 4) * 4
|
|
|
2b78f7 |
+ < ((siglen + 3) / 4) * 4)
|
|
|
2b78f7 |
return (XEVNT_LEN);
|
|
|
2b78f7 |
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
@@ -1528,6 +1542,7 @@ crypto_verify(
|
|
|
2b78f7 |
* proventic bit. What a relief.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
EVP_VerifyInit(&ctx, peer->digest);
|
|
|
2b78f7 |
+ /* XXX: the "+ 12" needs to be at least documented... */
|
|
|
2b78f7 |
EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12);
|
|
|
2b78f7 |
if (EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen,
|
|
|
2b78f7 |
pkey) <= 0)
|
|
|
2b78f7 |
@@ -1540,34 +1555,32 @@ crypto_verify(
|
|
|
2b78f7 |
|
|
|
2b78f7 |
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
- * crypto_encrypt - construct encrypted cookie and signature from
|
|
|
2b78f7 |
- * extension field and cookie
|
|
|
2b78f7 |
+ * crypto_encrypt - construct vp (encrypted cookie and signature) from
|
|
|
2b78f7 |
+ * the public key and cookie.
|
|
|
2b78f7 |
*
|
|
|
2b78f7 |
- * Returns
|
|
|
2b78f7 |
+ * Returns:
|
|
|
2b78f7 |
* XEVNT_OK success
|
|
|
2b78f7 |
* XEVNT_CKY bad or missing cookie
|
|
|
2b78f7 |
* XEVNT_PUB bad or missing public key
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
static int
|
|
|
2b78f7 |
crypto_encrypt(
|
|
|
2b78f7 |
- struct exten *ep, /* extension pointer */
|
|
|
2b78f7 |
- struct value *vp, /* value pointer */
|
|
|
2b78f7 |
- keyid_t *cookie /* server cookie */
|
|
|
2b78f7 |
+ const u_char *ptr, /* Public Key */
|
|
|
2b78f7 |
+ u_int vallen, /* Length of Public Key */
|
|
|
2b78f7 |
+ keyid_t *cookie, /* server cookie */
|
|
|
2b78f7 |
+ struct value *vp /* value pointer */
|
|
|
2b78f7 |
)
|
|
|
2b78f7 |
{
|
|
|
2b78f7 |
EVP_PKEY *pkey; /* public key */
|
|
|
2b78f7 |
EVP_MD_CTX ctx; /* signature context */
|
|
|
2b78f7 |
tstamp_t tstamp; /* NTP timestamp */
|
|
|
2b78f7 |
u_int32 temp32;
|
|
|
2b78f7 |
- u_int len;
|
|
|
2b78f7 |
- u_char *ptr;
|
|
|
2b78f7 |
+ u_char *puch;
|
|
|
2b78f7 |
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
* Extract the public key from the request.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
- len = ntohl(ep->vallen);
|
|
|
2b78f7 |
- ptr = (u_char *)ep->pkt;
|
|
|
2b78f7 |
- pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, len);
|
|
|
2b78f7 |
+ pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, vallen);
|
|
|
2b78f7 |
if (pkey == NULL) {
|
|
|
2b78f7 |
msyslog(LOG_ERR, "crypto_encrypt: %s",
|
|
|
2b78f7 |
ERR_error_string(ERR_get_error(), NULL));
|
|
|
2b78f7 |
@@ -1581,12 +1594,12 @@ crypto_encrypt(
|
|
|
2b78f7 |
tstamp = crypto_time();
|
|
|
2b78f7 |
vp->tstamp = htonl(tstamp);
|
|
|
2b78f7 |
vp->fstamp = hostval.tstamp;
|
|
|
2b78f7 |
- len = EVP_PKEY_size(pkey);
|
|
|
2b78f7 |
- vp->vallen = htonl(len);
|
|
|
2b78f7 |
- vp->ptr = emalloc(len);
|
|
|
2b78f7 |
- ptr = vp->ptr;
|
|
|
2b78f7 |
+ vallen = EVP_PKEY_size(pkey);
|
|
|
2b78f7 |
+ vp->vallen = htonl(vallen);
|
|
|
2b78f7 |
+ vp->ptr = emalloc(vallen);
|
|
|
2b78f7 |
+ puch = vp->ptr;
|
|
|
2b78f7 |
temp32 = htonl(*cookie);
|
|
|
2b78f7 |
- if (RSA_public_encrypt(4, (u_char *)&temp32, ptr,
|
|
|
2b78f7 |
+ if (RSA_public_encrypt(4, (u_char *)&temp32, puch,
|
|
|
2b78f7 |
pkey->pkey.rsa, RSA_PKCS1_OAEP_PADDING) <= 0) {
|
|
|
2b78f7 |
msyslog(LOG_ERR, "crypto_encrypt: %s",
|
|
|
2b78f7 |
ERR_error_string(ERR_get_error(), NULL));
|
|
|
2b78f7 |
@@ -1601,8 +1614,8 @@ crypto_encrypt(
|
|
|
2b78f7 |
vp->sig = emalloc(sign_siglen);
|
|
|
2b78f7 |
EVP_SignInit(&ctx, sign_digest);
|
|
|
2b78f7 |
EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
|
|
|
2b78f7 |
- EVP_SignUpdate(&ctx, vp->ptr, len);
|
|
|
2b78f7 |
- if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
|
|
|
2b78f7 |
+ EVP_SignUpdate(&ctx, vp->ptr, vallen);
|
|
|
2b78f7 |
+ if (EVP_SignFinal(&ctx, vp->sig, &vallen, sign_pkey))
|
|
|
2b78f7 |
vp->siglen = htonl(sign_siglen);
|
|
|
2b78f7 |
return (XEVNT_OK);
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
@@ -1673,6 +1686,9 @@ crypto_ident(
|
|
|
2b78f7 |
* call in the protocol module.
|
|
|
2b78f7 |
*
|
|
|
2b78f7 |
* Returns extension field pointer (no errors)
|
|
|
2b78f7 |
+ *
|
|
|
2b78f7 |
+ * XXX: opcode and len should really be 32-bit quantities and
|
|
|
2b78f7 |
+ * we should make sure that str is not too big.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
struct exten *
|
|
|
2b78f7 |
crypto_args(
|
|
|
2b78f7 |
@@ -1685,24 +1701,31 @@ crypto_args(
|
|
|
2b78f7 |
tstamp_t tstamp; /* NTP timestamp */
|
|
|
2b78f7 |
struct exten *ep; /* extension field pointer */
|
|
|
2b78f7 |
u_int len; /* extension field length */
|
|
|
2b78f7 |
+ size_t slen;
|
|
|
2b78f7 |
|
|
|
2b78f7 |
tstamp = crypto_time();
|
|
|
2b78f7 |
len = sizeof(struct exten);
|
|
|
2b78f7 |
- if (str != NULL)
|
|
|
2b78f7 |
- len += strlen(str);
|
|
|
2b78f7 |
+ if (str != NULL) {
|
|
|
2b78f7 |
+ slen = strlen(str);
|
|
|
2b78f7 |
+ INSIST(slen < MAX_VALLEN);
|
|
|
2b78f7 |
+ len += slen;
|
|
|
2b78f7 |
+ }
|
|
|
2b78f7 |
ep = emalloc(len);
|
|
|
2b78f7 |
memset(ep, 0, len);
|
|
|
2b78f7 |
if (opcode == 0)
|
|
|
2b78f7 |
return (ep);
|
|
|
2b78f7 |
|
|
|
2b78f7 |
+ REQUIRE(0 == (len & ~0x0000ffff));
|
|
|
2b78f7 |
+ REQUIRE(0 == (opcode & ~0xffff0000));
|
|
|
2b78f7 |
+
|
|
|
2b78f7 |
ep->opcode = htonl(opcode + len);
|
|
|
2b78f7 |
ep->associd = htonl(associd);
|
|
|
2b78f7 |
ep->tstamp = htonl(tstamp);
|
|
|
2b78f7 |
ep->fstamp = hostval.tstamp;
|
|
|
2b78f7 |
ep->vallen = 0;
|
|
|
2b78f7 |
if (str != NULL) {
|
|
|
2b78f7 |
- ep->vallen = htonl(strlen(str));
|
|
|
2b78f7 |
- memcpy((char *)ep->pkt, str, strlen(str));
|
|
|
2b78f7 |
+ ep->vallen = htonl(slen);
|
|
|
2b78f7 |
+ memcpy((char *)ep->pkt, str, slen);
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
return (ep);
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
@@ -1715,6 +1738,8 @@ crypto_args(
|
|
|
2b78f7 |
* Note: it is not polite to send a nonempty signature with zero
|
|
|
2b78f7 |
* timestamp or a nonzero timestamp with an empty signature, but those
|
|
|
2b78f7 |
* rules are not enforced here.
|
|
|
2b78f7 |
+ *
|
|
|
2b78f7 |
+ * XXX This code won't work on a box with 16-bit ints.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
int
|
|
|
2b78f7 |
crypto_send(
|
|
|
2b78f7 |
@@ -1730,8 +1755,9 @@ crypto_send(
|
|
|
2b78f7 |
* Calculate extension field length and check for buffer
|
|
|
2b78f7 |
* overflow. Leave room for the MAC.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
- len = 16;
|
|
|
2b78f7 |
+ len = 16; /* XXX Document! */
|
|
|
2b78f7 |
vallen = ntohl(vp->vallen);
|
|
|
2b78f7 |
+ INSIST(vallen <= MAX_VALLEN);
|
|
|
2b78f7 |
len += ((vallen + 3) / 4 + 1) * 4;
|
|
|
2b78f7 |
siglen = ntohl(vp->siglen);
|
|
|
2b78f7 |
len += ((siglen + 3) / 4 + 1) * 4;
|
|
|
2b78f7 |
@@ -1772,6 +1798,7 @@ crypto_send(
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
opcode = ntohl(ep->opcode);
|
|
|
2b78f7 |
ep->opcode = htonl((opcode & 0xffff0000) | len);
|
|
|
2b78f7 |
+ ENSURE(len <= MAX_VALLEN);
|
|
|
2b78f7 |
return (len);
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
|
|
|
2b78f7 |
@@ -1807,7 +1834,6 @@ crypto_update(void)
|
|
|
2b78f7 |
if (hostval.tstamp == 0)
|
|
|
2b78f7 |
return;
|
|
|
2b78f7 |
|
|
|
2b78f7 |
-
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
* Sign public key and timestamps. The filestamp is derived from
|
|
|
2b78f7 |
* the host key file extension from wherever the file was
|
|
|
2b78f7 |
@@ -2108,7 +2134,8 @@ crypto_bob(
|
|
|
2b78f7 |
tstamp_t tstamp; /* NTP timestamp */
|
|
|
2b78f7 |
BIGNUM *bn, *bk, *r;
|
|
|
2b78f7 |
u_char *ptr;
|
|
|
2b78f7 |
- u_int len;
|
|
|
2b78f7 |
+ u_int len; /* extension field length */
|
|
|
2b78f7 |
+ u_int vallen = 0; /* value length */
|
|
|
2b78f7 |
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
* If the IFF parameters are not valid, something awful
|
|
|
2b78f7 |
@@ -2123,8 +2150,11 @@ crypto_bob(
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
* Extract r from the challenge.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
- len = ntohl(ep->vallen);
|
|
|
2b78f7 |
- if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
|
|
|
2b78f7 |
+ vallen = ntohl(ep->vallen);
|
|
|
2b78f7 |
+ len = ntohl(ep->opcode) & 0x0000ffff;
|
|
|
2b78f7 |
+ if (vallen == 0 || len < VALUE_LEN || len - VALUE_LEN < vallen)
|
|
|
2b78f7 |
+ return XEVNT_LEN;
|
|
|
2b78f7 |
+ if ((r = BN_bin2bn((u_char *)ep->pkt, vallen, NULL)) == NULL) {
|
|
|
2b78f7 |
msyslog(LOG_ERR, "crypto_bob: %s",
|
|
|
2b78f7 |
ERR_error_string(ERR_get_error(), NULL));
|
|
|
2b78f7 |
return (XEVNT_ERR);
|
|
|
2b78f7 |
@@ -2136,7 +2166,7 @@ crypto_bob(
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new();
|
|
|
2b78f7 |
sdsa = DSA_SIG_new();
|
|
|
2b78f7 |
- BN_rand(bk, len * 8, -1, 1); /* k */
|
|
|
2b78f7 |
+ BN_rand(bk, vallen * 8, -1, 1); /* k */
|
|
|
2b78f7 |
BN_mod_mul(bn, dsa->priv_key, r, dsa->q, bctx); /* b r mod q */
|
|
|
2b78f7 |
BN_add(bn, bn, bk);
|
|
|
2b78f7 |
BN_mod(bn, bn, dsa->q, bctx); /* k + b r mod q */
|
|
|
2b78f7 |
@@ -2155,30 +2185,37 @@ crypto_bob(
|
|
|
2b78f7 |
* Encode the values in ASN.1 and sign. The filestamp is from
|
|
|
2b78f7 |
* the local file.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
- len = i2d_DSA_SIG(sdsa, NULL);
|
|
|
2b78f7 |
- if (len == 0) {
|
|
|
2b78f7 |
+ vallen = i2d_DSA_SIG(sdsa, NULL);
|
|
|
2b78f7 |
+ if (vallen == 0) {
|
|
|
2b78f7 |
msyslog(LOG_ERR, "crypto_bob: %s",
|
|
|
2b78f7 |
ERR_error_string(ERR_get_error(), NULL));
|
|
|
2b78f7 |
DSA_SIG_free(sdsa);
|
|
|
2b78f7 |
return (XEVNT_ERR);
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
+ if (vallen > MAX_VALLEN) {
|
|
|
2b78f7 |
+ msyslog(LOG_ERR, "crypto_bob: signature is too big: %d",
|
|
|
2b78f7 |
+ vallen);
|
|
|
2b78f7 |
+ DSA_SIG_free(sdsa);
|
|
|
2b78f7 |
+ return (XEVNT_LEN);
|
|
|
2b78f7 |
+ }
|
|
|
2b78f7 |
memset(vp, 0, sizeof(struct value));
|
|
|
2b78f7 |
tstamp = crypto_time();
|
|
|
2b78f7 |
vp->tstamp = htonl(tstamp);
|
|
|
2b78f7 |
vp->fstamp = htonl(iffkey_info->fstamp);
|
|
|
2b78f7 |
- vp->vallen = htonl(len);
|
|
|
2b78f7 |
- ptr = emalloc(len);
|
|
|
2b78f7 |
+ vp->vallen = htonl(vallen);
|
|
|
2b78f7 |
+ ptr = emalloc(vallen);
|
|
|
2b78f7 |
vp->ptr = ptr;
|
|
|
2b78f7 |
i2d_DSA_SIG(sdsa, &ptr);
|
|
|
2b78f7 |
DSA_SIG_free(sdsa);
|
|
|
2b78f7 |
if (tstamp == 0)
|
|
|
2b78f7 |
return (XEVNT_OK);
|
|
|
2b78f7 |
|
|
|
2b78f7 |
+ /* XXX: more validation to make sure the sign fits... */
|
|
|
2b78f7 |
vp->sig = emalloc(sign_siglen);
|
|
|
2b78f7 |
EVP_SignInit(&ctx, sign_digest);
|
|
|
2b78f7 |
EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
|
|
|
2b78f7 |
- EVP_SignUpdate(&ctx, vp->ptr, len);
|
|
|
2b78f7 |
- if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
|
|
|
2b78f7 |
+ EVP_SignUpdate(&ctx, vp->ptr, vallen);
|
|
|
2b78f7 |
+ if (EVP_SignFinal(&ctx, vp->sig, &vallen, sign_pkey))
|
|
|
2b78f7 |
vp->siglen = htonl(sign_siglen);
|
|
|
2b78f7 |
return (XEVNT_OK);
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
diff -up ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2014-9297 ntp-4.2.6p5/ntpd/ntp_proto.c
|
|
|
2b78f7 |
--- ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2014-9297 2015-02-04 11:37:44.490673080 +0100
|
|
|
2b78f7 |
+++ ntp-4.2.6p5/ntpd/ntp_proto.c 2015-02-04 11:47:42.653868627 +0100
|
|
|
2b78f7 |
@@ -431,7 +431,7 @@ receive(
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
authlen = LEN_PKT_NOMAC;
|
|
|
2b78f7 |
has_mac = rbufp->recv_length - authlen;
|
|
|
2b78f7 |
- while (has_mac != 0) {
|
|
|
2b78f7 |
+ while (has_mac > 0) {
|
|
|
2b78f7 |
u_int32 len;
|
|
|
2b78f7 |
|
|
|
2b78f7 |
if (has_mac % 4 != 0 || has_mac < MIN_MAC_LEN) {
|
|
|
2b78f7 |
@@ -456,6 +456,14 @@ receive(
|
|
|
2b78f7 |
}
|
|
|
2b78f7 |
|
|
|
2b78f7 |
/*
|
|
|
2b78f7 |
+ * If has_mac is < 0 we had a malformed packet.
|
|
|
2b78f7 |
+ */
|
|
|
2b78f7 |
+ if (has_mac < 0) {
|
|
|
2b78f7 |
+ sys_badlength++;
|
|
|
2b78f7 |
+ return; /* bad length */
|
|
|
2b78f7 |
+ }
|
|
|
2b78f7 |
+
|
|
|
2b78f7 |
+ /*
|
|
|
2b78f7 |
* If authentication required, a MAC must be present.
|
|
|
2b78f7 |
*/
|
|
|
2b78f7 |
if (restrict_mask & RES_DONTTRUST && has_mac == 0) {
|