yonghong-song cf8833e4cc
[BPF] Fix CORE optimization bug in BPFMISimplifyPatchable (#183446)
Commit ffd57408efd4 ("[BPF] Enable relocation location for
load/store/shifts") enabled CORE relocation for load/store/shirts. In
particular, the commit did optimization to have load/store/shift insn
itself having the relocation. For the load and store, the optimization
has the following:
  rX = *(rY + <relocation>) and *(rX + <relocation>) = rY

There is no value-range check for the above '<relocation>'. For example,
if the original `<relocation>` is 0x10006 due to a large struct, the
insn encoding of `<relocaiton>` will be truncated into '6' and incorrect
result will happen.

This patch fixed the issue by checking the value range of
'<relocation>'. If the `<relocation>` is more than INT16_MAX,
optimization will be skipped.

Even llvm side is fixed, libbpf side may still have issues with the
current approach since libbpf may change the value of <relocation>. If
the <relocation> value is more than INT16_MAX, libbpf will either fail
or need to patch insns.

Let us say we have
  rX = *(rY + <relocation>) and *(rX + <relocation>) = rY

libbpf will modify `<relocation>` value depending on the actual offset
in kernel data structure. If `<relocation>` is more than INT16_MAX, more
than one insn will be necessary. llvm can add nop instructions for patch
purpose (see [1]).

The following are major patching cases:
  case 1: rX = *(rY + <relocation>) // rX and rY are different
    rX = <relocation>
    rX += rY
    rX = *(rX + 0)
  case 2: rX = *(rX + <relocation>)
    rX += <relocation>
    rX = *(rX + 0)
  case 3: *(rX + <relocation>) = imm
    rX += <relocation>
    *(rX + 0) = imm
    rX -= <relocation>
  case 4: *(rX + <relocation>) = rY // rX and rY are different
    rX += <relocation>
    *(rX + 0) = rY
    rX -= <relocation>
  case 5: *(rX + <relocation>) = rX
    // We are not able to resolve this issue.

A llvm option (-disable-bpf-core-optimization) is implemented to
disable bpf core optimizaiton, which means the relocation will not
be in load/store insns. This can workaround the above case 5.

[1] https://github.com/llvm/llvm-project/compare/main...yonghong-song:llvm-project:fix-core-overflow-debug
2026-03-10 16:42:57 -07:00
..