Skip to content

Commit 90b1163

Browse files
olsajiriKernel Patches Daemon
authored andcommitted
bpf: Allow uprobe program to change context registers
Currently uprobe (BPF_PROG_TYPE_KPROBE) program can't write to the context registers data. While this makes sense for kprobe attachments, for uprobe attachment it might make sense to be able to change user space registers to alter application execution. Since uprobe and kprobe programs share the same type (BPF_PROG_TYPE_KPROBE), we can't deny write access to context during the program load. We need to check on it during program attachment to see if it's going to be kprobe or uprobe. Storing the program's write attempt to context and checking on it during the attachment. Signed-off-by: Jiri Olsa <[email protected]>
1 parent dca857a commit 90b1163

File tree

3 files changed

+6
-2
lines changed

3 files changed

+6
-2
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,7 @@ struct bpf_prog_aux {
16091609
bool priv_stack_requested;
16101610
bool changes_pkt_data;
16111611
bool might_sleep;
1612+
bool kprobe_write_ctx;
16121613
u64 prog_array_member_cnt; /* counts how many times as member of prog_array */
16131614
struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */
16141615
struct bpf_arena *arena;

kernel/events/core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11205,6 +11205,10 @@ static int __perf_event_set_bpf_prog(struct perf_event *event,
1120511205
if (prog->kprobe_override && !is_kprobe)
1120611206
return -EINVAL;
1120711207

11208+
/* Writing to context allowed only for uprobes. */
11209+
if (prog->aux->kprobe_write_ctx && !is_uprobe)
11210+
return -EINVAL;
11211+
1120811212
if (is_tracepoint || is_syscall_tp) {
1120911213
int off = trace_event_get_offsets(event->tp_event);
1121011214

kernel/trace/bpf_trace.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,8 +1521,6 @@ static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type
15211521
{
15221522
if (off < 0 || off >= sizeof(struct pt_regs))
15231523
return false;
1524-
if (type != BPF_READ)
1525-
return false;
15261524
if (off % size != 0)
15271525
return false;
15281526
/*
@@ -1532,6 +1530,7 @@ static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type
15321530
if (off + size > sizeof(struct pt_regs))
15331531
return false;
15341532

1533+
prog->aux->kprobe_write_ctx |= type == BPF_WRITE;
15351534
return true;
15361535
}
15371536

0 commit comments

Comments
 (0)