Re: bpf_probe_read_user EFAULT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 12/28/22 6:00 AM, Victor Laforet wrote:
Yes I am sorry I did not mention that the example I sent was a minimal working example. I am filtering the events to select only preempted and events with the right pid as prev.

Would bpf_copy_from_user_task work better in this setting than bpf_probe_read_user ?
I don’t really understand why bpf_probe_read_user would not work for this use case.

Right, bpf_copy_from_user_task() is better than bpf_probe_read_user(). You could also use bpf_copy_from_user() if you have target_pid checking.

It is possible that the user variable you intended to access is not in memory. In such cases, bpf_probe_read_user() will return EFAULT. But
bpf_copy_from_user() and bpf_copy_from_user_task() will go through
page fault process to bring the variable to the memory.
Also because of this extra work, bpf_copy_from_user() and
bpf_copy_from_user_task() only work for sleepable programs.


Victor

----- Mail original -----
De: "Jiri Olsa" <olsajiri@xxxxxxxxx>
À: "Victor Laforet" <victor.laforet@xxxxxxxxxxx>
Cc: "bpf" <bpf@xxxxxxxxxxxxxxx>
Envoyé: Mardi 27 Décembre 2022 17:00:42
Objet: Re: bpf_probe_read_user EFAULT

On Tue, Dec 27, 2022 at 03:56:06PM +0100, Victor Laforet wrote:
Hi all,

I am trying to use bpf_probe_read_user to read a user space value from BPF. The issue is that I am getting -14 (-EFAULT) result from bpf_probe_read_user. I haven’t been able to make this function work reliably. Sometimes I get no error code then it goes back to EFAULT.

I am seeking your help to try and make this code work.
Thank you!

My goal is to read the variable pid on every bpf event.
Here is a full example:
(cat /sys/kernel/debug/tracing/trace_pipe to read the output).

sched_switch.bpf.c
```
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

int *input_pid;

char _license[4] SEC("license") = "GPL";

SEC("tp_btf/sched_switch")
int handle_sched_switch(u64 *ctx)

you might want to filter for your task, because sched_switch
tracepoint is called for any task scheduler switch

check BPF_PROG macro in bpf selftests on how to access tp_btf
arguments from context, for sched_switch it's:

         TP_PROTO(bool preempt,
                  struct task_struct *prev,
                  struct task_struct *next,
                  unsigned int prev_state),

and call the read helper only for prev->pid == 'your app pid',

there's bpf_copy_from_user_task helper you could use to read
another task's user memory reliably, but it needs to be called
from sleepable probe and you need to have the task pointer

jirka

{
   int pid;
   int err;

   err = bpf_probe_read_user(&pid, sizeof(int), (void *)input_pid);
   if (err != 0)
   {
     bpf_printk("Error on bpf_probe_read_user(pid) -> %d.\n", err);
     return 0;
   }

   bpf_printk("pid %d.\n", pid);
   return 0;
}
```

sched_switch.c
```
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include "sched_switch.skel.h"
#include <time.h>

static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
   return vfprintf(stderr, format, args);
}

int main(int argc, char **argv)
{
   struct sched_switch_bpf *skel;
   int err;
   int pid = getpid();

   libbpf_set_print(libbpf_print_fn);

   skel = sched_switch_bpf__open();
   if (!skel)
   {
     fprintf(stderr, "Failed to open BPF skeleton\n");
     return 1;
   }

   skel->bss->input_pid = &pid;

   err = sched_switch_bpf__load(skel);
   if (err)
   {
     fprintf(stderr, "Failed to load and verify BPF skeleton\n");
     goto cleanup;
   }

   err = sched_switch_bpf__attach(skel);
   if (err)
   {
     fprintf(stderr, "Failed to attach BPF skeleton\n");
     goto cleanup;
   }

   while (1);

cleanup:
   sched_switch_bpf__destroy(skel);
   return -err;
}
```



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux