Merge pull request #11269 from aidankeefe2022/fenrir-10736

Fix: Unchecked buffer overrun when adding Cert Directory
pull/11363/merge
JacobBarthelmeh 2026-09-15 10:42:20 -06:00 committed by GitHub
commit 5a59a56e36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 120 additions and 1 deletions

View File

@ -8580,6 +8580,8 @@ WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
/* @param argl file type, either WOLFSSL_FILETYPE_PEM or */
/* WOLFSSL_FILETYPE_ASN1 */
/* @return WOLFSSL_SUCCESS on successful, otherwise negative or zero */
/* Note: on failure, path elements parsed before the failing one have */
/* already been added to ctx->dir_entry */
static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
{
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
@ -8653,7 +8655,7 @@ static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
return 0;
}
XSTRNCPY(entry->dir_name, buf, pathLen);
XMEMCPY(entry->dir_name, buf, pathLen);
entry->dir_name[pathLen] = '\0';
if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) <= 0) {
@ -8668,6 +8670,11 @@ static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
pathLen = 0;
XMEMSET(buf, 0, MAX_FILENAME_SZ);
}
if (pathLen >= MAX_FILENAME_SZ) {
WOLFSSL_MSG("dir name too long for internal buffer");
WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
return 0;
}
buf[pathLen++] = *c;
} while(*c++ != '\0');
@ -8695,6 +8702,8 @@ static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
/* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/
/* yet implemented. It returns WOLFSSL_NOT_IMPLEMENTED */
/* when those control commands are passed. */
/* Note: on failure, path elements parsed before the failing one have */
/* already been added to ctx->dir_entry */
int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd,
const char *argc, long argl, char **ret)
{

View File

@ -294,6 +294,114 @@ int test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void)
return EXPECT_RESULT();
}
/* Check that a path element longer than the internal MAX_FILENAME_SZ buffer is
* rejected instead of overflowing it. */
int test_wolfSSL_X509_LOOKUP_ctrl_dir_len(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
X509_STORE* str = NULL;
X509_LOOKUP* lookup = NULL;
char* longPath = NULL;
const int longPathCap = MAX_FILENAME_SZ + 5;
ExpectNotNull((longPath = (char*)XMALLOC(longPathCap, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER)));
/* One Path One Over Max Size */
if (EXPECT_SUCCESS()) {
XMEMSET(longPath, 'a', MAX_FILENAME_SZ + 1);
XMEMSET(longPath + MAX_FILENAME_SZ + 1, '\0',
longPathCap - MAX_FILENAME_SZ - 1);
}
ExpectNotNull((str = X509_STORE_new()));
ExpectNotNull((lookup = X509_STORE_add_lookup(str,
X509_LOOKUP_file())));
ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR,
longPath, SSL_FILETYPE_PEM, NULL), 0);
X509_STORE_free(str);
str = NULL;
ExpectNotNull((str = X509_STORE_new()));
ExpectNotNull((lookup = X509_STORE_add_lookup(str,
X509_LOOKUP_file())));
/* One Path Max Size */
if (EXPECT_SUCCESS()) {
XMEMSET(longPath, 'a', MAX_FILENAME_SZ);
XMEMSET(longPath + MAX_FILENAME_SZ, '\0',
longPathCap - MAX_FILENAME_SZ);
}
ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR,
longPath, SSL_FILETYPE_PEM, NULL), WOLFSSL_SUCCESS);
X509_STORE_free(str);
str = NULL;
ExpectNotNull((str = X509_STORE_new()));
ExpectNotNull((lookup = X509_STORE_add_lookup(str,
X509_LOOKUP_file())));
/* Second path one too long */
if (EXPECT_SUCCESS()) {
XMEMSET(longPath, 'a', longPathCap);
XMEMSET(longPath, 'b', 2);
longPath[2] = SEPARATOR_CHAR;
longPath[longPathCap-1] = '\0';
}
ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR,
longPath, SSL_FILETYPE_PEM, NULL), 0);
X509_STORE_free(str);
str = NULL;
ExpectNotNull((str = X509_STORE_new()));
ExpectNotNull((lookup = X509_STORE_add_lookup(str,
X509_LOOKUP_file())));
/* Two Paths Correct Size */
if (EXPECT_SUCCESS()) {
XMEMSET(longPath, 'a', longPathCap);
XMEMSET(longPath, 'b', 2);
longPath[2] = SEPARATOR_CHAR;
longPath[longPathCap - 2] = '\0';
}
ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR,
longPath, SSL_FILETYPE_PEM, NULL), WOLFSSL_SUCCESS);
X509_STORE_free(str);
str = NULL;
ExpectNotNull((str = X509_STORE_new()));
ExpectNotNull((lookup = X509_STORE_add_lookup(str,
X509_LOOKUP_file())));
/* path max size terminated by separator char */
if (EXPECT_SUCCESS()) {
XMEMSET(longPath, 'a', longPathCap);
longPath[MAX_FILENAME_SZ] = SEPARATOR_CHAR;
longPath[MAX_FILENAME_SZ + 1] = '\0';
}
ExpectIntEQ(X509_LOOKUP_ctrl(lookup, X509_L_ADD_DIR,
longPath, SSL_FILETYPE_PEM, NULL), WOLFSSL_SUCCESS);
X509_STORE_free(str);
str = NULL;
if (longPath != NULL) {
XFREE(longPath, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_X509_load_crl_file(void)
{
EXPECT_DECLS;

View File

@ -27,6 +27,7 @@
int test_wolfSSL_X509_LOOKUP_load_file(void);
int test_wolfSSL_X509_LOOKUP_ctrl_file(void);
int test_wolfSSL_X509_LOOKUP_ctrl_hash_dir(void);
int test_wolfSSL_X509_LOOKUP_ctrl_dir_len(void);
int test_wolfSSL_X509_load_crl_file(void);
int test_X509_LOOKUP_add_dir(void);
@ -34,6 +35,7 @@ int test_X509_LOOKUP_add_dir(void);
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_load_file), \
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_file), \
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_hash_dir), \
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_dir_len), \
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_load_crl_file), \
TEST_DECL_GROUP("ossl_x509_lu", test_X509_LOOKUP_add_dir)