aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hw_breakpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hw_breakpoint.c')
-rw-r--r--kernel/hw_breakpoint.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index 9ed9ae3a48b3..89e8a050c43a 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -308,6 +308,28 @@ int dbg_release_bp_slot(struct perf_event *bp)
308 return 0; 308 return 0;
309} 309}
310 310
311static int validate_hw_breakpoint(struct perf_event *bp)
312{
313 int ret;
314
315 ret = arch_validate_hwbkpt_settings(bp);
316 if (ret)
317 return ret;
318
319 if (arch_check_bp_in_kernelspace(bp)) {
320 if (bp->attr.exclude_kernel)
321 return -EINVAL;
322 /*
323 * Don't let unprivileged users set a breakpoint in the trap
324 * path to avoid trap recursion attacks.
325 */
326 if (!capable(CAP_SYS_ADMIN))
327 return -EPERM;
328 }
329
330 return 0;
331}
332
311int register_perf_hw_breakpoint(struct perf_event *bp) 333int register_perf_hw_breakpoint(struct perf_event *bp)
312{ 334{
313 int ret; 335 int ret;
@@ -316,7 +338,7 @@ int register_perf_hw_breakpoint(struct perf_event *bp)
316 if (ret) 338 if (ret)
317 return ret; 339 return ret;
318 340
319 ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task); 341 ret = validate_hw_breakpoint(bp);
320 342
321 /* if arch_validate_hwbkpt_settings() fails then release bp slot */ 343 /* if arch_validate_hwbkpt_settings() fails then release bp slot */
322 if (ret) 344 if (ret)
@@ -363,7 +385,7 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
363 if (attr->disabled) 385 if (attr->disabled)
364 goto end; 386 goto end;
365 387
366 err = arch_validate_hwbkpt_settings(bp, bp->ctx->task); 388 err = validate_hw_breakpoint(bp);
367 if (!err) 389 if (!err)
368 perf_event_enable(bp); 390 perf_event_enable(bp);
369 391