diff --git a/bpf/lib/process.h b/bpf/lib/process.h index bdadea67115..9594b721447 100644 --- a/bpf/lib/process.h +++ b/bpf/lib/process.h @@ -151,7 +151,7 @@ struct msg_execve_key { __u32 pid; // Process TGID - __u8 pad[4]; + __u32 auid; // loginuid __u64 ktime; }; // All fields aligned so no 'packed' attribute. diff --git a/bpf/process/bpf_execve_event.c b/bpf/process/bpf_execve_event.c index a00ae3a115f..3542d33812b 100644 --- a/bpf/process/bpf_execve_event.c +++ b/bpf/process/bpf_execve_event.c @@ -283,6 +283,7 @@ execve_send(struct sched_execve_args *ctx) #endif curr->key.pid = p->pid; curr->key.ktime = p->ktime; + curr->key.auid = p->auid; curr->nspid = p->nspid; curr->pkey = event->parent; if (curr->flags & EVENT_COMMON_FLAG_CLONE) { diff --git a/bpf/process/bpf_exit.h b/bpf/process/bpf_exit.h index b683bac7a5d..7292d04e2bd 100644 --- a/bpf/process/bpf_exit.h +++ b/bpf/process/bpf_exit.h @@ -50,10 +50,7 @@ static inline __attribute__((always_inline)) void event_exit_send(void *ctx, __u exit->common.ktime = ktime_get_ns(); exit->current.pid = tgid; - exit->current.pad[0] = 0; - exit->current.pad[1] = 0; - exit->current.pad[2] = 0; - exit->current.pad[3] = 0; + exit->current.auid = enter->key.auid; exit->current.ktime = enter->key.ktime; /** diff --git a/bpf/process/bpf_generic_retkprobe.c b/bpf/process/bpf_generic_retkprobe.c index f5b9bca0b9a..ee65c51a08e 100644 --- a/bpf/process/bpf_generic_retkprobe.c +++ b/bpf/process/bpf_generic_retkprobe.c @@ -150,12 +150,9 @@ BPF_KRETPROBE(generic_retkprobe_event, unsigned long ret) if (enter) { e->current.pid = enter->key.pid; + e->current.auid = enter->key.auid; e->current.ktime = enter->key.ktime; } - e->current.pad[0] = 0; - e->current.pad[1] = 0; - e->current.pad[2] = 0; - e->current.pad[3] = 0; e->func_id = config->func_id; e->common.size = size; diff --git a/bpf/process/generic_calls.h b/bpf/process/generic_calls.h index d23ac848fbc..9dda93968e6 100644 --- a/bpf/process/generic_calls.h +++ b/bpf/process/generic_calls.h @@ -105,11 +105,6 @@ generic_process_init(struct msg_generic_kprobe *e, u8 op, struct event_config *c e->common.size = 0; e->common.ktime = ktime_get_ns(); - e->current.pad[0] = 0; - e->current.pad[1] = 0; - e->current.pad[2] = 0; - e->current.pad[3] = 0; - e->action = 0; /** diff --git a/bpf/process/pfilter.h b/bpf/process/pfilter.h index d8daf84c237..e0ed98047eb 100644 --- a/bpf/process/pfilter.h +++ b/bpf/process/pfilter.h @@ -135,6 +135,52 @@ process_filter_pid(__u32 i, __u32 off, __u32 *f, __u64 ty, __u64 flags, return __process_filter_pid(ty, flags, sel, pid, enter); } +static inline __attribute__((always_inline)) int +__process_filter_loginuid(__u32 ty, __u32 sel, struct execve_map_value *enter) +{ + __u32 auid; + + auid = enter->key.auid; + + switch (ty) { + case op_filter_lt: + if (sel > auid) + return PFILTER_ACCEPT; + break; + case op_filter_gt: + if (sel < auid) + return PFILTER_ACCEPT; + break; + case op_filter_eq: + if (sel == auid) + return PFILTER_ACCEPT; + break; + case op_filter_neq: + if (sel != auid) + return PFILTER_ACCEPT; + break; + default: + return PFILTER_REJECT; + } + return PFILTER_REJECT; +} + +static inline __attribute__((always_inline)) int +process_filter_loginuid(__u32 i, __u32 off, __u32 *f, __u64 ty, __u64 flags, + struct execve_map_value *enter, struct msg_ns *n, + struct msg_capabilities *c) +{ + __u32 sel; + __u32 o = off; + + o = o / 4; + asm volatile("%[o] &= 0x3ff;\n" ::[o] "+r"(o) + :); + sel = f[o]; + + return __process_filter_loginuid(ty, sel, enter); +} + static inline __attribute__((always_inline)) int process_filter_namespace(__u32 i, __u32 off, __u32 *f, __u64 ty, __u64 nsid, struct execve_map_value *enter, struct msg_ns *n, @@ -310,7 +356,7 @@ selector_match(__u32 *f, __u32 index, __u64 ty, __u64 flags, __u64 len, int res1 = 0, res2 = 0, res3 = 0, res4 = 0; /* For NotIn op we AND results so default to 1 so we fallthru open */ - if (ty == op_filter_notin) + if (ty == op_filter_notin || ty == op_filter_neq) res1 = res2 = res3 = res4 = 1; /* Unrolling this loop was problematic for clang so rather @@ -342,7 +388,7 @@ selector_match(__u32 *f, __u32 index, __u64 ty, __u64 flags, __u64 len, res1 = process_filter(0, index, f, ty, flags, enter, n, c); index = next_pid_value(index, f, ty); - if (ty == op_filter_notin) + if (ty == op_filter_notin || ty == op_filter_neq) return res1 & res2 & res3 & res4; else return res1 | res2 | res3 | res4; @@ -374,6 +420,12 @@ struct nc_filter { u32 value; /* contains all namespaces to monitor (i.e. bit 0 is for ns_uts, bit 1 for ns_ipc etc.) */ } __attribute__((packed)); +struct loginuid_filter { + u32 op; + u32 len; /* number of values */ + u32 val[]; /* values */ +} __attribute__((packed)); + #define VALUES_MASK 0x1f /* max 4 values with 4 bytes each | 0x1f == 31 */ /* If you update the value of NUM_NS_FILTERS_SMALL below you should @@ -381,6 +433,48 @@ struct nc_filter { */ #define NUM_NS_FILTERS_SMALL 4 +static inline __attribute__((always_inline)) int +__process_filter_loginuids(__u32 *f, __u32 *index, struct execve_map_value *enter) +{ + int res = PFILTER_ACCEPT; + struct loginuid_filter *loginuid; + + loginuid = (struct loginuid_filter *)((u64)f + (*index & INDEX_MASK)); + *index += sizeof(struct loginuid_filter); /* 4: op */ + res = selector_match(f, *index, loginuid->op, 0, loginuid->len, + enter, NULL, NULL, &process_filter_loginuid); + + *index += ((loginuid->len * sizeof(loginuid->val[0])) & VALUES_MASK); + + if (res == PFILTER_REJECT) + return res; + + return res; +} + +static inline __attribute__((always_inline)) int +process_filter_loginuids(__u32 *f, __u32 index, struct execve_map_value *enter, int len) +{ + int i = 0; + int loginuid_len = 0; + int res = PFILTER_ACCEPT; + struct loginuid_filter *loginuid; + +#pragma unroll + for (i = 0; i < 4; i++) { + loginuid = (struct loginuid_filter *)((u64)f + (index & INDEX_MASK)); + index += sizeof(struct loginuid_filter); /* 4: op */ + res = selector_match(f, index, loginuid->op, 0, loginuid->len, enter, NULL, NULL, &process_filter_loginuid); + + index += ((loginuid->len * sizeof(loginuid->val[0])) & VALUES_MASK); + loginuid_len += sizeof(struct loginuid_filter) + ((loginuid->len * sizeof(loginuid->val[0])) & VALUES_MASK); + + if (res == PFILTER_REJECT || loginuid_len >= len) + return res; + } + return res; +} + static inline __attribute__((always_inline)) int selector_process_filter(__u32 *f, __u32 index, struct execve_map_value *enter, struct msg_selector_data *sel, struct msg_ns *n, @@ -408,6 +502,10 @@ selector_process_filter(__u32 *f, __u32 index, struct execve_map_value *enter, /* selector section offset by reading the relative offset in the array */ index += *(__u32 *)((__u64)f + (index & INDEX_MASK)); index &= INDEX_MASK; + + len = *(__u32 *)((__u64)f + + (index & + INDEX_MASK)); index += 4; /* skip selector size field */ /* matchPid */ @@ -513,6 +611,22 @@ selector_process_filter(__u32 *f, __u32 index, struct execve_map_value *enter, return res; #endif + /* matchLoginuids */ + len = *(__u32 *)((__u64)f + + (index & + INDEX_MASK)); /* (sizeof(LoginUid1) + sizeof(LoginUid2) + ... + 4) */ + index += 4; /* 4: LoginUid1 header */ + len -= 4; + + if (len > 0) { + res = process_filter_loginuids(f, index, enter, len); + if (res == PFILTER_REJECT) + return res; + + index += (len & VALUES_MASK); + } + if (res == PFILTER_REJECT) + return res; return res; } diff --git a/bpf/process/types/basic.h b/bpf/process/types/basic.h index fb4c1433cd3..5f310d1afb2 100644 --- a/bpf/process/types/basic.h +++ b/bpf/process/types/basic.h @@ -1768,6 +1768,8 @@ selector_arg_offset(__u8 *f, struct msg_generic_kprobe *e, __u32 selidx, seloff += *(__u32 *)((__u64)f + (seloff & INDEX_MASK)); /* skip the matchCapabilityChanges by reading its length */ seloff += *(__u32 *)((__u64)f + (seloff & INDEX_MASK)); + /* skip the matchLoginuids by reading its length */ + seloff += *(__u32 *)((__u64)f + (seloff & INDEX_MASK)); } /* Making binary selectors fixes size helps on some kernels */ diff --git a/docs/content/en/docs/concepts/tracing-policy/selectors.md b/docs/content/en/docs/concepts/tracing-policy/selectors.md index f1a8ee74483..331b603c2d6 100644 --- a/docs/content/en/docs/concepts/tracing-policy/selectors.md +++ b/docs/content/en/docs/concepts/tracing-policy/selectors.md @@ -19,6 +19,7 @@ A `TracingPolicy` can contain from 0 to 5 selectors. A selector is composed of - [`matchCapabilityChanges`](#capability-changes-filter): filter on Linux capabilities changes. - [`matchActions`](#actions-filter): apply an action on selector matching. - [`matchReturnActions`](#return-actions-filter): apply an action on return selector matching. +- [`matchLoginUids`](#auid-filter): filter on audit ID. ## Arguments filter @@ -1541,3 +1542,26 @@ exist. Return actions filters are a list of actions that execute when an return selector matches. They are defined under `matchReturnActions` and currently support all the [Actions filter](#actions-filter) `action` types. + +## Auid filter + +Auids filters can be specified under the `matchLoginUids` field and provide filtering +based on the value of audit id of the process. For example, the following +`matchLoginUids` filter tells the BPF code that observe only hooks for which the +audit id is not equal to `-1`: + +```yaml +- matchLoginUids: + - operator: "NotEqual" + values: + - 4294967295 +``` + +The available operators for `matchLoginUids` are: +- `Equal` +- `NotEqual` +- `GreaterThan` +- `LessThan` + +In a selector, the `matchLoginUids` filter supports defining up to four operators, +which are logically `AND` together. diff --git a/pkg/api/processapi/processapi.go b/pkg/api/processapi/processapi.go index dffcec3da15..ba0180d6e0d 100644 --- a/pkg/api/processapi/processapi.go +++ b/pkg/api/processapi/processapi.go @@ -63,7 +63,7 @@ type MsgExec struct { type MsgExecveKey struct { Pid uint32 `align:"pid"` - Pad uint32 `align:"pad"` + Auid uint32 `align:"auid"` Ktime uint64 `align:"ktime"` } diff --git a/pkg/grpc/exec/exec_test_helper.go b/pkg/grpc/exec/exec_test_helper.go index d0a0376288e..e5cf3e34ec8 100644 --- a/pkg/grpc/exec/exec_test_helper.go +++ b/pkg/grpc/exec/exec_test_helper.go @@ -99,7 +99,7 @@ func CreateEvents[EXEC notify.Message, EXIT notify.Message](Pid uint32, Ktime ui }, Parent: tetragonAPI.MsgExecveKey{ Pid: 0, - Pad: 0, + Auid: 0, Ktime: 0, }, ParentFlags: 0, @@ -140,7 +140,7 @@ func CreateEvents[EXEC notify.Message, EXIT notify.Message](Pid uint32, Ktime ui }, Parent: tetragonAPI.MsgExecveKey{ Pid: 1, - Pad: 0, + Auid: 0, Ktime: 0, }, ParentFlags: 0, @@ -181,7 +181,7 @@ func CreateEvents[EXEC notify.Message, EXIT notify.Message](Pid uint32, Ktime ui }, Parent: tetragonAPI.MsgExecveKey{ Pid: ParentPid, - Pad: 0, + Auid: 0, Ktime: ParentKtime, }, ParentFlags: 0, @@ -215,7 +215,7 @@ func CreateEvents[EXEC notify.Message, EXIT notify.Message](Pid uint32, Ktime ui }, ProcessKey: tetragonAPI.MsgExecveKey{ Pid: Pid, - Pad: 0, + Auid: 0, Ktime: Ktime, }, Info: tetragonAPI.MsgExitInfo{ @@ -241,7 +241,7 @@ func CreateCloneEvents[CLONE notify.Message, EXIT notify.Message](Pid uint32, Kt }, Parent: tetragonAPI.MsgExecveKey{ Pid: ParentPid, - Pad: 0, + Auid: 0, Ktime: ParentKtime, }, PID: Pid, @@ -263,7 +263,7 @@ func CreateCloneEvents[CLONE notify.Message, EXIT notify.Message](Pid uint32, Kt }, ProcessKey: tetragonAPI.MsgExecveKey{ Pid: Pid, - Pad: 0, + Auid: 0, Ktime: Ktime, }, Info: tetragonAPI.MsgExitInfo{ diff --git a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml index dc23dfaa56a..aff6150a2bb 100644 --- a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml +++ b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml @@ -467,6 +467,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1123,6 +1146,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1680,6 +1726,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: diff --git a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml index 8ff37a67567..973379bcd25 100644 --- a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml +++ b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml @@ -467,6 +467,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1123,6 +1146,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1680,6 +1726,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 7a6cc982d23..685527a7d49 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/types.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/types.go @@ -125,6 +125,9 @@ type KProbeSelector struct { // +kubebuilder:validation:Optional // IDs for capabilities changes MatchCapabilityChanges []CapabilitiesSelector `json:"matchCapabilityChanges,omitempty"` + // +kubebuilder:validation:Optional + // A list of login uid filters. + MatchLoginUids []LoginUidSelector `json:"matchLoginUids,omitempty"` } type NamespaceChangesSelector struct { @@ -163,6 +166,14 @@ type CapabilitiesSelector struct { Values []string `json:"values"` } +type LoginUidSelector struct { + // +kubebuilder:validation:Enum=Equal;NotEqual;GreaterThan;LessThan + // LoginUid selector operator. + Operator string `json:"operator"` + // LoginUid to match. + Values []uint32 `json:"values"` +} + type PIDSelector struct { // +kubebuilder:validation:Enum=In;NotIn // PID selector operator. diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/version.go b/pkg/k8s/apis/cilium.io/v1alpha1/version.go index d5703baa3bf..d4655606d64 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/version.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/version.go @@ -7,4 +7,4 @@ package v1alpha1 // Used to determine if CRD needs to be updated in cluster // // Developers: Bump patch for each change in the CRD schema. -const CustomResourceDefinitionSchemaVersion = "1.1.8" +const CustomResourceDefinitionSchemaVersion = "1.1.9" diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go b/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go index 78e6da551f3..44fbbe0c922 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go @@ -198,6 +198,13 @@ func (in *KProbeSelector) DeepCopyInto(out *KProbeSelector) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.MatchLoginUids != nil { + in, out := &in.MatchLoginUids, &out.MatchLoginUids + *out = make([]LoginUidSelector, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -270,6 +277,27 @@ func (in *ListSpec) DeepCopy() *ListSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoginUidSelector) DeepCopyInto(out *LoginUidSelector) { + *out = *in + if in.Values != nil { + in, out := &in.Values, &out.Values + *out = make([]uint32, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginUidSelector. +func (in *LoginUidSelector) DeepCopy() *LoginUidSelector { + if in == nil { + return nil + } + out := new(LoginUidSelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespaceChangesSelector) DeepCopyInto(out *NamespaceChangesSelector) { *out = *in diff --git a/pkg/selectors/kernel.go b/pkg/selectors/kernel.go index 9d23d0b4115..8ea5fbac6ad 100644 --- a/pkg/selectors/kernel.go +++ b/pkg/selectors/kernel.go @@ -341,6 +341,41 @@ func ParseMatchPids(k *KernelSelectorState, matchPids []v1alpha1.PIDSelector) er return nil } +func loginuidSelectorValue(loginuid *v1alpha1.LoginUidSelector) ([]byte, uint32) { + b := make([]byte, len(loginuid.Values)*4) + + for i, v := range loginuid.Values { + off := i * 4 + binary.LittleEndian.PutUint32(b[off:], v) + } + return b, uint32(len(b)) +} + +func ParseMatchLoginuid(k *KernelSelectorState, loginuid *v1alpha1.LoginUidSelector) error { + op, err := SelectorOp(loginuid.Operator) + if err != nil { + return fmt.Errorf("matchloginuid error: %w", err) + } + WriteSelectorUint32(&k.data, op) + + value, size := loginuidSelectorValue(loginuid) + WriteSelectorUint32(&k.data, size/4) + WriteSelectorByteArray(&k.data, value, size) + return nil +} + +func ParseMatchLoginuids(k *KernelSelectorState, matchLoginuids []v1alpha1.LoginUidSelector) error { + loff := AdvanceSelectorLength(&k.data) + + for _, p := range matchLoginuids { + if err := ParseMatchLoginuid(k, &p); err != nil { + return err + } + } + WriteSelectorLength(&k.data, loff) + return nil +} + func ActionTypeFromString(action string) int32 { act, ok := actionTypeTable[strings.ToLower(action)] if !ok { @@ -1231,6 +1266,7 @@ func ParseMatchBinaries(k *KernelSelectorState, binarys []v1alpha1.BinarySelecto // [matchCapabilities] // [matchNamespaceChanges] // [matchCapabilityChanges] +// [matchLoginuids] // [matchArgs] // [matchActions] // @@ -1239,6 +1275,7 @@ func ParseMatchBinaries(k *KernelSelectorState, binarys []v1alpha1.BinarySelecto // matchCapabilities := [length][CAx][CAy]...[CAn] // matchNamespaceChanges := [length][NCx][NCy]...[NCn] // matchCapabilityChanges := [length][CAx][CAy]...[CAn] +// matchLoginuids := [length] [LoginUid1][LoginUid2]...[LoginUidn] // matchArgs := [length][ARGx][ARGy]...[ARGn] // PIDn := [op][flags][nValues][v1]...[vn] // Argn := [index][op][valueGen] @@ -1304,6 +1341,9 @@ func InitKernelSelectorState(selectors []v1alpha1.KProbeSelector, args []v1alpha if err := ParseMatchCapabilityChanges(k, selectors.MatchCapabilityChanges); err != nil { return fmt.Errorf("parseMatchCapabilityChanges error: %w", err) } + if err := ParseMatchLoginuids(k, selectors.MatchLoginUids); err != nil { + return fmt.Errorf("parseMatchLoginuids error: %w", err) + } if err := ParseMatchBinaries(k, selectors.MatchBinaries, selIdx); err != nil { return fmt.Errorf("parseMatchBinaries error: %w", err) } diff --git a/pkg/selectors/kernel_test.go b/pkg/selectors/kernel_test.go index 73edf9182a4..06426bd56f0 100644 --- a/pkg/selectors/kernel_test.go +++ b/pkg/selectors/kernel_test.go @@ -380,6 +380,46 @@ func TestParseMatchPid(t *testing.T) { } } +func TestParseMatchLoginuids(t *testing.T) { + loginuids1 := &v1alpha1.LoginUidSelector{Operator: "Equal", Values: []uint32{1, 2, 3}} + k := &KernelSelectorState{data: KernelSelectorData{off: 0}} + d := &k.data + expected1 := []byte{ + 0x03, 0x00, 0x00, 0x00, // op == Equal + 0x03, 0x00, 0x00, 0x00, // length == 0x3 + 0x01, 0x00, 0x00, 0x00, // Values[0] == 1 + 0x02, 0x00, 0x00, 0x00, // Values[1] == 2 + 0x03, 0x00, 0x00, 0x00, // Values[2] == 3 + } + if err := ParseMatchLoginuid(k, loginuids1); err != nil || bytes.Equal(expected1, d.e[0:d.off]) == false { + t.Errorf("ParseMatchLoginuids: error %v expected %v bytes %v parsing %v\n", err, expected1, d.e[0:d.off], loginuids1) + } + + nextloginuids := d.off + loginuids2 := &v1alpha1.LoginUidSelector{Operator: "NotEqual", Values: []uint32{1, 2, 3, 4}} + expected2 := []byte{ + 0x04, 0x00, 0x00, 0x00, // op == NotEqual + 0x04, 0x00, 0x00, 0x00, // length == 0x4 + 0x01, 0x00, 0x00, 0x00, // Values[0] == 1 + 0x02, 0x00, 0x00, 0x00, // Values[1] == 2 + 0x03, 0x00, 0x00, 0x00, // Values[2] == 3 + 0x04, 0x00, 0x00, 0x00, // Values[2] == 3 + } + if err := ParseMatchLoginuid(k, loginuids2); err != nil || bytes.Equal(expected2, d.e[nextloginuids:d.off]) == false { + t.Errorf("ParseMatchLoginuids: error %v expected %v bytes %v parsing %v\n", err, expected2, d.e[nextloginuids:d.off], loginuids2) + } + + length := []byte{48, 0x00, 0x00, 0x00} + expected3 := append(length, expected1[:]...) + expected3 = append(expected3, expected2[:]...) + loginuids3 := []v1alpha1.LoginUidSelector{*loginuids1, *loginuids2} + ks := &KernelSelectorState{data: KernelSelectorData{off: 0}} + d = &ks.data + if err := ParseMatchLoginuids(ks, loginuids3); err != nil || bytes.Equal(expected3, d.e[0:d.off]) == false { + t.Errorf("ParseMatchLoginuids: error %v expected %v bytes %v parsing %v\n", err, expected3, d.e[0:d.off], loginuids3) + } +} + func TestParseMatchNamespaces(t *testing.T) { ns1 := &v1alpha1.NamespaceSelector{Namespace: "Pid", Operator: "In", Values: []string{"1", "2", "3"}} k := &KernelSelectorState{data: KernelSelectorData{off: 0}} @@ -559,8 +599,8 @@ func TestMultipleSelectorsExample(t *testing.T) { // value absolute offset explanation expU32Push(2) // off: 0 number of selectors expU32Push(8) // off: 4 relative ofset of 1st selector (4 + 8 = 12) - expU32Push(100) // off: 8 relative ofset of 2nd selector (8 + 124 = 132) - expU32Push(96) // off: 12 selector1: length (76 + 12 = 96) + expU32Push(104) // off: 8 relative ofset of 2nd selector (8 + 124 = 132) + expU32Push(100) // off: 12 selector1: length (76 + 12 = 96) expU32Push(24) // off: 16 selector1: MatchPIDs: len expU32Push(SelectorOpNotIn) // off: 20 selector1: MatchPIDs[0]: op expU32Push(0) // off: 24 selector1: MatchPIDs[0]: flags @@ -571,6 +611,7 @@ func TestMultipleSelectorsExample(t *testing.T) { expU32Push(4) // off: 44 selector1: MatchCapabilities: len expU32Push(4) // off: 48 selector1: MatchNamespaceChanges: len expU32Push(4) // off: 52 selector1: MatchCapabilityChanges: len + expU32Push(4) // off: 56 selector1: MatchLoginuids: len expU32Push(48) // off: 80 selector1: matchArgs: len expU32Push(24) // off: 84 selector1: matchArgs[0]: offset expU32Push(0) // off: 88 selector1: matchArgs[1]: offset @@ -584,7 +625,7 @@ func TestMultipleSelectorsExample(t *testing.T) { expU32Push(10) // off: 120 selector1: matchArgs: arg0: val0: 10 expU32Push(20) // off: 124 selector1: matchArgs: arg0: val1: 20 expU32Push(4) // off: 128 selector1: matchActions: length - expU32Push(96) // off: 132 selector2: length + expU32Push(100) // off: 132 selector2: length // ... everything else should be the same as selector1 ... if bytes.Equal(expected[:expectedLen], b[:expectedLen]) == false { @@ -601,11 +642,11 @@ func TestInitKernelSelectors(t *testing.T) { } expected_selsize_small := []byte{ - 0x10, 0x01, 0x00, 0x00, // size = pids + args + actions + namespaces + capabilities + 4 + 0x40, 0x01, 0x00, 0x00, // size = pids + args + actions + namespaces + capabilities + loginuid + 4 } expected_selsize_large := []byte{ - 0x44, 0x01, 0x00, 0x00, // size = pids + args + actions + namespaces + namespacesChanges + capabilities + capabilityChanges + 4 + 0x74, 0x01, 0x00, 0x00, // size = pids + args + actions + namespaces + namespacesChanges + capabilities + capabilityChanges + loginuid + 4 } expected_filters := []byte{ @@ -688,6 +729,26 @@ func TestInitKernelSelectors(t *testing.T) { 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // Values (uint64) } + expected_loginuid := []byte{ + // loginuid header + 48, 0x00, 0x00, 0x00, // size = sizeof(loginuids1) + sizeof(loginuids2) + 4 + 4 + + //loginuids1 size = 20 + 0x03, 0x00, 0x00, 0x00, // op == Equal + 0x03, 0x00, 0x00, 0x00, // length == 0x3 + 0x01, 0x00, 0x00, 0x00, // Values[0] == 1 + 0x02, 0x00, 0x00, 0x00, // Values[1] == 2 + 0x03, 0x00, 0x00, 0x00, // Values[2] == 3 + + //loginuids2 size = 24 + 0x04, 0x00, 0x00, 0x00, // op == NotEqual + 0x04, 0x00, 0x00, 0x00, // length == 0x4 + 0x01, 0x00, 0x00, 0x00, // Values[0] == 1 + 0x02, 0x00, 0x00, 0x00, // Values[1] == 2 + 0x03, 0x00, 0x00, 0x00, // Values[2] == 3 + 0x04, 0x00, 0x00, 0x00, // Values[2] == 3 + } + expected_last_large := []byte{ // arg header 108, 0x00, 0x00, 0x00, // size = sizeof(arg2) + sizeof(arg1) + 24 @@ -775,11 +836,13 @@ func TestInitKernelSelectors(t *testing.T) { expected = append(expected, expected_selsize_large...) expected = append(expected, expected_filters...) expected = append(expected, expected_changes...) + expected = append(expected, expected_loginuid...) expected = append(expected, expected_last_large...) } else { expected = append(expected, expected_selsize_small...) expected = append(expected, expected_filters...) expected = append(expected, expected_changes_empty...) + expected = append(expected, expected_loginuid...) expected = append(expected, expected_last_small...) } @@ -802,6 +865,9 @@ func TestInitKernelSelectors(t *testing.T) { cc := &v1alpha1.CapabilitiesSelector{Type: "Effective", Operator: "In", IsNamespaceCapability: false, Values: []string{"CAP_SYS_ADMIN", "CAP_NET_RAW"}} matchCapabilityChanges = append(matchCapabilityChanges, *cc) } + loginuids1 := &v1alpha1.LoginUidSelector{Operator: "Equal", Values: []uint32{1, 2, 3}} + loginuids2 := &v1alpha1.LoginUidSelector{Operator: "NotEqual", Values: []uint32{1, 2, 3, 4}} + matchLoginuids := []v1alpha1.LoginUidSelector{*loginuids1, *loginuids2} var matchArgs []v1alpha1.ArgSelector if kernels.EnableLargeProgs() { arg1 := &v1alpha1.ArgSelector{Index: 1, Operator: "Equal", Values: []string{"foobar"}} @@ -824,6 +890,7 @@ func TestInitKernelSelectors(t *testing.T) { MatchCapabilities: matchCapabilities, MatchNamespaceChanges: matchNamespaceChanges, MatchCapabilityChanges: matchCapabilityChanges, + MatchLoginUids: matchLoginuids, MatchArgs: matchArgs, MatchActions: matchActions, }, diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml index dc23dfaa56a..aff6150a2bb 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpolicies.yaml @@ -467,6 +467,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1123,6 +1146,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1680,6 +1726,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml index 8ff37a67567..973379bcd25 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml @@ -467,6 +467,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1123,6 +1146,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: @@ -1680,6 +1726,29 @@ spec: - values type: object type: array + matchLoginUids: + description: A list of login uid filters. + items: + properties: + operator: + description: LoginUid selector operator. + enum: + - Equal + - NotEqual + - GreaterThan + - LessThan + type: string + values: + description: LoginUid to match. + items: + format: int32 + type: integer + type: array + required: + - operator + - values + type: object + type: array matchNamespaceChanges: description: IDs for namespace changes items: diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 7a6cc982d23..685527a7d49 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go @@ -125,6 +125,9 @@ type KProbeSelector struct { // +kubebuilder:validation:Optional // IDs for capabilities changes MatchCapabilityChanges []CapabilitiesSelector `json:"matchCapabilityChanges,omitempty"` + // +kubebuilder:validation:Optional + // A list of login uid filters. + MatchLoginUids []LoginUidSelector `json:"matchLoginUids,omitempty"` } type NamespaceChangesSelector struct { @@ -163,6 +166,14 @@ type CapabilitiesSelector struct { Values []string `json:"values"` } +type LoginUidSelector struct { + // +kubebuilder:validation:Enum=Equal;NotEqual;GreaterThan;LessThan + // LoginUid selector operator. + Operator string `json:"operator"` + // LoginUid to match. + Values []uint32 `json:"values"` +} + type PIDSelector struct { // +kubebuilder:validation:Enum=In;NotIn // PID selector operator. diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go index d5703baa3bf..d4655606d64 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/version.go @@ -7,4 +7,4 @@ package v1alpha1 // Used to determine if CRD needs to be updated in cluster // // Developers: Bump patch for each change in the CRD schema. -const CustomResourceDefinitionSchemaVersion = "1.1.8" +const CustomResourceDefinitionSchemaVersion = "1.1.9" diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go index 78e6da551f3..44fbbe0c922 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go @@ -198,6 +198,13 @@ func (in *KProbeSelector) DeepCopyInto(out *KProbeSelector) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.MatchLoginUids != nil { + in, out := &in.MatchLoginUids, &out.MatchLoginUids + *out = make([]LoginUidSelector, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -270,6 +277,27 @@ func (in *ListSpec) DeepCopy() *ListSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoginUidSelector) DeepCopyInto(out *LoginUidSelector) { + *out = *in + if in.Values != nil { + in, out := &in.Values, &out.Values + *out = make([]uint32, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginUidSelector. +func (in *LoginUidSelector) DeepCopy() *LoginUidSelector { + if in == nil { + return nil + } + out := new(LoginUidSelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespaceChangesSelector) DeepCopyInto(out *NamespaceChangesSelector) { *out = *in