Skip to content

Commit 7384893

Browse files
olsajiriAlexei Starovoitov
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. Acked-by: Andrii Nakryiko <[email protected]> Signed-off-by: Jiri Olsa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 34f033a commit 7384893

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,7 @@ struct bpf_prog_aux {
16391639
bool priv_stack_requested;
16401640
bool changes_pkt_data;
16411641
bool might_sleep;
1642+
bool kprobe_write_ctx;
16421643
u64 prog_array_member_cnt; /* counts how many times as member of prog_array */
16431644
struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */
16441645
struct bpf_arena *arena;

kernel/events/core.c

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

11235+
/* Writing to context allowed only for uprobes. */
11236+
if (prog->aux->kprobe_write_ctx && !is_uprobe)
11237+
return -EINVAL;
11238+
1123511239
if (is_tracepoint || is_syscall_tp) {
1123611240
int off = trace_event_get_offsets(event->tp_event);
1123711241

kernel/trace/bpf_trace.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,8 +1338,6 @@ static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type
13381338
{
13391339
if (off < 0 || off >= sizeof(struct pt_regs))
13401340
return false;
1341-
if (type != BPF_READ)
1342-
return false;
13431341
if (off % size != 0)
13441342
return false;
13451343
/*
@@ -1349,6 +1347,9 @@ static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type
13491347
if (off + size > sizeof(struct pt_regs))
13501348
return false;
13511349

1350+
if (type == BPF_WRITE)
1351+
prog->aux->kprobe_write_ctx = true;
1352+
13521353
return true;
13531354
}
13541355

@@ -2735,6 +2736,10 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
27352736
if (!is_kprobe_multi(prog))
27362737
return -EINVAL;
27372738

2739+
/* Writing to context is not allowed for kprobes. */
2740+
if (prog->aux->kprobe_write_ctx)
2741+
return -EINVAL;
2742+
27382743
flags = attr->link_create.kprobe_multi.flags;
27392744
if (flags & ~BPF_F_KPROBE_MULTI_RETURN)
27402745
return -EINVAL;

0 commit comments

Comments
 (0)