]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Work around Coverity issue over mismatch of formal and paket layout.
authorJuergen Perlinger <perlinger@ntp.org>
Wed, 6 Aug 2014 20:22:18 +0000 (22:22 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Wed, 6 Aug 2014 20:22:18 +0000 (22:22 +0200)
bk: 53e28e7abivJnio2A9SGuIJVTWaGWg

sntp/networking.c

index 46c008dfd761d8b79d4b77f7e01b23fb82516c7f..3a6bb8e8616211dbb3d9fa2b5811dc51e94c8cb0 100644 (file)
@@ -62,6 +62,30 @@ recvdata(
        return recvc;
 }
 
+/* Parsing from a short 'struct pkt' directly is bound to create
+ * coverity warnings. These are hard to avoid, as the formal declaration
+ * does not reflect the true layout in the presence of autokey extension
+ * fields. Parsing and skipping the extension fields od a received paket
+ * until there's only the MAC left is better done in this separate
+ * function.
+ */
+static void*
+skip_efields(
+       u_int32 *head,  /* head of extension chain      */
+       u_int32 *tail   /* tail/end of extension chain  */
+       )
+{
+       
+       u_int nlen;     /* next extension length */
+       while ((tail - head) > 6) {
+               nlen = ntohl(*head++) & 0xffff;
+               nlen = (nlen + 3) >> 2;
+               if (nlen > (tail - head) || nlen < 4)
+                       return NULL;    /* Blooper! Inconsistent! */
+               head += nlen;
+       }
+       return head;
+}
 
 /*
 ** Check if it's data for us and whether it's useable or not.
@@ -82,16 +106,15 @@ process_pkt (
        u_int           key_id;
        struct key *    pkt_key;
        int             is_authentic;
-       u_int           exten_words;
-       u_int           exten_words_used;
        int             mac_size;
        u_int           exten_len;
+       u_int32 *       exten_end;
+       u_int32 *       paket_end;
        l_fp            sent_xmt;
        l_fp            resp_org;
 
        key_id = 0;
        pkt_key = NULL;
-       exten_words_used = 0;
        is_authentic = (HAVE_OPT(AUTHENTICATION)) ? 0 : -1;
 
        /*
@@ -113,35 +136,36 @@ unusable:
                        func_name, pkt_len);
                return PACKET_UNUSEABLE;
        }
-       /* skip past the extensions, if any */
-       exten_words = ((unsigned)pkt_len - LEN_PKT_NOMAC) >> 2;
-       while (exten_words > 6) {
-               exten_len = ntohl(rpkt->exten[exten_words_used]) & 0xffff;
-               exten_len = (exten_len + 7) >> 2; /* convert to words, add 1 */
-               if (exten_len > exten_words || exten_len < 5)
-                       goto unusable;
-               exten_words -= exten_len;
-               exten_words_used += exten_len;
-       }
+       /* Note: pkt_len is a multiple of 4 at this point! */
+       paket_end = (u_int32*)((char*)rpkt + pkt_len);
+       exten_end = skip_efields(rpkt->exten, paket_end);
+       if (NULL == exten_end)
+               goto unusable;
+       /* get size of MAC in cells; can be zero */
+       exten_len = (u_int)(paket_end - exten_end);
 
-       switch (exten_words) {
+       /* deduce action required from remaining length */
+       switch (exten_len) {
 
-       case 0:
+       case 0: /* no MAC at all */
                break;
 
-       case 1:
-               key_id = ntohl(rpkt->exten[exten_words_used]);
+       case 1: /* crypto NAK */                
+               key_id = ntohl(*exten_end);
                printf("Crypto NAK = 0x%08x\n", key_id);
                break;
 
-       case 5:
-       case 6:
+       case 3: /* key ID + 3DES MAC -- unsupported! */
+               goto unusable;
+
+       case 5: /* key ID + MD5 MAC */
+       case 6: /* key ID + SHA MAC */
                /*
                ** Look for the key used by the server in the specified
                ** keyfile and if existent, fetch it or else leave the
                ** pointer untouched
                */
-               key_id = ntohl(rpkt->exten[exten_words_used]);
+               key_id = ntohl(*exten_end);
                get_key(key_id, &pkt_key);
                if (!pkt_key) {
                        printf("unrecognized key ID = 0x%08x\n", key_id);
@@ -153,7 +177,7 @@ unusable:
                ** Generate a md5sum of the packet with the key from our
                ** keyfile and compare those md5sums.
                */
-               mac_size = exten_words << 2;
+               mac_size = exten_len << 2;
                if (!auth_md5((char *)rpkt, pkt_len - mac_size,
                              mac_size - 4, pkt_key)) {
                        is_authentic = FALSE;
@@ -167,7 +191,6 @@ unusable:
 
        default:
                goto unusable;
-               break;
        }
 
        switch (is_authentic) {