Bläddra i källkod

aya: fix is_probe_read_kernel_supported in aarch64 kernels 5.5 (#1235)

In aarch64, with kernel 5.5, my programs that use `bpf_probe_read_user`
don't work successfully because `aya` is mistakenly re-writting it
`bpf_probe_read` because it falsely detects that the kernel doesn't
support `bpf_probe_read_user`.

I hadn't updated my `aya` version in a while, but while updating it to
fix a separate issue (panics when parsing kernel versions of PVE
kernels) and running my test suite I saw tests failing on aarch64 5.5
kernels. A git bisect led me to this commit:
942ea51906fea4e3152e1bd3ef5832bc0df5b205 and further investigation in the
difference of the new and old assembly showed that the only difference
was subtracting 8 vs adding -8. When I put it back as adding 8 (but
without handwritten assembly) then things work as expected. Since it
used to be `BPF_ADD` and the commit that changed it was just about no
longer handwriting assembly without any reason for the switch to
`BPF_SUB` putting it back as `BPF_ADD` seems reasonable. 

When using `BPF_SUB` 8, the handwritten program in this function
returns a permission error which is treated by this function as
`bpf_probe_read_kernel` not being supported when it is but for some
reason `BPF_SUB` is not. My guess is that it might be an early verifier
error but I am not 100% sure as I thought verifier errors are normally
`EINVAL` not `EPERM` but I have a vague memory of seeing `EPERM` in the
past for errors that happened very early in the verifier.

Fixes: #1233
Andres 2 dagar sedan
förälder
incheckning
fc69a06972
1 ändrade filer med 4 tillägg och 4 borttagningar
  1. 4 4
      aya/src/sys/bpf.rs

+ 4 - 4
aya/src/sys/bpf.rs

@@ -16,13 +16,13 @@ use aya_obj::{
     },
     generated::{
         BPF_ALU64, BPF_CALL, BPF_DW, BPF_EXIT, BPF_F_REPLACE, BPF_IMM, BPF_JMP, BPF_K, BPF_LD,
-        BPF_MEM, BPF_MOV, BPF_PSEUDO_MAP_VALUE, BPF_ST, BPF_SUB, BPF_X, bpf_attach_type, bpf_attr,
+        BPF_MEM, BPF_MOV, BPF_PSEUDO_MAP_VALUE, BPF_ST, BPF_X, bpf_attach_type, bpf_attr,
         bpf_btf_info, bpf_cmd, bpf_func_id::*, bpf_insn, bpf_link_info, bpf_map_info, bpf_map_type,
         bpf_prog_info, bpf_prog_type, bpf_stats_type,
     },
     maps::{LegacyMap, bpf_map_def},
 };
-use libc::{ENOENT, ENOSPC};
+use libc::{BPF_ADD, ENOENT, ENOSPC};
 
 use crate::{
     Btf, FEATURES, Pod, VerifierLogLevel,
@@ -781,13 +781,13 @@ pub(crate) fn is_probe_read_kernel_supported() -> bool {
     let u = unsafe { &mut attr.__bindgen_anon_3 };
 
     let mov64_reg = (BPF_ALU64 | BPF_MOV | BPF_X) as _;
-    let sub64_imm = (BPF_ALU64 | BPF_SUB | BPF_K) as _;
+    let add64_imm = (BPF_ALU64 | BPF_ADD | BPF_K) as _;
     let mov64_imm = (BPF_ALU64 | BPF_MOV | BPF_K) as _;
     let call = (BPF_JMP | BPF_CALL) as _;
     let exit = (BPF_JMP | BPF_EXIT) as _;
     let insns = [
         new_insn(mov64_reg, 1, 10, 0, 0),
-        new_insn(sub64_imm, 1, 0, 0, 8),
+        new_insn(add64_imm, 1, 0, 0, -8),
         new_insn(mov64_imm, 2, 0, 0, 8),
         new_insn(mov64_imm, 3, 0, 0, 0),
         new_insn(call, 0, 0, 0, BPF_FUNC_probe_read_kernel as _),