From 5caf3e1ed0f17fcf83abe57edbdcac11addda85a Mon Sep 17 00:00:00 2001 From: Sylvain Afchain Date: Tue, 26 Nov 2024 12:34:50 +0100 Subject: [PATCH] [CWS] add a bypass if raw packet disabled or no rules (#31438) --- .../ebpf/c/include/hooks/network/tc.h | 13 +++++++++ pkg/security/ebpf/c/include/maps.h | 1 + pkg/security/probe/probe_ebpf.go | 29 +++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/pkg/security/ebpf/c/include/hooks/network/tc.h b/pkg/security/ebpf/c/include/hooks/network/tc.h index 1ed6bdd8d0c66..8445905aa3ccf 100644 --- a/pkg/security/ebpf/c/include/hooks/network/tc.h +++ b/pkg/security/ebpf/c/include/hooks/network/tc.h @@ -52,9 +52,18 @@ __attribute__((always_inline)) int prepare_raw_packet_event(struct __sk_buff *sk return ACT_OK; } +__attribute__((always_inline)) int is_raw_packet_enabled() { + u32 key = 0; + u32 *enabled = bpf_map_lookup_elem(&raw_packet_enabled, &key); + return enabled && *enabled; +} SEC("classifier/ingress") int classifier_raw_packet_ingress(struct __sk_buff *skb) { + if (!is_raw_packet_enabled()) { + return ACT_OK; + } + struct packet_t *pkt = parse_packet(skb, INGRESS); if (!pkt) { return ACT_OK; @@ -76,6 +85,10 @@ int classifier_raw_packet_ingress(struct __sk_buff *skb) { SEC("classifier/egress") int classifier_raw_packet_egress(struct __sk_buff *skb) { + if (!is_raw_packet_enabled()) { + return ACT_OK; + } + struct packet_t *pkt = parse_packet(skb, EGRESS); if (!pkt) { return ACT_OK; diff --git a/pkg/security/ebpf/c/include/maps.h b/pkg/security/ebpf/c/include/maps.h index c5050fd5545c7..2019c630c6f4c 100644 --- a/pkg/security/ebpf/c/include/maps.h +++ b/pkg/security/ebpf/c/include/maps.h @@ -89,6 +89,7 @@ BPF_PERCPU_ARRAY_MAP(selinux_write_buffer, struct selinux_write_buffer_t, 1) BPF_PERCPU_ARRAY_MAP(is_new_kthread, u32, 1) BPF_PERCPU_ARRAY_MAP(syscalls_stats, struct syscalls_stats_t, EVENT_MAX) BPF_PERCPU_ARRAY_MAP(raw_packet_event, struct raw_packet_event_t, 1) +BPF_PERCPU_ARRAY_MAP(raw_packet_enabled, u32, 1) BPF_PROG_ARRAY(args_envs_progs, 3) BPF_PROG_ARRAY(dentry_resolver_kprobe_or_fentry_callbacks, EVENT_MAX) diff --git a/pkg/security/probe/probe_ebpf.go b/pkg/security/probe/probe_ebpf.go index bd73d1b34e4a0..81d5f6cb01154 100644 --- a/pkg/security/probe/probe_ebpf.go +++ b/pkg/security/probe/probe_ebpf.go @@ -115,6 +115,7 @@ type EBPFProbe struct { profileManagers *SecurityProfileManagers fieldHandlers *EBPFFieldHandlers eventPool *ddsync.TypedPool[model.Event] + numCPU int ctx context.Context cancelFnc context.CancelFunc @@ -384,6 +385,14 @@ func (p *EBPFProbe) setupRawPacketProgs(rs *rules.RuleSet) error { return errors.New("unable to find `classifier_router` map") } + enabledMap, _, err := p.Manager.GetMap("raw_packet_enabled") + if err != nil { + return err + } + if enabledMap == nil { + return errors.New("unable to find `raw_packet_enabled` map") + } + var rawPacketFilters []rawpacket.Filter for id, rule := range rs.GetRules() { for _, field := range rule.GetFieldValues("packet.filter") { @@ -394,12 +403,28 @@ func (p *EBPFProbe) setupRawPacketProgs(rs *rules.RuleSet) error { } } + // enable raw packet or not + enabled := make([]uint32, p.numCPU) + if len(rawPacketFilters) > 0 { + for i := range enabled { + enabled[i] = 1 + } + } + if err = enabledMap.Put(uint32(0), enabled); err != nil { + seclog.Errorf("couldn't push raw_packet_enabled entry to kernel space: %s", err) + } + // unload the previews one if p.rawPacketFilterCollection != nil { p.rawPacketFilterCollection.Close() ddebpf.RemoveNameMappingsCollection(p.rawPacketFilterCollection) } + // not enabled + if enabled[0] == 0 { + return nil + } + // adapt max instruction limits depending of the kernel version opts := rawpacket.DefaultProgOpts if p.kernelVersion.Code >= kernel.Kernel5_2 { @@ -1894,12 +1919,12 @@ func NewEBPFProbe(probe *Probe, config *config.Config, opts Opts, telemetry tele p.monitors = NewEBPFMonitors(p) - numCPU, err := utils.NumCPU() + p.numCPU, err = utils.NumCPU() if err != nil { return nil, fmt.Errorf("failed to parse CPU count: %w", err) } - p.managerOptions.MapSpecEditors = probes.AllMapSpecEditors(numCPU, probes.MapSpecEditorOpts{ + p.managerOptions.MapSpecEditors = probes.AllMapSpecEditors(p.numCPU, probes.MapSpecEditorOpts{ TracedCgroupSize: config.RuntimeSecurity.ActivityDumpTracedCgroupsCount, UseRingBuffers: useRingBuffers, UseMmapableMaps: useMmapableMaps,