]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Don't overwrite packet data when checking the signature.
authorGuy Harris <[email protected]>
Mon, 28 Dec 2015 00:58:52 +0000 (16:58 -0800)
committerGuy Harris <[email protected]>
Mon, 28 Dec 2015 00:58:52 +0000 (16:58 -0800)
Instead, make a copy, and overwrite that.

print-isoclns.c
signature.c
signature.h

index 08be550da929b0e7452ec98bd560300ee53174d8..e34e1dc6b0622fb0bfd0246a107a49a9f0444f6e 100644 (file)
@@ -31,6 +31,7 @@
 #include <netdissect-stdinc.h>
 
 #include <string.h>
+#include <stdlib.h>
 
 #include "netdissect.h"
 #include "addrtoname.h"
@@ -2063,7 +2064,7 @@ isis_print(netdissect_options *ndo,
 
     const struct isis_iih_lan_header *header_iih_lan;
     const struct isis_iih_ptp_header *header_iih_ptp;
-    struct isis_lsp_header *header_lsp;
+    const struct isis_lsp_header *header_lsp;
     const struct isis_csnp_header *header_csnp;
     const struct isis_psnp_header *header_psnp;
 
@@ -2078,6 +2079,9 @@ isis_print(netdissect_options *ndo,
     u_short packet_len,pdu_len, key_id;
     u_int i,vendor_id;
     int sigcheck;
+#ifdef HAVE_LIBCRYPTO
+    uint8_t *packet_copy;
+#endif
 
     packet_len=length;
     optr = p; /* initialize the _o_riginal pointer to the packet start -
@@ -2088,7 +2092,7 @@ isis_print(netdissect_options *ndo,
     pptr = p+(ISIS_COMMON_HEADER_SIZE);
     header_iih_lan = (const struct isis_iih_lan_header *)pptr;
     header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
-    header_lsp = (struct isis_lsp_header *)pptr;
+    header_lsp = (const struct isis_lsp_header *)pptr;
     header_csnp = (const struct isis_csnp_header *)pptr;
     header_psnp = (const struct isis_psnp_header *)pptr;
 
@@ -2315,19 +2319,11 @@ isis_print(netdissect_options *ndo,
                EXTRACT_16BITS(header_lsp->remaining_lifetime),
                EXTRACT_16BITS(header_lsp->checksum)));
 
-        if (osi_print_cksum(ndo, (uint8_t *)header_lsp->lsp_id,
+        if (osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
                             EXTRACT_16BITS(header_lsp->checksum),
                             12, length-12) == 0)
                                 goto trunc;
 
-        /*
-         * Clear checksum and lifetime prior to signature verification.
-         */
-        header_lsp->checksum[0] = 0;
-        header_lsp->checksum[1] = 0;
-        header_lsp->remaining_lifetime[0] = 0;
-        header_lsp->remaining_lifetime[1] = 0;
-
        ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
                pdu_len,
                ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""));
@@ -2662,8 +2658,35 @@ isis_print(netdissect_options *ndo,
                     ND_PRINT((ndo, ", (invalid subTLV) "));
 
 #ifdef HAVE_LIBCRYPTO
-                sigcheck = signature_verify(ndo, optr, length,
-                                            (unsigned char *)tptr + 1);
+                /*
+                 * Make a copy of the packet, so we don't overwrite the
+                 * original.
+                 */
+                ND_TCHECK2(*optr, packet_len);
+                packet_copy = malloc(packet_len);
+                if (packet_copy == NULL)
+                    sigcheck = CANT_ALLOCATE_COPY;
+                else {
+                    struct isis_lsp_header *header_lsp_copy;
+                    u_int8_t *tptr_copy;
+
+                    memcpy(packet_copy, optr, packet_len);
+
+                    /*
+                     * Clear checksum and lifetime in the copy prior to
+                     * signature verification.
+                     */
+                    header_lsp_copy = (struct isis_lsp_header *)(packet_copy + ISIS_COMMON_HEADER_SIZE);
+                    header_lsp_copy->checksum[0] = 0;
+                    header_lsp_copy->checksum[1] = 0;
+                    header_lsp_copy->remaining_lifetime[0] = 0;
+                    header_lsp_copy->remaining_lifetime[1] = 0;
+
+                    tptr_copy = packet_copy + (tptr - optr);
+                    sigcheck = signature_verify(ndo, packet_copy, length,
+                                                tptr_copy + 1);
+                    free(packet_copy);
+                }
 #else
                 sigcheck = CANT_CHECK_SIGNATURE;
 #endif
index 18449fc24bc2ff016612e9434dcdec039f1c52f8..b989baff19305cb09f031ec65a49ba809747fc9b 100644 (file)
@@ -33,6 +33,7 @@
 const struct tok signature_check_values[] = {
     { SIGNATURE_VALID, "valid"},
     { SIGNATURE_INVALID, "invalid"},
+    { CANT_ALLOCATE_COPY, "can't allocate memory"},
     { CANT_CHECK_SIGNATURE, "unchecked"},
     { 0, NULL }
 };
index a052df866fb865e713bad86095d83384924bc362..6df7227d7c9fdbd4b7cd0ec9de83521ff9a00e7c 100644 (file)
@@ -21,7 +21,8 @@
 /* signature checking result codes */
 #define SIGNATURE_VALID                0
 #define SIGNATURE_INVALID      1
-#define CANT_CHECK_SIGNATURE   2
+#define CANT_ALLOCATE_COPY     2
+#define CANT_CHECK_SIGNATURE   3
 
 extern const struct tok signature_check_values[];
 extern int signature_verify(netdissect_options *, const u_char *, u_int, u_char *);