diff options
author | nicolson%netscape.com <devnull@localhost> | 2002-03-26 01:23:21 +0000 |
---|---|---|
committer | nicolson%netscape.com <devnull@localhost> | 2002-03-26 01:23:21 +0000 |
commit | fd2ee11966e537f1110d93b11d58e19eff19d2a3 (patch) | |
tree | a56c1967a0afc65bfed78185042b99266dfd3715 | |
parent | 374bc36d19156330a6c2c5393a7fa7e2ec69e8d6 (diff) | |
download | nss-hg-fd2ee11966e537f1110d93b11d58e19eff19d2a3.tar.gz |
Fix 130522: ASN.1 decoder asserts with corrupt input.
r=wtc
-rw-r--r-- | security/nss/lib/util/secasn1d.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c index e414bc84d..58c52c1f6 100644 --- a/security/nss/lib/util/secasn1d.c +++ b/security/nss/lib/util/secasn1d.c @@ -1487,7 +1487,11 @@ sec_asn1d_next_substring (sec_asn1d_state *state) if (state->pending) { PORT_Assert (!state->indefinite); - PORT_Assert (child_consumed <= state->pending); + if( child_consumed > state->pending ) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return; + } state->pending -= child_consumed; if (state->pending == 0) @@ -1602,7 +1606,11 @@ sec_asn1d_next_in_group (sec_asn1d_state *state) */ if (state->pending) { PORT_Assert (!state->indefinite); - PORT_Assert (child_consumed <= state->pending); + if( child_consumed > state->pending ) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return; + } state->pending -= child_consumed; if (state->pending == 0) { @@ -1668,7 +1676,11 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state) sec_asn1d_free_child (child, PR_FALSE); if (state->pending) { PORT_Assert (!state->indefinite); - PORT_Assert (child_consumed <= state->pending); + if( child_consumed > state->pending ) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return; + } state->pending -= child_consumed; if (state->pending == 0) { child->theTemplate++; @@ -1713,8 +1725,13 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state) */ if (state->indefinite && child->endofcontents) { PORT_Assert (child_consumed == 2); - state->consumed += child_consumed; - state->place = afterEndOfContents; + if( child_consumed != 2 ) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + } else { + state->consumed += child_consumed; + state->place = afterEndOfContents; + } } else { PORT_SetError (SEC_ERROR_BAD_DER); state->top->status = decodeError; @@ -2064,8 +2081,12 @@ sec_asn1d_pop_state (sec_asn1d_state *state) state->consumed += state->child->consumed; if (state->pending) { PORT_Assert (!state->indefinite); - PORT_Assert (state->child->consumed <= state->pending); - state->pending -= state->child->consumed; + if( state->child->consumed > state->pending ) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + } else { + state->pending -= state->child->consumed; + } } state->child->consumed = 0; } @@ -2150,7 +2171,11 @@ sec_asn1d_during_choice /* cargo'd from next_in_sequence innards */ if( state->pending ) { PORT_Assert(!state->indefinite); - PORT_Assert(child->consumed <= state->pending); + if( child->consumed > state->pending ) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return NULL; + } state->pending -= child->consumed; if( 0 == state->pending ) { /* XXX uh.. not sure if I should have stopped this @@ -2406,6 +2431,11 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, /* We should not consume more than we have. */ PORT_Assert (consumed <= len); + if( consumed > len ) { + PORT_SetError (SEC_ERROR_BAD_DER); + cx->status = decodeError; + break; + } /* It might have changed, so we have to update our local copy. */ state = cx->current; |