]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Sec 3387] NTP-01-012: Authenticated DoS via Malicious Config Option
authorJuergen Perlinger <perlinger@ntp.org>
Sun, 12 Feb 2017 10:08:16 +0000 (11:08 +0100)
committerJuergen Perlinger <perlinger@ntp.org>
Sun, 12 Feb 2017 10:08:16 +0000 (11:08 +0100)
bk: 58a03410Wgv3k8FUIty8KGhffw-O4Q

ChangeLog
ntpd/ntp_config.c

index 595a3d77629ef0c056a6c4fb26f723863cf7d42e..534448f42bcaef6c06b916993b60bba37e464467 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+---
+ * [Sec 3387] NTP-01-012: Authenticated DoS via Malicious Config Option
+   (Pentest report 01.2017) <perlinger@ntp.org>
+
 ---
 (4.2.8p9-win) 2017/02/01 Released by Harlan Stenn <stenn@ntp.org>
 
index c36a21896c6a85fd98a7a609653699f9eeecca97..e8b3981e199a1015d40f5c8d33f92633b6c359fb 100644 (file)
@@ -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;
                }
                /*