Commit 4f183765aa for openssl.org
commit 4f183765aab81df08aa53baf483b26d02ad677bb
Author: Bob Beck <beck@openssl.org>
Date: Wed Aug 5 15:54:01 2026 -0600
Sweep for printf UB - don't printf %s NULL
As an asn1_string of length 0 will have NULL data, don't
printf %s NULL.
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Thu Aug 27 13:52:48 2026
Merged-from: https://github.com/openssl/openssl/pull/32178
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 7c2c77d4ff..2deb87a1f8 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -1289,7 +1289,9 @@ void print_attribute(BIO *out, const ASN1_TYPE *av)
case V_ASN1_UTF8STRING:
BIO_printf(out, "%.*s\n", (int)ASN1_STRING_get_length(av->value.utf8string),
- ASN1_STRING_get0_data(av->value.utf8string));
+ ASN1_STRING_get_length(av->value.utf8string)
+ ? ASN1_STRING_get0_data(av->value.utf8string)
+ : (const unsigned char *)"");
break;
case V_ASN1_OCTET_STRING:
diff --git a/crypto/cmp/cmp_status.c b/crypto/cmp/cmp_status.c
index 8483dd290e..6ea36528c9 100644
--- a/crypto/cmp/cmp_status.c
+++ b/crypto/cmp/cmp_status.c
@@ -217,7 +217,8 @@ static char *snprint_PKIStatusInfo_parts(int status, int fail_info,
text = sk_ASN1_UTF8STRING_value(status_strings, i);
printed_chars = snprintf(write_ptr, bufsize, "\"%.*s\"%s",
(int)ASN1_STRING_get_length(text),
- ASN1_STRING_get0_data(text),
+ ASN1_STRING_get_length(text) ? ASN1_STRING_get0_data(text)
+ : (const unsigned char *)"",
i < n_status_strings - 1 ? ", " : "");
ADVANCE_BUFFER;
}
diff --git a/crypto/x509/v3_attrdesc.c b/crypto/x509/v3_attrdesc.c
index 997241fac0..142343bab2 100644
--- a/crypto/x509/v3_attrdesc.c
+++ b/crypto/x509/v3_attrdesc.c
@@ -100,7 +100,11 @@ static int i2r_OSSL_INFO_SYNTAX(X509V3_EXT_METHOD *method,
case OSSL_INFO_SYNTAX_TYPE_CONTENT:
if (BIO_printf(out, "%*sContent: ", indent, "") <= 0)
return 0;
- if (BIO_printf(out, "%.*s", info->choice.content->length, info->choice.content->data) <= 0)
+ if (BIO_printf(out, "%.*s", info->choice.content->length,
+ info->choice.content->length
+ ? info->choice.content->data
+ : (const unsigned char *)"")
+ <= 0)
return 0;
if (BIO_puts(out, "\n") <= 0)
return 0;
@@ -145,18 +149,28 @@ static int i2r_OSSL_ATTRIBUTE_DESCRIPTOR(X509V3_EXT_METHOD *method,
if (BIO_printf(out, "%*sSyntax:\n", indent, "") <= 0)
return 0;
if (BIO_printf(out, "%*s%.*s", indent + 4, "",
- ad->attributeSyntax->length, ad->attributeSyntax->data)
+ ad->attributeSyntax->length,
+ ad->attributeSyntax->length
+ ? ad->attributeSyntax->data
+ : (const unsigned char *)"")
<= 0)
return 0;
if (BIO_puts(out, "\n\n") <= 0)
return 0;
if (ad->name != NULL) {
- if (BIO_printf(out, "%*sName: %.*s\n", indent, "", ad->name->length, ad->name->data) <= 0)
+ if (BIO_printf(out, "%*sName: %.*s\n", indent, "", ad->name->length,
+ ad->name->length
+ ? ad->name->data
+ : (const unsigned char *)"")
+ <= 0)
return 0;
}
if (ad->description != NULL) {
if (BIO_printf(out, "%*sDescription: %.*s\n", indent, "",
- ad->description->length, ad->description->data)
+ ad->description->length,
+ ad->description->length
+ ? ad->description->data
+ : (const unsigned char *)"")
<= 0)
return 0;
}
diff --git a/crypto/x509/v3_cpols.c b/crypto/x509/v3_cpols.c
index f9abeaa959..c45bbc2c81 100644
--- a/crypto/x509/v3_cpols.c
+++ b/crypto/x509/v3_cpols.c
@@ -444,7 +444,9 @@ static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
case NID_id_qt_cps:
BIO_printf(out, "%*sCPS: %.*s", indent, "",
qualinfo->d.cpsuri->length,
- qualinfo->d.cpsuri->data);
+ qualinfo->d.cpsuri->length
+ ? qualinfo->d.cpsuri->data
+ : (const unsigned char *)"");
break;
case NID_id_qt_unotice:
@@ -469,7 +471,9 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent)
ref = notice->noticeref;
BIO_printf(out, "%*sOrganization: %.*s\n", indent, "",
ref->organization->length,
- ref->organization->data);
+ ref->organization->length
+ ? ref->organization->data
+ : (const unsigned char *)"");
BIO_printf(out, "%*sNumber%s: ", indent, "",
sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
@@ -494,7 +498,9 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent)
if (notice->exptext)
BIO_printf(out, "%*sExplicit Text: %.*s", indent, "",
notice->exptext->length,
- notice->exptext->data);
+ notice->exptext->length
+ ? notice->exptext->data
+ : (const unsigned char *)"");
}
void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
diff --git a/crypto/x509/v3_san.c b/crypto/x509/v3_san.c
index 025cd25ca9..52d8eb498c 100644
--- a/crypto/x509/v3_san.c
+++ b/crypto/x509/v3_san.c
@@ -225,27 +225,37 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
case NID_id_on_SmtpUTF8Mailbox:
BIO_printf(out, "othername:SmtpUTF8Mailbox:%.*s",
gen->d.otherName->value->value.utf8string->length,
- gen->d.otherName->value->value.utf8string->data);
+ gen->d.otherName->value->value.utf8string->length
+ ? gen->d.otherName->value->value.utf8string->data
+ : (const unsigned char *)"");
break;
case NID_XmppAddr:
BIO_printf(out, "othername:XmppAddr:%.*s",
gen->d.otherName->value->value.utf8string->length,
- gen->d.otherName->value->value.utf8string->data);
+ gen->d.otherName->value->value.utf8string->length
+ ? gen->d.otherName->value->value.utf8string->data
+ : (const unsigned char *)"");
break;
case NID_SRVName:
BIO_printf(out, "othername:SRVName:%.*s",
gen->d.otherName->value->value.ia5string->length,
- gen->d.otherName->value->value.ia5string->data);
+ gen->d.otherName->value->value.ia5string->length
+ ? gen->d.otherName->value->value.ia5string->data
+ : (const unsigned char *)"");
break;
case NID_ms_upn:
BIO_printf(out, "othername:UPN:%.*s",
gen->d.otherName->value->value.utf8string->length,
- gen->d.otherName->value->value.utf8string->data);
+ gen->d.otherName->value->value.utf8string->length
+ ? gen->d.otherName->value->value.utf8string->data
+ : (const unsigned char *)"");
break;
case NID_NAIRealm:
BIO_printf(out, "othername:NAIRealm:%.*s",
gen->d.otherName->value->value.utf8string->length,
- gen->d.otherName->value->value.utf8string->data);
+ gen->d.otherName->value->value.utf8string->length
+ ? gen->d.otherName->value->value.utf8string->data
+ : (const unsigned char *)"");
break;
default:
BIO_printf(out, "othername:<unsupported>");
diff --git a/crypto/x509/v3_timespec.c b/crypto/x509/v3_timespec.c
index f29265f4be..79dfdbe0a8 100644
--- a/crypto/x509/v3_timespec.c
+++ b/crypto/x509/v3_timespec.c
@@ -142,7 +142,11 @@ static int i2r_OSSL_TIME_SPEC_ABSOLUTE(X509V3_EXT_METHOD *method,
return 0;
if (!ossl_asn1_time_print_ex(out, time->startTime, 0))
return 0;
- if (BIO_printf(out, "%.*s", time->startTime->length, time->startTime->data) <= 0)
+ if (BIO_printf(out, "%.*s", time->startTime->length,
+ time->startTime->length
+ ? time->startTime->data
+ : (const unsigned char *)"")
+ <= 0)
return 0;
} else if (time->endTime != NULL) {
if (!BIO_puts(out, "Any time until "))
diff --git a/crypto/x509/v3_usernotice.c b/crypto/x509/v3_usernotice.c
index 8a53eff96e..ce6627bf23 100644
--- a/crypto/x509/v3_usernotice.c
+++ b/crypto/x509/v3_usernotice.c
@@ -29,7 +29,9 @@ static int print_notice(BIO *out, USERNOTICE *notice, int indent)
ref = notice->noticeref;
if (BIO_printf(out, "%*sOrganization: %.*s\n", indent, "",
ref->organization->length,
- ref->organization->data)
+ ref->organization->length
+ ? ref->organization->data
+ : (const unsigned char *)"")
<= 0)
return 0;
if (BIO_printf(out, "%*sNumber%s: ", indent, "",
@@ -61,7 +63,9 @@ static int print_notice(BIO *out, USERNOTICE *notice, int indent)
return BIO_printf(out, "%*sExplicit Text: %.*s", indent, "",
notice->exptext->length,
- notice->exptext->data)
+ notice->exptext->length
+ ? notice->exptext->data
+ : (const unsigned char *)"")
>= 0;
}
diff --git a/crypto/x509/x_attrib.c b/crypto/x509/x_attrib.c
index 648d64bcf3..98a99cc43b 100644
--- a/crypto/x509/x_attrib.c
+++ b/crypto/x509/x_attrib.c
@@ -135,7 +135,9 @@ int ossl_print_attribute_value(BIO *out,
case V_ASN1_OBJECT_DESCRIPTOR:
return BIO_printf(out, "%*s%.*s", indent, "",
av->value.generalstring->length,
- av->value.generalstring->data)
+ av->value.generalstring->length
+ ? av->value.generalstring->data
+ : (const unsigned char *)"")
>= 0;
/* EXTERNAL would go here. */
@@ -144,7 +146,9 @@ int ossl_print_attribute_value(BIO *out,
case V_ASN1_UTF8STRING:
return BIO_printf(out, "%*s%.*s", indent, "",
av->value.utf8string->length,
- av->value.utf8string->data)
+ av->value.utf8string->length
+ ? av->value.utf8string->data
+ : (const unsigned char *)"")
>= 0;
case V_ASN1_REAL:
@@ -208,25 +212,33 @@ int ossl_print_attribute_value(BIO *out,
case V_ASN1_NUMERICSTRING:
return BIO_printf(out, "%*s%.*s", indent, "",
av->value.visiblestring->length,
- av->value.visiblestring->data)
+ av->value.visiblestring->length
+ ? av->value.visiblestring->data
+ : (const unsigned char *)"")
>= 0;
case V_ASN1_PRINTABLESTRING:
return BIO_printf(out, "%*s%.*s", indent, "",
av->value.printablestring->length,
- av->value.printablestring->data)
+ av->value.printablestring->length
+ ? av->value.printablestring->data
+ : (const unsigned char *)"")
>= 0;
case V_ASN1_T61STRING:
return BIO_printf(out, "%*s%.*s", indent, "",
av->value.t61string->length,
- av->value.t61string->data)
+ av->value.t61string->length
+ ? av->value.t61string->data
+ : (const unsigned char *)"")
>= 0;
case V_ASN1_IA5STRING:
return BIO_printf(out, "%*s%.*s", indent, "",
av->value.ia5string->length,
- av->value.ia5string->data)
+ av->value.ia5string->length
+ ? av->value.ia5string->data
+ : (const unsigned char *)"")
>= 0;
/* UniversalString would go here. */