Как изменить память пользовательского пространства с помощью eBPF?

Я пытаюсь написать пример кода и посмотреть, как он работает на практике.

Как сказано здесь и обсуждается здесь.

Если все верно, вывод должен быть:

$ cat foo1
this is foo1 content
$ cat foo2
this is foo2 content
$ sudo bcc_mangle_open.py &
[1] 63453
$ cat foo1
this is foo2 content

Я написал образец в BCC, который выглядит так:

from bcc import BPF

# define BPF program
prog = """
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>
int trace_entry(struct pt_regs *ctx)
{
    char buf[10];
    char foo2[] = "foo2";
    char *fname = (char *) PT_REGS_PARM1(ctx);

    bpf_probe_read_str(buf, sizeof(buf), fname);
    if (buf[0] != 'f' || buf[1] != 'o' || buf[2] != 'o' || buf[3] != '1') {
        return 0;
    }

    bpf_probe_write_user(fname, foo2, sizeof(foo2));

    return 0;
};
"""

# load BPF program
b = BPF(text=prog)

b.attach_kprobe("do_sys_open", fn_name="trace_entry")

Содержимое foo1 должно измениться, но этого не происходит.

И я попытался напечатать fname и даже buf с помощью bpf_trace_printk(), но на экране ничего не появилось.

Любая идея, почему содержимое не меняется?

обновление-1

Как было предложено @Queole

.Это сработало..Поэтому мы должны дать (char *) PT_REGS_PARM2(ctx) вместо (char *) PT_REGS_PARM1(ctx). Я получил вывод, но немного странно. через каких-то 3-4 cat foo1 содержимое меняется.

$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo2 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo1 content
$ cat foo1
this is foo2 content

В чем причина такого поведения?


person avsr    schedule 27.07.2020    source источник
comment
Не могли бы вы проверить значение, возвращаемое bpf_probe_write_user? В случае ошибки оно должно быть отрицательным.   -  person pchaigno    schedule 27.07.2020
comment
Вы пробовали читать второй аргумент вместо первого? Похоже, что do_sys_open() в ядре получает имя файла на второй позиции.   -  person Qeole    schedule 27.07.2020
comment
Спасибо.. Это сработало.. Поэтому мы должны указать (char *) PT_REGS_PARM2(ctx) вместо (char *) PT_REGS_PARM1(ctx). Я получил вывод, но немного странно. после каких-то 3-4 cat foo1 содержимое меняется.   -  person avsr    schedule 28.07.2020
comment
Я обновил вопрос. Вы знаете, почему он так себя ведет?   -  person avsr    schedule 28.07.2020
comment
Я могу воспроизвести. В этом случае bpf_probe_write_user() большую часть времени возвращает -EFAULT (-14), указывая на то, что не удалось скопировать foo2 в fname. Я пока не нашел, как это исправить.   -  person Qeole    schedule 28.07.2020