Commit 38dd8ec5e3 for openssl.org
commit 38dd8ec5e3be47325b09f08abdef5dbebe89100f
Author: Dr. David von Oheimb <dev@ddvo.net>
Date: Thu Jun 18 19:29:20 2026 +0200
Fix get_cert_by_subject_ex() to gracefully handle broken symlinks (but not on Windows)
Also gloss over errors reading cert/CRL contents from existing symlinked files.
Fixes #23882
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed Aug 19 19:29:03 2026
(Merged from https://github.com/openssl/openssl/pull/31594)
diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c
index d9a3e986e9..e93ab4d47f 100644
--- a/crypto/x509/by_dir.c
+++ b/crypto/x509/by_dir.c
@@ -228,7 +228,7 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
X509 st_x509;
X509_CRL crl;
} data;
- int ok = 0;
+ int res, ok = 0;
int i, j, k;
unsigned long h;
BUF_MEM *b = NULL;
@@ -320,25 +320,35 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
}
#ifndef OPENSSL_NO_POSIX_IO
#ifdef _WIN32
+#define lstat _stat
#define stat _stat
#endif
{
struct stat st;
- if (stat(b->data, &st) < 0)
- break;
- }
+ if (lstat(b->data, &st) < 0)
+ break; /* file does not exist, not even a symlink */
+#ifndef _WIN32
+ if (stat(b->data, &st) < 0) {
+ k++;
+ continue; /* symlink is broken: following it went wrong */
+ }
#endif
- /* found one. */
- if (type == X509_LU_X509) {
- if ((X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx,
- propq))
- == 0)
- break;
- } else if (type == X509_LU_CRL) {
- if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0)
- break;
}
+#endif
+ res = 0;
+ ERR_set_mark();
+ if (type == X509_LU_X509)
+ res = X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx, propq);
+ else if (type == X509_LU_CRL)
+ res = X509_load_crl_file(xl, b->data, ent->dir_type);
/* else case will caught higher up */
+ ERR_pop_to_mark();
+ /* unless OPENSSL_NO_POSIX_IO, gracefully skip found file if cert/CRL fails to load. */
+#ifndef OPENSSL_NO_POSIX_IO
+ res = 1;
+#endif
+ if (res == 0)
+ break;
k++;
}