Don't read it->funcs without checking it->itype. it->funcs is only an ASN1_AUX for ASN1_ITYPE_SEQUENCE and ASN1_ITYPE_CHOICE. Fortunately, the other possible types for it->funcs are larger than ASN1_AUX and we don't touch the result when we shouldn't, so this is merely a strict aliasing violation. Change-Id: I29e94249e0b137fe8df0b16254366ae6705c8784 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49351 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 0d123cc..c5a6477 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c
@@ -170,8 +170,6 @@ { const ASN1_TEMPLATE *tt, *errtt = NULL; const ASN1_EXTERN_FUNCS *ef; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; const unsigned char *p = NULL, *q; unsigned char oclass; char seq_eoc, seq_nolen, cst, isopt; @@ -183,10 +181,6 @@ aclass &= ~ASN1_TFLG_COMBINE; if (!pval) return 0; - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - else - asn1_cb = 0; /* * Bound |len| to comfortably fit in an int. Lengths in this module often @@ -264,7 +258,7 @@ ef = it->funcs; return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); - case ASN1_ITYPE_CHOICE: + case ASN1_ITYPE_CHOICE: { /* * It never makes sense for CHOICE types to have implicit tagging, so if * tag != -1, then this looks like an error in the template. @@ -274,6 +268,8 @@ goto err; } + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) goto auxerr; @@ -327,8 +323,9 @@ goto auxerr; *in = p; return 1; + } - case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: { p = *in; /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ @@ -356,6 +353,8 @@ goto err; } + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) goto auxerr; @@ -462,6 +461,7 @@ goto auxerr; *in = p; return 1; + } default: return 0;
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c index 6dddb52..7abd34b 100644 --- a/crypto/asn1/tasn_enc.c +++ b/crypto/asn1/tasn_enc.c
@@ -131,8 +131,6 @@ { const ASN1_TEMPLATE *tt = NULL; int i, seqcontlen, seqlen; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = NULL; /* All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s. * Optional primitives are handled later. */ @@ -144,9 +142,6 @@ return -1; } - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - switch (it->itype) { case ASN1_ITYPE_PRIMITIVE: @@ -179,6 +174,8 @@ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); return -1; } + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) return -1; i = asn1_get_choice_selector(pval, it); @@ -214,7 +211,7 @@ return ret; } - case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: { i = asn1_enc_restore(&seqcontlen, out, pval, it); /* An error occurred */ if (i < 0) @@ -231,6 +228,8 @@ aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) | V_ASN1_UNIVERSAL; } + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) return -1; /* First work out sequence content length */ @@ -267,6 +266,7 @@ if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) return -1; return seqlen; + } default: OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c index 2f5032d..b847901 100644 --- a/crypto/asn1/tasn_fre.c +++ b/crypto/asn1/tasn_fre.c
@@ -79,17 +79,11 @@ { const ASN1_TEMPLATE *tt = NULL, *seqtt; const ASN1_EXTERN_FUNCS *ef; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; int i; if (!pval) return; if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) return; - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - else - asn1_cb = 0; switch (it->itype) { @@ -104,7 +98,9 @@ ASN1_primitive_free(pval, it); break; - case ASN1_ITYPE_CHOICE: + case ASN1_ITYPE_CHOICE: { + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb) { i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); if (i == 2) @@ -124,6 +120,7 @@ *pval = NULL; } break; + } case ASN1_ITYPE_EXTERN: ef = it->funcs; @@ -131,9 +128,11 @@ ef->asn1_ex_free(pval, it); break; - case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: { if (!asn1_refcount_dec_and_test_zero(pval, it)) return; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb) { i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); if (i == 2) @@ -162,6 +161,7 @@ } break; } + } } void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c index 346887b..eea219d 100644 --- a/crypto/asn1/tasn_new.c +++ b/crypto/asn1/tasn_new.c
@@ -95,14 +95,8 @@ { const ASN1_TEMPLATE *tt = NULL; const ASN1_EXTERN_FUNCS *ef; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; ASN1_VALUE **pseqval; int i; - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - else - asn1_cb = 0; switch (it->itype) { @@ -127,7 +121,9 @@ goto memerr; break; - case ASN1_ITYPE_CHOICE: + case ASN1_ITYPE_CHOICE: { + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb) { i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); if (!i) @@ -146,8 +142,11 @@ if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) goto auxerr2; break; + } - case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: { + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; if (asn1_cb) { i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); if (!i) @@ -173,6 +172,7 @@ goto auxerr2; break; } + } return 1; memerr2:
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c index 24ad8c3..9b1da0b 100644 --- a/crypto/asn1/tasn_utl.c +++ b/crypto/asn1/tasn_utl.c
@@ -118,6 +118,7 @@ } static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) { + assert(it->itype == ASN1_ITYPE_SEQUENCE); const ASN1_AUX *aux; if (!pval || !*pval) { return NULL;