From 2f834a0b41079f9be4dc33ff877d50a5fba869d4 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 22 Dec 2014 18:54:55 +0000 Subject: [PATCH] Fix multiple ntp vulnerabilities. Reviewed by: roberto (earlier revision), philip Security: CVE-2014-9293, CVE-2014-9294 Security: CVE-2014-9295, CVE-2014-9296 Security: FreeBSD-SA-14:31.ntp Differential Revision: https://reviews.freebsd.org/D1343 --- contrib/ntp/ntpd/ntp_config.c | 2 +- contrib/ntp/ntpd/ntp_control.c | 17 ++++++++++++++++- contrib/ntp/ntpd/ntp_crypto.c | 22 +++++++++++++++++----- contrib/ntp/ntpd/ntp_proto.c | 1 + contrib/ntp/util/ntp-keygen.c | 6 +++--- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/contrib/ntp/ntpd/ntp_config.c b/contrib/ntp/ntpd/ntp_config.c index a28bd1b417c4..e038f205790c 100644 --- a/contrib/ntp/ntpd/ntp_config.c +++ b/contrib/ntp/ntpd/ntp_config.c @@ -1887,7 +1887,7 @@ getconfig( for (i = 0; i < 8; i++) for (j = 1; j < 100; ++j) { - rankey[i] = (char) (ntp_random() & 0xff); + rankey[i] = (char) (arc4random() & 0xff); if (rankey[i] != 0) break; } rankey[8] = 0; diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c index 15f5856f2798..dbee89a0cdc5 100644 --- a/contrib/ntp/ntpd/ntp_control.c +++ b/contrib/ntp/ntpd/ntp_control.c @@ -24,6 +24,10 @@ #include #include +#ifndef MIN +#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) +#endif + /* * Structure to hold request procedure information */ @@ -893,6 +897,7 @@ ctl_putdata( ) { int overhead; + unsigned int currentlen; overhead = 0; if (!bin) { @@ -916,12 +921,22 @@ ctl_putdata( /* * Save room for trailing junk */ - if (dlen + overhead + datapt > dataend) { + while (dlen + overhead + datapt > dataend) { /* * Not enough room in this one, flush it out. */ + currentlen = MIN(dlen, dataend - datapt); + + memcpy(datapt, dp, currentlen); + + datapt += currentlen; + dp += currentlen; + dlen -= currentlen; + datalinelen += currentlen; + ctl_flushpkt(CTL_MORE); } + memmove((char *)datapt, dp, (unsigned)dlen); datapt += dlen; datalinelen += dlen; diff --git a/contrib/ntp/ntpd/ntp_crypto.c b/contrib/ntp/ntpd/ntp_crypto.c index cce95a8e1ea3..37427f4ee6c5 100644 --- a/contrib/ntp/ntpd/ntp_crypto.c +++ b/contrib/ntp/ntpd/ntp_crypto.c @@ -864,12 +864,24 @@ crypto_recv( * errors. */ if (vallen == (u_int) EVP_PKEY_size(host_pkey)) { - RSA_private_decrypt(vallen, + u_int32 *cookiebuf = malloc( + RSA_size(host_pkey->pkey.rsa)); + if (cookiebuf == NULL) { + rval = XEVNT_CKY; + break; + } + if (RSA_private_decrypt(vallen, (u_char *)ep->pkt, - (u_char *)&temp32, + (u_char *)cookiebuf, host_pkey->pkey.rsa, - RSA_PKCS1_OAEP_PADDING); - cookie = ntohl(temp32); + RSA_PKCS1_OAEP_PADDING) != 4) { + rval = XEVNT_CKY; + free(cookiebuf); + break; + } else { + cookie = ntohl(*cookiebuf); + free(cookiebuf); + } } else { rval = XEVNT_CKY; break; @@ -3914,7 +3926,7 @@ crypto_setup(void) rand_file); exit (-1); } - get_systime(&seed); + arc4random_buf(&seed, sizeof(l_fp)); RAND_seed(&seed, sizeof(l_fp)); RAND_write_file(rand_file); OpenSSL_add_all_algorithms(); diff --git a/contrib/ntp/ntpd/ntp_proto.c b/contrib/ntp/ntpd/ntp_proto.c index 0ab249883010..179e118b5f07 100644 --- a/contrib/ntp/ntpd/ntp_proto.c +++ b/contrib/ntp/ntpd/ntp_proto.c @@ -649,6 +649,7 @@ receive( has_mac)) { is_authentic = AUTH_ERROR; sys_badauth++; + return; } else { is_authentic = AUTH_OK; } diff --git a/contrib/ntp/util/ntp-keygen.c b/contrib/ntp/util/ntp-keygen.c index 6c1451889551..056121e68c8c 100644 --- a/contrib/ntp/util/ntp-keygen.c +++ b/contrib/ntp/util/ntp-keygen.c @@ -642,7 +642,7 @@ gen_md5( for (i = 1; i <= MD5KEYS; i++) { for (j = 0; j < 16; j++) { while (1) { - temp = ntp_random() & 0xff; + temp = arc4random() & 0xff; if (temp == '#') continue; if (temp > 0x20 && temp < 0x7f) @@ -675,7 +675,7 @@ gen_rsa( FILE *str; fprintf(stderr, "Generating RSA keys (%d bits)...\n", modulus); - rsa = RSA_generate_key(modulus, 3, cb, "RSA"); + rsa = RSA_generate_key(modulus, 65537, cb, "RSA"); fprintf(stderr, "\n"); if (rsa == NULL) { fprintf(stderr, "RSA generate keys fails\n%s\n", @@ -954,7 +954,7 @@ gen_gqpar( */ fprintf(stderr, "Generating GQ parameters (%d bits)...\n", modulus); - rsa = RSA_generate_key(modulus, 3, cb, "GQ"); + rsa = RSA_generate_key(modulus, 65537, cb, "GQ"); fprintf(stderr, "\n"); if (rsa == NULL) { fprintf(stderr, "RSA generate keys fails\n%s\n",