[Devel] [PATCH VZ9/VZ10] x86/cpuid_fault: Fix possible UAF in cpuid_override_info

Vladimir Riabchun vladimir.riabchun at virtuozzo.com
Thu May 7 22:01:55 MSK 2026


If there are two writers, there following race is possible:
Writer 1:                           | Writer 2:
cpuid_override_update(T1)           |
 spin_lock(&cpuid_override_lock)    |
 cpuid_override = T1                |
 spin_unlock(&cpuid_override_lock)  |
 <Context switched>                 |
                                    | cpuid_override_update(T2)
                                    |  spin_lock(&cpuid_override_lock)
                                    |  old_table = T1
                                    |  cpuid_override = T2
                                    |  spin_unlock(&cpuid_override_lock)
                                    |
                                    |  kfree_rcu(T1, rcu_head);
                                    |  ^^^^^ No rcu_read_lock, free now
 cpuid_override_info(T1) <<< UAF    |

Fix it by dumping override table under cpuid_override_lock.

Fixes: a8dfdcae85ac ("x86/cpuid_fault: Log table updates")
Signed-off-by: Vladimir Riabchun <vladimir.riabchun at virtuozzo.com>
---
 arch/x86/kernel/cpuid_fault.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpuid_fault.c b/arch/x86/kernel/cpuid_fault.c
index 117c971f531a..ed5349b955f8 100644
--- a/arch/x86/kernel/cpuid_fault.c
+++ b/arch/x86/kernel/cpuid_fault.c
@@ -59,9 +59,8 @@ static void cpuid_override_update(struct cpuid_override_table *new_table)
 	spin_lock(&cpuid_override_lock);
 	old_table = rcu_access_pointer(cpuid_override);
 	rcu_assign_pointer(cpuid_override, new_table);
-	spin_unlock(&cpuid_override_lock);
-
 	cpuid_override_info(new_table);
+	spin_unlock(&cpuid_override_lock);
 
 	if (old_table)
 		kfree_rcu(old_table, rcu_head);
-- 
2.43.0



More information about the Devel mailing list