- fixed BER decoder infinite length handling to avoid inifite loop while decoding (LIB61850-516)

v1.6
Michael Zillgith 4 weeks ago
parent 813b62356e
commit cb343b6de6

@ -291,7 +291,8 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* /*
* Read in the "end of data chunks"'s. * Read in the "end of data chunks"'s.
*/ */
while(ctx->left < 0) { while(ctx->left < 0)
{
ssize_t tl; ssize_t tl;
tl = ber_fetch_tag(ptr, LEFT, &tlv_tag); tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
@ -304,13 +305,17 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* /*
* Expected <0><0>... * Expected <0><0>...
*/ */
if(((const uint8_t *)ptr)[0] == 0) { if (((const uint8_t*)ptr)[0] == 0)
if(LEFT < 2) { {
if (LEFT < 2)
{
if (SIZE_VIOLATION) if (SIZE_VIOLATION)
RETURN(RC_FAIL); RETURN(RC_FAIL);
else else
RETURN(RC_WMORE); RETURN(RC_WMORE);
} else if(((const uint8_t *)ptr)[1] == 0) { }
else if (((const uint8_t*)ptr)[1] == 0)
{
/* /*
* Correctly finished with <0><0>. * Correctly finished with <0><0>.
*/ */
@ -318,7 +323,14 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ctx->left++; ctx->left++;
continue; continue;
} }
} else { else
{
/* this case should not happen when the message is correctly encoded */
RETURN(RC_FAIL);
}
}
else
{
RETURN(RC_FAIL); RETURN(RC_FAIL);
} }

@ -223,19 +223,21 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
case -1: RETURN(RC_FAIL); case -1: RETURN(RC_FAIL);
} }
if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) { if (ctx->left < 0 && ((const uint8_t*)ptr)[0] == 0)
if(LEFT < 2) { {
if (LEFT < 2)
{
if (SIZE_VIOLATION) if (SIZE_VIOLATION)
RETURN(RC_FAIL); RETURN(RC_FAIL);
else else
RETURN(RC_WMORE); RETURN(RC_WMORE);
} else if(((const uint8_t *)ptr)[1] == 0) { }
else if (((const uint8_t*)ptr)[1] == 0)
{
if((edx + elements[edx].optional if ((edx + elements[edx].optional == td->elements_count) ||
== td->elements_count) (IN_EXTENSION_GROUP(specs, edx) && specs->ext_before > td->elements_count))
|| (IN_EXTENSION_GROUP(specs, edx) {
&& specs->ext_before
> td->elements_count)) {
/* /*
* Yeah, baby! Found the terminator * Yeah, baby! Found the terminator
* of the indefinite length structure. * of the indefinite length structure.
@ -248,6 +250,11 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
goto phase3; goto phase3;
} }
} }
else
{
/* this case should not happen when the message is correctly encoded */
RETURN(RC_FAIL);
}
} }
/* /*
@ -421,14 +428,17 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* /*
* If expected <0><0>... * If expected <0><0>...
*/ */
if(ctx->left < 0 if (ctx->left < 0 && ((const uint8_t*)ptr)[0] == 0)
&& ((const uint8_t *)ptr)[0] == 0) { {
if(LEFT < 2) { if (LEFT < 2)
{
if (SIZE_VIOLATION) if (SIZE_VIOLATION)
RETURN(RC_FAIL); RETURN(RC_FAIL);
else else
RETURN(RC_WMORE); RETURN(RC_WMORE);
} else if(((const uint8_t *)ptr)[1] == 0) { }
else if (((const uint8_t*)ptr)[1] == 0)
{
/* /*
* Correctly finished with <0><0>. * Correctly finished with <0><0>.
*/ */
@ -436,6 +446,11 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ctx->left++; ctx->left++;
ctx->phase = 4; ctx->phase = 4;
continue; continue;
}
else
{
/* this case should not happen when the message is correctly encoded */
RETURN(RC_FAIL);
} }
} }

@ -158,19 +158,28 @@ SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
case -1: RETURN(RC_FAIL); case -1: RETURN(RC_FAIL);
} }
if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) { if (ctx->left < 0 && ((const uint8_t*)ptr)[0] == 0)
if(LEFT < 2) { {
if (LEFT < 2)
{
if (SIZE_VIOLATION) if (SIZE_VIOLATION)
RETURN(RC_FAIL); RETURN(RC_FAIL);
else else
RETURN(RC_WMORE); RETURN(RC_WMORE);
} else if(((const uint8_t *)ptr)[1] == 0) { }
else if (((const uint8_t*)ptr)[1] == 0)
{
/* /*
* Found the terminator of the * Found the terminator of the
* indefinite length structure. * indefinite length structure.
*/ */
break; break;
} }
else
{
/* this case should not happen when the message is correctly encoded */
RETURN(RC_FAIL);
}
} }
/* Outmost tag may be unknown and cannot be fetched/compared */ /* Outmost tag may be unknown and cannot be fetched/compared */

Loading…
Cancel
Save