From 06e5462a4b5bfe488c097cd4d7e4e42460e4dde1 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 20 Mar 2026 17:20:55 +0100 Subject: [PATCH] credential-factory: Enforce an upper limit when creating nested credentials This mainly intended as defense-in-depth measure to avoid parsing massively nested structures that could cause a call stack overflow due to the massive recursion. In particular PKCS#7 signed data is prone to this as these can be nested basically infinitely. When used in IKEv1 via ENC_PKCS7_WRAPPED_X509 CERT payloads, our default of 10000 bytes for IKE messages guards against this, but that's configurable and there might be a chance for some bug that triggers problematic recursive parsing for smaller input. The upper limit is chosen arbitrarily, but there are currently no known cases that require a depth of more than 10 levels. --- src/libstrongswan/credentials/credential_factory.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c index 07e1de76e..15f4ba9a4 100644 --- a/src/libstrongswan/credentials/credential_factory.c +++ b/src/libstrongswan/credentials/credential_factory.c @@ -25,6 +25,11 @@ #include #include +/** + * Maximum depth/recursion before failing to create a credential. + */ +#define CREATE_MAX_DEPTH 10 + ENUM(credential_type_names, CRED_PRIVATE_KEY, CRED_CONTAINER, "CRED_PRIVATE_KEY", "CRED_PUBLIC_KEY", @@ -137,6 +142,12 @@ METHOD(credential_factory_t, create, void*, } level = (uintptr_t)this->recursive->get(this->recursive); + if (level >= CREATE_MAX_DEPTH) + { + DBG1(DBG_LIB, "building %N - %N failed, reached depth limit (%d)", + credential_type_names, type, names, subtype, CREATE_MAX_DEPTH); + return NULL; + } this->recursive->set(this->recursive, (void*)level + 1); this->lock->read_lock(this->lock);