ASN.1 PER + ATN-ULCS: Add checks for nulls in sequences.

In ASN.1 PER, Stop dissection if our sequence offset hasn't advanced
after 50 items.

atn-ulcs.asn overrides the definition of AttributeTypeAndValue as a
sequence of NULLs. Update our .cnf file so that we only dissect the
first item in that case.

Fixes #17842.
This commit is contained in:
Gerald Combs 2022-02-01 18:44:42 -08:00
parent 758b41a017
commit 13f5d72453
3 changed files with 57 additions and 3 deletions

View File

@ -422,6 +422,35 @@ PDV-list/presentation-data-values/arbitrary pdv-list_presentation-data-values_ar
#.END
#.FN_BODY RDNSequence
/*
* atn-ulcs.asn currently defines
*
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
* RelativeDistinguishedName ::= SET SIZE (1 .. MAX) OF AttributeTypeAndValue
* AttributeTypeAndValue ::= SEQUENCE { null NULL}
*
* which makes it easy to spam the dissection tree with null items. Dissect
* the first item only.
*/
offset = dissect_per_constrained_sequence_of(tvb, offset, actx, tree, hf_index,
ett_atn_ulcs_RDNSequence, RDNSequence_sequence_of,
1, 1, FALSE);
#.END
#.FN_BODY RelativeDistinguishedName
/*
* Dissect the first null item only, similar to RDNSequence.
*/
offset = dissect_per_constrained_set_of(tvb, offset, actx, tree, hf_index,
ett_atn_ulcs_RelativeDistinguishedName, RelativeDistinguishedName_set_of,
1, 1, FALSE);
#.END
#.FN_BODY EXTERNALt/data-value-descriptor
offset = dissect_per_octet_string(

View File

@ -770,9 +770,14 @@ static const per_sequence_t RelativeDistinguishedName_set_of[1] = {
static int
dissect_atn_ulcs_RelativeDistinguishedName(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
/*
* Dissect the first null item only, similar to RDNSequence.
*/
offset = dissect_per_constrained_set_of(tvb, offset, actx, tree, hf_index,
ett_atn_ulcs_RelativeDistinguishedName, RelativeDistinguishedName_set_of,
1, NO_BOUND, FALSE);
1, 1, FALSE);
return offset;
}
@ -784,8 +789,21 @@ static const per_sequence_t RDNSequence_sequence_of[1] = {
static int
dissect_atn_ulcs_RDNSequence(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_sequence_of(tvb, offset, actx, tree, hf_index,
ett_atn_ulcs_RDNSequence, RDNSequence_sequence_of);
/*
* atn-ulcs.asn currently defines
*
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
* RelativeDistinguishedName ::= SET SIZE (1 .. MAX) OF AttributeTypeAndValue
* AttributeTypeAndValue ::= SEQUENCE { null NULL}
*
* which makes it easy to spam the dissection tree with null items. Dissect
* the first item only.
*/
offset = dissect_per_constrained_sequence_of(tvb, offset, actx, tree, hf_index,
ett_atn_ulcs_RDNSequence, RDNSequence_sequence_of,
1, 1, FALSE);
return offset;
}

View File

@ -555,12 +555,16 @@ dissect_per_null(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree
}
/* 19 this function dissects a sequence of */
// Arbitrary. Allow a sequence of NULLs, but not too many since we might add
// a hierarchy of tree items per NULL
#define PER_SEQUENCE_OF_MAX_NULLS 10
static guint32
dissect_per_sequence_of_helper(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, per_type_fn func, int hf_index, guint32 length)
{
guint32 i;
DEBUG_ENTRY("dissect_per_sequence_of_helper");
guint32 old_offset = offset;
for(i=0;i<length;i++){
guint32 lold_offset=offset;
proto_item *litem;
@ -570,6 +574,9 @@ DEBUG_ENTRY("dissect_per_sequence_of_helper");
offset=(*func)(tvb, offset, actx, ltree, hf_index);
proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
if (i >= PER_SEQUENCE_OF_MAX_NULLS-1 && offset <= old_offset) {
dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many nulls in sequence");
}
}
return offset;