diff options
author | glebius <glebius@FreeBSD.org> | 2015-10-26 11:35:40 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2015-10-26 11:35:40 +0000 |
commit | c62812877398840dae0ba74b03e9e6a43cc56fc5 (patch) | |
tree | 304551aa93f09787d4f56a966c6409faf1b1bcb0 /contrib/ntp/libntp/authreadkeys.c | |
parent | 9e809ce638c9be9ffb800ced1b91c0e8997f4c9e (diff) | |
download | FreeBSD-src-c62812877398840dae0ba74b03e9e6a43cc56fc5.zip FreeBSD-src-c62812877398840dae0ba74b03e9e6a43cc56fc5.tar.gz |
Upgrade NTP to 4.2.8p4.
Security: FreeBSD-SA-15:25.ntp
Security: CVE-2015-7871
Security: CVE-2015-7855
Security: CVE-2015-7854
Security: CVE-2015-7853
Security: CVE-2015-7852
Security: CVE-2015-7851
Security: CVE-2015-7850
Security: CVE-2015-7849
Security: CVE-2015-7848
Security: CVE-2015-7701
Security: CVE-2015-7703
Security: CVE-2015-7704, CVE-2015-7705
Security: CVE-2015-7691, CVE-2015-7692, CVE-2015-7702
Diffstat (limited to 'contrib/ntp/libntp/authreadkeys.c')
-rw-r--r-- | contrib/ntp/libntp/authreadkeys.c | 89 |
1 files changed, 71 insertions, 18 deletions
diff --git a/contrib/ntp/libntp/authreadkeys.c b/contrib/ntp/libntp/authreadkeys.c index e8ddc94..1c4c07c 100644 --- a/contrib/ntp/libntp/authreadkeys.c +++ b/contrib/ntp/libntp/authreadkeys.c @@ -62,6 +62,40 @@ nexttok( } +/* TALOS-CAN-0055: possibly DoS attack by setting the key file to the + * log file. This is hard to prevent (it would need to check two files + * to be the same on the inode level, which will not work so easily with + * Windows or VMS) but we can avoid the self-amplification loop: We only + * log the first 5 errors, silently ignore the next 10 errors, and give + * up when when we have found more than 15 errors. + * + * This avoids the endless file iteration we will end up with otherwise, + * and also avoids overflowing the log file. + * + * Nevertheless, once this happens, the keys are gone since this would + * require a save/swap strategy that is not easy to apply due to the + * data on global/static level. + */ + +static const size_t nerr_loglimit = 5u; +static const size_t nerr_maxlimit = 15; + +static void log_maybe(size_t*, const char*, ...) NTP_PRINTF(2, 3); + +static void +log_maybe( + size_t *pnerr, + const char *fmt , + ...) +{ + va_list ap; + if (++(*pnerr) <= nerr_loglimit) { + va_start(ap, fmt); + mvsyslog(LOG_ERR, fmt, ap); + va_end(ap); + } +} + /* * authreadkeys - (re)read keys from a file. */ @@ -79,7 +113,7 @@ authreadkeys( u_char keystr[32]; /* Bug 2537 */ size_t len; size_t j; - + size_t nerr; /* * Open file. Complain and return if it can't be opened. */ @@ -99,7 +133,10 @@ authreadkeys( /* * Now read lines from the file, looking for key entries */ + nerr = 0; while ((line = fgets(buf, sizeof buf, fp)) != NULL) { + if (nerr > nerr_maxlimit) + break; token = nexttok(&line); if (token == NULL) continue; @@ -109,15 +146,16 @@ authreadkeys( */ keyno = atoi(token); if (keyno == 0) { - msyslog(LOG_ERR, - "authreadkeys: cannot change key %s", token); + log_maybe(&nerr, + "authreadkeys: cannot change key %s", + token); continue; } if (keyno > NTP_MAXKEY) { - msyslog(LOG_ERR, - "authreadkeys: key %s > %d reserved for Autokey", - token, NTP_MAXKEY); + log_maybe(&nerr, + "authreadkeys: key %s > %d reserved for Autokey", + token, NTP_MAXKEY); continue; } @@ -126,8 +164,9 @@ authreadkeys( */ token = nexttok(&line); if (token == NULL) { - msyslog(LOG_ERR, - "authreadkeys: no key type for key %d", keyno); + log_maybe(&nerr, + "authreadkeys: no key type for key %d", + keyno); continue; } #ifdef OPENSSL @@ -139,13 +178,15 @@ authreadkeys( */ keytype = keytype_from_text(token, NULL); if (keytype == 0) { - msyslog(LOG_ERR, - "authreadkeys: invalid type for key %d", keyno); + log_maybe(&nerr, + "authreadkeys: invalid type for key %d", + keyno); continue; } if (EVP_get_digestbynid(keytype) == NULL) { - msyslog(LOG_ERR, - "authreadkeys: no algorithm for key %d", keyno); + log_maybe(&nerr, + "authreadkeys: no algorithm for key %d", + keyno); continue; } #else /* !OPENSSL follows */ @@ -155,8 +196,9 @@ authreadkeys( * 'm' for compatibility. */ if (!(*token == 'M' || *token == 'm')) { - msyslog(LOG_ERR, - "authreadkeys: invalid type for key %d", keyno); + log_maybe(&nerr, + "authreadkeys: invalid type for key %d", + keyno); continue; } keytype = KEY_TYPE_MD5; @@ -170,8 +212,8 @@ authreadkeys( */ token = nexttok(&line); if (token == NULL) { - msyslog(LOG_ERR, - "authreadkeys: no key for key %d", keyno); + log_maybe(&nerr, + "authreadkeys: no key for key %d", keyno); continue; } len = strlen(token); @@ -195,13 +237,24 @@ authreadkeys( keystr[j / 2] = temp << 4; } if (j < jlim) { - msyslog(LOG_ERR, - "authreadkeys: invalid hex digit for key %d", keyno); + log_maybe(&nerr, + "authreadkeys: invalid hex digit for key %d", + keyno); continue; } MD5auth_setkey(keyno, keytype, keystr, jlim / 2); } } fclose(fp); + if (nerr > nerr_maxlimit) { + msyslog(LOG_ERR, + "authreadkeys: emergency break after %u errors", + nerr); + return (0); + } else if (nerr > nerr_loglimit) { + msyslog(LOG_ERR, + "authreadkeys: found %u more error(s)", + nerr - nerr_loglimit); + } return (1); } |