Skip to content

Commit 50e74e1

Browse files
Perf(BPF): Switched from udp_sendmsg to udp_send_skb for DNS visibility (#2738)
* add udp_send_skb, deprecate udp_sendmsg Signed-off-by: Achref Ben Saad <achref9612@gmail.com> * resolve udphdr sizeof issue Signed-off-by: Achref Ben Saad <achref9612@gmail.com> * update go to 1.26.5 Signed-off-by: Achref Ben Saad <achref9612@gmail.com> --------- Signed-off-by: Achref Ben Saad <achref9612@gmail.com>
1 parent 7488b3a commit 50e74e1

16 files changed

Lines changed: 108 additions & 23 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
### Builder
55

6-
FROM golang:1.26-alpine3.22@sha256:457d8584db11412777c4196146b8060fdaabe0b0ba7b62c553d08e07d8c22bd3 AS builder
6+
FROM golang:1.26-alpine3.22@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder
77

88
RUN apk --no-cache update && apk upgrade --no-cache libcrypto3 libssl3 zlib libexpat
99
RUN apk add --no-cache git clang llvm make gcc protobuf protobuf-dev curl elfutils-dev

KubeArmor/BPF/system_monitor.c

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ enum
205205
_TCP_ACCEPT_v6 = 403,
206206

207207
// UDP_MSG
208-
_UDP_SENDMSG = 10000
208+
_UDP_SENDMSG = 10000,
209+
_UDP_SEND_SKB = 10001
209210
};
210211

211212
// forward declartaion for CWD
@@ -2529,6 +2530,83 @@ int kretprobe__inet_csk_accept(struct pt_regs *ctx)
25292530
return 0;
25302531
}
25312532

