Skip to content

Commit 9c06895

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. Acked-by: Andrii Nakryiko <[email protected]> Signed-off-by: Jiri Olsa <[email protected]>
1 parent 2b3c471 commit 9c06895

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
@@ -1624,6 +1624,7 @@ struct bpf_prog_aux {
16241624
bool priv_stack_requested;
16251625
bool changes_pkt_data;
16261626
bool might_sleep;
1627+
bool kprobe_write_ctx;
16271628
u64 prog_array_member_cnt; /* counts how many times as member of prog_array */
16281629
struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */
16291630
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
@@ -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,9 @@ 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+
if (type == BPF_WRITE)
1534+
prog->aux->kprobe_write_ctx = true;
1535+
15351536
return true;
15361537
}
15371538

@@ -2918,6 +2919,10 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
29182919
if (!is_kprobe_multi(prog))
29192920
return -EINVAL;
29202921

2922+
/* Writing to context is not allowed for kprobes. */
2923+
if (prog->aux->kprobe_write_ctx)
2924+
return -EINVAL;
2925+
29212926
flags = attr->link_create.kprobe_multi.flags;
29222927
if (flags & ~BPF_F_KPROBE_MULTI_RETURN)
29232928
return -EINVAL;

0 commit comments

Comments
 (0)