summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-12-27 16:58:52 -0800
committerGuy Harris <guy@alum.mit.edu>2015-12-27 16:58:52 -0800
commit20f164f5e4825a605d97906b9ac6bf4222b9eef4 (patch)
tree04809c19cd29804223dd912b0c92a3adb403aeb4
parente40b5d4303c922852b78e06d9332104ead10c206 (diff)
downloadtcpdump-20f164f5e4825a605d97906b9ac6bf4222b9eef4.tar.gz
Don't overwrite packet data when checking the signature.
Instead, make a copy, and overwrite that.
-rw-r--r--print-isoclns.c49
-rw-r--r--signature.c1
-rw-r--r--signature.h3
3 files changed, 39 insertions, 14 deletions
diff --git a/print-isoclns.c b/print-isoclns.c
index 08be550d..e34e1dc6 100644
--- a/print-isoclns.c
+++ b/print-isoclns.c
@@ -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
diff --git a/signature.c b/signature.c
index 18449fc2..b989baff 100644
--- a/signature.c
+++ b/signature.c
@@ -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 }
};
diff --git a/signature.h b/signature.h
index a052df86..6df7227d 100644
--- a/signature.h
+++ b/signature.h
@@ -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 *);