2533+
2534+
#define UDPHDR_LEN 8
2535+
2536+
SEC("kprobe/udp_send_skb")
2537+
int kprobe__udp_send_skb(struct pt_regs *ctx){
2538+
2539+
if (skip_syscall())
2540+
return 0;
2541+
2542+
if (get_kubearmor_config(_ENFORCER_BPFLSM) && drop_syscall(_DNS_PROBE))
2543+
return 0;
2544+
2545+
struct sk_buff *skb = (struct sk_buff *)PT_REGS_PARM1(ctx);
2546+
struct flowi4 *fl4 = (struct flowi4 *)PT_REGS_PARM2(ctx);
2547+
if (skb == NULL || fl4 == NULL)
2548+
return 0;
2549+
2550+
struct sock *sk = NULL;
2551+
bpf_probe_read(&sk, sizeof(sk), &skb->sk);
2552+
if (sk == NULL)
2553+
return 0;
2554+
2555+
__u16 dport = 0;
2556+
bpf_probe_read(&dport, sizeof(dport), &fl4->uli.ports.dport);
2557+
dport = ntohs(dport);
2558+
if (dport != 53)
2559+
return 0;
2560+
2561+
__u32 skb_len = 0;
2562+
bpf_probe_read(&skb_len, sizeof(skb_len), &skb->len);
2563+
if (skb_len > 512 + UDPHDR_LEN) // MAX_DNS_SIZE + udp header
2564+
return 0;
2565+
2566+
unsigned char *head = NULL;
2567+
__u16 trans_off = 0;
2568+
bpf_probe_read(&head, sizeof(head), &skb->head);
2569+
bpf_probe_read(&trans_off, sizeof(trans_off), &skb->transport_header);
2570+
void *data = head + trans_off + UDPHDR_LEN;
2571+
2572+
sys_context_t context = {};
2573+
args_t args = {};
2574+
u64 types = 0;
2575+
init_context(&context);
2576+
context.argnum = 3;
2577+
context.retval = 0;
2578+
context.event_id = _UDP_SEND_SKB;
2579+
2580+
if (context.retval >= 0 && drop_syscall(_DNS_PROBE))
2581+
return 0;
2582+
2583+
if (context.retval < 0 && !get_kubearmor_config(_ENFORCER_BPFLSM) &&
2584+
get_kubearmor_config(_ALERT_THROTTLING) &&
2585+
should_drop_alerts_per_container(&context, ctx, types, &args))
2586+
return 0;
2587+
2588+
set_buffer_offset(DNS_BUF_TYPE, sizeof(sys_context_t));
2589+
bufs_t *bufs_p = get_buffer(DNS_BUF_TYPE);
2590+
if (bufs_p == NULL)
2591+
return 0;
2592+
save_context_to_buffer(bufs_p, (void *)&context);
2593+
2594+
2595+
struct sock_common conn = READ_KERN(sk->__sk_common);
2596+
struct sockaddr_in sockv4 = {};
2597+
sockv4.sin_family = conn.skc_family;
2598+
bpf_probe_read(&sockv4.sin_addr.s_addr, sizeof(sockv4.sin_addr.s_addr), &fl4->daddr);
2599+
sockv4.sin_port = dport;
2600+
2601+
save_to_buffer(bufs_p, DNS_BUF_TYPE, (void *)&sockv4, sizeof(struct sockaddr_in), SOCKADDR_T);
2602+
save_dns_data_to_dns_buffer(bufs_p, data, UDP_MSG);
2603+
events_perf_submit(ctx, DNS_BUF_TYPE);
2604+
return 0;
2605+
}
2606+
2607+
// This probe is currently not attached by the system monitor.
2608+
// The decision to disable attaching this probe was taken for performance reasons.
2609+
25322610
SEC("kprobe/udp_sendmsg")
25332611
int kprobe__udp_sendmsg(struct pt_regs *ctx)
25342612
{

KubeArmor/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/kubearmor/KubeArmor/KubeArmor
22

3-
go 1.26.4
3+
go 1.26.5
44

55
replace (
66
github.com/kubearmor/KubeArmor => ../../

KubeArmor/monitor/logUpdate.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ func (mon *SystemMonitor) UpdateLogs() {
521521
log.Resource = ""
522522
log.Data = "syscall=" + GetSyscallName(int32(msg.ContextSys.EventID)) + " fd=" + fd
523523

524-
case UDPSendMsg:
524+
case UDPSendMsg, UDPSendSkb:
525525
if len(msg.ContextArgs) != 3 {
526526
continue
527527
}
@@ -542,8 +542,13 @@ func (mon *SystemMonitor) UpdateLogs() {
542542
qtype = "AAAA"
543543
}
544544
}
545+
kfunc := "kfunc=UDP_SENDSKB"
546+
// UDPSendMsg is disabled.
547+
if msg.ContextSys.EventID == UDPSendMsg {
548+
kfunc = "kfunc=UDP_SENDMSG"
545549

546-
log.Data = "kfunc=UDP_SENDMSG" + " domain=" + domains[:len(domains)-1] + // removed trailing . from domain name
550+
}
551+
log.Data = kfunc + " domain=" + domains[:len(domains)-1] + // removed trailing . from domain name
547552
" daddr=" + sockAddr["sin_addr"] +
548553
" qtype=" + qtype
549554
log.Operation = "Network"

KubeArmor/monitor/syscalls_amd64.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const (
6565
DropAlert = 0
6666

6767
UDPSendMsg = 10000
68+
UDPSendSkb = 10001
6869

6970
SocketSendMsg = 465
7071
)

KubeArmor/monitor/syscalls_arm64.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const (
6767
DropAlert = 0
6868

6969
UDPSendMsg = 10000
70+
UDPSendSkb = 10001
7071

7172
SocketSendMsg = 465
7273
)

KubeArmor/monitor/systemMonitor.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -593,10 +593,10 @@ func (mon *SystemMonitor) InitBPF() error {
593593

594594
mon.Probes = make(map[string]link.Link)
595595

596-
mon.Probes["kprobe__udp_sendmsg"], err = link.Kprobe("udp_sendmsg", mon.BpfModule.Programs["kprobe__udp_sendmsg"], nil)
596+
mon.Probes["kprobe__udp_send_skb"], err = link.Kprobe("udp_send_skb", mon.BpfModule.Programs["kprobe__udp_send_skb"], nil)
597597
if err != nil {
598-
mon.Logger.Warnf("error loading kprobe udp_sendmsg %v", err)
599-
delete(mon.Probes, "kprobe__udp_sendmsg")
598+
mon.Logger.Warnf("error loading kprobe udp_send_skb %v", err)
599+
delete(mon.Probes, "kprobe__udp_send_skb")
600600
}
601601

602602
for _, syscallName := range systemCalls {
@@ -1148,7 +1148,7 @@ func (mon *SystemMonitor) TraceSyscall() {
11481148
if len(args) != 2 {
11491149
continue
11501150
}
1151-
} else if ctx.EventID == UDPSendMsg {
1151+
} else if ctx.EventID == UDPSendMsg || ctx.EventID == UDPSendSkb {
11521152
if len(args) != 3 {
11531153
continue
11541154
}

deployments/go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/kubearmor/KubeArmor/deployments
22

3-
go 1.26.4
3+
go 1.26.5
44

55
replace (
66
github.com/kubearmor/KubeArmor => ../
@@ -38,8 +38,8 @@ require (
3838
go.yaml.in/yaml/v2 v2.4.4 // indirect
3939
go.yaml.in/yaml/v3 v3.0.4 // indirect
4040
golang.org/x/net v0.55.0 // indirect
41-
golang.org/x/sys v0.45.0 // indirect
42-
golang.org/x/text v0.37.0 // indirect
41+
golang.org/x/sys v0.46.0 // indirect
42+
golang.org/x/text v0.38.0 // indirect
4343
gopkg.in/inf.v0 v0.9.1 // indirect
4444
k8s.io/apiextensions-apiserver v0.36.1 // indirect
4545
k8s.io/klog/v2 v2.140.0 // indirect

deployments/go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
6666
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
6767
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
6868
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
69-
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
70-
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
71-
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
72-
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
69+
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
70+
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
71+
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
72+
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
7373
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
7474
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
7575
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

deployments/podman/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/kubearmor/KubeArmor/deployments/podman
22

3-
go 1.26.4
3+
go 1.26.5
44

55
require (
66
github.com/kubearmor/KubeArmor/KubeArmor v0.0.0-20260521154542-6789b83a8cee

0 commit comments

Comments
 (0)