aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-10-10 16:18:49 +0000
committerEvan Huus <eapache@gmail.com>2013-10-10 16:18:49 +0000
commita50dee3286db96e5749e21bba6f9b4bab3fb6dfc (patch)
treee54c24449cd5d5269bc435678e22a19309d5b61c
parent1370003beeecb819de990e215d65c02a8d7c3d92 (diff)
From Ed Beroset via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9246
Fix memory leaks and bad memory accesses in c1222 dissector. From me: use realloc in a handoff function since it may get called multiple times, and we only need the latest. svn path=/trunk/; revision=52497
-rw-r--r--asn1/c1222/c1222.cnf3
-rw-r--r--asn1/c1222/packet-c1222-template.c31
-rw-r--r--epan/dissectors/packet-c1222.c43
-rw-r--r--epan/oids.c22
4 files changed, 60 insertions, 39 deletions
diff --git a/asn1/c1222/c1222.cnf b/asn1/c1222/c1222.cnf
index ec0e9b3704..851f40c3f5 100644
--- a/asn1/c1222/c1222.cnf
+++ b/asn1/c1222/c1222.cnf
@@ -98,4 +98,7 @@ AE-qualifier TYPE=FT_UINT32
%(DEFAULT_BODY)s
FILL_TABLE(iv_element);
+#.FN_BODY MESSAGE
+ clear_canon();
+ %(DEFAULT_BODY)s
#.END
diff --git a/asn1/c1222/packet-c1222-template.c b/asn1/c1222/packet-c1222-template.c
index 7b9ee42f77..a467d899d3 100644
--- a/asn1/c1222/packet-c1222-template.c
+++ b/asn1/c1222/packet-c1222-template.c
@@ -305,19 +305,18 @@ static uat_t *c1222_uat;
#define FILL_START int length, start_offset = offset;
#define FILL_TABLE(fieldname) \
length = offset - start_offset; \
- if (fieldname != NULL) g_free(fieldname); \
- fieldname = (guint8 *)tvb_memdup(NULL, tvb, start_offset, length); \
+ fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \
fieldname##_len = length;
#define FILL_TABLE_TRUNCATE(fieldname, len) \
length = 1 + 2*(offset - start_offset); \
- fieldname = (guint8 *)tvb_memdup(NULL, tvb, start_offset, length); \
+ fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \
fieldname##_len = len;
#define FILL_TABLE_APTITLE(fieldname) \
length = offset - start_offset; \
switch (tvb_get_guint8(tvb, start_offset)) { \
case 0x80: /* relative OID */ \
fieldname##_len = length + c1222_baseoid_len; \
- fieldname = (guint8 *)wmem_alloc(NULL, fieldname##_len); \
+ fieldname = (guint8 *)wmem_alloc(wmem_packet_scope(), fieldname##_len); \
fieldname[0] = 0x06; /* create absolute OID tag */ \
fieldname[1] = (fieldname##_len - 2) & 0xff; \
memcpy(&(fieldname[2]), c1222_baseoid, c1222_baseoid_len); \
@@ -325,7 +324,7 @@ static uat_t *c1222_uat;
break; \
case 0x06: /* absolute OID */ \
default: \
- fieldname = (guint8 *)tvb_memdup(NULL, tvb, start_offset, length); \
+ fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \
fieldname##_len = length; \
break; \
}
@@ -673,6 +672,17 @@ static const TOP_ELEMENT_CONTROL canonifyTable[] = {
{ FALSE, FALSE, 0x0, TRUE, NULL, NULL }
};
+static void
+clear_canon(void)
+{
+ const TOP_ELEMENT_CONTROL *t = canonifyTable;
+
+ for (t = canonifyTable; t->element != NULL; t++) {
+ *(t->length) = 0;
+ *(t->element) = NULL;
+ }
+}
+
/**
* Calculates the size of the passed number n as encoded as a BER length field.
*
@@ -769,7 +779,6 @@ canonify_unencrypted_header(guchar *buff, guint32 *offset, guint32 buffsize)
memcpy(&buff[*offset], *(t->element), len);
(*offset) += len;
if (t->addtag) {
- g_free(*(t->element));
*(t->element) = NULL;
}
}
@@ -944,9 +953,8 @@ dissect_epsem(tvbuff_t *tvb, int offset, guint32 len, packet_info *pinfo, proto_
return offset;
encrypted = TRUE;
if (c1222_decrypt) {
- buffer = (guchar *)tvb_memdup(NULL, tvb, offset, len2);
+ buffer = (guchar *)tvb_memdup(wmem_packet_scope(), tvb, offset, len2);
if (!decrypt_packet(buffer, len2, TRUE)) {
- g_free(buffer);
crypto_bad = TRUE;
} else {
epsem_buffer = tvb_new_real_data(buffer, len2, len2);
@@ -963,7 +971,7 @@ dissect_epsem(tvbuff_t *tvb, int offset, guint32 len, packet_info *pinfo, proto_
len2 = tvb_length_remaining(tvb, offset);
if (len2 <= 0)
return offset;
- buffer = (guchar *)tvb_memdup(NULL, tvb, offset, len2);
+ buffer = (guchar *)tvb_memdup(wmem_packet_scope(), tvb, offset, len2);
epsem_buffer = tvb_new_subset_remaining(tvb, offset);
if (c1222_decrypt) {
if (!decrypt_packet(buffer, len2, FALSE)) {
@@ -1410,6 +1418,7 @@ void
proto_reg_handoff_c1222(void)
{
static gboolean initialized = FALSE;
+ guint8 *temp = NULL;
if( !initialized ) {
c1222_handle = create_dissector_handle(dissect_c1222, proto_c1222);
@@ -1418,5 +1427,7 @@ proto_reg_handoff_c1222(void)
dissector_add_uint("udp.port", global_c1222_port, c1222_udp_handle);
initialized = TRUE;
}
- c1222_baseoid_len = oid_string2encoded(c1222_baseoid_str, &c1222_baseoid);
+ c1222_baseoid_len = oid_string2encoded(c1222_baseoid_str, &temp);
+ c1222_baseoid = (guint8 *)wmem_realloc(wmem_epan_scope(), c1222_baseoid, c1222_baseoid_len);
+ memcpy(c1222_baseoid, temp, c1222_baseoid_len);
}
diff --git a/epan/dissectors/packet-c1222.c b/epan/dissectors/packet-c1222.c
index 5e16f06546..8b3a649fd9 100644
--- a/epan/dissectors/packet-c1222.c
+++ b/epan/dissectors/packet-c1222.c
@@ -356,19 +356,18 @@ static uat_t *c1222_uat;
#define FILL_START int length, start_offset = offset;
#define FILL_TABLE(fieldname) \
length = offset - start_offset; \
- if (fieldname != NULL) g_free(fieldname); \
- fieldname = (guint8 *)tvb_memdup(NULL, tvb, start_offset, length); \
+ fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \
fieldname##_len = length;
#define FILL_TABLE_TRUNCATE(fieldname, len) \
length = 1 + 2*(offset - start_offset); \
- fieldname = (guint8 *)tvb_memdup(NULL, tvb, start_offset, length); \
+ fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \
fieldname##_len = len;
#define FILL_TABLE_APTITLE(fieldname) \
length = offset - start_offset; \
switch (tvb_get_guint8(tvb, start_offset)) { \
case 0x80: /* relative OID */ \
fieldname##_len = length + c1222_baseoid_len; \
- fieldname = (guint8 *)wmem_alloc(NULL, fieldname##_len); \
+ fieldname = (guint8 *)wmem_alloc(wmem_packet_scope(), fieldname##_len); \
fieldname[0] = 0x06; /* create absolute OID tag */ \
fieldname[1] = (fieldname##_len - 2) & 0xff; \
memcpy(&(fieldname[2]), c1222_baseoid, c1222_baseoid_len); \
@@ -376,7 +375,7 @@ static uat_t *c1222_uat;
break; \
case 0x06: /* absolute OID */ \
default: \
- fieldname = (guint8 *)tvb_memdup(NULL, tvb, start_offset, length); \
+ fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \
fieldname##_len = length; \
break; \
}
@@ -724,6 +723,17 @@ static const TOP_ELEMENT_CONTROL canonifyTable[] = {
{ FALSE, FALSE, 0x0, TRUE, NULL, NULL }
};
+static void
+clear_canon(void)
+{
+ const TOP_ELEMENT_CONTROL *t = canonifyTable;
+
+ for (t = canonifyTable; t->element != NULL; t++) {
+ *(t->length) = 0;
+ *(t->element) = NULL;
+ }
+}
+
/**
* Calculates the size of the passed number n as encoded as a BER length field.
*
@@ -820,7 +830,6 @@ canonify_unencrypted_header(guchar *buff, guint32 *offset, guint32 buffsize)
memcpy(&buff[*offset], *(t->element), len);
(*offset) += len;
if (t->addtag) {
- g_free(*(t->element));
*(t->element) = NULL;
}
}
@@ -995,9 +1004,8 @@ dissect_epsem(tvbuff_t *tvb, int offset, guint32 len, packet_info *pinfo, proto_
return offset;
encrypted = TRUE;
if (c1222_decrypt) {
- buffer = (guchar *)tvb_memdup(NULL, tvb, offset, len2);
+ buffer = (guchar *)tvb_memdup(wmem_packet_scope(), tvb, offset, len2);
if (!decrypt_packet(buffer, len2, TRUE)) {
- g_free(buffer);
crypto_bad = TRUE;
} else {
epsem_buffer = tvb_new_real_data(buffer, len2, len2);
@@ -1014,7 +1022,7 @@ dissect_epsem(tvbuff_t *tvb, int offset, guint32 len, packet_info *pinfo, proto_
len2 = tvb_length_remaining(tvb, offset);
if (len2 <= 0)
return offset;
- buffer = (guchar *)tvb_memdup(NULL, tvb, offset, len2);
+ buffer = (guchar *)tvb_memdup(wmem_packet_scope(), tvb, offset, len2);
epsem_buffer = tvb_new_subset_remaining(tvb, offset);
if (c1222_decrypt) {
if (!decrypt_packet(buffer, len2, FALSE)) {
@@ -1538,9 +1546,13 @@ dissect_c1222_MESSAGE_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset
static int
dissect_c1222_MESSAGE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
- offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
+#line 102 "../../asn1/c1222/c1222.cnf"
+ clear_canon();
+ offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
hf_index, BER_CLASS_APP, 0, TRUE, dissect_c1222_MESSAGE_U);
+
+
return offset;
}
@@ -1554,7 +1566,7 @@ static void dissect_MESSAGE_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto
/*--- End of included file: packet-c1222-fn.c ---*/
-#line 1044 "../../asn1/c1222/packet-c1222-template.c"
+#line 1052 "../../asn1/c1222/packet-c1222-template.c"
/**
* Dissects a a full (reassembled) C12.22 message.
@@ -1941,7 +1953,7 @@ void proto_register_c1222(void) {
"OCTET_STRING_SIZE_CONSTR002", HFILL }},
/*--- End of included file: packet-c1222-hfarr.c ---*/
-#line 1326 "../../asn1/c1222/packet-c1222-template.c"
+#line 1334 "../../asn1/c1222/packet-c1222-template.c"
};
/* List of subtrees */
@@ -1964,7 +1976,7 @@ void proto_register_c1222(void) {
&ett_c1222_Calling_authentication_value_c1221_U,
/*--- End of included file: packet-c1222-ettarr.c ---*/
-#line 1336 "../../asn1/c1222/packet-c1222-template.c"
+#line 1344 "../../asn1/c1222/packet-c1222-template.c"
};
static ei_register_info ei[] = {
@@ -2042,6 +2054,7 @@ void
proto_reg_handoff_c1222(void)
{
static gboolean initialized = FALSE;
+ guint8 *temp = NULL;
if( !initialized ) {
c1222_handle = create_dissector_handle(dissect_c1222, proto_c1222);
@@ -2050,5 +2063,7 @@ proto_reg_handoff_c1222(void)
dissector_add_uint("udp.port", global_c1222_port, c1222_udp_handle);
initialized = TRUE;
}
- c1222_baseoid_len = oid_string2encoded(c1222_baseoid_str, &c1222_baseoid);
+ c1222_baseoid_len = oid_string2encoded(c1222_baseoid_str, &temp);
+ c1222_baseoid = (guint8 *)wmem_realloc(wmem_epan_scope(), c1222_baseoid, c1222_baseoid_len);
+ memcpy(c1222_baseoid, temp, c1222_baseoid_len);
}
diff --git a/epan/oids.c b/epan/oids.c
index a93b950e4d..f232d93c20 100644
--- a/epan/oids.c
+++ b/epan/oids.c
@@ -1044,15 +1044,13 @@ guint oid_subid2encoded(guint subids_len, guint32* subids, guint8** bytes_p) {
guint32 subid;
guint8* b;
- if ( !subids || subids_len <= 0) {
+ if ( !subids || subids_len <= 1) {
*bytes_p = NULL;
return 0;
}
- subid = (subids[0] * 40) + subids[1];
- i = 2;
-
- do {
+ for (subid=subids[0] * 40, i = 1; i<subids_len; i++, subid=0) {
+ subid += subids[i];
if (subid <= 0x0000007F) {
bytelen += 1;
} else if (subid <= 0x00003FFF ) {
@@ -1064,18 +1062,14 @@ guint oid_subid2encoded(guint subids_len, guint32* subids, guint8** bytes_p) {
} else {
bytelen += 5;
}
-
- subid = subids[i];
- } while ( i++ < subids_len );
+ }
*bytes_p = b = (guint8 *)ep_alloc(bytelen);
- subid = (subids[0] * 40) + subids[1];
- i = 2;
-
- do {
+ for (subid=subids[0] * 40, i = 1; i<subids_len; i++, subid=0) {
guint len;
+ subid += subids[i];
if ((subid <= 0x0000007F )) len = 1;
else if ((subid <= 0x00003FFF )) len = 2;
else if ((subid <= 0x001FFFFF )) len = 3;
@@ -1090,9 +1084,7 @@ guint oid_subid2encoded(guint subids_len, guint32* subids, guint8** bytes_p) {
case 2: *(b++) = ((subid & 0x00003F80) >> 7) | 0x80;
case 1: *(b++) = subid & 0x0000007F ; break;
}
-
- subid = subids[i];
- } while ( i++ < subids_len);
+ }
return bytelen;
}