From: Juergen Perlinger Date: Sun, 12 Feb 2017 10:08:16 +0000 (+0100) Subject: [Sec 3387] NTP-01-012: Authenticated DoS via Malicious Config Option X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb815b14e5fe105b87d71533cc9cefd4f08b4a01;p=thirdparty%2Fntp.git [Sec 3387] NTP-01-012: Authenticated DoS via Malicious Config Option bk: 58a03410Wgv3k8FUIty8KGhffw-O4Q --- diff --git a/ChangeLog b/ChangeLog index 595a3d776..534448f42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +--- + * [Sec 3387] NTP-01-012: Authenticated DoS via Malicious Config Option + (Pentest report 01.2017) + --- (4.2.8p9-win) 2017/02/01 Released by Harlan Stenn diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index c36a21896..e8b3981e1 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -1328,8 +1328,8 @@ create_unpeer_node( ) { unpeer_node * my_node; - u_int u; - char * pch; + u_long u; + const u_char * pch; my_node = emalloc_zero(sizeof(*my_node)); @@ -1338,16 +1338,15 @@ create_unpeer_node( * its generic T_String definition of a name/address "address". * We treat all valid 16-bit numbers as association IDs. */ - pch = addr->address; - while (*pch && isdigit((unsigned char)*pch)) - pch++; - - if (!*pch - && 1 == sscanf(addr->address, "%u", &u) - && u <= ASSOCID_MAX) { + for (u = 0, pch = (u_char*)addr->address; isdigit(*pch); ++pch) { + /* accumulate with overflow retention */ + u = (10 * u + *pch - '0') | (u & 0xFF000000u); + } + + if (!*pch && u <= ASSOCID_MAX) { my_node->assocID = (associd_t)u; - destroy_address_node(addr); my_node->addr = NULL; + destroy_address_node(addr); } else { my_node->assocID = 0; my_node->addr = addr; @@ -4040,10 +4039,10 @@ config_unpeers( curr_unpeer = HEAD_PFIFO(ptree->unpeers); for (; curr_unpeer != NULL; curr_unpeer = curr_unpeer->link) { /* - * Either AssocID will be zero, and we unpeer by name/ - * address addr, or it is nonzero and addr NULL. + * If we have no address attached, assume we have to + * unpeer by AssocID. */ - if (curr_unpeer->assocID) { + if (!curr_unpeer->addr) { p = findpeerbyassoc(curr_unpeer->assocID); if (p != NULL) { msyslog(LOG_NOTICE, "unpeered %s", @@ -4051,7 +4050,6 @@ config_unpeers( peer_clear(p, "GONE"); unpeer(p); } - continue; } @@ -4070,7 +4068,6 @@ config_unpeers( peer_clear(p, "GONE"); unpeer(p); } - continue; } /*