CVE-2014-9295 ntp: Multiple buffer overflows via specially-crafted packets Upstream-Status: Backport [Debian] Signed-off-by: Armin Kuster 2014-12-12 11:06:03+00:00, stenn@psp-fb1.ntp.org +12 -3 [Sec 2667] buffer overflow in crypto_recv() 2014-12-12 11:13:40+00:00, stenn@psp-fb1.ntp.org +16 -1 [Sec 2668] buffer overflow in ctl_putdata() 2014-12-12 11:19:37+00:00, stenn@psp-fb1.ntp.org +14 -0 [Sec 2669] buffer overflow in configure() Index: git/ntpd/ntp_crypto.c =================================================================== --- git.orig/ntpd/ntp_crypto.c 2014-12-20 18:45:44.208851199 +0100 +++ git/ntpd/ntp_crypto.c 2014-12-20 18:45:56.425100776 +0100 @@ -789,15 +789,24 @@ * errors. */ if (vallen == (u_int)EVP_PKEY_size(host_pkey)) { + u_int32 *cookiebuf = malloc( + RSA_size(host_pkey->pkey.rsa)); + if (!cookiebuf) { + 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) <= 0) { + RSA_PKCS1_OAEP_PADDING) != 4) { rval = XEVNT_CKY; + free(cookiebuf); break; } else { - cookie = ntohl(temp32); + cookie = ntohl(*cookiebuf); + free(cookiebuf); } } else { rval = XEVNT_CKY; Index: git/ntpd/ntp_control.c =================================================================== --- git.orig/ntpd/ntp_control.c 2014-12-20 18:45:44.208851199 +0100 +++ git/ntpd/ntp_control.c 2014-12-20 18:45:56.429100859 +0100 @@ -486,6 +486,10 @@ static char *reqpt; static char *reqend; +#ifndef MIN +#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) +#endif + /* * init_control - initialize request data */ @@ -995,6 +999,7 @@ ) { int overhead; + unsigned int currentlen; overhead = 0; if (!bin) { @@ -1018,12 +1023,22 @@ /* * 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; @@ -2492,6 +2507,20 @@ /* Initialize the remote config buffer */ data_count = reqend - reqpt; + + if (data_count > sizeof(remote_config.buffer) - 2) { + snprintf(remote_config.err_msg, + sizeof(remote_config.err_msg), + "runtime configuration failed: request too long"); + ctl_putdata(remote_config.err_msg, + strlen(remote_config.err_msg), 0); + ctl_flushpkt(0); + msyslog(LOG_NOTICE, + "runtime config from %s rejected: request too long", + stoa(&rbufp->recv_srcadr)); + return; + } + memcpy(remote_config.buffer, reqpt, data_count); if (data_count > 0 && '\n' != remote_config.buffer[data_count - 1])