The n in ptrace_get_debugreg() is indirectly controlled by userspace via 
syscall: ptrace(defined in kernel/ptrace.c), hence leading to a potential 
exploitation of the Spectre variant 1 vulnerability.
The n can be controlled from: ptrace -> arch_ptrace -> ptrace_get_debugreg.

Fix this by sanitizing n before using it to index thread->ptrace_bps.

Signed-off-by: Dianzhang Chen <[email protected]>
---
 arch/x86/kernel/ptrace.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 4b8ee05..3f8f158 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -24,6 +24,7 @@
 #include <linux/rcupdate.h>
 #include <linux/export.h>
 #include <linux/context_tracking.h>
+#include <linux/nospec.h>
 
 #include <linux/uaccess.h>
 #include <asm/pgtable.h>
@@ -644,7 +645,8 @@ static unsigned long ptrace_get_debugreg(struct task_struct 
*tsk, int n)
        unsigned long val = 0;
 
        if (n < HBP_NUM) {
-               struct perf_event *bp = thread->ptrace_bps[n];
+               struct perf_event *bp =
+                       thread->ptrace_bps[array_index_nospec(n, HBP_NUM)];
 
                if (bp)
                        val = bp->hw.info.address;
-- 
2.7.4

Reply via email to