Skip to content

Commit 2b3b9e5

Browse files
tetragon/windows: Support Windows create and exit process - sensor changes
This PR lists sensor side changes to support CreateProcess and ExitProcess events. The program loader needs to load the entire collection of native Windows ebps program image using cilium/ebpf library. The specs for a native Windows bpf program is not available as it is not in ELF format This changes the order in which maps are loaded - collection is loaded first which loads maps and programs automatically. Signed-off-by: Anadi Anadi<[email protected]>
1 parent 6148689 commit 2b3b9e5

File tree

10 files changed

+679
-391
lines changed

10 files changed

+679
-391
lines changed

pkg/sensors/base/base.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -155,33 +155,6 @@ func GetTetragonConfMap() *program.Map {
155155
return TetragonConfMap
156156
}
157157

158-
func GetDefaultPrograms() []*program.Program {
159-
progs := []*program.Program{
160-
Exit,
161-
Fork,
162-
Execve,
163-
ExecveBprmCommit,
164-
}
165-
return progs
166-
}
167-
168-
func GetDefaultMaps() []*program.Map {
169-
maps := []*program.Map{
170-
ExecveMap,
171-
ExecveJoinMap,
172-
ExecveStats,
173-
ExecveJoinMapStats,
174-
ExecveTailCallsMap,
175-
TCPMonMap,
176-
TetragonConfMap,
177-
StatsMap,
178-
MatchBinariesSetMap,
179-
ErrMetricsMap,
180-
}
181-
return maps
182-
183-
}
184-
185158
func initBaseSensor() *sensors.Sensor {
186159
sensor := sensors.Sensor{
187160
Name: basePolicy,

pkg/sensors/base/base_linux.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Authors of Tetragon
3+
4+
package base
5+
6+
import (
7+
"github.com/cilium/tetragon/pkg/sensors/program"
8+
)
9+
10+
func GetDefaultPrograms() []*program.Program {
11+
progs := []*program.Program{
12+
Exit,
13+
Fork,
14+
Execve,
15+
ExecveBprmCommit,
16+
}
17+
return progs
18+
}
19+
20+
func GetDefaultMaps() []*program.Map {
21+
maps := []*program.Map{
22+
ExecveMap,
23+
ExecveJoinMap,
24+
ExecveStats,
25+
ExecveJoinMapStats,
26+
ExecveTailCallsMap,
27+
TCPMonMap,
28+
TetragonConfMap,
29+
StatsMap,
30+
MatchBinariesSetMap,
31+
ErrMetricsMap,
32+
}
33+
return maps
34+
35+
}

pkg/sensors/base/base_windows.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Authors of Tetragon
3+
4+
package base
5+
6+
import (
7+
"github.com/cilium/tetragon/pkg/sensors/program"
8+
)
9+
10+
var (
11+
CreateProcess = program.Builder(
12+
"process_monitor.sys",
13+
"process",
14+
"ProcessMonitor",
15+
"process::program",
16+
"windows",
17+
).SetPolicy(basePolicy)
18+
19+
ProcessRingBufMap = program.MapBuilder("process_ringbuf", CreateProcess)
20+
ProcessPidMap = program.MapBuilder("process_map", CreateProcess)
21+
ProcessCmdMap = program.MapBuilder("command_map", CreateProcess)
22+
)
23+
24+
func GetDefaultPrograms() []*program.Program {
25+
progs := []*program.Program{
26+
CreateProcess,
27+
}
28+
return progs
29+
}
30+
31+
func GetDefaultMaps() []*program.Map {
32+
maps := []*program.Map{
33+
ProcessRingBufMap,
34+
ProcessCmdMap,
35+
ProcessPidMap,
36+
}
37+
return maps
38+
39+
}

pkg/sensors/config/confmap/confmap.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import (
1111
"github.com/cilium/ebpf"
1212
"github.com/cilium/tetragon/pkg/cgroups"
1313
"github.com/cilium/tetragon/pkg/config"
14+
"github.com/cilium/tetragon/pkg/constants"
1415
"github.com/cilium/tetragon/pkg/logger"
1516
"github.com/cilium/tetragon/pkg/option"
1617
"github.com/cilium/tetragon/pkg/sensors/base"
1718
"github.com/cilium/tetragon/pkg/sensors/program"
1819
"github.com/sirupsen/logrus"
19-
"golang.org/x/sys/unix"
2020
)
2121

2222
const (
@@ -122,7 +122,7 @@ func UpdateTgRuntimeConf(mapDir string, nspid int) error {
122122
return err
123123
}
124124

125-
if v.CgrpFsMagic == unix.CGROUP2_SUPER_MAGIC {
125+
if v.CgrpFsMagic == constants.CGROUP2_SUPER_MAGIC {
126126
log.WithFields(logrus.Fields{
127127
"confmap-update": configMapName,
128128
"deployment.mode": deployMode.String(),

pkg/sensors/load.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"path/filepath"
1111
"strings"
1212

13+
"github.com/cilium/tetragon/pkg/kernels"
1314
"github.com/cilium/tetragon/pkg/logger"
1415
"github.com/cilium/tetragon/pkg/option"
1516
"github.com/cilium/tetragon/pkg/sensors/program"
@@ -102,6 +103,92 @@ func (s *Sensor) removeDirs() {
102103
os.Remove(filepath.Join(s.BpfDir, s.policyDir()))
103104
}
104105

106+
// Load loads the sensor, by loading all the BPF programs and maps.
107+
func (s *Sensor) Load(bpfDir string) (err error) {
108+
if s == nil {
109+
return nil
110+
}
111+
112+
if s.Destroyed {
113+
return fmt.Errorf("sensor %s has been previously destroyed, please recreate it before loading", s.Name)
114+
}
115+
116+
logger.GetLogger().WithField("metadata", getCachedBTFFile()).Info("BTF file: using metadata file")
117+
if _, err = observerMinReqs(); err != nil {
118+
return fmt.Errorf("tetragon, aborting minimum requirements not met: %w", err)
119+
}
120+
121+
var (
122+
loadedMaps []*program.Map
123+
loadedProgs []*program.Program
124+
)
125+
126+
s.createDirs(bpfDir)
127+
defer func() {
128+
if err != nil {
129+
for _, m := range loadedMaps {
130+
m.Unload(true)
131+
}
132+
for _, p := range loadedProgs {
133+
unloadProgram(p, true)
134+
}
135+
s.removeDirs()
136+
}
137+
}()
138+
139+
l := logger.GetLogger()
140+
141+
l.WithField("name", s.Name).Info("Loading sensor")
142+
if s.Loaded {
143+
return fmt.Errorf("loading sensor %s failed: sensor already loaded", s.Name)
144+
}
145+
146+
_, verStr, _ := kernels.GetKernelVersion(option.Config.KernelVersion, option.Config.ProcFS)
147+
l.Infof("Loading kernel version %s", verStr)
148+
149+
if err = s.FindPrograms(); err != nil {
150+
return fmt.Errorf("tetragon, aborting could not find BPF programs: %w", err)
151+
}
152+
if loadedMaps, err = s.preLoadMaps(bpfDir, loadedMaps); err != nil {
153+
return err
154+
}
155+
for _, p := range s.Progs {
156+
if p.LoadState.IsLoaded() {
157+
l.WithField("prog", p.Name).Info("BPF prog is already loaded, incrementing reference count")
158+
p.LoadState.RefInc()
159+
continue
160+
}
161+
162+
if err = observerLoadInstance(bpfDir, p, s.Maps); err != nil {
163+
return err
164+
}
165+
p.LoadState.RefInc()
166+
loadedProgs = append(loadedProgs, p)
167+
l.WithField("prog", p.Name).WithField("label", p.Label).Debugf("BPF prog was loaded")
168+
}
169+
170+
// Add the *loaded* programs and maps, so they can be unloaded later
171+
progsAdd(s.Progs)
172+
AllMaps = append(AllMaps, s.Maps...)
173+
174+
if s.PostLoadHook != nil {
175+
if err := s.PostLoadHook(); err != nil {
176+
logger.GetLogger().WithError(err).WithField("sensor", s.Name).Warn("Post load hook failed")
177+
}
178+
}
179+
180+
// cleanup the BTF once we have loaded all sensor's program
181+
flushKernelSpec()
182+
183+
l.WithFields(logrus.Fields{
184+
"sensor": s.Name,
185+
"maps": loadedMaps,
186+
"progs": loadedProgs,
187+
}).Infof("Loaded BPF maps and events for sensor successfully")
188+
s.Loaded = true
189+
return nil
190+
}
191+
105192
func (s *Sensor) Unload(unpin bool) error {
106193
logger.GetLogger().Infof("Unloading sensor %s", s.Name)
107194
if !s.Loaded {

pkg/sensors/load_linux.go

Lines changed: 18 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -17,97 +17,6 @@ import (
1717
"github.com/sirupsen/logrus"
1818
)
1919

20-
// Load loads the sensor, by loading all the BPF programs and maps.
21-
func (s *Sensor) Load(bpfDir string) (err error) {
22-
if s == nil {
23-
return nil
24-
}
25-
26-
if s.Destroyed {
27-
return fmt.Errorf("sensor %s has been previously destroyed, please recreate it before loading", s.Name)
28-
}
29-
30-
logger.GetLogger().WithField("metadata", cachedbtf.GetCachedBTFFile()).Info("BTF file: using metadata file")
31-
if _, err = observerMinReqs(); err != nil {
32-
return fmt.Errorf("tetragon, aborting minimum requirements not met: %w", err)
33-
}
34-
35-
var (
36-
loadedMaps []*program.Map
37-
loadedProgs []*program.Program
38-
)
39-
40-
s.createDirs(bpfDir)
41-
defer func() {
42-
if err != nil {
43-
for _, m := range loadedMaps {
44-
m.Unload(true)
45-
}
46-
for _, p := range loadedProgs {
47-
unloadProgram(p, true)
48-
}
49-
s.removeDirs()
50-
}
51-
}()
52-
53-
l := logger.GetLogger()
54-
55-
l.WithField("name", s.Name).Info("Loading sensor")
56-
if s.Loaded {
57-
return fmt.Errorf("loading sensor %s failed: sensor already loaded", s.Name)
58-
}
59-
60-
_, verStr, _ := kernels.GetKernelVersion(option.Config.KernelVersion, option.Config.ProcFS)
61-
l.Infof("Loading kernel version %s", verStr)
62-
63-
if err = s.FindPrograms(); err != nil {
64-
return fmt.Errorf("tetragon, aborting could not find BPF programs: %w", err)
65-
}
66-
67-
for _, m := range s.Maps {
68-
if err = s.loadMap(bpfDir, m); err != nil {
69-
return fmt.Errorf("tetragon, aborting could not load sensor BPF maps: %w", err)
70-
}
71-
loadedMaps = append(loadedMaps, m)
72-
}
73-
74-
for _, p := range s.Progs {
75-
if p.LoadState.IsLoaded() {
76-
l.WithField("prog", p.Name).Info("BPF prog is already loaded, incrementing reference count")
77-
p.LoadState.RefInc()
78-
continue
79-
}
80-
81-
if err = observerLoadInstance(bpfDir, p, s.Maps); err != nil {
82-
return err
83-
}
84-
p.LoadState.RefInc()
85-
loadedProgs = append(loadedProgs, p)
86-
l.WithField("prog", p.Name).WithField("label", p.Label).Debugf("BPF prog was loaded")
87-
}
88-
89-
// Add the *loaded* programs and maps, so they can be unloaded later
90-
progsAdd(s.Progs)
91-
AllMaps = append(AllMaps, s.Maps...)
92-
93-
if s.PostLoadHook != nil {
94-
if err := s.PostLoadHook(); err != nil {
95-
logger.GetLogger().WithError(err).WithField("sensor", s.Name).Warn("Post load hook failed")
96-
}
97-
}
98-
99-
// cleanup the BTF once we have loaded all sensor's program
100-
btf.FlushKernelSpec()
101-
102-
l.WithFields(logrus.Fields{
103-
"sensor": s.Name,
104-
"maps": loadedMaps,
105-
"progs": loadedProgs,
106-
}).Infof("Loaded BPF maps and events for sensor successfully")
107-
s.Loaded = true
108-
return nil
109-
}
110-
11120
func (s *Sensor) setMapPinPath(m *program.Map) {
11221
policy := s.policyDir()
11322
switch m.Type {
@@ -122,6 +31,16 @@ func (s *Sensor) setMapPinPath(m *program.Map) {
12231
}
12332
}
12433

34+
func (s *Sensor) preLoadMaps(bpfDir string, loadedMaps []*program.Map) ([]*program.Map, error) {
35+
for _, m := range s.Maps {
36+
if err := s.loadMap(bpfDir, m); err != nil {
37+
return loadedMaps, fmt.Errorf("tetragon, aborting could not load sensor BPF maps: %w", err)
38+
}
39+
loadedMaps = append(loadedMaps, m)
40+
}
41+
return loadedMaps, nil
42+
}
43+
12544
// loadMap loads BPF map in the sensor.
12645
func (s *Sensor) loadMap(bpfDir string, m *program.Map) error {
12746
l := logger.GetLogger()
@@ -282,3 +201,11 @@ func observerMinReqs() (bool, error) {
282201
}
283202
return true, nil
284203
}
204+
205+
func flushKernelSpec() {
206+
btf.FlushKernelSpec()
207+
}
208+
209+
func getCachedBTFFile() string {
210+
return cachedbtf.GetCachedBTFFile()
211+
}

0 commit comments

Comments
 (0)