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;