The PSA Protected Storage credential backend (subsys/net/lib/tls_credentials/tls_credentials_trusted.c) declared its credential-store mutex as a plain zero-filled static struct k_mutex credential_lock; and never called k_mutex_init() on it. A statically zero-filled k_mutex has an uninitialized wait queue (its dlist head/tail are NULL instead of the self-referential sentinels that k_mutex_init/K_MUTEX_DEFINE install). The uncontended lock path does not touch the wait queue, so the defect is latent and serialized use behaves correctly.
When two execution contexts contend on the lock, k_mutex_lock() pends the blocking thread on the wait queue via z_pend_curr(), which calls sys_dlist_append() on the zeroed list and dereferences a NULL tail pointer (tail->next = node), faulting the kernel. The lock is held during TLS handshake credential loading and by all credential add/get/delete operations, so a deployment performing concurrent TLS handshakes (for example a server handling multiple simultaneous connections from a remote peer) or a credential-management operation concurrent with a handshake can trigger the dereference.
The impact is a denial of service: a deterministic kernel panic / device reset on the first contention. There is no memory corruption beyond the NULL dereference and no confidentiality or integrity impact; mutual exclusion on the fast path remains correct. Exposure is limited to builds with CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE enabled (PSA Protected Storage / TF-M platforms); the default volatile RAM backend initializes its lock correctly and is unaffected.
The fix initializes the mutex statically with K_MUTEX_DEFINE(credential_lock), providing a valid wait queue so the contended path no longer touches a NULL list.
Affected components
subsys/net/lib/tls_credentials
Affected versions
v3.2.0 through v4.4.0 (all releases since the trusted PSA credential backend was added), only when CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE is enabled
Fix
Fixed (merged) in 29581d5
Projected fixed version: 4.5.0 (the fix is merged on main but not yet released; this forecast should be confirmed against the actual release).
Introduced by: fe7ffcf (tls_credentials: add Trusted Credential storage backend, 2022-08-18)
Evidence
- subsys/net/lib/tls_credentials/tls_credentials_trusted.c:41 — pre-fix
static struct k_mutex credential_lock; with no k_mutex_init anywhere in the file (post-fix uses K_MUTEX_DEFINE)
- subsys/net/lib/tls_credentials/tls_credentials_trusted.c:306-365 — credential_lock guards credentials_lock() (held during TLS handshake credential load) and tls_credential_add/get/delete
- subsys/net/lib/tls_credentials/tls_credentials.c:22-28 — the sibling volatile backend correctly calls k_mutex_init(&credential_lock), confirming the trusted backend's omission
- kernel/mutex.c:120-168 — uncontended path skips the wait queue; contended path calls z_pend_curr(&mutex->wait_q,...)
- include/zephyr/sys/dlist.h:415-424 — sys_dlist_append on a zeroed list does
tail = list->tail (NULL); tail->next = node; → NULL pointer dereference
- subsys/net/lib/tls_credentials/CMakeLists.txt:9-10 — file built only under CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE
- git tag --contains fe7ffcf — introduced 2022-08-18, present v3.2.0 through v4.4.0 (shipped, reportable)
Patches
For more information
If you have any questions or comments about this advisory:
embargo: 2026-08-11
The PSA Protected Storage credential backend (subsys/net/lib/tls_credentials/tls_credentials_trusted.c) declared its credential-store mutex as a plain zero-filled
static struct k_mutex credential_lock;and never calledk_mutex_init()on it. A statically zero-filledk_mutexhas an uninitialized wait queue (its dlist head/tail are NULL instead of the self-referential sentinels thatk_mutex_init/K_MUTEX_DEFINEinstall). The uncontended lock path does not touch the wait queue, so the defect is latent and serialized use behaves correctly.When two execution contexts contend on the lock,
k_mutex_lock()pends the blocking thread on the wait queue viaz_pend_curr(), which callssys_dlist_append()on the zeroed list and dereferences a NULL tail pointer (tail->next = node), faulting the kernel. The lock is held during TLS handshake credential loading and by all credential add/get/delete operations, so a deployment performing concurrent TLS handshakes (for example a server handling multiple simultaneous connections from a remote peer) or a credential-management operation concurrent with a handshake can trigger the dereference.The impact is a denial of service: a deterministic kernel panic / device reset on the first contention. There is no memory corruption beyond the NULL dereference and no confidentiality or integrity impact; mutual exclusion on the fast path remains correct. Exposure is limited to builds with
CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGEenabled (PSA Protected Storage / TF-M platforms); the default volatile RAM backend initializes its lock correctly and is unaffected.The fix initializes the mutex statically with
K_MUTEX_DEFINE(credential_lock), providing a valid wait queue so the contended path no longer touches a NULL list.Affected components
subsys/net/lib/tls_credentialsAffected versions
v3.2.0 through v4.4.0 (all releases since the trusted PSA credential backend was added), only when CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE is enabled
Fix
Fixed (merged) in 29581d5
Projected fixed version: 4.5.0 (the fix is merged on
mainbut not yet released; this forecast should be confirmed against the actual release).Introduced by: fe7ffcf (tls_credentials: add Trusted Credential storage backend, 2022-08-18)
Evidence
static struct k_mutex credential_lock;with no k_mutex_init anywhere in the file (post-fix uses K_MUTEX_DEFINE)tail = list->tail (NULL); tail->next = node;→ NULL pointer dereferencePatches
mainv4.4-branchv4.3-branchv3.7-branchFor more information
If you have any questions or comments about this advisory:
embargo: 2026-08-11