|
@@ -25,6 +25,7 @@
|
|
|
#include <linux/sched/signal.h>
|
|
|
#include <linux/sched/task_stack.h>
|
|
|
#include <linux/mm.h>
|
|
|
+#include <linux/nospec.h>
|
|
|
#include <linux/smp.h>
|
|
|
#include <linux/ptrace.h>
|
|
|
#include <linux/user.h>
|
|
@@ -249,15 +250,20 @@ static struct perf_event *ptrace_hbp_get_event(unsigned int note_type,
|
|
|
|
|
|
switch (note_type) {
|
|
|
case NT_ARM_HW_BREAK:
|
|
|
- if (idx < ARM_MAX_BRP)
|
|
|
- bp = tsk->thread.debug.hbp_break[idx];
|
|
|
+ if (idx >= ARM_MAX_BRP)
|
|
|
+ goto out;
|
|
|
+ idx = array_index_nospec(idx, ARM_MAX_BRP);
|
|
|
+ bp = tsk->thread.debug.hbp_break[idx];
|
|
|
break;
|
|
|
case NT_ARM_HW_WATCH:
|
|
|
- if (idx < ARM_MAX_WRP)
|
|
|
- bp = tsk->thread.debug.hbp_watch[idx];
|
|
|
+ if (idx >= ARM_MAX_WRP)
|
|
|
+ goto out;
|
|
|
+ idx = array_index_nospec(idx, ARM_MAX_WRP);
|
|
|
+ bp = tsk->thread.debug.hbp_watch[idx];
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+out:
|
|
|
return bp;
|
|
|
}
|
|
|
|
|
@@ -1458,9 +1464,7 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
|
|
|
{
|
|
|
int ret;
|
|
|
u32 kdata;
|
|
|
- mm_segment_t old_fs = get_fs();
|
|
|
|
|
|
- set_fs(KERNEL_DS);
|
|
|
/* Watchpoint */
|
|
|
if (num < 0) {
|
|
|
ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata);
|
|
@@ -1471,7 +1475,6 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
|
|
|
} else {
|
|
|
ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata);
|
|
|
}
|
|
|
- set_fs(old_fs);
|
|
|
|
|
|
if (!ret)
|
|
|
ret = put_user(kdata, data);
|
|
@@ -1484,7 +1487,6 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
|
|
|
{
|
|
|
int ret;
|
|
|
u32 kdata = 0;
|
|
|
- mm_segment_t old_fs = get_fs();
|
|
|
|
|
|
if (num == 0)
|
|
|
return 0;
|
|
@@ -1493,12 +1495,10 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- set_fs(KERNEL_DS);
|
|
|
if (num < 0)
|
|
|
ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata);
|
|
|
else
|
|
|
ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata);
|
|
|
- set_fs(old_fs);
|
|
|
|
|
|
return ret;
|
|
|
}
|