From: Nikola Pajkovsky Date: Tue, 16 Jun 2026 10:58:45 +0000 (+0200) Subject: asn1: centralize aux const-callback dispatch to avoid function pointer cast X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39f46844c6e06e26bea34f300c7fc61c06bb20b8;p=thirdparty%2Fopenssl.git asn1: centralize aux const-callback dispatch to avoid function pointer cast Replace the per-call-site `(ASN1_aux_const_cb *)aux->asn1_cb` cast in ASN1_item_ex_i2d() and asn1_item_print_ctx() with a shared helper, ossl_asn1_aux_const_cb(), which invokes the legacy non-const callback through its real type. This avoids the UBSAN function-pointer-type mismatch while preserving backward compatibility. Fixes: https://github.com/openssl/project/issues/1970 Signed-off-by: Nikola Pajkovsky Reviewed-by: Bob Beck Reviewed-by: Eugene Syromiatnikov Reviewed-by: Neil Horman MergeDate: Sun Jun 21 23:38:12 2026 (Merged from https://github.com/openssl/openssl/pull/31541) --- diff --git a/crypto/asn1/asn1_local.h b/crypto/asn1/asn1_local.h index 46d7aca7a20..0fd1d0a842a 100644 --- a/crypto/asn1/asn1_local.h +++ b/crypto/asn1/asn1_local.h @@ -12,6 +12,7 @@ #if !defined(OSSL_LIBCRYPTO_ASN1_ASN1_LOCAL_H) #define OSSL_LIBCRYPTO_ASN1_ASN1_LOCAL_H +#include #include "crypto/asn1.h" typedef const ASN1_VALUE const_ASN1_VALUE; @@ -99,5 +100,7 @@ int ossl_asn1_item_ex_new_intern(ASN1_VALUE **pval, const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, const char *propq); int ossl_asn1_time_time_t_to_tm(const time_t *time, struct tm *out_tm); int ossl_asn1_time_tm_to_time_t(const struct tm *tm, time_t *out); +int ossl_asn1_call_aux_cb(const ASN1_AUX *aux, int operation, + const ASN1_VALUE **in, const ASN1_ITEM *it, void *exarg); #endif /* !defined(OSSL_LIBCRYPTO_ASN1_ASN1_LOCAL_H) */ diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c index 834d087ebcc..e489e29a0c0 100644 --- a/crypto/asn1/tasn_enc.c +++ b/crypto/asn1/tasn_enc.c @@ -85,16 +85,10 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, int i, seqcontlen, seqlen, ndef = 1; const ASN1_EXTERN_FUNCS *ef; const ASN1_AUX *aux = it->funcs; - ASN1_aux_const_cb *asn1_cb = NULL; if ((it->itype != ASN1_ITYPE_PRIMITIVE) && *pval == NULL) return 0; - if (aux != NULL) { - asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb - : (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */ - } - switch (it->itype) { case ASN1_ITYPE_PRIMITIVE: @@ -123,7 +117,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE); return -1; } - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) + if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_PRE, pval, it, NULL)) return 0; i = ossl_asn1_get_choice_selector_const(pval, it); if ((i >= 0) && (i < it->tcount)) { @@ -134,7 +128,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass); } /* Fixme: error condition if selector out of range */ - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) + if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_POST, pval, it, NULL)) return 0; break; @@ -166,7 +160,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) | V_ASN1_UNIVERSAL; } - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) + if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_PRE, pval, it, NULL)) return 0; /* First work out sequence content length */ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { @@ -200,7 +194,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, } if (ndef == 2) ASN1_put_eoc(out); - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) + if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_POST, pval, it, NULL)) return 0; return seqlen; diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c index 080b5623e42..72922c6530a 100644 --- a/crypto/asn1/tasn_prn.c +++ b/crypto/asn1/tasn_prn.c @@ -138,15 +138,12 @@ static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent, const ASN1_EXTERN_FUNCS *ef; const ASN1_VALUE **tmpfld; const ASN1_AUX *aux = it->funcs; - ASN1_aux_const_cb *asn1_cb = NULL; ASN1_PRINT_ARG parg; int i; if (aux != NULL) { parg.out = out; parg.indent = indent; parg.pctx = pctx; - asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb - : (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */ } if (((it->itype != ASN1_ITYPE_PRIMITIVE) @@ -220,13 +217,11 @@ static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent, } } - if (asn1_cb) { - i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); - if (i == 0) - return 0; - if (i == 2) - return 1; - } + i = ossl_asn1_call_aux_cb(aux, ASN1_OP_PRINT_PRE, fld, it, &parg); + if (i == 0) + return 0; + if (i == 2) + return 1; /* Print each field entry */ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { @@ -244,11 +239,9 @@ static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent, return 0; } - if (asn1_cb) { - i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); - if (i == 0) - return 0; - } + i = ossl_asn1_call_aux_cb(aux, ASN1_OP_PRINT_POST, fld, it, &parg); + if (i == 0) + return 0; break; default: diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c index 5e82a10fbdb..a4ab7629601 100644 --- a/crypto/asn1/tasn_utl.c +++ b/crypto/asn1/tasn_utl.c @@ -288,3 +288,19 @@ err: ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); return NULL; } + +int ossl_asn1_call_aux_cb(const ASN1_AUX *aux, int operation, + const ASN1_VALUE **in, const ASN1_ITEM *it, void *exarg) +{ + if (aux == NULL) + return 1; + + if ((aux->flags & ASN1_AFLG_CONST_CB) != 0) { + if (aux->asn1_const_cb != NULL) + return aux->asn1_const_cb(operation, in, it, exarg); + } else if (aux->asn1_cb != NULL) { + return aux->asn1_cb(operation, (ASN1_VALUE **)in, it, exarg); + } + + return 1; +}