View Issue Details

IDProjectCategoryView StatusLast Update
0007031CloudGeneralpublic2024-06-05 15:49
ReporterJon Doron Assigned ToNeil Hanlon  
PrioritynormalSeveritymajorReproducibilityalways
Status acknowledgedResolutionopen 
Summary0007031: bpf_probe_read is broken
DescriptionThere is an issue in the latest image:
projects/rocky-linux-cloud/global/images/rocky-linux-8-optimized-gcp-v20240515, 4.18.0-513.18.1.el8_9.cloud.0.4.x86_64

The patch sev-snp.patch, breaks bpf_probe_read (and probe kernel read), my guess is that it was an attempt to backport:
 https://lore.kernel.org/all/20230912002703.3924521-2-acdunlap@google.com/

But the backport patched the wrong function..., in short the problem in the patch is:
diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c
index e3b7882e4..6aafc5994 100644
--- a/arch/x86/mm/maccess.c
+++ b/arch/x86/mm/maccess.c
@@ -7,12 +7,21 @@
 static __always_inline bool invalid_probe_range(u64 vaddr)
 {
     /*
- * Range covering the highest possible canonical userspace address
- * as well as non-canonical address range. For the canonical range
- * we also need to include the userspace guard page.
+ * Do not allow userspace addresses. This disallows
+ * normal userspace and the userspace guard page:
      */
- return vaddr < TASK_SIZE_MAX + PAGE_SIZE ||
- !__is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
+ if (vaddr < TASK_SIZE_MAX + PAGE_SIZE)
+ return false;
+
+ /*
+ * Allow everything during early boot before 'x86_virt_bits'
+ * is initialized. Needed for instruction decoding in early
+ * exception handlers.
+ */
+ if (!boot_cpu_data.x86_virt_bits)
+ return true;
+
+ return __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits); <<<<<<<<<<<<<<< Here you need to return NOT
so it's
return !__is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);

Since you have patched invalid_probe_range...

But like I originally said I believe the backport is just going in the wrong place...
Steps To ReproduceUsing the latest bpftrace, (for example if you have docker you can do)
sudo docker run --name devel --rm -it --privileged --pid host ubuntu:devel bash

Then once you install bpftrace you need to mount:
mount -t debugfs none /sys/kernel/debug

Then create a file with a sample program like:
```
$ cat /tmp/sched.bt
#include <stdio.h>
#include <stdlib.h>

rawtracepoint:sched_process_exec
{
    printf("raw bprm=%p filename=%p\n", arg2, ((struct linux_binprm *)arg2)->filename )
}

tracepoint:sched:sched_process_exec
{
    printf("filename=%p\n", args->filename);
}
```

And run:
```
bpftrace /tmp/sched.bt
```

You will notice an output like:
```
Attaching 2 probes...
raw bprm=0xffff96da2f24f000 filename=(nil)
filename=0xffffd4bd7fd29124


raw bprm=0xffff96da018f9a00 filename=(nil)
filename=0xffffd4bd7fc29124
```

notice the (nil) that should not happen... that's a result of bpf_probe_read failing...
Tagsbpf, cloud, kernel

Activities

Neil Hanlon

Neil Hanlon

2024-06-05 15:49

administrator   ~0007362

Thanks for the report. We're investigating this now.

Issue History

Date Modified Username Field Change
2024-06-05 13:21 Jon Doron New Issue
2024-06-05 13:21 Jon Doron Tag Attached: bpf
2024-06-05 13:21 Jon Doron Tag Attached: cloud
2024-06-05 13:21 Jon Doron Tag Attached: kernel
2024-06-05 15:49 Neil Hanlon Project Rocky Linux SIG => Cloud
2024-06-05 15:49 Neil Hanlon Assigned To => Neil Hanlon
2024-06-05 15:49 Neil Hanlon Status new => acknowledged
2024-06-05 15:49 Neil Hanlon Note Added: 0007362