Commit e99307b011 for openssl.org
commit e99307b011fb5313b6edd58e8715b8196553b040
Author: Bob Beck <beck@openssl.org>
Date: Wed Jun 17 20:41:58 2026 -0600
Replace strlen-then-snprintf preconditions with snprintf-return
This restructureis the apps/lib/apps.c file-rotation helpers
to use snprintf for truncation detection, since they now can.
This also collapses the per-snprintf VMS ifdef into one
SUFFIX_SEP macro because the ifdef-per-call shape was making my eyes
bleed from all the copypasta'ed snprintf lines with only one character
changed in the format string.
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
MergeDate: Wed Aug 26 16:20:32 2026
(Merged from https://github.com/openssl/openssl/pull/31640)
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index 14b6d6d814..86c69cb337 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -1738,6 +1738,16 @@ err:
return ret;
}
+/*
+ * Character that separates a filename from its suffix in the file-rotation
+ * helpers below. On VMS, '.' is structural so we use '-' instead.
+ */
+#ifndef OPENSSL_SYS_VMS
+#define SUFFIX_SEP '.'
+#else
+#define SUFFIX_SEP '-'
+#endif
+
int save_serial(const char *serialfile, const char *suffix,
const BIGNUM *serial, ASN1_INTEGER **retai)
{
@@ -1747,23 +1757,14 @@ int save_serial(const char *serialfile, const char *suffix,
ASN1_INTEGER *ai = NULL;
if (suffix == NULL) {
- if (OPENSSL_strlcpy(buf[0], serialfile, BSIZE) >= BSIZE) {
- BIO_puts(bio_err, "File name too long\n");
- goto err;
- }
+ if (OPENSSL_strlcpy(buf[0], serialfile, BSIZE) >= BSIZE)
+ goto too_long;
} else {
- int n = snprintf(buf[0], sizeof(buf[0]),
-#ifndef OPENSSL_SYS_VMS
- "%s.%s",
-#else
- "%s-%s",
-#endif
- serialfile, suffix);
+ int n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s",
+ serialfile, SUFFIX_SEP, suffix);
- if (n < 0 || (size_t)n >= sizeof(buf[0])) {
- BIO_puts(bio_err, "File name too long\n");
- goto err;
- }
+ if (n < 0 || (size_t)n >= sizeof(buf[0]))
+ goto too_long;
}
out = BIO_new_file(buf[0], "w");
if (out == NULL) {
@@ -1781,6 +1782,9 @@ int save_serial(const char *serialfile, const char *suffix,
*retai = ai;
ai = NULL;
}
+ goto err;
+too_long:
+ BIO_puts(bio_err, "File name too long\n");
err:
if (!ret)
ERR_print_errors(bio_err);
@@ -1793,23 +1797,16 @@ int rotate_serial(const char *serialfile, const char *new_suffix,
const char *old_suffix)
{
char buf[2][BSIZE];
- size_t i, j;
-
- i = strlen(serialfile) + strlen(old_suffix);
- j = strlen(serialfile) + strlen(new_suffix);
- if (i > j)
- j = i;
- if (j + 1 >= BSIZE) {
- BIO_puts(bio_err, "File name too long\n");
- goto err;
- }
-#ifndef OPENSSL_SYS_VMS
- snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, new_suffix);
- snprintf(buf[1], sizeof(buf[1]), "%s.%s", serialfile, old_suffix);
-#else
- snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, new_suffix);
- snprintf(buf[1], sizeof(buf[1]), "%s-%s", serialfile, old_suffix);
-#endif
+ int n;
+
+ n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s",
+ serialfile, SUFFIX_SEP, new_suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[0]))
+ goto too_long;
+ n = snprintf(buf[1], sizeof(buf[1]), "%s%c%s",
+ serialfile, SUFFIX_SEP, old_suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[1]))
+ goto too_long;
if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
#ifdef ENOTDIR
&& errno != ENOTDIR
@@ -1828,6 +1825,8 @@ int rotate_serial(const char *serialfile, const char *new_suffix,
goto err;
}
return 1;
+too_long:
+ BIO_puts(bio_err, "File name too long\n");
err:
ERR_print_errors(bio_err);
return 0;
@@ -1892,11 +1891,7 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
goto err;
-#ifndef OPENSSL_SYS_VMS
- snprintf(buf, sizeof(buf), "%s.attr", dbfile);
-#else
- snprintf(buf, sizeof(buf), "%s-attr", dbfile);
-#endif
+ snprintf(buf, sizeof(buf), "%s%cattr", dbfile, SUFFIX_SEP);
dbattr_conf = app_load_config_quiet(buf);
retdb = app_malloc(sizeof(*retdb), "new DB");
@@ -1968,22 +1963,20 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db)
{
char buf[3][BSIZE];
BIO *out;
- int j;
-
- j = (int)(strlen(dbfile) + strlen(suffix));
- if (j + 6 >= BSIZE) {
- BIO_puts(bio_err, "File name too long\n");
- goto err;
- }
-#ifndef OPENSSL_SYS_VMS
- snprintf(buf[2], sizeof(buf[2]), "%s.attr", dbfile);
- snprintf(buf[1], sizeof(buf[1]), "%s.attr.%s", dbfile, suffix);
- snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, suffix);
-#else
- snprintf(buf[2], sizeof(buf[2]), "%s-attr", dbfile);
- snprintf(buf[1], sizeof(buf[1]), "%s-attr-%s", dbfile, suffix);
- snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, suffix);
-#endif
+ int j, n;
+
+ n = snprintf(buf[2], sizeof(buf[2]), "%s%cattr",
+ dbfile, SUFFIX_SEP);
+ if (n < 0 || (size_t)n >= sizeof(buf[2]))
+ goto too_long;
+ n = snprintf(buf[1], sizeof(buf[1]), "%s%cattr%c%s",
+ dbfile, SUFFIX_SEP, SUFFIX_SEP, suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[1]))
+ goto too_long;
+ n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s",
+ dbfile, SUFFIX_SEP, suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[0]))
+ goto too_long;
out = BIO_new_file(buf[0], "w");
if (out == NULL) {
perror(dbfile);
@@ -2006,6 +1999,8 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db)
BIO_free(out);
return 1;
+too_long:
+ BIO_puts(bio_err, "File name too long\n");
err:
ERR_print_errors(bio_err);
return 0;
@@ -2015,29 +2010,28 @@ int rotate_index(const char *dbfile, const char *new_suffix,
const char *old_suffix)
{
char buf[5][BSIZE];
- size_t i, j;
-
- i = strlen(dbfile) + strlen(old_suffix);
- j = strlen(dbfile) + strlen(new_suffix);
- if (i > j)
- j = i;
- if (j + 6 >= BSIZE) {
- BIO_puts(bio_err, "File name too long\n");
- goto err;
- }
-#ifndef OPENSSL_SYS_VMS
- snprintf(buf[4], sizeof(buf[4]), "%s.attr", dbfile);
- snprintf(buf[3], sizeof(buf[3]), "%s.attr.%s", dbfile, old_suffix);
- snprintf(buf[2], sizeof(buf[2]), "%s.attr.%s", dbfile, new_suffix);
- snprintf(buf[1], sizeof(buf[1]), "%s.%s", dbfile, old_suffix);
- snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, new_suffix);
-#else
- snprintf(buf[4], sizeof(buf[4]), "%s-attr", dbfile);
- snprintf(buf[3], sizeof(buf[3]), "%s-attr-%s", dbfile, old_suffix);
- snprintf(buf[2], sizeof(buf[2]), "%s-attr-%s", dbfile, new_suffix);
- snprintf(buf[1], sizeof(buf[1]), "%s-%s", dbfile, old_suffix);
- snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, new_suffix);
-#endif
+ int n;
+
+ n = snprintf(buf[4], sizeof(buf[4]), "%s%cattr",
+ dbfile, SUFFIX_SEP);
+ if (n < 0 || (size_t)n >= sizeof(buf[4]))
+ goto too_long;
+ n = snprintf(buf[3], sizeof(buf[3]), "%s%cattr%c%s",
+ dbfile, SUFFIX_SEP, SUFFIX_SEP, old_suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[3]))
+ goto too_long;
+ n = snprintf(buf[2], sizeof(buf[2]), "%s%cattr%c%s",
+ dbfile, SUFFIX_SEP, SUFFIX_SEP, new_suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[2]))
+ goto too_long;
+ n = snprintf(buf[1], sizeof(buf[1]), "%s%c%s",
+ dbfile, SUFFIX_SEP, old_suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[1]))
+ goto too_long;
+ n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s",
+ dbfile, SUFFIX_SEP, new_suffix);
+ if (n < 0 || (size_t)n >= sizeof(buf[0]))
+ goto too_long;
if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
#ifdef ENOTDIR
&& errno != ENOTDIR
@@ -2073,6 +2067,8 @@ int rotate_index(const char *dbfile, const char *new_suffix,
goto err;
}
return 1;
+too_long:
+ BIO_puts(bio_err, "File name too long\n");
err:
ERR_print_errors(bio_err);
return 0;
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index e05c5832e3..49831e812a 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -981,22 +981,20 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
continue;
#endif
- if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
- ERR_raise(ERR_LIB_SSL, SSL_R_PATH_TOO_LONG);
- goto err;
- }
#ifdef OPENSSL_SYS_VMS
r = snprintf(buf, sizeof(buf), "%s%s", dir, filename);
#else
r = snprintf(buf, sizeof(buf), "%s/%s", dir, filename);
#endif
+ if (r < 0 || (size_t)r >= sizeof(buf)) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_PATH_TOO_LONG);
+ goto err;
+ }
#ifndef OPENSSL_NO_POSIX_IO
/* Skip subdirectories */
if (!stat(buf, &st) && S_ISDIR(st.st_mode))
continue;
#endif
- if (r <= 0 || r >= (int)sizeof(buf))
- goto err;
if (!add_file_cert_subjects_to_stack(stack, buf, name_hash))
goto err;
}