Describe the bug
BatchLookup() calls into batchLookupCmd(), which in turn calls haveBatchAPI() indiscriminately, caching the result to avoid future calls. The problem here is that haveBatchAPI() creates a small temporary ebpf map which it then batch updates to verify that the system supports batching. However, the creation of the map implies CAP_BPF capabiliries.
BatchDelete (and BatchUpdate(), for that matter) was improved in #1071 to have the haveBatchAPI() being called only after a failure is observed while calling the underlying BPF syscall, to check if the cause was lack of batching support.
I'm suggesting the same for the same to be done for BatchLookup(), otherwise this can lead to awkward to debug errors like
batch lookup: map batch lookup: map batch api not supported (requires >= v5.6)".
Our binary is split in two - A and B, where A creates the maps and B reads and performs several read operations. B runs with minimal permissions, so suddenly having to require CAP_BPF is surprising and hard to justify.
How to reproduce
// Bellow BatchUpdate and BatchDelete work, but BatchLookup doesn't.
fun() {
m, err := ebpf.LoadPinnedMap(path, nil)
if err != nil {
fmt.Fprintln(os.Stderr, "[run] LoadPinnedMap:", err)
os.Exit(1)
}
defer m.Close()
keys := []uint32{1, 2}
vals := []uint32{11, 22}
// BatchUpdate first: populates entries we can later delete/lookup.
n, err := m.BatchUpdate(keys, vals, nil)
fmt.Printf("[run] BatchUpdate n=%d err=%v\n", n, err)
// BatchLookup: this is the call cilium gates with the probe.
var cursor ebpf.MapBatchCursor
outKeys := make([]uint32, 2)
outVals := make([]uint32, 2)
n, err = m.BatchLookup(&cursor, outKeys, outVals, nil)
fmt.Printf("[run] BatchLookup n=%d err=%v keys=%v vals=%v\n", n, err, outKeys, outVals)
if errors.Is(err, ebpf.ErrKeyNotExist) {
fmt.Println("[run] (ErrKeyNotExist is the normal end-of-iteration signal)")
}
// BatchDelete: should succeed even without caps on the happy path.
n, err = m.BatchDelete(keys, nil)
fmt.Printf("[run] BatchDelete n=%d err=%v\n", n, err)
}
Version information
All versions
Describe the bug
BatchLookup()calls into batchLookupCmd(), which in turn callshaveBatchAPI()indiscriminately, caching the result to avoid future calls. The problem here is thathaveBatchAPI()creates a small temporary ebpf map which it then batch updates to verify that the system supports batching. However, the creation of the map impliesCAP_BPFcapabiliries.BatchDelete(andBatchUpdate(), for that matter) was improved in #1071 to have thehaveBatchAPI()being called only after a failure is observed while calling the underlying BPF syscall, to check if the cause was lack of batching support.I'm suggesting the same for the same to be done for
BatchLookup(), otherwise this can lead to awkward to debug errors likeOur binary is split in two - A and B, where A creates the maps and B reads and performs several read operations. B runs with minimal permissions, so suddenly having to require CAP_BPF is surprising and hard to justify.
How to reproduce
// Bellow BatchUpdate and BatchDelete work, but BatchLookup doesn't.
Version information
All versions