From e1c4bbccf9bd27883d3367cbdaad5236fdcb1958 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Thu, 28 Apr 2022 12:43:16 -0700 Subject: [PATCH] Add sentry/task_exit point Updates #4805 PiperOrigin-RevId: 445222912 --- examples/seccheck/pod_init.json | 3 +++ examples/seccheck/server.cc | 1 + pkg/sentry/kernel/task_exit.go | 15 +++++++++++++++ pkg/sentry/seccheck/checkers/remote/remote.go | 7 +++++++ pkg/sentry/seccheck/metadata.go | 5 +++++ pkg/sentry/seccheck/points/sentry.proto | 8 ++++++++ pkg/sentry/seccheck/seccheck.go | 7 +++++++ 7 files changed, 46 insertions(+) diff --git a/examples/seccheck/pod_init.json b/examples/seccheck/pod_init.json index d606b2245..627687458 100644 --- a/examples/seccheck/pod_init.json +++ b/examples/seccheck/pod_init.json @@ -7,6 +7,9 @@ }, { "name": "sentry/clone" + }, + { + "name": "sentry/task_exit" } ], "sinks": [ diff --git a/examples/seccheck/server.cc b/examples/seccheck/server.cc index 51729d39e..bf1941306 100644 --- a/examples/seccheck/server.cc +++ b/examples/seccheck/server.cc @@ -72,6 +72,7 @@ std::map dispatchers = { {"gvisor.sentry.ExecveInfo", unpack<::gvisor::sentry::ExecveInfo>}, {"gvisor.sentry.ExitNotifyParentInfo", unpack<::gvisor::sentry::ExitNotifyParentInfo>}, + {"gvisor.sentry.TaskExit", unpack<::gvisor::sentry::TaskExit>}, }; void unpack(const absl::string_view buf) { diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index 08ff782be..3c37e01d9 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -204,6 +204,21 @@ type runExitMain struct{} func (*runExitMain) execute(t *Task) taskRunState { t.traceExitEvent() + + if seccheck.Global.Enabled(seccheck.PointTaskExit) { + info := &pb.TaskExit{ + ExitStatus: int32(t.tg.exitStatus), + } + fields := seccheck.Global.GetFieldSet(seccheck.PointTaskExit) + if !fields.Context.Empty() { + info.ContextData = &pb.ContextData{} + LoadSeccheckData(t, fields.Context, info.ContextData) + } + seccheck.Global.SendToCheckers(func(c seccheck.Checker) error { + return c.TaskExit(t, fields, info) + }) + } + lastExiter := t.exitThreadGroup() t.ResetKcov() diff --git a/pkg/sentry/seccheck/checkers/remote/remote.go b/pkg/sentry/seccheck/checkers/remote/remote.go index b2b25dc30..ceb072d36 100644 --- a/pkg/sentry/seccheck/checkers/remote/remote.go +++ b/pkg/sentry/seccheck/checkers/remote/remote.go @@ -174,6 +174,13 @@ func (r *Remote) ExitNotifyParent(_ context.Context, _ seccheck.FieldSet, info * return nil } +// TaskExit implements seccheck.Checker. +func (r *Remote) TaskExit(_ context.Context, _ seccheck.FieldSet, info *pb.TaskExit) error { + r.write(info) + return nil +} + +// ContainerStart implements seccheck.Checker. func (r *Remote) ContainerStart(_ context.Context, _ seccheck.FieldSet, info *pb.Start) error { r.write(info) return nil diff --git a/pkg/sentry/seccheck/metadata.go b/pkg/sentry/seccheck/metadata.go index a6c63cb54..d4a0ba287 100644 --- a/pkg/sentry/seccheck/metadata.go +++ b/pkg/sentry/seccheck/metadata.go @@ -192,4 +192,9 @@ func init() { Name: "sentry/exit_notify_parent", ContextFields: defaultContextFields, }) + registerPoint(PointDesc{ + ID: PointTaskExit, + Name: "sentry/task_exit", + ContextFields: defaultContextFields, + }) } diff --git a/pkg/sentry/seccheck/points/sentry.proto b/pkg/sentry/seccheck/points/sentry.proto index 8a4f21056..6618533c0 100644 --- a/pkg/sentry/seccheck/points/sentry.proto +++ b/pkg/sentry/seccheck/points/sentry.proto @@ -65,3 +65,11 @@ message ExitNotifyParentInfo { // by wait*(). int32 exit_status = 2; } + +message TaskExit { + gvisor.common.ContextData context_data = 1; + + // ExitStatus is the exiting thread group's exit status, as reported + // by wait*(). + int32 exit_status = 2; +} diff --git a/pkg/sentry/seccheck/seccheck.go b/pkg/sentry/seccheck/seccheck.go index d24cc3d15..e73807576 100644 --- a/pkg/sentry/seccheck/seccheck.go +++ b/pkg/sentry/seccheck/seccheck.go @@ -32,6 +32,7 @@ const ( PointExecve PointExitNotifyParent PointContainerStart + PointTaskExit // Add new Points above this line. pointLength @@ -117,6 +118,7 @@ type Checker interface { Clone(ctx context.Context, fields FieldSet, info *pb.CloneInfo) error Execve(ctx context.Context, fields FieldSet, info *pb.ExecveInfo) error ExitNotifyParent(ctx context.Context, fields FieldSet, info *pb.ExitNotifyParentInfo) error + TaskExit(context.Context, FieldSet, *pb.TaskExit) error ContainerStart(context.Context, FieldSet, *pb.Start) error } @@ -146,6 +148,11 @@ func (CheckerDefaults) ContainerStart(context.Context, FieldSet, *pb.Start) erro return nil } +// TaskExit implements Checker.TaskExit. +func (CheckerDefaults) TaskExit(context.Context, FieldSet, *pb.TaskExit) error { + return nil +} + // PointReq indicates what Point a corresponding Checker runs at, and what // information it requires at those Points. type PointReq struct {