...
1
16
17 package v2
18
19 import (
20 "fmt"
21
22 "github.com/cilium/ebpf"
23 "github.com/cilium/ebpf/asm"
24 "github.com/cilium/ebpf/link"
25 "github.com/opencontainers/runtime-spec/specs-go"
26 "golang.org/x/sys/unix"
27 )
28
29
30
31
32
33
34 func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD int) (func() error, error) {
35 nilCloser := func() error {
36 return nil
37 }
38 spec := &ebpf.ProgramSpec{
39 Type: ebpf.CGroupDevice,
40 Instructions: insts,
41 License: license,
42 }
43 prog, err := ebpf.NewProgram(spec)
44 if err != nil {
45 return nilCloser, err
46 }
47 err = link.RawAttachProgram(link.RawAttachProgramOptions{
48 Target: dirFD,
49 Program: prog,
50 Attach: ebpf.AttachCGroupDevice,
51 Flags: unix.BPF_F_ALLOW_MULTI,
52 })
53 if err != nil {
54 return nilCloser, fmt.Errorf("failed to call BPF_PROG_ATTACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI): %w", err)
55 }
56 closer := func() error {
57 err = link.RawDetachProgram(link.RawDetachProgramOptions{
58 Target: dirFD,
59 Program: prog,
60 Attach: ebpf.AttachCGroupDevice,
61 })
62 if err != nil {
63 return fmt.Errorf("failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE): %w", err)
64 }
65 return nil
66 }
67 return closer, nil
68 }
69
70 func isRWM(cgroupPermissions string) bool {
71 r := false
72 w := false
73 m := false
74 for _, rn := range cgroupPermissions {
75 switch rn {
76 case 'r':
77 r = true
78 case 'w':
79 w = true
80 case 'm':
81 m = true
82 }
83 }
84 return r && w && m
85 }
86
87
88
89 func canSkipEBPFError(devices []specs.LinuxDeviceCgroup) bool {
90 for _, dev := range devices {
91 if dev.Allow || !isRWM(dev.Access) {
92 return false
93 }
94 }
95 return true
96 }
97
View as plain text