github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/cmd/agent/daemon/enrichment/enrichers_test.go (about) 1 package enrichment 2 3 import ( 4 "context" 5 "crypto/rand" 6 "crypto/sha256" 7 "path/filepath" 8 "strconv" 9 "testing" 10 "testing/fstest" 11 "time" 12 13 castpb "github.com/castai/kvisor/api/v1/runtime" 14 "github.com/castai/kvisor/pkg/ebpftracer/types" 15 "github.com/castai/kvisor/pkg/logging" 16 "github.com/castai/kvisor/pkg/proc" 17 "github.com/stretchr/testify/require" 18 ) 19 20 func TestFileHashEnricher(t *testing.T) { 21 t.Run("should set sha256 hash of file", func(t *testing.T) { 22 r := require.New(t) 23 containerID := "12354" 24 fileName := "test" 25 pid := uint32(22) 26 testFile := generateExecutableTestMapFile(2048) 27 wantedSum := sha256.Sum256(testFile.Data) 28 fsys := fstest.MapFS{ 29 filepath.Join(strconv.Itoa(int(pid)), "root", fileName): testFile, 30 } 31 32 enricher := EnrichWithFileHash( 33 logging.New(&logging.Config{}), 34 createDummyMntNSPIDStore(0, 10), 35 fsys) 36 37 event := &castpb.Event{ 38 EventType: castpb.EventType_EVENT_EXEC, 39 ContainerId: containerID, 40 Data: &castpb.Event_Exec{ 41 Exec: &castpb.Exec{ 42 Path: filepath.Join(fileName), 43 Args: []string{}, 44 }, 45 }, 46 } 47 48 enricher.Enrich(context.TODO(), &EnrichRequest{ 49 Event: event, 50 EbpfEvent: &types.Event{ 51 Context: &types.EventContext{ 52 NodeHostPid: pid, 53 }, 54 Args: types.SchedProcessExecArgs{}, 55 }, 56 }) 57 58 r.Equal(wantedSum[:], event.GetExec().GetMeta().GetHashSha256()) 59 }) 60 61 t.Run("should ignore missing file", func(t *testing.T) { 62 r := require.New(t) 63 containerID := "12354" 64 fileName := "test" 65 fsys := fstest.MapFS{} 66 67 enricher := EnrichWithFileHash(logging.New(&logging.Config{}), 68 createDummyMntNSPIDStore(0, 1), 69 fsys) 70 71 event := &castpb.Event{ 72 EventType: castpb.EventType_EVENT_EXEC, 73 ContainerId: containerID, 74 Data: &castpb.Event_Exec{ 75 Exec: &castpb.Exec{ 76 Path: filepath.Join(fileName), 77 Args: []string{}, 78 }, 79 }, 80 } 81 82 enricher.Enrich(context.TODO(), &EnrichRequest{ 83 Event: event, 84 EbpfEvent: &types.Event{ 85 Context: &types.EventContext{}, 86 Args: types.SchedProcessExecArgs{}, 87 }, 88 }) 89 90 r.Nil(event.GetExec().Meta) 91 }) 92 93 t.Run("should ignore non exec event", func(t *testing.T) { 94 r := require.New(t) 95 containerID := "12354" 96 fsys := fstest.MapFS{} 97 98 enricher := EnrichWithFileHash(logging.New(&logging.Config{}), 99 createDummyMntNSPIDStore(0, 1), 100 fsys) 101 102 event := &castpb.Event{ 103 EventType: castpb.EventType_EVENT_DNS, 104 ContainerId: containerID, 105 } 106 107 enricher.Enrich(context.TODO(), &EnrichRequest{ 108 Event: event, 109 EbpfEvent: &types.Event{ 110 Context: &types.EventContext{}, 111 Args: types.SchedProcessExecArgs{}, 112 }, 113 }) 114 115 r.Nil(event.GetExec()) 116 }) 117 118 t.Run("should set sha256 hash of file for two same events", func(t *testing.T) { 119 r := require.New(t) 120 containerID := "12354" 121 fileName := "test" 122 pid := proc.PID(22) 123 testFile := generateExecutableTestMapFile(2048) 124 wantedSum := sha256.Sum256(testFile.Data) 125 fsys := fstest.MapFS{ 126 filepath.Join(strconv.Itoa(int(pid)), "root", fileName): testFile, 127 } 128 129 enricher := EnrichWithFileHash( 130 logging.New(&logging.Config{}), 131 createDummyMntNSPIDStore(0, pid), 132 fsys) 133 134 event := &castpb.Event{ 135 EventType: castpb.EventType_EVENT_EXEC, 136 ContainerId: containerID, 137 Data: &castpb.Event_Exec{ 138 Exec: &castpb.Exec{ 139 Path: filepath.Join(fileName), 140 Args: []string{}, 141 }, 142 }, 143 } 144 145 enricher.Enrich(context.TODO(), &EnrichRequest{ 146 Event: event, 147 EbpfEvent: &types.Event{ 148 Context: &types.EventContext{ 149 NodeHostPid: pid, 150 }, 151 Args: types.SchedProcessExecArgs{}, 152 }, 153 }) 154 155 r.Equal(wantedSum[:], event.GetExec().GetMeta().GetHashSha256()) 156 157 event = &castpb.Event{ 158 EventType: castpb.EventType_EVENT_EXEC, 159 ContainerId: containerID, 160 Data: &castpb.Event_Exec{ 161 Exec: &castpb.Exec{ 162 Path: filepath.Join(fileName), 163 Args: []string{}, 164 }, 165 }, 166 } 167 168 enricher.Enrich(context.TODO(), &EnrichRequest{ 169 Event: event, 170 EbpfEvent: &types.Event{ 171 Context: &types.EventContext{ 172 NodeHostPid: pid, 173 }, 174 Args: types.SchedProcessExecArgs{}, 175 }, 176 }) 177 178 r.Equal(wantedSum[:], event.GetExec().GetMeta().GetHashSha256()) 179 }) 180 181 t.Run("should fallback to other pids in mount ns if file is missing", func(t *testing.T) { 182 r := require.New(t) 183 containerID := "12354" 184 fileName := "test" 185 pid := proc.PID(22) 186 mountNSID := proc.NamespaceID(10) 187 testFile := generateExecutableTestMapFile(2048) 188 wantedSum := sha256.Sum256(testFile.Data) 189 fsys := fstest.MapFS{ 190 filepath.Join(strconv.Itoa(int(pid)), "root", fileName): testFile, 191 } 192 193 enricher := EnrichWithFileHash( 194 logging.New(&logging.Config{}), 195 createDummyMntNSPIDStore(mountNSID, pid), 196 fsys) 197 198 event := &castpb.Event{ 199 EventType: castpb.EventType_EVENT_EXEC, 200 ContainerId: containerID, 201 Data: &castpb.Event_Exec{ 202 Exec: &castpb.Exec{ 203 Path: filepath.Join(fileName), 204 Args: []string{}, 205 }, 206 }, 207 } 208 209 enricher.Enrich(context.TODO(), &EnrichRequest{ 210 Event: event, 211 EbpfEvent: &types.Event{ 212 Context: &types.EventContext{ 213 MntID: uint32(mountNSID), 214 }, 215 Args: types.SchedProcessExecArgs{}, 216 }, 217 }) 218 219 r.Equal(wantedSum[:], event.GetExec().GetMeta().GetHashSha256()) 220 }) 221 } 222 223 func generateTestData(size uint32) []byte { 224 result := make([]byte, size) 225 rand.Read(result) 226 return result 227 } 228 229 func generateExecutableTestMapFile(size uint32) *fstest.MapFile { 230 return &fstest.MapFile{ 231 Data: generateTestData(size), 232 Mode: 0777, 233 ModTime: time.Now(), 234 } 235 } 236 237 func createDummyMntNSPIDStore(ns proc.NamespaceID, pids ...proc.PID) *types.PIDsPerNamespace { 238 b, err := types.NewPIDsPerNamespaceCache(10, 5) 239 if err != nil { 240 panic(err) 241 } 242 243 for _, pid := range pids { 244 b.AddToBucket(ns, pid) 245 } 246 247 return b 248 }