aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2016-02-24 03:06:46 +0100
committerAnders Broman <a.broman58@gmail.com>2016-02-24 06:06:31 +0000
commit9ff932bf5ea554f9e94ee1364284aff9eb3fd619 (patch)
tree18443cf3ef79e676e2fc68f914f21a2c4bc49e32 /epan
parente395633224fd448fd93af0450b812228192d3a1b (diff)
ber: avoid deep recursion for constructed strings
Bound the recursion depth to avoid a stack overflow while parsing a deeply nested constructed string. Call chain before this patch: - dissect_ber_octet_string - dissect_ber_constrained_octet_string - reassemble_octet_string (called for constructed types) - dissect_ber_octet_string *recursion* After this patch, the reassemble_octet_string will throw if the maximum recursion depth is reached. Bug: 11822 Change-Id: I6753e3c9f5dcbfab0e4c174418b2c7eb784d64d2 Reviewed-on: https://code.wireshark.org/review/14108 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-ber.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c
index 81e4d38feb..43dffa438c 100644
--- a/epan/dissectors/packet-ber.c
+++ b/epan/dissectors/packet-ber.c
@@ -1421,7 +1421,10 @@ static void ber_defragment_cleanup(void) {
}
static int
-reassemble_octet_string(asn1_ctx_t *actx, proto_tree *tree, gint hf_id, tvbuff_t *tvb, int offset, guint32 con_len, gboolean ind, tvbuff_t **out_tvb)
+dissect_ber_constrained_octet_string_impl(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, gint hf_id, tvbuff_t **out_tvb, guint nest_level);
+
+static int
+reassemble_octet_string(asn1_ctx_t *actx, proto_tree *tree, gint hf_id, tvbuff_t *tvb, int offset, guint32 con_len, gboolean ind, tvbuff_t **out_tvb, guint nest_level)
{
fragment_head *fd_head = NULL;
tvbuff_t *next_tvb = NULL;
@@ -1431,6 +1434,11 @@ reassemble_octet_string(asn1_ctx_t *actx, proto_tree *tree, gint hf_id, tvbuff_t
gboolean fragment = TRUE;
gboolean firstFragment = TRUE;
+ if (nest_level > BER_MAX_NESTING) {
+ /* Assume that we have a malformed packet. */
+ THROW(ReportedBoundsError);
+ }
+
/* so we need to consume octet strings for the given length */
if (out_tvb)
@@ -1444,7 +1452,8 @@ reassemble_octet_string(asn1_ctx_t *actx, proto_tree *tree, gint hf_id, tvbuff_t
while(!fd_head) {
- offset = dissect_ber_octet_string(FALSE, actx, NULL, tvb, offset, hf_id, &next_tvb);
+ offset = dissect_ber_constrained_octet_string_impl(FALSE, actx, NULL,
+ tvb, offset, NO_BOUND, NO_BOUND, hf_id, &next_tvb, nest_level + 1);
if (next_tvb == NULL) {
/* Assume that we have a malformed packet. */
@@ -1520,6 +1529,11 @@ reassemble_octet_string(asn1_ctx_t *actx, proto_tree *tree, gint hf_id, tvbuff_t
/* 8.7 Encoding of an octetstring value */
int
dissect_ber_constrained_octet_string(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, gint hf_id, tvbuff_t **out_tvb) {
+ return dissect_ber_constrained_octet_string_impl(implicit_tag, actx, tree, tvb, offset, min_len, max_len, hf_id, out_tvb, 0);
+}
+
+static int
+dissect_ber_constrained_octet_string_impl(gboolean implicit_tag, asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset, gint32 min_len, gint32 max_len, gint hf_id, tvbuff_t **out_tvb, guint nest_level) {
gint8 ber_class;
gboolean pc, ind;
gint32 tag;
@@ -1613,7 +1627,7 @@ printf("OCTET STRING dissect_ber_octet_string(%s) entered\n", name);
if (pc) {
/* constructed */
- end_offset = reassemble_octet_string(actx, tree, hf_id, tvb, offset, len, ind, out_tvb);
+ end_offset = reassemble_octet_string(actx, tree, hf_id, tvb, offset, len, ind, out_tvb, nest_level);
} else {
/* primitive */
gint length_remaining;