]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
arm64/gcs: task_gcs_el0_enable() should use passed task
authorJeremy Linton <jeremy.linton@arm.com>
Sat, 19 Jul 2025 04:37:33 +0000 (23:37 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 Aug 2025 14:38:51 +0000 (16:38 +0200)
[ Upstream commit cbbcfb94c55c02a8c4ce52b5da0770b5591a314c ]

Mark Rutland noticed that the task parameter is ignored and
'current' is being used instead. Since this is usually
what its passed, it hasn't yet been causing problems but likely
will as the code gets more testing.

But, once this is fixed, it creates a new bug in copy_thread_gcs()
since the gcs_el_mode isn't yet set for the task before its being
checked. Move gcs_alloc_thread_stack() after the new task's
gcs_el0_mode initialization to avoid this.

Fixes: fc84bc5378a8 ("arm64/gcs: Context switch GCS state for EL0")
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20250719043740.4548-2-jeremy.linton@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm64/include/asm/gcs.h
arch/arm64/kernel/process.c

index f50660603ecf5dc09a92740062df3a089b02b219..5bc432234d3abaf39ba9492feb5d2c7ad1c520a1 100644 (file)
@@ -58,7 +58,7 @@ static inline u64 gcsss2(void)
 
 static inline bool task_gcs_el0_enabled(struct task_struct *task)
 {
-       return current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE;
+       return task->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE;
 }
 
 void gcs_set_el0_mode(struct task_struct *task);
index 08b7042a2e2d4727adb1a5b7b00b129560a5135c..3e1baff5e88d928ec95aaadaa5f5ee1a072eb9b6 100644 (file)
@@ -307,13 +307,13 @@ static int copy_thread_gcs(struct task_struct *p,
        p->thread.gcs_base = 0;
        p->thread.gcs_size = 0;
 
+       p->thread.gcs_el0_mode = current->thread.gcs_el0_mode;
+       p->thread.gcs_el0_locked = current->thread.gcs_el0_locked;
+
        gcs = gcs_alloc_thread_stack(p, args);
        if (IS_ERR_VALUE(gcs))
                return PTR_ERR((void *)gcs);
 
-       p->thread.gcs_el0_mode = current->thread.gcs_el0_mode;
-       p->thread.gcs_el0_locked = current->thread.gcs_el0_locked;
-
        return 0;
 }