CVE-2026-45876
Description
In the Linux kernel, the following vulnerability has been resolved:
arm64/gcs: Fix error handling in arch_set_shadow_stack_status()
alloc_gcs() returns an error-encoded pointer on failure, which comes from do_mmap(), not NULL.
The current NULL check fails to detect errors, which could lead to using an invalid GCS address.
Use IS_ERR_VALUE() to properly detect errors, consistent with the check in gcs_alloc_thread_stack().
Affected products
1Patches
653c998527ffaarm64/gcs: Fix error handling in arch_set_shadow_stack_status()
1 file changed · +2 −3
arch/arm64/mm/gcs.c+2 −3 modifieddiff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c index 6e93f78de79b17..04a23a497f2051 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -199,8 +199,8 @@ int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) size = gcs_size(0); gcs = alloc_gcs(0, size); - if (!gcs) - return -ENOMEM; + if (IS_ERR_VALUE(gcs)) + return gcs; task->thread.gcspr_el0 = gcs + size - sizeof(u64); task->thread.gcs_base = gcs; -- cgit 1.3-korg
c787a235deb3arm64/gcs: Fix error handling in arch_set_shadow_stack_status()
1 file changed · +2 −3
arch/arm64/mm/gcs.c+2 −3 modifieddiff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c index 6e93f78de79b17..04a23a497f2051 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -199,8 +199,8 @@ int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) size = gcs_size(0); gcs = alloc_gcs(0, size); - if (!gcs) - return -ENOMEM; + if (IS_ERR_VALUE(gcs)) + return gcs; task->thread.gcspr_el0 = gcs + size - sizeof(u64); task->thread.gcs_base = gcs; -- cgit 1.3-korg
a4741114c962arm64/gcs: Fix error handling in arch_set_shadow_stack_status()
1 file changed · +2 −3
arch/arm64/mm/gcs.c+2 −3 modifieddiff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c index 6e93f78de79b17..04a23a497f2051 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -199,8 +199,8 @@ int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) size = gcs_size(0); gcs = alloc_gcs(0, size); - if (!gcs) - return -ENOMEM; + if (IS_ERR_VALUE(gcs)) + return gcs; task->thread.gcspr_el0 = gcs + size - sizeof(u64); task->thread.gcs_base = gcs; -- cgit 1.3-korg
c787a235deb3arm64/gcs: Fix error handling in arch_set_shadow_stack_status()
1 file changed · +2 −3
arch/arm64/mm/gcs.c+2 −3 modifieddiff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c index 6e93f78de79b17..04a23a497f2051 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -199,8 +199,8 @@ int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) size = gcs_size(0); gcs = alloc_gcs(0, size); - if (!gcs) - return -ENOMEM; + if (IS_ERR_VALUE(gcs)) + return gcs; task->thread.gcspr_el0 = gcs + size - sizeof(u64); task->thread.gcs_base = gcs; -- cgit 1.3-korg
a4741114c962arm64/gcs: Fix error handling in arch_set_shadow_stack_status()
1 file changed · +2 −3
arch/arm64/mm/gcs.c+2 −3 modifieddiff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c index 6e93f78de79b17..04a23a497f2051 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -199,8 +199,8 @@ int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) size = gcs_size(0); gcs = alloc_gcs(0, size); - if (!gcs) - return -ENOMEM; + if (IS_ERR_VALUE(gcs)) + return gcs; task->thread.gcspr_el0 = gcs + size - sizeof(u64); task->thread.gcs_base = gcs; -- cgit 1.3-korg
53c998527ffaarm64/gcs: Fix error handling in arch_set_shadow_stack_status()
1 file changed · +2 −3
arch/arm64/mm/gcs.c+2 −3 modifieddiff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c index 6e93f78de79b17..04a23a497f2051 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -199,8 +199,8 @@ int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg) size = gcs_size(0); gcs = alloc_gcs(0, size); - if (!gcs) - return -ENOMEM; + if (IS_ERR_VALUE(gcs)) + return gcs; task->thread.gcspr_el0 = gcs + size - sizeof(u64); task->thread.gcs_base = gcs; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Incorrect error-checking logic in arch_set_shadow_stack_status(): the code checks for NULL after calling alloc_gcs(), but alloc_gcs() returns an error-encoded pointer (from do_mmap()) on failure, not NULL, so allocation failures are not detected."
Attack vector
An attacker who can trigger a memory allocation failure in the kernel (e.g., by exhausting memory or hitting a limit) when the arch_set_shadow_stack_status() function is invoked via the shadow stack prctl() interface will cause the function to proceed with an invalid error-encoded pointer. This pointer is then stored as the task's GCS base and GCS pointer register value, leading to use of an invalid GCS address. The bug is in the error-handling path of arch/arm64/mm/gcs.c [patch_id=2661783].
Affected code
The vulnerable code is in `arch/arm64/mm/gcs.c` in the function `arch_set_shadow_stack_status()`. The error check after calling `alloc_gcs()` at line ~201 incorrectly tested for NULL instead of using `IS_ERR_VALUE()` [patch_id=2661783].
What the fix does
The patch replaces the NULL check `if (!gcs)` with `if (IS_ERR_VALUE(gcs))` and changes the return value from the hardcoded `-ENOMEM` to `return gcs`, which propagates the actual error code from do_mmap(). This matches the error-checking pattern already used in gcs_alloc_thread_stack() in the same file. The fix ensures that when alloc_gcs() fails, the error is properly detected and returned to the caller instead of allowing the invalid pointer to be used as a GCS address [patch_id=2661783].
Preconditions
- inputThe attacker must be able to trigger a memory allocation failure in the kernel (e.g., by exhausting system memory or hitting a per-process memory limit) while the arch_set_shadow_stack_status() function is executing.
- configThe attacker must be able to invoke the shadow stack prctl() interface on a system where arm64 GCS (Guarded Control Stack) support is enabled.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.