diff options
author | Evan Huus <eapache@gmail.com> | 2013-10-10 16:18:49 +0000 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2013-10-10 16:18:49 +0000 |
commit | a50dee3286db96e5749e21bba6f9b4bab3fb6dfc (patch) | |
tree | e54c24449cd5d5269bc435678e22a19309d5b61c | |
parent | 1370003beeecb819de990e215d65c02a8d7c3d92 (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.cnf | 3 | ||||
-rw-r--r-- | asn1/c1222/packet-c1222-template.c | 31 | ||||
-rw-r--r-- | epan/dissectors/packet-c1222.c | 43 | ||||
-rw-r--r-- | epan/oids.c | 22 |
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; } |