From f56b3dac03b7d7e32e7bb1c9fa77d7cd25e706e4 Mon Sep 17 00:00:00 2001 From: Jianlin Lv Date: Thu, 14 Mar 2024 07:21:33 -0700 Subject: [PATCH] Tracing: add support for file permissions For the observed file/directory, add the associated permission and output the complete file/directory permission information, consistent with the format of 'ls -l'. Can be used in user space to further filter/identify events based on specific file attributes. Signed-off-by: Jianlin Lv --- api/v1/README.md | 2 + .../codegen/eventchecker/eventchecker.pb.go | 38 +++++++++-- api/v1/tetragon/tetragon.pb.go | 40 +++++++++--- api/v1/tetragon/tetragon.proto | 2 + bpf/process/types/basic.h | 17 +++-- docs/content/en/docs/reference/grpc-api.md | 2 + pkg/api/tracingapi/client_kprobe.go | 18 ++--- pkg/grpc/tracing/tracing.go | 10 +-- .../v1alpha1/cilium.io_tracingpolicies.yaml | 4 ++ .../cilium.io_tracingpoliciesnamespaced.yaml | 4 ++ pkg/k8s/apis/cilium.io/v1alpha1/types.go | 2 +- pkg/k8s/apis/cilium.io/v1alpha1/version.go | 2 +- pkg/reader/path/path.go | 65 +++++++++++++++++++ pkg/sensors/tracing/args.go | 16 +++++ .../codegen/eventchecker/eventchecker.pb.go | 38 +++++++++-- .../tetragon/api/v1/tetragon/tetragon.pb.go | 40 +++++++++--- .../tetragon/api/v1/tetragon/tetragon.proto | 2 + .../v1alpha1/cilium.io_tracingpolicies.yaml | 4 ++ .../cilium.io_tracingpoliciesnamespaced.yaml | 4 ++ .../pkg/k8s/apis/cilium.io/v1alpha1/types.go | 2 +- .../k8s/apis/cilium.io/v1alpha1/version.go | 2 +- 21 files changed, 260 insertions(+), 54 deletions(-) diff --git a/api/v1/README.md b/api/v1/README.md index 6b75d5c4515..a791cabdca6 100644 --- a/api/v1/README.md +++ b/api/v1/README.md @@ -543,6 +543,7 @@ https://github.com/opencontainers/runtime-spec/blob/main/config.md#createcontain | mount | [string](#string) | | | | path | [string](#string) | | | | flags | [string](#string) | | | +| permission | [string](#string) | | | @@ -590,6 +591,7 @@ https://github.com/opencontainers/runtime-spec/blob/main/config.md#createcontain | mount | [string](#string) | | | | path | [string](#string) | | | | flags | [string](#string) | | | +| permission | [string](#string) | | | diff --git a/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go b/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go index ddd762eab86..a85d9478baf 100644 --- a/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go +++ b/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go @@ -4144,9 +4144,10 @@ func (checker *KprobeNetDevChecker) FromKprobeNetDev(event *tetragon.KprobeNetDe // KprobePathChecker implements a checker struct to check a KprobePath field type KprobePathChecker struct { - Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` - Path *stringmatcher.StringMatcher `json:"path,omitempty"` - Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` + Path *stringmatcher.StringMatcher `json:"path,omitempty"` + Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Permission *stringmatcher.StringMatcher `json:"permission,omitempty"` } // NewKprobePathChecker creates a new KprobePathChecker @@ -4181,6 +4182,11 @@ func (checker *KprobePathChecker) Check(event *tetragon.KprobePath) error { return fmt.Errorf("Flags check failed: %w", err) } } + if checker.Permission != nil { + if err := checker.Permission.Match(event.Permission); err != nil { + return fmt.Errorf("Permission check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -4207,6 +4213,12 @@ func (checker *KprobePathChecker) WithFlags(check *stringmatcher.StringMatcher) return checker } +// WithPermission adds a Permission check to the KprobePathChecker +func (checker *KprobePathChecker) WithPermission(check *stringmatcher.StringMatcher) *KprobePathChecker { + checker.Permission = check + return checker +} + //FromKprobePath populates the KprobePathChecker using data from a KprobePath field func (checker *KprobePathChecker) FromKprobePath(event *tetragon.KprobePath) *KprobePathChecker { if event == nil { @@ -4215,14 +4227,16 @@ func (checker *KprobePathChecker) FromKprobePath(event *tetragon.KprobePath) *Kp checker.Mount = stringmatcher.Full(event.Mount) checker.Path = stringmatcher.Full(event.Path) checker.Flags = stringmatcher.Full(event.Flags) + checker.Permission = stringmatcher.Full(event.Permission) return checker } // KprobeFileChecker implements a checker struct to check a KprobeFile field type KprobeFileChecker struct { - Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` - Path *stringmatcher.StringMatcher `json:"path,omitempty"` - Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` + Path *stringmatcher.StringMatcher `json:"path,omitempty"` + Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Permission *stringmatcher.StringMatcher `json:"permission,omitempty"` } // NewKprobeFileChecker creates a new KprobeFileChecker @@ -4257,6 +4271,11 @@ func (checker *KprobeFileChecker) Check(event *tetragon.KprobeFile) error { return fmt.Errorf("Flags check failed: %w", err) } } + if checker.Permission != nil { + if err := checker.Permission.Match(event.Permission); err != nil { + return fmt.Errorf("Permission check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -4283,6 +4302,12 @@ func (checker *KprobeFileChecker) WithFlags(check *stringmatcher.StringMatcher) return checker } +// WithPermission adds a Permission check to the KprobeFileChecker +func (checker *KprobeFileChecker) WithPermission(check *stringmatcher.StringMatcher) *KprobeFileChecker { + checker.Permission = check + return checker +} + //FromKprobeFile populates the KprobeFileChecker using data from a KprobeFile field func (checker *KprobeFileChecker) FromKprobeFile(event *tetragon.KprobeFile) *KprobeFileChecker { if event == nil { @@ -4291,6 +4316,7 @@ func (checker *KprobeFileChecker) FromKprobeFile(event *tetragon.KprobeFile) *Kp checker.Mount = stringmatcher.Full(event.Mount) checker.Path = stringmatcher.Full(event.Path) checker.Flags = stringmatcher.Full(event.Flags) + checker.Permission = stringmatcher.Full(event.Permission) return checker } diff --git a/api/v1/tetragon/tetragon.pb.go b/api/v1/tetragon/tetragon.pb.go index 196b62a3e5a..6f18b24aca6 100644 --- a/api/v1/tetragon/tetragon.pb.go +++ b/api/v1/tetragon/tetragon.pb.go @@ -1945,9 +1945,10 @@ type KprobePath struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Permission string `protobuf:"bytes,4,opt,name=permission,proto3" json:"permission,omitempty"` } func (x *KprobePath) Reset() { @@ -2003,14 +2004,22 @@ func (x *KprobePath) GetFlags() string { return "" } +func (x *KprobePath) GetPermission() string { + if x != nil { + return x.Permission + } + return "" +} + type KprobeFile struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Permission string `protobuf:"bytes,4,opt,name=permission,proto3" json:"permission,omitempty"` } func (x *KprobeFile) Reset() { @@ -2066,6 +2075,13 @@ func (x *KprobeFile) GetFlags() string { return "" } +func (x *KprobeFile) GetPermission() string { + if x != nil { + return x.Permission + } + return "" +} + type KprobeTruncatedBytes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4216,16 +4232,20 @@ var file_tetragon_tetragon_proto_rawDesc = []byte{ 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x22, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x65, 0x22, 0x6c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, - 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, - 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, + 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, + 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0x6c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x50, 0x0a, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1e, 0x0a, + 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x14, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x41, diff --git a/api/v1/tetragon/tetragon.proto b/api/v1/tetragon/tetragon.proto index 5ae873e83dc..ef5deaeb538 100644 --- a/api/v1/tetragon/tetragon.proto +++ b/api/v1/tetragon/tetragon.proto @@ -325,12 +325,14 @@ message KprobePath { string mount = 1; string path = 2; string flags = 3; + string permission = 4; } message KprobeFile { string mount = 1; string path = 2; string flags = 3; + string permission = 4; } message KprobeTruncatedBytes { diff --git a/bpf/process/types/basic.h b/bpf/process/types/basic.h index f4a57438603..17e2ea57de7 100644 --- a/bpf/process/types/basic.h +++ b/bpf/process/types/basic.h @@ -445,6 +445,7 @@ copy_path(char *args, const struct path *arg) int size = 0, flags = 0; char *buffer; void *curr = &args[4]; + umode_t i_mode; buffer = d_path_local(arg, &size, &flags); if (!buffer) @@ -456,12 +457,14 @@ copy_path(char *args, const struct path *arg) *s = size; size += 4; + BPF_CORE_READ_INTO(&i_mode, arg, dentry, d_inode, i_mode); + /* * the format of the path is: - * ------------------------------- - * | 4 bytes | N bytes | 4 bytes | - * | pathlen | path | flags | - * ------------------------------- + * ----------------------------------------- + * | 4 bytes | N bytes | 4 bytes | 2 bytes | + * | pathlen | path | flags | mode | + * ----------------------------------------- * Next we set up the flags. */ asm volatile goto( @@ -472,12 +475,14 @@ copy_path(char *args, const struct path *arg) "r1 += r7;\n" "r2 = *(u32 *)%[flags];\n" "*(u32 *)(r1 + 0) = r2;\n" + "r2 = *(u16 *)%[mode];\n" + "*(u16 *)(r1 + 4) = r2;\n" : - : [pid] "m"(args), [flags] "m"(flags), [offset] "+m"(size) + : [pid] "m"(args), [flags] "m"(flags), [offset] "+m"(size), [mode] "m"(i_mode) : "r0", "r1", "r2", "r7", "memory" : a); a: - size += sizeof(u32); // for the flags + size += sizeof(u32) + sizeof(u16); // for the flags + i_mode return size; } diff --git a/docs/content/en/docs/reference/grpc-api.md b/docs/content/en/docs/reference/grpc-api.md index 7eb78ae3f9f..aeda244aa11 100644 --- a/docs/content/en/docs/reference/grpc-api.md +++ b/docs/content/en/docs/reference/grpc-api.md @@ -302,6 +302,7 @@ https://github.com/opencontainers/runtime-spec/blob/main/config.md#createcontain | mount | [string](#string) | | | | path | [string](#string) | | | | flags | [string](#string) | | | +| permission | [string](#string) | | | @@ -328,6 +329,7 @@ https://github.com/opencontainers/runtime-spec/blob/main/config.md#createcontain | mount | [string](#string) | | | | path | [string](#string) | | | | flags | [string](#string) | | | +| permission | [string](#string) | | | diff --git a/pkg/api/tracingapi/client_kprobe.go b/pkg/api/tracingapi/client_kprobe.go index 5651e69e464..a8332a4f151 100644 --- a/pkg/api/tracingapi/client_kprobe.go +++ b/pkg/api/tracingapi/client_kprobe.go @@ -58,10 +58,11 @@ type MsgGenericKprobe struct { } type MsgGenericKprobeArgPath struct { - Index uint64 - Value string - Flags uint32 - Label string + Index uint64 + Value string + Flags uint32 + Permission uint16 + Label string } func (m MsgGenericKprobeArgPath) GetIndex() uint64 { @@ -73,10 +74,11 @@ func (m MsgGenericKprobeArgPath) IsReturnArg() bool { } type MsgGenericKprobeArgFile struct { - Index uint64 - Value string - Flags uint32 - Label string + Index uint64 + Value string + Flags uint32 + Permission uint16 + Label string } func (m MsgGenericKprobeArgFile) GetIndex() uint64 { diff --git a/pkg/grpc/tracing/tracing.go b/pkg/grpc/tracing/tracing.go index 5e6404c4553..0ab44b29401 100644 --- a/pkg/grpc/tracing/tracing.go +++ b/pkg/grpc/tracing/tracing.go @@ -168,15 +168,17 @@ func getKprobeArgument(arg tracingapi.MsgGenericKprobeArg) *tetragon.KprobeArgum a.Label = e.Label case api.MsgGenericKprobeArgFile: fileArg := &tetragon.KprobeFile{ - Path: e.Value, - Flags: path.FilePathFlagsToStr(e.Flags), + Path: e.Value, + Flags: path.FilePathFlagsToStr(e.Flags), + Permission: path.FilePathModeToStr(e.Permission), } a.Arg = &tetragon.KprobeArgument_FileArg{FileArg: fileArg} a.Label = e.Label case api.MsgGenericKprobeArgPath: pathArg := &tetragon.KprobePath{ - Path: e.Value, - Flags: path.FilePathFlagsToStr(e.Flags), + Path: e.Value, + Flags: path.FilePathFlagsToStr(e.Flags), + Permission: path.FilePathModeToStr(e.Permission), } a.Arg = &tetragon.KprobeArgument_PathArg{PathArg: pathArg} a.Label = e.Label 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..b7f29ba014c 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 @@ -114,6 +114,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -212,6 +213,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -863,6 +865,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -1420,6 +1423,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event 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..784f8cc18fc 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 @@ -114,6 +114,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -212,6 +213,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -863,6 +865,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -1420,6 +1423,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 7a6cc982d23..40827d0eb6a 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/types.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/types.go @@ -55,7 +55,7 @@ type KProbeArg struct { // +kubebuilder:validation:Minimum=0 // Position of the argument. Index uint32 `json:"index"` - // +kubebuilder:validation:Enum=auto;int;int8;uint8;int16;uint16;uint32;int32;uint64;int64;char_buf;char_iovec;size_t;skb;sock;string;fd;file;filename;path;nop;bpf_attr;perf_event;bpf_map;user_namespace;capability;kiocb;iov_iter;cred;load_info;module;syscall64;kernel_cap_t;cap_inheritable;cap_permitted;cap_effective;linux_binprm;data_loc;net_device + // +kubebuilder:validation:Enum=auto;int;int8;uint8;int16;uint16;uint32;int32;uint64;int64;char_buf;char_iovec;size_t;skb;sock;string;fd;file;filename;path;permission;nop;bpf_attr;perf_event;bpf_map;user_namespace;capability;kiocb;iov_iter;cred;load_info;module;syscall64;kernel_cap_t;cap_inheritable;cap_permitted;cap_effective;linux_binprm;data_loc;net_device // +kubebuilder:default=auto // Argument type. Type string `json:"type"` 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/reader/path/path.go b/pkg/reader/path/path.go index 5d657de4cd6..2e31f058e30 100644 --- a/pkg/reader/path/path.go +++ b/pkg/reader/path/path.go @@ -5,6 +5,9 @@ package path import ( "path/filepath" + "strings" + "syscall" + "unicode" "github.com/cilium/tetragon/pkg/api/processapi" ) @@ -22,3 +25,65 @@ func FilePathFlagsToStr(flags uint32) string { } return "" } + +func stickybitString(bits uint16, sticky string) byte { + if 0 == bits { + return 0 + } + + bits = bits >> 9 + for i := 2; i >= 0; i-- { + if bits&(1<= 0; i-- { + if bits&(1<>6, "xwr", stickybitString(mode&syscall.S_ISUID, "tss"))) + str.WriteString(permString((mode>>3)&7, "xwr", stickybitString(mode&syscall.S_ISGID, "tss"))) + str.WriteString(permString(mode&7, "xwr", stickybitString(mode&syscall.S_ISVTX, "tss"))) + + return str.String() +} diff --git a/pkg/sensors/tracing/args.go b/pkg/sensors/tracing/args.go index 58444113b18..3e5e676f559 100644 --- a/pkg/sensors/tracing/args.go +++ b/pkg/sensors/tracing/args.go @@ -95,6 +95,7 @@ func getArg(r *bytes.Reader, a argPrinter) tracingapi.MsgGenericKprobeArg { var arg api.MsgGenericKprobeArgFile var flags uint32 var b int32 + var mode uint16 /* Eat file descriptor its not used in userland */ if a.ty == gt.GenericFdType { @@ -122,12 +123,21 @@ func getArg(r *bytes.Reader, a argPrinter) tracingapi.MsgGenericKprobeArg { flags = 0 } + if a.ty == gt.GenericFileType || a.ty == gt.GenericKiocb { + err := binary.Read(r, binary.LittleEndian, &mode) + if err != nil { + mode = 0 + } + arg.Permission = mode + } + arg.Flags = flags arg.Label = a.label return arg case gt.GenericPathType: var arg api.MsgGenericKprobeArgPath var flags uint32 + var mode uint16 arg.Index = uint64(a.index) arg.Value, err = parseString(r) @@ -145,7 +155,13 @@ func getArg(r *bytes.Reader, a argPrinter) tracingapi.MsgGenericKprobeArg { flags = 0 } + err = binary.Read(r, binary.LittleEndian, &mode) + if err != nil { + mode = 0 + } + arg.Flags = flags + arg.Permission = mode arg.Label = a.label return arg case gt.GenericFilenameType, gt.GenericStringType, gt.GenericNetDev: diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go index ddd762eab86..a85d9478baf 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker/eventchecker.pb.go @@ -4144,9 +4144,10 @@ func (checker *KprobeNetDevChecker) FromKprobeNetDev(event *tetragon.KprobeNetDe // KprobePathChecker implements a checker struct to check a KprobePath field type KprobePathChecker struct { - Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` - Path *stringmatcher.StringMatcher `json:"path,omitempty"` - Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` + Path *stringmatcher.StringMatcher `json:"path,omitempty"` + Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Permission *stringmatcher.StringMatcher `json:"permission,omitempty"` } // NewKprobePathChecker creates a new KprobePathChecker @@ -4181,6 +4182,11 @@ func (checker *KprobePathChecker) Check(event *tetragon.KprobePath) error { return fmt.Errorf("Flags check failed: %w", err) } } + if checker.Permission != nil { + if err := checker.Permission.Match(event.Permission); err != nil { + return fmt.Errorf("Permission check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -4207,6 +4213,12 @@ func (checker *KprobePathChecker) WithFlags(check *stringmatcher.StringMatcher) return checker } +// WithPermission adds a Permission check to the KprobePathChecker +func (checker *KprobePathChecker) WithPermission(check *stringmatcher.StringMatcher) *KprobePathChecker { + checker.Permission = check + return checker +} + //FromKprobePath populates the KprobePathChecker using data from a KprobePath field func (checker *KprobePathChecker) FromKprobePath(event *tetragon.KprobePath) *KprobePathChecker { if event == nil { @@ -4215,14 +4227,16 @@ func (checker *KprobePathChecker) FromKprobePath(event *tetragon.KprobePath) *Kp checker.Mount = stringmatcher.Full(event.Mount) checker.Path = stringmatcher.Full(event.Path) checker.Flags = stringmatcher.Full(event.Flags) + checker.Permission = stringmatcher.Full(event.Permission) return checker } // KprobeFileChecker implements a checker struct to check a KprobeFile field type KprobeFileChecker struct { - Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` - Path *stringmatcher.StringMatcher `json:"path,omitempty"` - Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Mount *stringmatcher.StringMatcher `json:"mount,omitempty"` + Path *stringmatcher.StringMatcher `json:"path,omitempty"` + Flags *stringmatcher.StringMatcher `json:"flags,omitempty"` + Permission *stringmatcher.StringMatcher `json:"permission,omitempty"` } // NewKprobeFileChecker creates a new KprobeFileChecker @@ -4257,6 +4271,11 @@ func (checker *KprobeFileChecker) Check(event *tetragon.KprobeFile) error { return fmt.Errorf("Flags check failed: %w", err) } } + if checker.Permission != nil { + if err := checker.Permission.Match(event.Permission); err != nil { + return fmt.Errorf("Permission check failed: %w", err) + } + } return nil } if err := fieldChecks(); err != nil { @@ -4283,6 +4302,12 @@ func (checker *KprobeFileChecker) WithFlags(check *stringmatcher.StringMatcher) return checker } +// WithPermission adds a Permission check to the KprobeFileChecker +func (checker *KprobeFileChecker) WithPermission(check *stringmatcher.StringMatcher) *KprobeFileChecker { + checker.Permission = check + return checker +} + //FromKprobeFile populates the KprobeFileChecker using data from a KprobeFile field func (checker *KprobeFileChecker) FromKprobeFile(event *tetragon.KprobeFile) *KprobeFileChecker { if event == nil { @@ -4291,6 +4316,7 @@ func (checker *KprobeFileChecker) FromKprobeFile(event *tetragon.KprobeFile) *Kp checker.Mount = stringmatcher.Full(event.Mount) checker.Path = stringmatcher.Full(event.Path) checker.Flags = stringmatcher.Full(event.Flags) + checker.Permission = stringmatcher.Full(event.Permission) return checker } diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go index 196b62a3e5a..6f18b24aca6 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.go @@ -1945,9 +1945,10 @@ type KprobePath struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Permission string `protobuf:"bytes,4,opt,name=permission,proto3" json:"permission,omitempty"` } func (x *KprobePath) Reset() { @@ -2003,14 +2004,22 @@ func (x *KprobePath) GetFlags() string { return "" } +func (x *KprobePath) GetPermission() string { + if x != nil { + return x.Permission + } + return "" +} + type KprobeFile struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Permission string `protobuf:"bytes,4,opt,name=permission,proto3" json:"permission,omitempty"` } func (x *KprobeFile) Reset() { @@ -2066,6 +2075,13 @@ func (x *KprobeFile) GetFlags() string { return "" } +func (x *KprobeFile) GetPermission() string { + if x != nil { + return x.Permission + } + return "" +} + type KprobeTruncatedBytes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4216,16 +4232,20 @@ var file_tetragon_tetragon_proto_rawDesc = []byte{ 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x22, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x22, 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x65, 0x22, 0x6c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, - 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, - 0x4c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, + 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, + 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0x6c, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x50, 0x0a, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1e, 0x0a, + 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x14, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x41, diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto index 5ae873e83dc..ef5deaeb538 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto @@ -325,12 +325,14 @@ message KprobePath { string mount = 1; string path = 2; string flags = 3; + string permission = 4; } message KprobeFile { string mount = 1; string path = 2; string flags = 3; + string permission = 4; } message KprobeTruncatedBytes { 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..b7f29ba014c 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 @@ -114,6 +114,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -212,6 +213,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -863,6 +865,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -1420,6 +1423,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event 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..784f8cc18fc 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 @@ -114,6 +114,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -212,6 +213,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -863,6 +865,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event @@ -1420,6 +1423,7 @@ spec: - file - filename - path + - permission - nop - bpf_attr - perf_event 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..40827d0eb6a 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 @@ -55,7 +55,7 @@ type KProbeArg struct { // +kubebuilder:validation:Minimum=0 // Position of the argument. Index uint32 `json:"index"` - // +kubebuilder:validation:Enum=auto;int;int8;uint8;int16;uint16;uint32;int32;uint64;int64;char_buf;char_iovec;size_t;skb;sock;string;fd;file;filename;path;nop;bpf_attr;perf_event;bpf_map;user_namespace;capability;kiocb;iov_iter;cred;load_info;module;syscall64;kernel_cap_t;cap_inheritable;cap_permitted;cap_effective;linux_binprm;data_loc;net_device + // +kubebuilder:validation:Enum=auto;int;int8;uint8;int16;uint16;uint32;int32;uint64;int64;char_buf;char_iovec;size_t;skb;sock;string;fd;file;filename;path;permission;nop;bpf_attr;perf_event;bpf_map;user_namespace;capability;kiocb;iov_iter;cred;load_info;module;syscall64;kernel_cap_t;cap_inheritable;cap_permitted;cap_effective;linux_binprm;data_loc;net_device // +kubebuilder:default=auto // Argument type. Type string `json:"type"` 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"