On Mon, Nov 09, 2020 at 02:22:28PM +0000, Kevin Sheldrake wrote: > I triggered the corruption by sending samples larger than 64KB-24 bytes > to a perf ring buffer from eBPF using bpf_perf_event_output(). The u16 > that holds the size in the struct perf_event_header is overflowed and > the distance between adjacent samples in the perf ring buffer is set > by this overflowed value; hence if samples of 64KB are sent, adjacent > samples are placed 24 bytes apart in the ring buffer, with the later ones > overwriting parts of the earlier ones. If samples aren't read as quickly > as they are received, then they are corrupted by the time they are read. > > Attempts to fix this in the eBPF verifier failed as the actual sample is > constructed from a variable sized header in addition to the raw data > supplied from eBPF. The sample is constructed in perf_prepare_sample(), > outside of the eBPF engine. > > My proposed fix is to check that the constructed size is <U16_MAX before > committing it to the struct perf_event_header::size variable. > > A reproduction of the bug can be found at: > https://github.com/microsoft/OMS-Auditd-Plugin/tree/MSTIC-Research/ebpf_perf_output_poc OK, so I can't actually operate any of this fancy BPF nonsense. But if I'm not mistaken this calls into: kernel/trace/bpf_trace.c:BPF_CALL_5(bpf_perf_event_output) with a giant @data. Let me try and figure out what that code does.