6
6
"fmt"
7
7
"regexp"
8
8
"runtime"
9
+ "slices"
9
10
"strings"
10
11
"time"
11
12
@@ -53,10 +54,12 @@ type ApplicationProfileManager struct {
53
54
savedExecs maps.SafeMap [string , cache.ExpiringCache ] // key is k8sContainerID
54
55
savedOpens maps.SafeMap [string , cache.ExpiringCache ] // key is k8sContainerID
55
56
savedSyscalls maps.SafeMap [string , mapset.Set [string ]] // key is k8sContainerID
57
+ savedRulePolicies maps.SafeMap [string , cache.ExpiringCache ] // key is k8sContainerID
56
58
toSaveCapabilities maps.SafeMap [string , mapset.Set [string ]] // key is k8sContainerID
57
59
toSaveEndpoints maps.SafeMap [string , * maps.SafeMap [string , * v1beta1.HTTPEndpoint ]] // key is k8sContainerID
58
60
toSaveExecs maps.SafeMap [string , * maps.SafeMap [string , []string ]] // key is k8sContainerID
59
61
toSaveOpens maps.SafeMap [string , * maps.SafeMap [string , mapset.Set [string ]]] // key is k8sContainerID
62
+ toSaveRulePolicies maps.SafeMap [string , * maps.SafeMap [string , * v1beta1.RulePolicy ]] // key is k8sContainerID
60
63
watchedContainerChannels maps.SafeMap [string , chan error ] // key is ContainerID
61
64
k8sClient k8sclient.K8sClientInterface
62
65
k8sObjectCache objectcache.K8sObjectCache
@@ -146,10 +149,12 @@ func (am *ApplicationProfileManager) deleteResources(watchedContainer *utils.Wat
146
149
am .savedExecs .Delete (watchedContainer .K8sContainerID )
147
150
am .savedOpens .Delete (watchedContainer .K8sContainerID )
148
151
am .savedSyscalls .Delete (watchedContainer .K8sContainerID )
152
+ am .savedRulePolicies .Delete (watchedContainer .K8sContainerID )
149
153
am .toSaveCapabilities .Delete (watchedContainer .K8sContainerID )
150
154
am .toSaveEndpoints .Delete (watchedContainer .K8sContainerID )
151
155
am .toSaveExecs .Delete (watchedContainer .K8sContainerID )
152
156
am .toSaveOpens .Delete (watchedContainer .K8sContainerID )
157
+ am .toSaveRulePolicies .Delete (watchedContainer .K8sContainerID )
153
158
am .watchedContainerChannels .Delete (watchedContainer .ContainerID )
154
159
}
155
160
@@ -173,7 +178,8 @@ func (am *ApplicationProfileManager) monitorContainer(ctx context.Context, conta
173
178
watchedContainer .SetCompletionStatus (utils .WatchedContainerCompletionStatusFull )
174
179
}
175
180
watchedContainer .SetStatus (utils .WatchedContainerStatusInitializing )
176
- am .saveProfile (ctx , watchedContainer , container .K8s .Namespace )
181
+
182
+ initOps := GetInitOperations (watchedContainer .ContainerType .String (), watchedContainer .ContainerIndex )
177
183
178
184
for {
179
185
select {
@@ -184,20 +190,26 @@ func (am *ApplicationProfileManager) monitorContainer(ctx context.Context, conta
184
190
watchedContainer .UpdateDataTicker .Reset (utils .AddJitter (am .cfg .UpdateDataPeriod , am .cfg .MaxJitterPercentage ))
185
191
}
186
192
watchedContainer .SetStatus (utils .WatchedContainerStatusReady )
187
- am .saveProfile (ctx , watchedContainer , container .K8s .Namespace )
193
+ am .saveProfile (ctx , watchedContainer , container .K8s .Namespace , nil )
194
+
195
+ // save profile after initialaztion
196
+ if initOps != nil {
197
+ am .saveProfile (ctx , watchedContainer , container .K8s .Namespace , initOps )
198
+ initOps = nil
199
+ }
200
+
188
201
case err := <- watchedContainer .SyncChannel :
189
202
switch {
190
203
case errors .Is (err , utils .ContainerHasTerminatedError ):
191
204
// if exit code is 0 we set the status to completed
192
205
if objectcache .GetTerminationExitCode (am .k8sObjectCache , container .K8s .Namespace , container .K8s .PodName , container .K8s .ContainerName , container .Runtime .ContainerID ) == 0 {
193
206
watchedContainer .SetStatus (utils .WatchedContainerStatusCompleted )
194
207
}
195
-
196
- am .saveProfile (ctx , watchedContainer , container .K8s .Namespace )
208
+ am .saveProfile (ctx , watchedContainer , container .K8s .Namespace , nil )
197
209
return err
198
210
case errors .Is (err , utils .ContainerReachedMaxTime ):
199
211
watchedContainer .SetStatus (utils .WatchedContainerStatusCompleted )
200
- am .saveProfile (ctx , watchedContainer , container .K8s .Namespace )
212
+ am .saveProfile (ctx , watchedContainer , container .K8s .Namespace , nil )
201
213
return err
202
214
case errors .Is (err , utils .ObjectCompleted ):
203
215
watchedContainer .SetStatus (utils .WatchedContainerStatusCompleted )
@@ -211,7 +223,7 @@ func (am *ApplicationProfileManager) monitorContainer(ctx context.Context, conta
211
223
}
212
224
}
213
225
214
- func (am * ApplicationProfileManager ) saveProfile (ctx context.Context , watchedContainer * utils.WatchedContainerData , namespace string ) {
226
+ func (am * ApplicationProfileManager ) saveProfile (ctx context.Context , watchedContainer * utils.WatchedContainerData , namespace string , initalizeOperations []utils. PatchOperation ) {
215
227
ctx , span := otel .Tracer ("" ).Start (ctx , "ApplicationProfileManager.saveProfile" )
216
228
defer span .End ()
217
229
@@ -314,6 +326,18 @@ func (am *ApplicationProfileManager) saveProfile(ctx context.Context, watchedCon
314
326
opens [path ].Append (open .ToSlice ()... )
315
327
return true
316
328
})
329
+
330
+ // get rule policies
331
+ rulePolicies := make (map [string ]v1beta1.RulePolicy )
332
+ toSaveRulePolicies := am .toSaveRulePolicies .Get (watchedContainer .K8sContainerID )
333
+ // point IG to a new rule policies map
334
+ am .toSaveRulePolicies .Set (watchedContainer .K8sContainerID , new (maps.SafeMap [string , * v1beta1.RulePolicy ]))
335
+ // prepare rule policies map
336
+ toSaveRulePolicies .Range (func (ruleIdentifier string , rulePolicy * v1beta1.RulePolicy ) bool {
337
+ rulePolicies [ruleIdentifier ] = * rulePolicy
338
+ return true
339
+ })
340
+
317
341
// new activity
318
342
// the process tries to use JSON patching to avoid conflicts between updates on the same object from different containers
319
343
// 0. create both a patch and a new object
@@ -323,9 +347,13 @@ func (am *ApplicationProfileManager) saveProfile(ctx context.Context, watchedCon
323
347
// 3a. the object is missing its container slice - ADD one with the container profile at the right index
324
348
// 3b. the object is missing the container profile - ADD the container profile at the right index
325
349
// 3c. default - patch the container ourselves and REPLACE it at the right index
326
- if len (capabilities ) > 0 || len (endpoints ) > 0 || len (execs ) > 0 || len (opens ) > 0 || len (toSaveSyscalls ) > 0 || watchedContainer .StatusUpdated () {
350
+ if len (capabilities ) > 0 || len (endpoints ) > 0 || len (execs ) > 0 || len (opens ) > 0 || len (toSaveSyscalls ) > 0 || len ( initalizeOperations ) > 0 || watchedContainer .StatusUpdated () {
327
351
// 0. calculate patch
328
- operations := utils .CreateCapabilitiesPatchOperations (capabilities , observedSyscalls , execs , opens , endpoints , watchedContainer .ContainerType .String (), watchedContainer .ContainerIndex )
352
+ operations := utils .CreateCapabilitiesPatchOperations (capabilities , observedSyscalls , execs , opens , endpoints , rulePolicies , watchedContainer .ContainerType .String (), watchedContainer .ContainerIndex )
353
+ if len (initalizeOperations ) > 0 {
354
+ operations = append (operations , initalizeOperations ... )
355
+ }
356
+
329
357
operations = utils .AppendStatusAnnotationPatchOperations (operations , watchedContainer )
330
358
operations = append (operations , utils.PatchOperation {
331
359
Op : "add" ,
@@ -366,6 +394,7 @@ func (am *ApplicationProfileManager) saveProfile(ctx context.Context, watchedCon
366
394
Opens : make ([]v1beta1.OpenCalls , 0 ),
367
395
Capabilities : make ([]string , 0 ),
368
396
Syscalls : make ([]string , 0 ),
397
+ PolicyByRuleId : make (map [string ]v1beta1.RulePolicy ),
369
398
SeccompProfile : seccompProfile ,
370
399
})
371
400
}
@@ -377,7 +406,7 @@ func (am *ApplicationProfileManager) saveProfile(ctx context.Context, watchedCon
377
406
newObject .Spec .EphemeralContainers = addContainers (newObject .Spec .EphemeralContainers , watchedContainer .ContainerNames [utils .EphemeralContainer ])
378
407
// enrich container
379
408
newContainer := utils .GetApplicationProfileContainer (newObject , watchedContainer .ContainerType , watchedContainer .ContainerIndex )
380
- utils .EnrichApplicationProfileContainer (newContainer , capabilities , observedSyscalls , execs , opens , endpoints )
409
+ utils .EnrichApplicationProfileContainer (newContainer , capabilities , observedSyscalls , execs , opens , endpoints , rulePolicies )
381
410
// try to create object
382
411
if err := am .storageClient .CreateApplicationProfile (newObject , namespace ); err != nil {
383
412
gotErr = err
@@ -425,11 +454,12 @@ func (am *ApplicationProfileManager) saveProfile(ctx context.Context, watchedCon
425
454
Opens : make ([]v1beta1.OpenCalls , 0 ),
426
455
Capabilities : make ([]string , 0 ),
427
456
Syscalls : make ([]string , 0 ),
457
+ PolicyByRuleId : make (map [string ]v1beta1.RulePolicy ),
428
458
SeccompProfile : seccompProfile ,
429
459
}
430
460
}
431
461
// update it
432
- utils .EnrichApplicationProfileContainer (existingContainer , capabilities , observedSyscalls , execs , opens , endpoints )
462
+ utils .EnrichApplicationProfileContainer (existingContainer , capabilities , observedSyscalls , execs , opens , endpoints , rulePolicies )
433
463
// get existing containers
434
464
var existingContainers []v1beta1.ApplicationProfileContainer
435
465
if watchedContainer .ContainerType == utils .Container {
@@ -469,6 +499,7 @@ func (am *ApplicationProfileManager) saveProfile(ctx context.Context, watchedCon
469
499
Opens : make ([]v1beta1.OpenCalls , 0 ),
470
500
Capabilities : make ([]string , 0 ),
471
501
Syscalls : make ([]string , 0 ),
502
+ PolicyByRuleId : make (map [string ]v1beta1.RulePolicy ),
472
503
SeccompProfile : seccompProfile ,
473
504
},
474
505
})
@@ -558,11 +589,22 @@ func (am *ApplicationProfileManager) saveProfile(ctx context.Context, watchedCon
558
589
}
559
590
return true
560
591
})
592
+
593
+ // record saved rule policies
594
+ toSaveRulePolicies .Range (func (ruleIdentifier string , rulePolicy * v1beta1.RulePolicy ) bool {
595
+ if ! am .toSaveRulePolicies .Get (watchedContainer .K8sContainerID ).Has (ruleIdentifier ) {
596
+ am .savedRulePolicies .Get (watchedContainer .K8sContainerID ).Set (ruleIdentifier , rulePolicy )
597
+ }
598
+ return true
599
+ })
600
+
561
601
logger .L ().Debug ("ApplicationProfileManager - saved application profile" ,
562
602
helpers .Int ("capabilities" , len (capabilities )),
563
603
helpers .Int ("endpoints" , toSaveEndpoints .Len ()),
564
604
helpers .Int ("execs" , toSaveExecs .Len ()),
565
605
helpers .Int ("opens" , toSaveOpens .Len ()),
606
+ helpers .Int ("rule policies" , toSaveRulePolicies .Len ()),
607
+ helpers .Int ("init operations" , len (initalizeOperations )),
566
608
helpers .String ("slug" , slug ),
567
609
helpers .Int ("container index" , watchedContainer .ContainerIndex ),
568
610
helpers .String ("container ID" , watchedContainer .ContainerID ),
@@ -638,10 +680,12 @@ func (am *ApplicationProfileManager) ContainerCallback(notif containercollection
638
680
am .savedExecs .Set (k8sContainerID , cache .NewTTL (5 * am .cfg .UpdateDataPeriod , am .cfg .UpdateDataPeriod ))
639
681
am .savedOpens .Set (k8sContainerID , cache .NewTTL (5 * am .cfg .UpdateDataPeriod , am .cfg .UpdateDataPeriod ))
640
682
am .savedSyscalls .Set (k8sContainerID , mapset .NewSet [string ]())
683
+ am .savedRulePolicies .Set (k8sContainerID , cache .NewTTL (5 * am .cfg .UpdateDataPeriod , am .cfg .UpdateDataPeriod ))
641
684
am .toSaveCapabilities .Set (k8sContainerID , mapset .NewSet [string ]())
642
685
am .toSaveEndpoints .Set (k8sContainerID , new (maps.SafeMap [string , * v1beta1.HTTPEndpoint ]))
643
686
am .toSaveExecs .Set (k8sContainerID , new (maps.SafeMap [string , []string ]))
644
687
am .toSaveOpens .Set (k8sContainerID , new (maps.SafeMap [string , mapset.Set [string ]]))
688
+ am .toSaveRulePolicies .Set (k8sContainerID , new (maps.SafeMap [string , * v1beta1.RulePolicy ]))
645
689
am .removedContainers .Remove (k8sContainerID ) // make sure container is not in the removed list
646
690
am .trackedContainers .Add (k8sContainerID )
647
691
go am .startApplicationProfiling (ctx , notif .Container , k8sContainerID )
@@ -718,8 +762,8 @@ func (am *ApplicationProfileManager) ReportHTTPEvent(k8sContainerID string, even
718
762
if err := am .waitForContainer (k8sContainerID ); err != nil {
719
763
return
720
764
}
721
- // get endpoint from event
722
- endpointIdentifier , err := am . GetEndpointIdentifier (event )
765
+
766
+ endpointIdentifier , err := GetEndpointIdentifier (event )
723
767
if err != nil {
724
768
logger .L ().Ctx (am .ctx ).Warning ("ApplicationProfileManager - failed to get endpoint identifier" , helpers .Error (err ))
725
769
return
@@ -737,3 +781,45 @@ func (am *ApplicationProfileManager) ReportHTTPEvent(k8sContainerID string, even
737
781
// add to endpoint map
738
782
am .toSaveEndpoints .Get (k8sContainerID ).Set (endpointHash , endpoint )
739
783
}
784
+
785
+ func (am * ApplicationProfileManager ) ReportRulePolicy (k8sContainerID , ruleId , allowedProcess string , allowedContainer bool ) {
786
+ if err := am .waitForContainer (k8sContainerID ); err != nil {
787
+ return
788
+ }
789
+
790
+ newPolicy := & v1beta1.RulePolicy {
791
+ AllowedContainer : allowedContainer ,
792
+ AllowedProcesses : []string {allowedProcess },
793
+ }
794
+
795
+ savedPolicies := am .savedRulePolicies .Get (k8sContainerID )
796
+ savedPolicy , ok := savedPolicies .Get (ruleId )
797
+ if ok {
798
+ savedPolicy := savedPolicy .(* v1beta1.RulePolicy )
799
+ if IsPolicyIncluded (savedPolicy , newPolicy ) {
800
+ return
801
+ }
802
+ }
803
+
804
+ toBeSavedPolicies := am .toSaveRulePolicies .Get (k8sContainerID )
805
+ toBeSavedPolicy := toBeSavedPolicies .Get (ruleId )
806
+
807
+ if IsPolicyIncluded (toBeSavedPolicy , newPolicy ) {
808
+ return
809
+ }
810
+
811
+ var finalPolicy * v1beta1.RulePolicy
812
+ if toBeSavedPolicy != nil {
813
+ finalPolicy = toBeSavedPolicy
814
+ if allowedContainer {
815
+ finalPolicy .AllowedContainer = true
816
+ }
817
+ if allowedProcess != "" && ! slices .Contains (finalPolicy .AllowedProcesses , allowedProcess ) {
818
+ finalPolicy .AllowedProcesses = append (finalPolicy .AllowedProcesses , allowedProcess )
819
+ }
820
+ } else {
821
+ finalPolicy = newPolicy
822
+ }
823
+
824
+ toBeSavedPolicies .Set (ruleId , finalPolicy )
825
+ }
0 commit comments