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>
chromium-5359
David Benjamin 4 years ago committed by Boringssl LUCI CQ
parent 866cccc548
commit afed9f762d
  1. 16
      crypto/asn1/tasn_dec.c
  2. 12
      crypto/asn1/tasn_enc.c
  3. 16
      crypto/asn1/tasn_fre.c
  4. 16
      crypto/asn1/tasn_new.c
  5. 1
      crypto/asn1/tasn_utl.c

@ -170,8 +170,6 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
{
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 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
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 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
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 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
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 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
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 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
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 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
goto auxerr;
*in = p;
return 1;
}
default:
return 0;

@ -131,8 +131,6 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
{
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 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
return -1;
}
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
@ -179,6 +174,8 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
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 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
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 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
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 @@ int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
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);

@ -79,17 +79,11 @@ void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
{
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 @@ void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
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 @@ void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
*pval = NULL;
}
break;
}
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
@ -131,9 +128,11 @@ void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
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 @@ void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
}
break;
}
}
}
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)

@ -95,14 +95,8 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
{
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 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
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 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
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 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
goto auxerr2;
break;
}
}
return 1;
memerr2:

@ -118,6 +118,7 @@ int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it) {
}
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;

Loading…
Cancel
Save