From baaa24fa5ceafe7a36e429ee9bfd6eb2e7131bf5 Mon Sep 17 00:00:00 2001 From: Lev Walkin <vlm@lionet.info> Date: Wed, 29 Sep 2004 14:19:14 +0000 Subject: [PATCH] added stack checking into ber_skip_length also --- skeletons/ber_decoder.c | 6 ++++-- skeletons/ber_tlv_length.c | 21 +++++++++++++++++++-- skeletons/ber_tlv_length.h | 5 ++++- skeletons/constr_CHOICE.c | 2 +- skeletons/constr_SEQUENCE.c | 4 ++-- skeletons/constr_SET.c | 4 ++-- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/skeletons/ber_decoder.c b/skeletons/ber_decoder.c index 95d71017..f932b3b2 100644 --- a/skeletons/ber_decoder.c +++ b/skeletons/ber_decoder.c @@ -71,10 +71,12 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx, int step = opt_ctx ? opt_ctx->step : 0; /* Where we left previously */ int tagno; + /* + * Make sure we didn't exceed the maximum stack size. + */ if(opt_codec_ctx && opt_codec_ctx->max_stack_size) { ptrdiff_t usedstack = ((char *)opt_codec_ctx - (char *)&size); - /* do not change the semantics: - * double negative is required to avoid int wrap-around */ + /* double negative is required to avoid int wrap-around */ if(usedstack > 0) usedstack = -usedstack; ASN_DEBUG("Current stack size %ld", -(long)usedstack); if(usedstack < -(ptrdiff_t)opt_codec_ctx->max_stack_size) { diff --git a/skeletons/ber_tlv_length.c b/skeletons/ber_tlv_length.c index a0ec1e5d..10a9e1c3 100644 --- a/skeletons/ber_tlv_length.c +++ b/skeletons/ber_tlv_length.c @@ -74,12 +74,28 @@ ber_fetch_length(int _is_constructed, void *bufptr, size_t size, } ssize_t -ber_skip_length(int _is_constructed, void *ptr, size_t size) { +ber_skip_length(asn_codec_ctx_t *opt_codec_ctx, + int _is_constructed, void *ptr, size_t size) { ber_tlv_len_t vlen; /* Length of V in TLV */ ssize_t tl; /* Length of L in TLV */ ssize_t ll; /* Length of L in TLV */ size_t skip; + /* + * Make sure we didn't exceed the maximum stack size. + */ + if(opt_codec_ctx && opt_codec_ctx->max_stack_size) { + ptrdiff_t usedstack = ((char *)opt_codec_ctx - (char *)&size); + /* double negative is required to avoid int wrap-around */ + if(usedstack > 0) usedstack = -usedstack; + ASN_DEBUG("Current stack size %ld", -(long)usedstack); + if(usedstack < -(ptrdiff_t)opt_codec_ctx->max_stack_size) { + ASN_DEBUG("Stack limit %ld reached", + (long)opt_codec_ctx->max_stack_size); + return -1; + } + } + /* * Determine the size of L in TLV. */ @@ -107,7 +123,8 @@ ber_skip_length(int _is_constructed, void *ptr, size_t size) { tl = ber_fetch_tag(ptr, size, &tag); if(tl <= 0) return tl; - ll = ber_skip_length(BER_TLV_CONSTRUCTED(ptr), + ll = ber_skip_length(opt_codec_ctx, + BER_TLV_CONSTRUCTED(ptr), ((char *)ptr) + tl, size - tl); if(ll <= 0) return ll; diff --git a/skeletons/ber_tlv_length.h b/skeletons/ber_tlv_length.h index 5222bbf4..9d99e663 100644 --- a/skeletons/ber_tlv_length.h +++ b/skeletons/ber_tlv_length.h @@ -27,7 +27,10 @@ ssize_t ber_fetch_length(int _is_constructed, void *bufptr, size_t size, * RETURN VALUES: * Standard {-1,0,>0} convention. */ -ssize_t ber_skip_length(int _is_constructed, void *bufptr, size_t size); +struct asn_codec_ctx_s; /* Forward declaration */ +ssize_t ber_skip_length( + struct asn_codec_ctx_s *opt_codec_ctx, /* optional context */ + int _is_constructed, void *bufptr, size_t size); /* * This function serializes the length (L from TLV) in DER format. diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index ab158462..4db6d7b1 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -209,7 +209,7 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ASN_DEBUG("Skipping unknown tag %s", ber_tlv_tag_string(tlv_tag)); - skip = ber_skip_length( + skip = ber_skip_length(opt_codec_ctx, BER_TLV_CONSTRUCTED(ptr), (char *)ptr + tag_len, LEFT - tag_len); diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index 740ce570..07c77728 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -352,7 +352,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* Skip this tag */ ssize_t skip; - skip = ber_skip_length( + skip = ber_skip_length(opt_codec_ctx, BER_TLV_CONSTRUCTED(ptr), (char *)ptr + tag_len, LEFT - tag_len); ASN_DEBUG("Skip length %d in %s", @@ -474,7 +474,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, RETURN(RC_FAIL); } - ll = ber_skip_length( + ll = ber_skip_length(opt_codec_ctx, BER_TLV_CONSTRUCTED(ptr), (char *)ptr + tl, LEFT - tl); switch(ll) { diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c index 647bb83a..d9f93c3b 100644 --- a/skeletons/constr_SET.c +++ b/skeletons/constr_SET.c @@ -259,7 +259,7 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ASN_DEBUG("Skipping unknown tag %s", ber_tlv_tag_string(tlv_tag)); - skip = ber_skip_length( + skip = ber_skip_length(opt_codec_ctx, BER_TLV_CONSTRUCTED(ptr), (char *)ptr + tag_len, LEFT - tag_len); @@ -381,7 +381,7 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, RETURN(RC_FAIL); } - ll = ber_skip_length( + ll = ber_skip_length(opt_codec_ctx, BER_TLV_CONSTRUCTED(ptr), (char *)ptr + tl, LEFT - tl); switch(ll) { -- GitLab