diff --git a/bpf/process/bpf_generic_tracepoint.c b/bpf/process/bpf_generic_tracepoint.c index bab84891bdb..f84367b9b23 100644 --- a/bpf/process/bpf_generic_tracepoint.c +++ b/bpf/process/bpf_generic_tracepoint.c @@ -68,12 +68,14 @@ static inline __attribute__((always_inline)) unsigned long get_ctx_ul(void *src, case s64_ty: case u64_ty: { u64 ret; + probe_read(&ret, sizeof(u64), src); return ret; } case size_type: { size_t ret; + probe_read(&ret, sizeof(size_t), src); return (unsigned long)ret; } @@ -81,6 +83,7 @@ static inline __attribute__((always_inline)) unsigned long get_ctx_ul(void *src, case nop_s32_ty: case s32_ty: { s32 ret; + probe_read(&ret, sizeof(u32), src); return ret; } @@ -88,6 +91,7 @@ static inline __attribute__((always_inline)) unsigned long get_ctx_ul(void *src, case nop_u32_ty: case u32_ty: { u32 ret; + probe_read(&ret, sizeof(u32), src); return ret; } @@ -99,10 +103,31 @@ static inline __attribute__((always_inline)) unsigned long get_ctx_ul(void *src, return (unsigned long)buff; } + case data_loc_type: { + u32 ret; + + probe_read(&ret, sizeof(ret), src); + return ret; + } + case const_buf_type: { return (unsigned long)src; } + case skb_type: { + struct sk_buff *skb; + + probe_read(&skb, sizeof(struct sk_buff *), src); + return (unsigned long)skb; + } + + case sock_type: { + struct sock *sk; + + probe_read(&sk, sizeof(struct sock *), src); + return (unsigned long)sk; + } + default: case nop_ty: return 0; diff --git a/bpf/process/types/basic.h b/bpf/process/types/basic.h index e4fe4e1cf65..d479851fa11 100644 --- a/bpf/process/types/basic.h +++ b/bpf/process/types/basic.h @@ -75,6 +75,8 @@ enum { linux_binprm_type = 37, + data_loc_type = 38, + nop_s64_ty = -10, nop_u64_ty = -11, nop_u32_ty = -12, @@ -478,15 +480,15 @@ copy_path(char *args, const struct path *arg) } static inline __attribute__((always_inline)) long -copy_strings(char *args, unsigned long arg) +copy_strings(char *args, char *arg, int max_size) { int *s = (int *)args; long size; // probe_read_str() always nul-terminates the string. // So add one to the length to allow for it. This should - // result in us honouring our MAX_STRING correctly. - size = probe_read_str(&args[4], MAX_STRING + 1, (char *)arg); + // result in us honouring our max_size correctly. + size = probe_read_str(&args[4], max_size + 1, arg); if (size <= 1) return invalid_ty; // Remove the nul character from end. @@ -1801,6 +1803,7 @@ selector_arg_offset(__u8 *f, struct msg_generic_kprobe *e, __u32 selidx, pass &= filter_file_buf(filter, (struct string_buf *)args); break; case string_type: + case data_loc_type: /* for strings, we just encode the length */ pass &= filter_char_buf(filter, args, 4); break; @@ -2586,8 +2589,15 @@ read_call_arg(void *ctx, struct msg_generic_kprobe *e, int index, int type, } // fallthrough to copy_string case string_type: - size = copy_strings(args, arg); + size = copy_strings(args, (char *)arg, MAX_STRING); break; + case data_loc_type: { + // data_loc: lower 16 bits is offset from ctx; upper 16 bits is length + long dl_len = (arg >> 16) & 0xfff; // masked to 4095 chars + char *dl_loc = ctx + (arg & 0xffff); + + size = copy_strings(args, dl_loc, dl_len); + } break; case syscall64_type: case size_type: case s64_ty: diff --git a/pkg/generictypes/generictypes.go b/pkg/generictypes/generictypes.go index 3dbb749f30f..0c190db5661 100644 --- a/pkg/generictypes/generictypes.go +++ b/pkg/generictypes/generictypes.go @@ -3,6 +3,8 @@ package generictypes +import "fmt" + const ( GenericIntType = 1 GenericCharBuffer = 2 @@ -51,87 +53,114 @@ const ( GenericLinuxBinprmType = 37 + GenericDataLoc = 38 + GenericNopType = -1 GenericInvalidType = -2 ) +var GenericStringToType = map[string]int{ + "string": GenericStringType, + "int": GenericIntType, + "uint64": GenericU64Type, + "unsigned long": GenericU64Type, + "ulong": GenericU64Type, + "uint32": GenericU32Type, + "sint64": GenericS64Type, + "int64": GenericS64Type, + "long": GenericS64Type, + "sint32": GenericS32Type, + "int32": GenericS32Type, + "skb": GenericSkbType, + "sock": GenericSockType, + "size_t": GenericSizeType, + "char_buf": GenericCharBuffer, + "char_iovec": GenericCharIovec, + "filename": GenericFilenameType, + "file": GenericFileType, + "path": GenericPathType, + "fd": GenericFdType, + "cred": GenericCredType, + "const_buf": GenericConstBuffer, + "nop": GenericNopType, + "bpf_attr": GenericBpfAttr, + "perf_event": GenericPerfEvent, + "bpf_map": GenericBpfMap, + "user_namespace": GenericUserNamespace, + "capability": GenericCapability, + "kiocb": GenericKiocb, + "iov_iter": GenericIovIter, + "load_info": GenericLoadModule, + "module": GenericKernelModule, + "syscall64": GenericSyscall64, + "sint16": GenericS16Type, + "int16": GenericS16Type, + "uint16": GenericU16Type, + "sint8": GenericS8Type, + "int8": GenericS8Type, + "uint8": GenericU8Type, + "kernel_cap_t": GenericKernelCap, + "cap_inheritable": GenericCapInheritable, + "cap_permitted": GenericCapPermitted, + "cap_effective": GenericCapEffective, + "linux_binprm": GenericLinuxBinprmType, + "data_loc": GenericDataLoc, +} + +var GenericTypeToStringTable = map[int]string{ + GenericStringType: "string", + GenericIntType: "int", + GenericU64Type: "uint64", + GenericU32Type: "uint32", + GenericS64Type: "int64", + GenericS32Type: "int32", + GenericSkbType: "skb", + GenericSockType: "sock", + GenericSizeType: "size_t", + GenericCharBuffer: "char_buf", + GenericCharIovec: "char_iovec", + GenericFilenameType: "filename", + GenericFileType: "file", + GenericPathType: "path", + GenericFdType: "fd", + GenericCredType: "cred", + GenericConstBuffer: "const_buf", + GenericNopType: "nop", + GenericBpfAttr: "bpf_attr", + GenericPerfEvent: "perf_event", + GenericBpfMap: "bpf_map", + GenericUserNamespace: "user_namespace", + GenericCapability: "capability", + GenericKiocb: "kiocb", + GenericIovIter: "iov_iter", + GenericLoadModule: "load_info", + GenericKernelModule: "module", + GenericSyscall64: "syscall64", + GenericS16Type: "int16", + GenericU16Type: "uint16", + GenericS8Type: "int8", + GenericU8Type: "uint8", + GenericKernelCap: "kernel_cap_t", + GenericCapInheritable: "cap_inheritable", + GenericCapPermitted: "cap_permitted", + GenericCapEffective: "cap_effective", + GenericLinuxBinprmType: "linux_binprm", + GenericDataLoc: "data_loc", + GenericInvalidType: "", +} + func GenericTypeFromString(arg string) int { - switch arg { - case "string": - return GenericStringType - case "int": - return GenericIntType - case "uint64", "unsigned long", "ulong": - return GenericU64Type - case "uint32": - return GenericU32Type - case "sint64", "int64", "long": - return GenericS64Type - case "sint32", "int32": - return GenericS32Type - case "skb": - return GenericSkbType - case "sock": - return GenericSockType - case "size_t": - return GenericSizeType - case "char_buf": - return GenericCharBuffer - case "char_iovec": - return GenericCharIovec - case "filename": - return GenericFilenameType - case "file": - return GenericFileType - case "path": - return GenericPathType - case "fd": - return GenericFdType - case "cred": - return GenericCredType - case "const_buf": - return GenericConstBuffer - case "nop": - return GenericNopType - case "bpf_attr": - return GenericBpfAttr - case "perf_event": - return GenericPerfEvent - case "bpf_map": - return GenericBpfMap - case "user_namespace": - return GenericUserNamespace - case "capability": - return GenericCapability - case "kiocb": - return GenericKiocb - case "iov_iter": - return GenericIovIter - case "load_info": - return GenericLoadModule - case "module": - return GenericKernelModule - case "syscall64": - return GenericSyscall64 - case "sint16", "int16": - return GenericS16Type - case "uint16": - return GenericU16Type - case "sint8", "int8": - return GenericS8Type - case "uint8": - return GenericU8Type - case "kernel_cap_t": - return GenericKernelCap - case "cap_inheritable": - return GenericCapInheritable - case "cap_permitted": - return GenericCapPermitted - case "cap_effective": - return GenericCapEffective - case "linux_binprm": - return GenericLinuxBinprmType - default: - return GenericInvalidType + ty, ok := GenericStringToType[arg] + if !ok { + ty = GenericInvalidType + } + return ty +} + +func GenericTypeToString(ty int) (string, error) { + arg, ok := GenericTypeToStringTable[ty] + if !ok { + return "", fmt.Errorf("invalid argument type") } + return arg, nil } diff --git a/pkg/grpc/tracing/tracing.go b/pkg/grpc/tracing/tracing.go index 4162a8ce950..1b2239747b6 100644 --- a/pkg/grpc/tracing/tracing.go +++ b/pkg/grpc/tracing/tracing.go @@ -385,6 +385,16 @@ func (msg *MsgGenericTracepointUnix) Retry(internal *process.ProcessInternal, ev return eventcache.HandleGenericEvent(internal, ev, &msg.Msg.Tid) } +func familyString(family uint16) string { + switch family { + case unix.AF_INET: + return "AF_INET" + case unix.AF_INET6: + return "AF_INET6" + } + return "" +} + func (msg *MsgGenericTracepointUnix) HandleMessage() *tetragon.GetEventsResponse { var tetragonParent, tetragonProcess *tetragon.Process @@ -430,6 +440,46 @@ func (msg *MsgGenericTracepointUnix) HandleMessage() *tetragon.GetEventsResponse BytesArg: v, }}) + case tracingapi.MsgGenericKprobeArgSkb: + skb := tetragon.KprobeSkb{ + Family: familyString(v.Family), + Hash: v.Hash, + Len: v.Len, + Priority: v.Priority, + Mark: v.Mark, + Saddr: v.Saddr, + Daddr: v.Daddr, + Sport: v.Sport, + Dport: v.Dport, + Proto: v.Proto, + Protocol: network.InetProtocol(uint16(v.Proto)), + SecPathLen: v.SecPathLen, + SecPathOlen: v.SecPathOLen, + } + + tetragonArgs = append(tetragonArgs, &tetragon.KprobeArgument{Arg: &tetragon.KprobeArgument_SkbArg{ + SkbArg: &skb, + }}) + + case tracingapi.MsgGenericKprobeArgSock: + sk := tetragon.KprobeSock{ + Family: familyString(v.Family), + Type: network.InetType(v.Type), + Protocol: network.InetProtocol(uint16(v.Protocol)), + Mark: v.Mark, + Priority: v.Priority, + Saddr: v.Saddr, + Daddr: v.Daddr, + Sport: v.Sport, + Dport: v.Dport, + Cookie: v.Sockaddr, + State: network.TcpState(v.State), + } + + tetragonArgs = append(tetragonArgs, &tetragon.KprobeArgument{Arg: &tetragon.KprobeArgument_SockArg{ + SockArg: &sk, + }}) + default: logger.GetLogger().Warnf("handleGenericTracepointMessage: unhandled value: %+v (%T)", arg, arg) } 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 e1a961f362e..d83ff0becce 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 @@ -131,6 +131,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -227,6 +228,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -876,6 +878,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -1431,6 +1434,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index 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 27d2b6f9fdd..da8deb3a2d9 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 @@ -131,6 +131,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -227,6 +228,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -876,6 +878,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -1431,6 +1434,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 3b1b22a97cd..9dd87f6a1c9 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 + // +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 // +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 c244cfd50a1..47b1babd1bf 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.6" +const CustomResourceDefinitionSchemaVersion = "1.1.7" diff --git a/pkg/selectors/kernel.go b/pkg/selectors/kernel.go index 296603c69bb..4762002d5c5 100644 --- a/pkg/selectors/kernel.go +++ b/pkg/selectors/kernel.go @@ -12,6 +12,7 @@ import ( "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/api/processapi" + gt "github.com/cilium/tetragon/pkg/generictypes" "github.com/cilium/tetragon/pkg/idtable" "github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1" "github.com/cilium/tetragon/pkg/kernels" @@ -153,75 +154,6 @@ var capabilitiesTypeTable = map[string]uint32{ "permitted": capsPermitted, } -const ( - argTypeInt = 1 - argTypeCharBuf = 2 - argTypeCharIovec = 3 - argTypeSizet = 4 - argTypeSkb = 5 - argTypeString = 6 - argTypeSock = 7 - - argTypeS64 = 10 - argTypeU64 = 11 - argTypeS32 = 12 - argTypeU32 = 13 - - argTypePath = 15 - argTypeFile = 16 - argTypeFd = 17 - - argTypeUrl = 18 - argTypeFqdn = 19 - - // mirrors gt.GenericSyscall64 - argTypeSyscall64 = 28 - - argTypeLinuxBinprm = 29 -) - -var argTypeTable = map[string]uint32{ - "int": argTypeInt, - "uint32": argTypeU32, - "int32": argTypeS32, - "uint64": argTypeU64, - "int64": argTypeS64, - "char_buf": argTypeCharBuf, - "char_iovec": argTypeCharIovec, - "sizet": argTypeSizet, - "skb": argTypeSkb, - "string": argTypeString, - "fd": argTypeFd, - "path": argTypePath, - "file": argTypeFile, - "sock": argTypeSock, - "url": argTypeUrl, - "fqdn": argTypeFqdn, - "syscall64": argTypeSyscall64, - "linux_binprm": argTypeLinuxBinprm, -} - -var argTypeStringTable = map[uint32]string{ - argTypeInt: "int", - argTypeU32: "uint32", - argTypeS32: "int32", - argTypeU64: "uint64", - argTypeS64: "int64", - argTypeCharBuf: "char_buf", - argTypeCharIovec: "char_iovec", - argTypeSizet: "sizet", - argTypeSkb: "skb", - argTypeString: "string", - argTypeFd: "fd", - argTypeFile: "file", - argTypePath: "path", - argTypeSock: "sock", - argTypeUrl: "url", - argTypeFqdn: "fqdn", - argTypeSyscall64: "syscall64", - argTypeLinuxBinprm: "linux_binprm", -} - const ( SelectorOpGT = 1 SelectorOpLT = 2 @@ -409,14 +341,6 @@ func ParseMatchPids(k *KernelSelectorState, matchPids []v1alpha1.PIDSelector) er return nil } -func kprobeArgType(t string) uint32 { - return argTypeTable[t] -} - -func ArgTypeToString(t uint32) string { - return argTypeStringTable[t] -} - func ActionTypeFromString(action string) int32 { act, ok := actionTypeTable[strings.ToLower(action)] if !ok { @@ -430,7 +354,7 @@ func argSelectorType(arg *v1alpha1.ArgSelector, sig []v1alpha1.KProbeArg) (uint3 if arg.Index == s.Index { // TBD: We shouldn't get this far with invalid KProbe args // KProbe args have already been validated - return kprobeArgType(s.Type), nil + return uint32(gt.GenericTypeFromString(s.Type)), nil } } return 0, fmt.Errorf("argFilter for unknown index") @@ -478,14 +402,14 @@ func writeRangeInMap(v string, ty uint32, op uint32, m *ValueMap) error { } for idx := 0; idx < 2; idx++ { switch ty { - case argTypeS64, argTypeInt: + case gt.GenericIntType, gt.GenericS64Type, gt.GenericS32Type, gt.GenericS16Type, gt.GenericS8Type, gt.GenericSyscall64, gt.GenericSizeType: i, err := strconv.ParseInt(rangeStr[idx], 10, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } sRangeVal[idx] = i - case argTypeU64: + case gt.GenericU64Type, gt.GenericU32Type, gt.GenericU16Type, gt.GenericU8Type: i, err := strconv.ParseUint(rangeStr[idx], 10, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) @@ -496,7 +420,7 @@ func writeRangeInMap(v string, ty uint32, op uint32, m *ValueMap) error { } } switch ty { - case argTypeS64, argTypeInt: + case gt.GenericIntType, gt.GenericS64Type, gt.GenericS32Type, gt.GenericS16Type, gt.GenericS8Type, gt.GenericSyscall64, gt.GenericSizeType: if sRangeVal[0] > sRangeVal[1] { sRangeVal[0], sRangeVal[1] = sRangeVal[1], sRangeVal[0] } @@ -506,7 +430,7 @@ func writeRangeInMap(v string, ty uint32, op uint32, m *ValueMap) error { m.Data[valByte] = struct{}{} } - case argTypeU64: + case gt.GenericU64Type, gt.GenericU32Type, gt.GenericU16Type, gt.GenericU8Type: if uRangeVal[0] > uRangeVal[1] { uRangeVal[0], uRangeVal[1] = uRangeVal[1], uRangeVal[0] } @@ -544,9 +468,9 @@ func writeListValuesInMap(k *KernelSelectorState, v string, ty uint32, m *ValueM var val [8]byte switch ty { - case argTypeS64, argTypeInt, argTypeSyscall64: + case gt.GenericIntType, gt.GenericS64Type, gt.GenericS32Type, gt.GenericS16Type, gt.GenericS8Type, gt.GenericSyscall64, gt.GenericSizeType: binary.LittleEndian.PutUint64(val[:], uint64(values[idx])) - case argTypeU64: + case gt.GenericU64Type, gt.GenericU32Type, gt.GenericU16Type, gt.GenericU8Type: binary.LittleEndian.PutUint64(val[:], uint64(values[idx])) default: return fmt.Errorf("Unknown type: %d", ty) @@ -577,13 +501,13 @@ func writeMatchValuesInMap(k *KernelSelectorState, values []string, ty uint32, o continue } switch ty { - case argTypeS64, argTypeInt, argTypeSyscall64: + case gt.GenericIntType, gt.GenericS64Type, gt.GenericS32Type, gt.GenericS16Type, gt.GenericS8Type, gt.GenericSyscall64, gt.GenericSizeType: i, err := strconv.ParseInt(v, 10, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } binary.LittleEndian.PutUint64(val[:], uint64(i)) - case argTypeU64: + case gt.GenericU64Type, gt.GenericU32Type, gt.GenericU16Type, gt.GenericU8Type: i, err := strconv.ParseUint(v, 10, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) @@ -690,33 +614,34 @@ func writeMatchValues(k *KernelSelectorState, values []string, ty, op uint32) er for _, v := range values { base := getBase(v) switch ty { - case argTypeS32, argTypeInt, argTypeSizet: + + case gt.GenericIntType, gt.GenericS32Type, gt.GenericSizeType: i, err := strconv.ParseInt(v, base, 32) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } WriteSelectorInt32(&k.data, int32(i)) - case argTypeU32: + case gt.GenericU32Type: i, err := strconv.ParseUint(v, base, 32) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } WriteSelectorUint32(&k.data, uint32(i)) - case argTypeS64: + case gt.GenericS64Type, gt.GenericSyscall64: i, err := strconv.ParseInt(v, base, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } WriteSelectorInt64(&k.data, int64(i)) - case argTypeU64: + case gt.GenericU64Type: i, err := strconv.ParseUint(v, base, 64) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) } WriteSelectorUint64(&k.data, uint64(i)) - case argTypeSock, argTypeSkb: + case gt.GenericSockType, gt.GenericSkbType: return fmt.Errorf("MatchArgs type sock and skb do not support operator %s", selectorOpStringTable[op]) - case argTypeCharIovec: + case gt.GenericCharIovec: return fmt.Errorf("MatchArgs values %s unsupported", v) } } @@ -727,7 +652,7 @@ func writeMatchStrings(k *KernelSelectorState, values []string, ty uint32) error maps := k.createStringMaps() for _, v := range values { - trimNulSuffix := ty == argTypeString + trimNulSuffix := ty == gt.GenericStringType value, size, err := ArgStringSelectorValue(v, trimNulSuffix) if err != nil { return fmt.Errorf("MatchArgs value %s invalid: %w", v, err) @@ -791,7 +716,7 @@ func writePostfixStrings(k *KernelSelectorState, values []string, ty uint32) err for _, v := range values { var value []byte var size uint32 - if ty == argTypeCharBuf { + if ty == gt.GenericCharBuffer { value, size = ArgPostfixSelectorValue(v, false) } else { value, size = ArgPostfixSelectorValue(v, true) @@ -849,7 +774,7 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al } case SelectorOpEQ, SelectorOpNEQ: switch ty { - case argTypeFd, argTypeFile, argTypePath, argTypeString, argTypeCharBuf, argTypeLinuxBinprm: + case gt.GenericFdType, gt.GenericFileType, gt.GenericPathType, gt.GenericStringType, gt.GenericCharBuffer, gt.GenericLinuxBinprmType, gt.GenericDataLoc: err := writeMatchStrings(k, arg.Values, ty) if err != nil { return fmt.Errorf("writeMatchStrings error: %w", err) @@ -871,15 +796,15 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al return fmt.Errorf("writePostfixStrings error: %w", err) } case SelectorOpSport, SelectorOpDport, SelectorOpNotSport, SelectorOpNotDport, SelectorOpProtocol, SelectorOpFamily, SelectorOpState: - if ty != argTypeSock && ty != argTypeSkb { + if ty != gt.GenericSockType && ty != gt.GenericSkbType { return fmt.Errorf("sock/skb operators specified for non-sock/skb type") } - err := writeMatchRangesInMap(k, arg.Values, argTypeU64, op) // force type for ports and protocols as ty is sock/skb + err := writeMatchRangesInMap(k, arg.Values, gt.GenericU64Type, op) // force type for ports and protocols as ty is sock/skb if err != nil { return fmt.Errorf("writeMatchRangesInMap error: %w", err) } case SelectorOpSaddr, SelectorOpDaddr, SelectorOpNotSaddr, SelectorOpNotDaddr: - if ty != argTypeSock && ty != argTypeSkb { + if ty != gt.GenericSockType && ty != gt.GenericSkbType { return fmt.Errorf("sock/skb operators specified for non-sock/skb type") } err := writeMatchAddrsInMap(k, arg.Values) @@ -888,7 +813,7 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al } case SelectorOpSportPriv, SelectorOpDportPriv, SelectorOpNotSportPriv, SelectorOpNotDportPriv: // These selectors do not take any values, but we do check that they are only used for sock/skb. - if ty != argTypeSock && ty != argTypeSkb { + if ty != gt.GenericSockType && ty != gt.GenericSkbType { return fmt.Errorf("sock/skb operators specified for non-sock/skb type") } default: diff --git a/pkg/selectors/kernel_test.go b/pkg/selectors/kernel_test.go index 05824be58c9..73edf9182a4 100644 --- a/pkg/selectors/kernel_test.go +++ b/pkg/selectors/kernel_test.go @@ -12,6 +12,7 @@ import ( "strings" "testing" + gt "github.com/cilium/tetragon/pkg/generictypes" "github.com/cilium/tetragon/pkg/idtable" "github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1" "github.com/cilium/tetragon/pkg/kernels" @@ -556,34 +557,34 @@ 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(24) // off: 16 selector1: MatchPIDs: len - expU32Push(SelectorOpNotIn) // off: 20 selector1: MatchPIDs[0]: op - expU32Push(0) // off: 24 selector1: MatchPIDs[0]: flags - expU32Push(2) // off: 28 selector1: MatchPIDs[0]: number of values - expU32Push(33) // off: 32 selector1: MatchPIDs[0]: val1 - expU32Push(44) // off: 36 selector1: MatchPIDs[0]: val2 - expU32Push(4) // off: 40 selector1: MatchNamespaces: len - expU32Push(4) // off: 44 selector1: MatchCapabilities: len - expU32Push(4) // off: 48 selector1: MatchNamespaceChanges: len - expU32Push(4) // off: 52 selector1: MatchCapabilityChanges: len - expU32Push(48) // off: 80 selector1: matchArgs: len - expU32Push(24) // off: 84 selector1: matchArgs[0]: offset - expU32Push(0) // off: 88 selector1: matchArgs[1]: offset - expU32Push(0) // off: 92 selector1: matchArgs[2]: offset - expU32Push(0) // off: 96 selector1: matchArgs[3]: offset - expU32Push(0) // off: 100 selector1: matchArgs[4]: offset - expU32Push(1) // off: 104 selector1: matchArgs: arg0: index - expU32Push(SelectorOpEQ) // off: 108 selector1: matchArgs: arg0: operator - expU32Push(16) // off: 112 selector1: matchArgs: arg0: len of vals - expU32Push(argTypeInt) // off: 116 selector1: matchArgs: arg0: type - 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(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(24) // off: 16 selector1: MatchPIDs: len + expU32Push(SelectorOpNotIn) // off: 20 selector1: MatchPIDs[0]: op + expU32Push(0) // off: 24 selector1: MatchPIDs[0]: flags + expU32Push(2) // off: 28 selector1: MatchPIDs[0]: number of values + expU32Push(33) // off: 32 selector1: MatchPIDs[0]: val1 + expU32Push(44) // off: 36 selector1: MatchPIDs[0]: val2 + expU32Push(4) // off: 40 selector1: MatchNamespaces: len + expU32Push(4) // off: 44 selector1: MatchCapabilities: len + expU32Push(4) // off: 48 selector1: MatchNamespaceChanges: len + expU32Push(4) // off: 52 selector1: MatchCapabilityChanges: len + expU32Push(48) // off: 80 selector1: matchArgs: len + expU32Push(24) // off: 84 selector1: matchArgs[0]: offset + expU32Push(0) // off: 88 selector1: matchArgs[1]: offset + expU32Push(0) // off: 92 selector1: matchArgs[2]: offset + expU32Push(0) // off: 96 selector1: matchArgs[3]: offset + expU32Push(0) // off: 100 selector1: matchArgs[4]: offset + expU32Push(1) // off: 104 selector1: matchArgs: arg0: index + expU32Push(SelectorOpEQ) // off: 108 selector1: matchArgs: arg0: operator + expU32Push(16) // off: 112 selector1: matchArgs: arg0: len of vals + expU32Push(gt.GenericIntType) // off: 116 selector1: matchArgs: arg0: type + 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 // ... everything else should be the same as selector1 ... if bytes.Equal(expected[:expectedLen], b[:expectedLen]) == false { @@ -892,22 +893,22 @@ func TestReturnSelectorArgInt(t *testing.T) { expectedLen += 4 } - expU32Push(1) // off: 0 number of selectors - expU32Push(4) // off: 4 relative ofset of selector (4 + 4 = 8) - expU32Push(56) // off: 8 selector: length - expU32Push(48) // off: 12 selector: matchReturnArgs length - expU32Push(24) // off: 16 selector: matchReturnArgs arg offset[0] - expU32Push(0) // off: 20 selector: matchReturnArgs arg offset[1] - expU32Push(0) // off: 24 selector: matchReturnArgs arg offset[2] - expU32Push(0) // off: 28 selector: matchReturnArgs arg offset[3] - expU32Push(0) // off: 32 selector: matchReturnArgs arg offset[4] - expU32Push(0) // off: 36 selector: matchReturnArgs[0].Index - expU32Push(SelectorOpEQ) // off: 40 selector: matchReturnArgs[0].Operator - expU32Push(16) // off: 44 selector: length (4 + 3*4) = 16 - expU32Push(argTypeInt) // off: 48 selector: matchReturnArgs[0].Type - expU32Push(10) // off: 52 selector: matchReturnArgs[0].Values[0] - expU32Push(20) // off: 56 selector: matchReturnArgs[0].Values[1] - expU32Push(4) // off: 60 selector: MatchActions length + expU32Push(1) // off: 0 number of selectors + expU32Push(4) // off: 4 relative ofset of selector (4 + 4 = 8) + expU32Push(56) // off: 8 selector: length + expU32Push(48) // off: 12 selector: matchReturnArgs length + expU32Push(24) // off: 16 selector: matchReturnArgs arg offset[0] + expU32Push(0) // off: 20 selector: matchReturnArgs arg offset[1] + expU32Push(0) // off: 24 selector: matchReturnArgs arg offset[2] + expU32Push(0) // off: 28 selector: matchReturnArgs arg offset[3] + expU32Push(0) // off: 32 selector: matchReturnArgs arg offset[4] + expU32Push(0) // off: 36 selector: matchReturnArgs[0].Index + expU32Push(SelectorOpEQ) // off: 40 selector: matchReturnArgs[0].Operator + expU32Push(16) // off: 44 selector: length (4 + 3*4) = 16 + expU32Push(gt.GenericIntType) // off: 48 selector: matchReturnArgs[0].Type + expU32Push(10) // off: 52 selector: matchReturnArgs[0].Values[0] + expU32Push(20) // off: 56 selector: matchReturnArgs[0].Values[1] + expU32Push(4) // off: 60 selector: MatchActions length if bytes.Equal(expected[:expectedLen], b[:expectedLen]) == false { t.Errorf("\ngot: %v\nexp: %v\n", b[:expectedLen], expected[:expectedLen]) diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index 2b3293653b2..2e8274195c4 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -24,6 +24,7 @@ import ( "github.com/cilium/tetragon/pkg/observer" "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/policyfilter" + "github.com/cilium/tetragon/pkg/reader/network" "github.com/cilium/tetragon/pkg/selectors" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/sensors/program" @@ -505,7 +506,10 @@ func (tp *genericTracepoint) InitKernelSelectors(lists []v1alpha1.ListSpec) erro if err != nil { return fmt.Errorf("output argument %v unsupported: %w", tpArg, err) } - selType := selectors.ArgTypeToString(uint32(ty)) + selType, err := gt.GenericTypeToString(ty) + if err != nil { + return fmt.Errorf("output argument %v type not found: %w", tpArg, err) + } // NB: this a selector argument, meant to be passed to InitKernelSelectors. // The only fields needed for the latter are Index and Type @@ -745,12 +749,55 @@ func handleMsgGenericTracepoint( logger.GetLogger().Warnf("failed to read array argument: unexpected base type: %w", intTy.Base) } } - case gt.GenericStringType: + case gt.GenericStringType, gt.GenericDataLoc: if arg, err := parseString(r); err != nil { logger.GetLogger().WithError(err).Warn("error parsing arg type string") } else { unix.Args = append(unix.Args, arg) } + case gt.GenericSkbType: + var skb api.MsgGenericKprobeSkb + var arg api.MsgGenericKprobeArgSkb + + err := binary.Read(r, binary.LittleEndian, &skb) + if err != nil { + logger.GetLogger().WithError(err).Warnf("skb type err") + } + + arg.Hash = skb.Hash + arg.Len = skb.Len + arg.Priority = skb.Priority + arg.Mark = skb.Mark + arg.Family = skb.Tuple.Family + arg.Saddr = network.GetIP(skb.Tuple.Saddr, skb.Tuple.Family).String() + arg.Daddr = network.GetIP(skb.Tuple.Daddr, skb.Tuple.Family).String() + arg.Sport = uint32(skb.Tuple.Sport) + arg.Dport = uint32(skb.Tuple.Dport) + arg.Proto = uint32(skb.Tuple.Protocol) + arg.SecPathLen = skb.SecPathLen + arg.SecPathOLen = skb.SecPathOLen + unix.Args = append(unix.Args, arg) + case gt.GenericSockType: + var sock api.MsgGenericKprobeSock + var arg api.MsgGenericKprobeArgSock + + err := binary.Read(r, binary.LittleEndian, &sock) + if err != nil { + logger.GetLogger().WithError(err).Warnf("sock type err") + } + + arg.Family = sock.Tuple.Family + arg.State = sock.State + arg.Type = sock.Type + arg.Protocol = sock.Tuple.Protocol + arg.Mark = sock.Mark + arg.Priority = sock.Priority + arg.Saddr = network.GetIP(sock.Tuple.Saddr, sock.Tuple.Family).String() + arg.Daddr = network.GetIP(sock.Tuple.Daddr, sock.Tuple.Family).String() + arg.Sport = uint32(sock.Tuple.Sport) + arg.Dport = uint32(sock.Tuple.Dport) + arg.Sockaddr = sock.Sockaddr + unix.Args = append(unix.Args, arg) default: logger.GetLogger().Warnf("handleGenericTracepoint: ignoring: %+v", out) 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 e1a961f362e..d83ff0becce 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 @@ -131,6 +131,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -227,6 +228,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -876,6 +878,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -1431,6 +1434,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index 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 27d2b6f9fdd..da8deb3a2d9 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 @@ -131,6 +131,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -227,6 +228,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -876,6 +878,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index @@ -1431,6 +1434,7 @@ spec: - cap_permitted - cap_effective - linux_binprm + - data_loc type: string required: - index 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 3b1b22a97cd..9dd87f6a1c9 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 + // +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 // +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 c244cfd50a1..47b1babd1bf 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.6" +const CustomResourceDefinitionSchemaVersion = "1.1.7"