Skip to content

Commit 0a5ea64

Browse files
committed
elf: refuse initialized BTF maps
BTF map definitions work by encoding map type, key size, etc. in a struct. Most of the time, the declared map is never initialized, even though space is allocated for it in the ELF. It is possible to intialize the map: struct { __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); __uint(max_entries, 4); __type(key, int); __array(values, struct ringbuf_map); } ringbuf_arr SEC(".maps") = { .values = { [0] = &ringbuf1, [2] = &ringbuf2, }, }; libbpf uses this for magic nested map initialization. Since we don't support this at the moment, check that the contents of a BTF map are zero, and bail out with internal.ErrNotSupported otherwise.
1 parent 3180b82 commit 0a5ea64

File tree

6 files changed

+35
-2
lines changed

6 files changed

+35
-2
lines changed

elf_reader.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,11 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec, mapSections map[elf.Sec
444444
}
445445

446446
for idx, sec := range mapSections {
447+
_, err := io.Copy(internal.DiscardZeroes{}, bufio.NewReader(sec.Open()))
448+
if err != nil {
449+
return fmt.Errorf("section %v: initializing BTF map definitions: %w", sec.Name, internal.ErrNotSupported)
450+
}
451+
447452
syms := ec.symbolsPerSection[idx]
448453
if len(syms) == 0 {
449454
return fmt.Errorf("section %v: no symbols", sec.Name)

elf_reader_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ebpf
22

33
import (
4+
"errors"
45
"flag"
56
"io/ioutil"
67
"os"
@@ -192,6 +193,16 @@ func TestLoadInvalidMapMissingSymbol(t *testing.T) {
192193
})
193194
}
194195

196+
func TestLoadInitializedBTFMap(t *testing.T) {
197+
testutils.TestFiles(t, "testdata/initialized_btf_map-*.elf", func(t *testing.T, file string) {
198+
_, err := LoadCollectionSpec(file)
199+
t.Log(err)
200+
if !errors.Is(err, internal.ErrNotSupported) {
201+
t.Fatal("Loading an initialized BTF map should be unsupported")
202+
}
203+
})
204+
}
205+
195206
func TestLoadRawTracepoint(t *testing.T) {
196207
testutils.SkipOnOldKernel(t, "4.17", "BPF_RAW_TRACEPOINT API")
197208

testdata/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ CLANG ?= $(LLVM_PREFIX)/clang
33
CFLAGS := -target bpf -O2 -g -Wall -Werror $(CFLAGS)
44

55
.PHONY: all clean
6-
all: loader-clang-6.0-el.elf loader-clang-7-el.elf loader-clang-8-el.elf loader-clang-9-el.elf invalid_map-el.elf raw_tracepoint-el.elf invalid_map_static-el.elf \
7-
loader-clang-6.0-eb.elf loader-clang-7-eb.elf loader-clang-8-eb.elf loader-clang-9-eb.elf invalid_map-eb.elf raw_tracepoint-eb.elf invalid_map_static-eb.elf
6+
all: loader-clang-6.0-el.elf loader-clang-7-el.elf loader-clang-8-el.elf loader-clang-9-el.elf invalid_map-el.elf raw_tracepoint-el.elf invalid_map_static-el.elf initialized_btf_map-el.elf \
7+
loader-clang-6.0-eb.elf loader-clang-7-eb.elf loader-clang-8-eb.elf loader-clang-9-eb.elf invalid_map-eb.elf raw_tracepoint-eb.elf invalid_map_static-eb.elf initialized_btf_map-eb.elf
88

99
clean:
1010
-$(RM) *.elf

testdata/initialized_btf_map-eb.elf

2.7 KB
Binary file not shown.

testdata/initialized_btf_map-el.elf

2.7 KB
Binary file not shown.

testdata/initialized_btf_map.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* This file excercises the ELF loader. It is not a valid BPF program. */
2+
3+
#include "common.h"
4+
5+
#if __clang_major__ >= 9
6+
struct {
7+
__uint(type, BPF_MAP_TYPE_HASH);
8+
__type(key, uint32_t);
9+
__type(value, uint64_t);
10+
__uint(max_entries, 1);
11+
} hash_map __section(".maps") = {
12+
/* This forces a non-zero byte into the .maps section. */
13+
.key = (void *)1,
14+
};
15+
#else
16+
#error This file has to be compiled with clang >= 9
17+
#endif

0 commit comments

Comments
 (0)