This is an archive of the discontinued LLVM Phabricator instance.

BPF: fix FIELD_EXISTS relocation with array subscripts
ClosedPublic

Authored by yonghong-song on May 6 2021, 5:05 PM.

Details

Summary

Lorenz Bauer reported an issue in bpf mailing list ([1]) where
for FIELD_EXISTS relocation, if the object is an array subscript,
the patched immediate is the object offset from the base address,
instead of 1.

Currently in BPF AbstractMemberAccess pass, the final offset
from the base address is the patched offset except FIELD_EXISTS
which is 1 unconditionally. In this particular case, the last
data structure access is not a field (struct/union offset)
so it didn't hit the place to set patched immediate to be 1.

This patch fixed the issue by checking the relocation type.
If the type is FIELD_EXISTS, just set to 1.
Tested by modifying some bpf selftests, libbpf is okay with
such types with FIELD_EXISTS relocation.

[1] https://lore.kernel.org/bpf/CACAyw99n-cMEtVst7aK-3BfHb99GMEChmRLCvhrjsRpHhPrtvA@mail.gmail.com/

Diff Detail

Event Timeline

yonghong-song created this revision.May 6 2021, 5:05 PM
yonghong-song requested review of this revision.May 6 2021, 5:05 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 6 2021, 5:05 PM
ast accepted this revision.May 6 2021, 6:30 PM
This revision is now accepted and ready to land.May 6 2021, 6:30 PM

But bar[1] is not a field, why can't we just return error for such case? If someone wants to check type existence we have a separate TYPE_EXISTS relocation.

That is true that bar[1] is not an field. We also support field relocation like bar[1] since if sizeof(bar[1]) changed we can adjust offset properly. So there is
a precedence to support array like bar[1] for *field* relocations. So I think supporting "bar[1]" for existence relocation is not a bad thing.