aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ber.c
diff options
context:
space:
mode:
authorGraeme Lunt <graeme.lunt@smhs.co.uk>2010-06-30 10:06:21 +0000
committerGraeme Lunt <graeme.lunt@smhs.co.uk>2010-06-30 10:06:21 +0000
commit852d60ca7e49dc13f637cbc2f3ebd141a76b8bcb (patch)
tree97364be2b7f4fac7a901045c3890ead012e16a31 /epan/dissectors/packet-ber.c
parente777398d4f031a13a135d631c83eadd6868bec6a (diff)
When determining a BER length, make sure the BER identifier was marked as constructed if an indefinite length is encountered.
This helps prevent a stack overflow problem reported in Bug 4951. svn path=/trunk/; revision=33383
Diffstat (limited to 'epan/dissectors/packet-ber.c')
-rw-r--r--epan/dissectors/packet-ber.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c
index 33b1417c71..0750c79304 100644
--- a/epan/dissectors/packet-ber.c
+++ b/epan/dissectors/packet-ber.c
@@ -949,12 +949,13 @@ int dissect_ber_identifier(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *t
*/
/* 8.1.3 Length octets */
static gboolean
-try_get_ber_length(tvbuff_t *tvb, int *bl_offset, guint32 *length, gboolean *ind) {
+try_get_ber_length(tvbuff_t *tvb, int *bl_offset, gboolean pc, guint32 *length, gboolean *ind) {
int offset = *bl_offset;
guint8 oct, len;
guint32 tmp_len;
gint8 tclass;
gint32 ttag;
+ gboolean tpc;
guint32 tmp_length;
gboolean tmp_ind;
int tmp_offset;
@@ -980,14 +981,17 @@ try_get_ber_length(tvbuff_t *tvb, int *bl_offset, guint32 *length, gboolean *ind
/* 8.1.3.6 */
/* indefinite length encoded - must be constructed */
+ if(!pc)
+ return FALSE;
+
tmp_offset = offset;
do {
- tmp_offset = get_ber_identifier(tvb, tmp_offset, &tclass, NULL, &ttag);
-
- try_get_ber_length(tvb, &tmp_offset, &tmp_len, &tmp_ind);
-
- tmp_offset += tmp_len;
+ tmp_offset = get_ber_identifier(tvb, tmp_offset, &tclass, &tpc, &ttag);
+ if(try_get_ber_length(tvb, &tmp_offset, tpc, &tmp_len, &tmp_ind))
+ tmp_offset += tmp_len;
+ else
+ return FALSE;
} while (!((tclass == BER_CLASS_UNI) && (ttag == 0) && (tmp_len == 0)));
@@ -1015,7 +1019,6 @@ get_ber_length(tvbuff_t *tvb, int offset, guint32 *length, gboolean *ind)
int bl_offset = offset;
guint32 bl_length;
-
gint8 save_class;
gboolean save_pc;
gint32 save_tag;
@@ -1025,15 +1028,18 @@ get_ber_length(tvbuff_t *tvb, int offset, guint32 *length, gboolean *ind)
save_pc = last_pc;
save_tag = last_tag;
- try_get_ber_length(tvb, &bl_offset, &bl_length, ind);
+ if(try_get_ber_length(tvb, &bl_offset, last_pc, &bl_length, ind)) {
+ if (length)
+ *length = bl_length;
+ } else
+ /* we couldn't get a length */
+ bl_offset = offset;
/* restore last tag */
last_class = save_class;
last_pc = save_pc;
last_tag = save_tag;
- if (length)
- *length = bl_length;
return bl_offset;
}