github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/gadget-collection/gadgets/trace/capabilities/gadget.go (about) 1 // Copyright 2019-2022 The Inspektor Gadget authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package capabilities 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "strconv" 21 22 log "github.com/sirupsen/logrus" 23 24 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-collection/gadgets" 25 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-collection/gadgets/trace" 26 27 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/capabilities/tracer" 28 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/capabilities/types" 29 30 gadgetv1alpha1 "github.com/inspektor-gadget/inspektor-gadget/pkg/apis/gadget/v1alpha1" 31 ) 32 33 type Trace struct { 34 helpers gadgets.GadgetHelpers 35 36 started bool 37 tracer trace.Tracer 38 } 39 40 type TraceFactory struct { 41 gadgets.BaseFactory 42 } 43 44 func NewFactory() gadgets.TraceFactory { 45 return &TraceFactory{ 46 BaseFactory: gadgets.BaseFactory{DeleteTrace: deleteTrace}, 47 } 48 } 49 50 func (f *TraceFactory) Description() string { 51 return `capabilities traces security capability checks"` 52 } 53 54 func (f *TraceFactory) OutputModesSupported() map[gadgetv1alpha1.TraceOutputMode]struct{} { 55 return map[gadgetv1alpha1.TraceOutputMode]struct{}{ 56 gadgetv1alpha1.TraceOutputModeStream: {}, 57 } 58 } 59 60 func deleteTrace(name string, t interface{}) { 61 trace := t.(*Trace) 62 if trace.tracer != nil { 63 trace.tracer.Stop() 64 } 65 } 66 67 func (f *TraceFactory) Operations() map[gadgetv1alpha1.Operation]gadgets.TraceOperation { 68 n := func() interface{} { 69 return &Trace{ 70 helpers: f.Helpers, 71 } 72 } 73 74 return map[gadgetv1alpha1.Operation]gadgets.TraceOperation{ 75 gadgetv1alpha1.OperationStart: { 76 Doc: "Start capabilities gadget", 77 Operation: func(name string, trace *gadgetv1alpha1.Trace) { 78 f.LookupOrCreate(name, n).(*Trace).Start(trace) 79 }, 80 }, 81 gadgetv1alpha1.OperationStop: { 82 Doc: "Stop capabilities gadget", 83 Operation: func(name string, trace *gadgetv1alpha1.Trace) { 84 f.LookupOrCreate(name, n).(*Trace).Stop(trace) 85 }, 86 }, 87 } 88 } 89 90 func (t *Trace) Start(trace *gadgetv1alpha1.Trace) { 91 if t.started { 92 trace.Status.State = gadgetv1alpha1.TraceStateStarted 93 return 94 } 95 96 auditOnly := types.AuditOnlyDefault 97 unique := types.UniqueDefault 98 99 if trace.Spec.Parameters != nil { 100 params := trace.Spec.Parameters 101 var err error 102 103 if val, ok := params[types.AuditOnlyParam]; ok { 104 auditOnly, err = strconv.ParseBool(val) 105 if err != nil { 106 trace.Status.OperationError = fmt.Sprintf("%q is not valid for %q", val, types.AuditOnlyParam) 107 return 108 } 109 } 110 if val, ok := params[types.UniqueParam]; ok { 111 unique, err = strconv.ParseBool(val) 112 if err != nil { 113 trace.Status.OperationError = fmt.Sprintf("%q is not valid for %q", val, types.UniqueParam) 114 return 115 } 116 } 117 } 118 119 traceName := gadgets.TraceName(trace.ObjectMeta.Namespace, trace.ObjectMeta.Name) 120 121 eventCallback := func(event *types.Event) { 122 r, err := json.Marshal(event) 123 if err != nil { 124 log.Warnf("Gadget %s: error marshaling event: %s", trace.Spec.Gadget, err) 125 return 126 } 127 t.helpers.PublishEvent(traceName, string(r)) 128 } 129 130 var err error 131 132 mountNsMap, err := t.helpers.TracerMountNsMap(traceName) 133 if err != nil { 134 trace.Status.OperationError = fmt.Sprintf("failed to find tracer's mount ns map: %s", err) 135 return 136 } 137 config := &tracer.Config{ 138 MountnsMap: mountNsMap, 139 AuditOnly: auditOnly, 140 Unique: unique, 141 } 142 143 t.tracer, err = tracer.NewTracer(config, t.helpers, eventCallback) 144 if err != nil { 145 trace.Status.OperationError = fmt.Sprintf("failed to create tracer: %s", err) 146 return 147 } 148 149 t.started = true 150 151 trace.Status.State = gadgetv1alpha1.TraceStateStarted 152 } 153 154 func (t *Trace) Stop(trace *gadgetv1alpha1.Trace) { 155 if !t.started { 156 trace.Status.OperationError = "Not started" 157 return 158 } 159 160 t.tracer.Stop() 161 t.tracer = nil 162 t.started = false 163 trace.Status.State = gadgetv1alpha1.TraceStateStopped 164 }