From 2d6e64019b0ba10f35b6add02426331a78f085ac Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Thu, 5 May 2022 19:27:16 -0700 Subject: [PATCH] Faster proto serialization The use of protobuf.Any is convenient, but adds to proto serialization time and number of memory allocations required to send a message. Instead, we now use an enum to indentify the message and use it to determine how to unmarshall the message on the receiveing end. It also speeds up event consuption by not requiring a map from string (proto names) to callbacks. BenchmarkProtoAny-6 115.9 ns/op 210 B/op 4 allocs/op BenchmarkProtoEnum-6 58.3 ns/op 2 B/op 1 allocs/op Updates #4805 PiperOrigin-RevId: 446879057 --- examples/seccheck/server.cc | 95 ++++++++----------- pkg/sentry/kernel/syscalls.go | 2 +- pkg/sentry/kernel/task_syscall.go | 9 +- pkg/sentry/seccheck/checkers/remote/BUILD | 1 - pkg/sentry/seccheck/checkers/remote/remote.go | 60 ++++++------ .../seccheck/checkers/remote/remote_test.go | 65 +++++++++++-- pkg/sentry/seccheck/points/common.proto | 19 ++++ pkg/sentry/seccheck/seccheck.go | 4 +- pkg/sentry/syscalls/linux/points.go | 36 +++---- 9 files changed, 166 insertions(+), 125 deletions(-) diff --git a/examples/seccheck/server.cc b/examples/seccheck/server.cc index f4a73fada..025280dc2 100644 --- a/examples/seccheck/server.cc +++ b/examples/seccheck/server.cc @@ -26,16 +26,14 @@ #include #include -#include "google/protobuf/any.pb.h" #include "absl/cleanup/cleanup.h" #include "absl/strings/string_view.h" #include "pkg/sentry/seccheck/points/container.pb.h" #include "pkg/sentry/seccheck/points/sentry.pb.h" #include "pkg/sentry/seccheck/points/syscall.pb.h" -typedef std::function Callback; +typedef std::function Callback; -constexpr size_t prefixLen = sizeof("type.googleapis.com/") - 1; constexpr size_t maxEventSize = 300 * 1024; bool quiet = false; @@ -43,6 +41,7 @@ bool quiet = false; #pragma pack(push, 1) struct header { uint16_t header_size; + uint16_t message_type; uint32_t dropped_count; }; #pragma pack(pop) @@ -57,52 +56,49 @@ void log(const char* fmt, ...) { } template -void unpackSyscall(const google::protobuf::Any& any) { +void unpackSyscall(absl::string_view buf) { T evt; - if (!any.UnpackTo(&evt)) { - err(1, "UnpackTo(): %s", any.DebugString().c_str()); + if (!evt.ParseFromArray(buf.data(), buf.size())) { + err(1, "ParseFromString(): %.*s", static_cast(buf.size()), buf.data()); } - auto last_dot = any.type_url().find_last_of('.'); - if (last_dot == std::string::npos) { - err(1, "invalid name: %.*s", static_cast(any.type_url().size()), - any.type_url().data()); - } - auto name = any.type_url().substr(last_dot + 1); - log("%s %.*s %s\n", evt.has_exit() ? "X" : "E", static_cast(name.size()), - name.data(), evt.ShortDebugString().c_str()); -} - -template -void unpack(const google::protobuf::Any& any) { - T evt; - if (!any.UnpackTo(&evt)) { - err(1, "UnpackTo(): %s", any.DebugString().c_str()); - } - auto name = any.type_url().substr(prefixLen); - log("%.*s => %s\n", static_cast(name.size()), name.data(), + log("%s %s %s\n", evt.has_exit() ? "X" : "E", + evt.GetMetadata().descriptor->name().c_str(), evt.ShortDebugString().c_str()); } -std::map dispatchers = { - {"gvisor.syscall.Syscall", unpackSyscall<::gvisor::syscall::Syscall>}, - {"gvisor.syscall.Read", unpackSyscall<::gvisor::syscall::Read>}, - {"gvisor.syscall.Open", unpackSyscall<::gvisor::syscall::Open>}, - {"gvisor.syscall.Connect", unpackSyscall<::gvisor::syscall::Connect>}, - {"gvisor.syscall.Execve", unpackSyscall<::gvisor::syscall::Execve>}, - {"gvisor.syscall.Close", unpackSyscall<::gvisor::syscall::Close>}, - {"gvisor.syscall.Socket", unpackSyscall<::gvisor::syscall::Socket>}, - {"gvisor.container.Start", unpack<::gvisor::container::Start>}, - {"gvisor.sentry.CloneInfo", unpack<::gvisor::sentry::CloneInfo>}, - {"gvisor.sentry.ExecveInfo", unpack<::gvisor::sentry::ExecveInfo>}, - {"gvisor.sentry.ExitNotifyParentInfo", - unpack<::gvisor::sentry::ExitNotifyParentInfo>}, - {"gvisor.sentry.TaskExit", unpack<::gvisor::sentry::TaskExit>}, +template +void unpack(absl::string_view buf) { + T evt; + if (!evt.ParseFromArray(buf.data(), buf.size())) { + err(1, "ParseFromString(): %.*s", static_cast(buf.size()), buf.data()); + } + log("%s => %s\n", evt.GetMetadata().descriptor->name().c_str(), + evt.ShortDebugString().c_str()); +} + +// List of dispatchers indexed based on MessageType enum values. +std::vector dispatchers = { + nullptr, + unpack<::gvisor::container::Start>, + unpack<::gvisor::sentry::CloneInfo>, + unpack<::gvisor::sentry::ExecveInfo>, + unpack<::gvisor::sentry::ExitNotifyParentInfo>, + unpack<::gvisor::sentry::TaskExit>, + unpackSyscall<::gvisor::syscall::Syscall>, + unpackSyscall<::gvisor::syscall::Open>, + unpackSyscall<::gvisor::syscall::Close>, + unpackSyscall<::gvisor::syscall::Read>, + unpackSyscall<::gvisor::syscall::Connect>, + unpackSyscall<::gvisor::syscall::Execve>, + unpackSyscall<::gvisor::syscall::Socket>, }; -void unpack(const absl::string_view buf) { +void unpack(absl::string_view buf) { const header* hdr = reinterpret_cast(&buf[0]); + + // Payload size can be zero when proto object contains only defaults values. size_t payload_size = buf.size() - hdr->header_size; - if (payload_size <= 0) { + if (payload_size < 0) { printf("Header size (%u) is larger than message %lu\n", hdr->header_size, buf.size()); return; @@ -115,23 +111,12 @@ void unpack(const absl::string_view buf) { return; } - google::protobuf::Any any; - if (!any.ParseFromArray(proto.data(), proto.size())) { - err(1, "invalid proto message"); - } - - auto url = any.type_url(); - if (url.size() <= prefixLen) { - printf("Invalid URL %s\n", any.type_url().data()); + if (hdr->message_type == 0 || hdr->message_type >= dispatchers.size()) { + printf("Invalid message type: %u\n", hdr->message_type); return; } - const std::string name(url.substr(prefixLen)); - Callback cb = dispatchers[name]; - if (cb == nullptr) { - printf("No callback registered for %s. Skipping it...\n", name.c_str()); - } else { - cb(any); - } + Callback cb = dispatchers[hdr->message_type]; + cb(proto); } void* pollLoop(void* ptr) { diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 0744c022c..60e14dc0c 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -399,7 +399,7 @@ func (s *SyscallTable) LookupSyscallToProto(sysno uintptr) SyscallToProto { // SyscallToProto is a callback function that converts generic syscall data to // schematized protobuf for the corresponding syscall. -type SyscallToProto func(*Task, seccheck.FieldSet, *pb.ContextData, SyscallInfo) proto.Message +type SyscallToProto func(*Task, seccheck.FieldSet, *pb.ContextData, SyscallInfo) (proto.Message, pb.MessageType) // SyscallInfo provides generic information about the syscall. type SyscallInfo struct { diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 28b235705..900a9de18 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -120,11 +120,10 @@ func (t *Task) executeSyscall(sysno uintptr, args arch.SyscallArguments) (rval u Sysno: sysno, Args: args, } - // TODO(fvoznika): Make cb take a *Task instead of Context. cb := t.SyscallTable().LookupSyscallToProto(sysno) - msg := cb(t, fields, ctxData, info) + msg, msgType := cb(t, fields, ctxData, info) seccheck.Global.SendToCheckers(func(c seccheck.Checker) error { - return c.Syscall(t, fields, ctxData, msg) + return c.Syscall(t, fields, ctxData, msgType, msg) }) } @@ -197,9 +196,9 @@ func (t *Task) executeSyscall(sysno uintptr, args arch.SyscallArguments) (rval u Rval: rval, Errno: ExtractErrno(err, int(sysno)), } - msg := cb(t, fields, ctxData, info) + msg, msgType := cb(t, fields, ctxData, info) seccheck.Global.SendToCheckers(func(c seccheck.Checker) error { - return c.Syscall(t, fields, ctxData, msg) + return c.Syscall(t, fields, ctxData, msgType, msg) }) } diff --git a/pkg/sentry/seccheck/checkers/remote/BUILD b/pkg/sentry/seccheck/checkers/remote/BUILD index c3b0e8034..200e2ece4 100644 --- a/pkg/sentry/seccheck/checkers/remote/BUILD +++ b/pkg/sentry/seccheck/checkers/remote/BUILD @@ -15,7 +15,6 @@ go_library( "//pkg/sentry/seccheck", "//pkg/sentry/seccheck/points:points_go_proto", "@org_golang_google_protobuf//proto:go_default_library", - "@org_golang_google_protobuf//types/known/anypb:go_default_library", "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/seccheck/checkers/remote/remote.go b/pkg/sentry/seccheck/checkers/remote/remote.go index d919d677f..8832c61a7 100644 --- a/pkg/sentry/seccheck/checkers/remote/remote.go +++ b/pkg/sentry/seccheck/checkers/remote/remote.go @@ -29,7 +29,6 @@ import ( "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/sentry/seccheck" - "google.golang.org/protobuf/types/known/anypb" pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto" ) @@ -47,8 +46,6 @@ func init() { // be sent, e.g. buffer full, the point is dropped on the floor to avoid // delaying/hanging indefinitely the application. type Remote struct { - seccheck.CheckerDefaults - endpoint *fd.FD } @@ -106,6 +103,10 @@ func New(_ map[string]interface{}, endpoint *fd.FD) (seccheck.Checker, error) { // Header is used to describe the message being sent to the remote process. // +// 0 --------- 16 ---------- 32 ----------- 64 -----------+ +// | HeaderSize | MessageType | DroppedCount | Payload... | +// +---- 16 ----+---- 16 -----+----- 32 -----+------------+ +// // +marshal type Header struct { // HeaderSize is the size of the header in bytes. The payload comes @@ -113,7 +114,13 @@ type Header struct { // expand in the future without breaking remotes that do not yet understand // the new fields. HeaderSize uint16 - _ uint16 + + // MessageType describes the payload. It must be one of the pb.MessageType + // values and determine how the payload is interpreted. This is more efficient + // than using protobuf.Any because Any uses the full protobuf name to identify + // the type. + MessageType uint16 + // DroppedCount is the number of points that failed to be written and had to // be dropped. It wraps around after max(uint32). DroppedCount uint32 @@ -122,78 +129,65 @@ type Header struct { // headerStructSize size of header struct in bytes. const headerStructSize = 8 -// TODO(gvisor.dev/issue/4805) Any requires writing the full type URL to the -// message. We're not memory bandwidth bound, but having an enum event type in -// the header to identify the proto type would reduce message size and speed -// up event dispatch in the consumer. -func (r *Remote) writeAny(any *anypb.Any) error { - out, err := proto.Marshal(any) +func (r *Remote) write(msg proto.Message, msgType pb.MessageType) { + out, err := proto.Marshal(msg) if err != nil { - return err + log.Debugf("Marshal(%+v): %v", msg, err) + return } hdr := Header{ - HeaderSize: uint16(headerStructSize), + HeaderSize: uint16(headerStructSize), + MessageType: uint16(msgType), } var hdrOut [headerStructSize]byte hdr.MarshalUnsafe(hdrOut[:]) // TODO(gvisor.dev/issue/4805): Change to non-blocking write. Count as dropped // if write fails. - _, err = unix.Writev(r.endpoint.FD(), [][]byte{hdrOut[:], out}) - return err -} - -func (r *Remote) write(msg proto.Message) { - any, err := anypb.New(msg) - if err != nil { - log.Debugf("anypd.New(%+v): %v", msg, err) + if _, err = unix.Writev(r.endpoint.FD(), [][]byte{hdrOut[:], out}); err != nil { + log.Debugf("write(%+v, %v): %v", msg, msgType, err) return } - if err := r.writeAny(any); err != nil { - log.Debugf("writeAny(%+v): %v", any, err) - return - } - return } // Clone implements seccheck.Checker. func (r *Remote) Clone(_ context.Context, _ seccheck.FieldSet, info *pb.CloneInfo) error { - r.write(info) + r.write(info, pb.MessageType_MESSAGE_SENTRY_CLONE) return nil } // Execve implements seccheck.Checker. func (r *Remote) Execve(_ context.Context, _ seccheck.FieldSet, info *pb.ExecveInfo) error { - r.write(info) + r.write(info, pb.MessageType_MESSAGE_SENTRY_EXEC) return nil } // ExitNotifyParent implements seccheck.Checker. func (r *Remote) ExitNotifyParent(_ context.Context, _ seccheck.FieldSet, info *pb.ExitNotifyParentInfo) error { - r.write(info) + r.write(info, pb.MessageType_MESSAGE_SENTRY_EXIT_NOTIFY_PARENT) return nil } // TaskExit implements seccheck.Checker. func (r *Remote) TaskExit(_ context.Context, _ seccheck.FieldSet, info *pb.TaskExit) error { - r.write(info) + r.write(info, pb.MessageType_MESSAGE_SENTRY_TASK_EXIT) return nil } // ContainerStart implements seccheck.Checker. func (r *Remote) ContainerStart(_ context.Context, _ seccheck.FieldSet, info *pb.Start) error { - r.write(info) + r.write(info, pb.MessageType_MESSAGE_CONTAINER_START) return nil } // RawSyscall implements seccheck.Checker. func (r *Remote) RawSyscall(_ context.Context, _ seccheck.FieldSet, info *pb.Syscall) error { - r.write(info) + r.write(info, pb.MessageType_MESSAGE_SYSCALL_RAW) return nil } // Syscall implements seccheck.Checker. -func (r *Remote) Syscall(ctx context.Context, fields seccheck.FieldSet, ctxData *pb.ContextData, msg proto.Message) error { - r.write(msg) +func (r *Remote) Syscall(ctx context.Context, fields seccheck.FieldSet, ctxData *pb.ContextData, msgType pb.MessageType, msg proto.Message) error { + r.write(msg, msgType) return nil } diff --git a/pkg/sentry/seccheck/checkers/remote/remote_test.go b/pkg/sentry/seccheck/checkers/remote/remote_test.go index 6091b3fd9..18b994d36 100644 --- a/pkg/sentry/seccheck/checkers/remote/remote_test.go +++ b/pkg/sentry/seccheck/checkers/remote/remote_test.go @@ -98,7 +98,12 @@ type server struct { mu sync.Mutex // +checklocks:mu - points []*anypb.Any + points []message +} + +type message struct { + msgType pb.MessageType + msg []byte } func newServer() (*server, error) { @@ -172,9 +177,9 @@ func (s *server) handleClient(client int) { } hdr := Header{} hdr.UnmarshalUnsafe(buf[0:headerStructSize]) - msg := &anypb.Any{} - if err := proto.Unmarshal(buf[hdr.HeaderSize:read], msg); err != nil { - panic("invalid proto") + msg := message{ + msgType: pb.MessageType(hdr.MessageType), + msg: buf[hdr.HeaderSize:read], } s.mu.Lock() s.points = append(s.points, msg) @@ -188,10 +193,10 @@ func (s *server) count() int { return len(s.points) } -func (s *server) getPoints() []*anypb.Any { +func (s *server) getPoints() []message { s.mu.Lock() defer s.mu.Unlock() - cpy := make([]*anypb.Any, len(s.points)) + cpy := make([]message, len(s.points)) copy(cpy, s.points) return cpy } @@ -242,11 +247,14 @@ func TestBasic(t *testing.T) { if want, got := 1, server.count(); want != got { t.Errorf("wrong number of points, want: %d, got: %d", want, got) } - any := server.getPoints()[0] + pt := server.getPoints()[0] + if want := pb.MessageType_MESSAGE_SENTRY_EXIT_NOTIFY_PARENT; pt.msgType != want { + t.Errorf("wrong message type, want: %v, got: %v", want, pt.msgType) + } got := &pb.ExitNotifyParentInfo{} - if err := any.UnmarshalTo(got); err != nil { - t.Errorf("any.UnmarshallTo(ExitNotifyParentInfo): %v", err) + if err := proto.Unmarshal(pt.msg, got); err != nil { + t.Errorf("proto.Unmarshal(ExitNotifyParentInfo): %v", err) } if !proto.Equal(info, got) { t.Errorf("Received point is different, want: %+v, got: %+v", info, got) @@ -286,7 +294,7 @@ func TestExample(t *testing.T) { gotRaw := server.out.String() // Collapse whitespace. got := strings.Join(strings.Fields(gotRaw), " ") - if !strings.Contains(got, "gvisor.sentry.ExitNotifyParentInfo => exit_status: 123") { + if !strings.Contains(got, "ExitNotifyParentInfo => exit_status: 123") { return fmt.Errorf("ExitNotifyParentInfo point didn't get to the server, out: %q, raw: %q", got, gotRaw) } return nil @@ -296,6 +304,13 @@ func TestExample(t *testing.T) { } } +func TestHeaderSize(t *testing.T) { + hdr := Header{} + if want, got := hdr.SizeBytes(), hdr.SizeBytes(); want != got { + t.Errorf("wrong const header size, want: %v, got: %v", want, got) + } +} + func BenchmarkSmall(t *testing.B) { // Run server in a separate process just to isolate it as much as possible. server, err := newExampleServer(false) @@ -330,3 +345,33 @@ func BenchmarkSmall(t *testing.B) { } }) } + +func BenchmarkProtoAny(t *testing.B) { + info := &pb.ExitNotifyParentInfo{ExitStatus: 123} + + t.ResetTimer() + t.RunParallel(func(sub *testing.PB) { + for sub.Next() { + any, err := anypb.New(info) + if err != nil { + t.Fatal(err) + } + if _, err := proto.Marshal(any); err != nil { + t.Fatal(err) + } + } + }) +} + +func BenchmarkProtoEnum(t *testing.B) { + info := &pb.ExitNotifyParentInfo{ExitStatus: 123} + + t.ResetTimer() + t.RunParallel(func(sub *testing.PB) { + for sub.Next() { + if _, err := proto.Marshal(info); err != nil { + t.Fatal(err) + } + } + }) +} diff --git a/pkg/sentry/seccheck/points/common.proto b/pkg/sentry/seccheck/points/common.proto index b087f9619..11aabfc42 100644 --- a/pkg/sentry/seccheck/points/common.proto +++ b/pkg/sentry/seccheck/points/common.proto @@ -45,3 +45,22 @@ message ContextData { string process_name = 9; } + +// MessageType describes the payload of a message sent to the remote process. +// LINT.IfChange +enum MessageType { + MESSAGE_UNKNOWN = 0; + MESSAGE_CONTAINER_START = 1; + MESSAGE_SENTRY_CLONE = 2; + MESSAGE_SENTRY_EXEC = 3; + MESSAGE_SENTRY_EXIT_NOTIFY_PARENT = 4; + MESSAGE_SENTRY_TASK_EXIT = 5; + MESSAGE_SYSCALL_RAW = 6; + MESSAGE_SYSCALL_OPEN = 7; + MESSAGE_SYSCALL_CLOSE = 8; + MESSAGE_SYSCALL_READ = 9; + MESSAGE_SYSCALL_CONNECT = 10; + MESSAGE_SYSCALL_EXECVE = 11; + MESSAGE_SYSCALL_SOCKET = 12; +} +// LINT.ThenChange(../../../../examples/seccheck/server.cc) diff --git a/pkg/sentry/seccheck/seccheck.go b/pkg/sentry/seccheck/seccheck.go index 9b4a7351d..ec2858a4a 100644 --- a/pkg/sentry/seccheck/seccheck.go +++ b/pkg/sentry/seccheck/seccheck.go @@ -103,7 +103,7 @@ type Checker interface { ContainerStart(context.Context, FieldSet, *pb.Start) error - Syscall(context.Context, FieldSet, *pb.ContextData, proto.Message) error + Syscall(context.Context, FieldSet, *pb.ContextData, pb.MessageType, proto.Message) error RawSyscall(context.Context, FieldSet, *pb.Syscall) error } @@ -144,7 +144,7 @@ func (CheckerDefaults) RawSyscall(context.Context, FieldSet, *pb.Syscall) error } // Syscall implements Checker.Syscall. -func (CheckerDefaults) Syscall(context.Context, FieldSet, *pb.ContextData, proto.Message) error { +func (CheckerDefaults) Syscall(context.Context, FieldSet, *pb.ContextData, pb.MessageType, proto.Message) error { return nil } diff --git a/pkg/sentry/syscalls/linux/points.go b/pkg/sentry/syscalls/linux/points.go index a13e44753..f6587b211 100644 --- a/pkg/sentry/syscalls/linux/points.go +++ b/pkg/sentry/syscalls/linux/points.go @@ -54,7 +54,7 @@ func getFilePath(t *kernel.Task, fd int32) string { } // PointOpen converts open(2) syscall to proto. -func PointOpen(t *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointOpen(t *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Open{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -70,11 +70,11 @@ func PointOpen(t *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, inf } } p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_OPEN } // PointOpenat converts openat(2) syscall to proto. -func PointOpenat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointOpenat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Open{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -99,11 +99,11 @@ func PointOpenat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextDa p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_OPEN } // PointCreat converts creat(2) syscall to proto. -func PointCreat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointCreat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Open{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -126,11 +126,11 @@ func PointCreat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextDat p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_OPEN } // PointClose converts close(2) syscall to proto. -func PointClose(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointClose(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Close{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -142,11 +142,11 @@ func PointClose(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextDat } p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_CLOSE } // PointRead converts read(2) syscall to proto. -func PointRead(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointRead(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Read{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -159,11 +159,11 @@ func PointRead(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_READ } // PointSocket converts socket(2) syscall to proto. -func PointSocket(_ *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointSocket(_ *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Socket{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -174,11 +174,11 @@ func PointSocket(_ *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, i p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_SOCKET } // PointConnect converts connect(2) syscall to proto. -func PointConnect(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointConnect(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Connect{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -198,11 +198,11 @@ func PointConnect(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextD p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_CONNECT } // PointExecve converts execve(2) syscall to proto. -func PointExecve(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointExecve(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Execve{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -226,11 +226,11 @@ func PointExecve(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextDa p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_EXECVE } // PointExecveat converts execveat(2) syscall to proto. -func PointExecveat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) proto.Message { +func PointExecveat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { p := &pb.Execve{ ContextData: cxtData, Sysno: uint64(info.Sysno), @@ -259,5 +259,5 @@ func PointExecveat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.Context p.Exit = newExitMaybe(info) - return p + return p, pb.MessageType_MESSAGE_SYSCALL_EXECVE }