aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNorbert Pocs <[email protected]>2026-07-18 16:49:06 +0200
committerNorbert Pocs <[email protected]>2026-07-21 14:54:46 +0200
commit4cef487f2a5615e59d919e6fd4094a02038950ff (patch)
treecfe94e1e1d31766b88677a294eac9d1f4dad1275
parentquic: report SRTM entry match status via an output argument (diff)
downloadopenssl-4cef487f2a5615e59d919e6fd4094a02038950ff.tar.gz
openssl-4cef487f2a5615e59d919e6fd4094a02038950ff.zip
Guard against NULL data in empty ASN1_STRINGs
Since 28179061bf a zero-length ASN1_STRING has data == NULL in fuzzing builds instead of a 1-byte allocation. Several call sites did pointer arithmetic or memcpy on the data pointer before any length check, which is undefined behaviour for NULL even with a zero offset and aborts the fuzz targets under UBSan: - asn1_string_canon: skip canonicalisation of empty values - do_buf, do_hex_dump: return early on an empty buffer - i2d_ocsp_nonce: skip the memcpy for an empty nonce The loops at these sites were already no-ops for zero length, so there is no behaviour change outside sanitizer builds. Assisted-By: Claude:claude-fable-5 Signed-off-by: Norbert Pocs <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> MergeDate: Tue Jul 21 12:54:48 2026 (Merged from https://github.com/openssl/openssl/pull/31998)
-rw-r--r--crypto/asn1/a_strex.c8
-rw-r--r--crypto/ocsp/v3_ocsp.c5
-rw-r--r--crypto/x509/x_name.c4
3 files changed, 14 insertions, 3 deletions
diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c
index e488c87f5bc..57a14f6f90c 100644
--- a/crypto/asn1/a_strex.c
+++ b/crypto/asn1/a_strex.c
@@ -142,6 +142,10 @@ static int do_buf(const unsigned char *buf, int buflen,
const unsigned char *p, *q;
uint32_t c;
+ if (buflen < 0)
+ return -1;
+ if (buflen == 0)
+ return 0;
p = buf;
q = buf + buflen;
outlen = 0;
@@ -236,6 +240,10 @@ static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
unsigned char *p, *q;
char hextmp[2];
+ if (buflen < 0)
+ return -1;
+ if (buflen == 0)
+ return 0;
if (arg) {
p = buf;
q = buf + buflen;
diff --git a/crypto/ocsp/v3_ocsp.c b/crypto/ocsp/v3_ocsp.c
index d31c74ef453..408c2a15486 100644
--- a/crypto/ocsp/v3_ocsp.c
+++ b/crypto/ocsp/v3_ocsp.c
@@ -143,7 +143,7 @@ static void *ocsp_nonce_new(void)
static int i2d_ocsp_nonce(const void *a, unsigned char **pp)
{
const ASN1_OCTET_STRING *os = a;
- if (pp) {
+ if (pp != NULL && os->length > 0) {
memcpy(*pp, os->data, os->length);
*pp += os->length;
}
@@ -164,7 +164,8 @@ static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
if (!ASN1_OCTET_STRING_set(os, *pp, length))
goto err;
- *pp += length;
+ if (length > 0)
+ *pp += length;
if (pos)
*pos = os;
diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c
index 90588c8c67e..961f474e5b4 100644
--- a/crypto/x509/x_name.c
+++ b/crypto/x509/x_name.c
@@ -404,8 +404,10 @@ static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in)
out->type = V_ASN1_UTF8STRING;
out->length = ASN1_STRING_to_UTF8(&out->data, in);
- if (out->length == -1)
+ if (out->length < 0)
return 0;
+ if (out->length == 0)
+ return 1;
to = out->data;
from = to;