Files
Nicolas Iooss af8a370421 Fix eBPF compare-and-exchange instruction
Linux kernel's documentation tells in
https://www.kernel.org/doc/html/v6.0/bpf/instruction-set.html#atomic-operations

> The BPF_CMPXCHG operation atomically compares the value addressed by
> dst_reg + off with R0. If they match, the value addressed by
> dst_reg + off is replaced with src_reg. In either case, the value that
> was at dst_reg + off before the operation is zero-extended and loaded
> back to R0.

If the values don't match, *(dst_reg + off) is not supposed to be
modified.

Moreover, register R0 is always modified and the 32-bit instruction
truncates its value (with a zero-extension). This is also clear in the
implementation of BPF_CMPXCHG in
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/core.c?h=v6.18#n2186

    case BPF_CMPXCHG:
            if (BPF_SIZE(insn->code) == BPF_W)
                    BPF_R0 = (u32) atomic_cmpxchg(
                            (atomic_t *)(unsigned long) (DST + insn->off),
                            (u32) BPF_R0, (u32) SRC);
            else if (BPF_SIZE(insn->code) == BPF_DW)
                    BPF_R0 = (u64) atomic64_cmpxchg(
                            (atomic64_t *)(unsigned long) (DST + insn->off),
                            (u64) BPF_R0, (u64) SRC);

Fix the semantic of the compare-and-exchange instruction accordingly.
2025-12-29 19:49:13 +00:00
..
2023-04-10 00:54:28 +03:00
2023-04-10 00:54:28 +03:00