inspektor-gadget
154 строки · 4.7 Кб
1// Copyright 2023 The Inspektor Gadget authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package kallsyms
16
17import (
18"os"
19"strings"
20"testing"
21
22"github.com/cilium/ebpf"
23"github.com/cilium/ebpf/btf"
24"github.com/stretchr/testify/require"
25
26utilstest "github.com/inspektor-gadget/inspektor-gadget/internal/test"
27)
28
29func TestCustomKAllSyms(t *testing.T) {
30kAllSymsStr := strings.Join([]string{
31"0000000000000000 A fixed_percpu_data",
32"ffffffffb4231f40 D bpf_prog_fops",
33"ffffffffb43723e0 d socket_file_ops",
34}, "\n")
35
36kAllSymsReader := strings.NewReader(kAllSymsStr)
37kAllSyms, err := NewKAllSymsFromReader(kAllSymsReader)
38require.Nil(t, err, "NewKAllSymsFromReader failed: %v", err)
39require.True(t, kAllSyms.SymbolExists("bpf_prog_fops"),
40"SymbolExists should have found bpf_prog_fops")
41require.False(t, kAllSyms.SymbolExists("abcde_bad_name"),
42"SymbolExists should not have found abcde_bad_name")
43
44lookupByInstructionPointerTests := []struct {
45instructionPointer uint64
46expectedSymbol string
47}{
48{0, "fixed_percpu_data"},
49{0xffffffffb4231f39, "fixed_percpu_data"},
50{0xffffffffb4231f40, "bpf_prog_fops"},
51// TODO: is it correct? should it be bpf_prog_fops?
52{0xffffffffb4231f41, "bpf_prog_fops"},
53{0xffffffffb43723df, "bpf_prog_fops"},
54{0xffffffffb43723e0, "socket_file_ops"},
55{0xffffffffb43723e1, "socket_file_ops"},
56}
57for _, tt := range lookupByInstructionPointerTests {
58require.Equal(t, tt.expectedSymbol, kAllSyms.LookupByInstructionPointer(tt.instructionPointer),
59"LookupByInstructionPointer(0x%x)", tt.instructionPointer)
60}
61}
62
63func TestRealKAllSyms(t *testing.T) {
64utilstest.RequireRoot(t)
65
66kAllSyms, err := NewKAllSyms()
67require.Nil(t, err, "NewKAllSyms failed: %v", err)
68require.True(t, kAllSyms.SymbolExists("bpf_prog_fops"),
69"SymbolExists should have found bpf_prog_fops")
70require.False(t, kAllSyms.SymbolExists("abcde_bad_name"),
71"SymbolExists should not have found abcde_bad_name")
72
73addr, ok := kAllSyms.symbolsMap["bpf_prog_fops"]
74require.True(t, ok, "bpf_prog_fops not found in symbolsMap")
75// /proc/kallsyms contains the address 0 without CAP_SYSLOG.
76// Since we use RequireRoot, it should not happen.
77require.NotEqual(t, 0, addr, "bpf_prog_fops has a zero address")
78}
79
80func TestSpecRewriteConstants(t *testing.T) {
81kAllSymsFactory := func() (*KAllSyms, error) {
82kAllSymsStr := strings.Join([]string{
83"0000000000000000 A fixed_percpu_data",
84"ffffffffb4231f40 D bpf_prog_fops",
85"ffffffffb43723e0 d socket_file_ops",
86}, "\n")
87
88kAllSymsReader := strings.NewReader(kAllSymsStr)
89kAllSyms, err := NewKAllSymsFromReader(kAllSymsReader)
90require.Nil(t, err, "NewKAllSymsFromReader failed: %v", err)
91return kAllSyms, nil
92}
93
94// Little endian representation of the addresses above:
95bpfProgFopsAddr := []byte{0x40, 0x1f, 0x23, 0xb4, 0xff, 0xff, 0xff, 0xff}
96socketFileOpsAddr := []byte{0xe0, 0x23, 0x37, 0xb4, 0xff, 0xff, 0xff, 0xff}
97
98spec := &ebpf.CollectionSpec{
99Maps: map[string]*ebpf.MapSpec{
100".rodata": {
101Type: ebpf.Array,
102KeySize: 4,
103ValueSize: 4,
104MaxEntries: 1,
105Value: &btf.Datasec{
106Vars: []btf.VarSecinfo{
107{
108Type: &btf.Var{
109Name: "bpf_prog_fops_addr",
110Type: &btf.Int{Size: 8},
111},
112Offset: 0,
113Size: 8,
114},
115{
116Type: &btf.Var{
117Name: "socket_file_ops_addr",
118Type: &btf.Int{Size: 8},
119},
120Offset: 8,
121Size: 8,
122},
123},
124},
125Contents: []ebpf.MapKV{
126{Key: uint32(0), Value: []byte{
1270, 0, 0, 0, 0, 0, 0, 0,
1280, 0, 0, 0, 0, 0, 0, 0,
129}},
130},
131},
132},
133}
134
135err := specUpdateAddresses(
136kAllSymsFactory,
137spec,
138[]string{"abcde_bad_name"},
139)
140require.ErrorIs(t, err, os.ErrNotExist, "specRewriteConstantsWithSymbolAddresses should have failed")
141
142err = specUpdateAddresses(
143kAllSymsFactory,
144spec,
145[]string{"bpf_prog_fops", "socket_file_ops"},
146)
147require.Nil(t, err, "specRewriteConstantsWithSymbolAddresses failed: %v", err)
148
149expectedContents := []byte{}
150expectedContents = append(expectedContents, bpfProgFopsAddr...)
151expectedContents = append(expectedContents, socketFileOpsAddr...)
152contents := spec.Maps[".rodata"].Contents[0].Value
153require.Equal(t, contents, expectedContents, "contents aren't equal")
154}
155