Add container/start Point

Updates #4805

PiperOrigin-RevId: 444983390
This commit is contained in:
Fabricio Voznika
2022-04-27 15:30:31 -07:00
committed by gVisor bot
parent 2ba23ca96c
commit 93185b4eec
11 changed files with 114 additions and 9 deletions
+1
View File
@@ -9,6 +9,7 @@ cc_binary(
deps = [
# any_cc_proto placeholder,
"//pkg/sentry/seccheck/points:points_cc_proto",
"@com_google_absl//absl/cleanup",
"@com_google_absl//absl/strings",
],
)
+3
View File
@@ -2,6 +2,9 @@
"trace_session": {
"name": "Default",
"points": [
{
"name": "container/start"
},
{
"name": "sentry/clone"
}
+5 -5
View File
@@ -27,7 +27,9 @@
#include <vector>
#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"
typedef std::function<void(const google::protobuf::Any& any)> Callback;
@@ -65,6 +67,7 @@ void unpack(const google::protobuf::Any& any) {
}
std::map<std::string, Callback> dispatchers = {
{"gvisor.container.Start", unpack<::gvisor::container::Start>},
{"gvisor.sentry.CloneInfo", unpack<::gvisor::sentry::CloneInfo>},
{"gvisor.sentry.ExecveInfo", unpack<::gvisor::sentry::ExecveInfo>},
{"gvisor.sentry.ExitNotifyParentInfo",
@@ -179,6 +182,7 @@ extern "C" int main(int argc, char** argv) {
if (sock < 0) {
err(1, "socket");
}
auto sock_closer = absl::MakeCleanup([sock] { close(sock); });
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
@@ -194,6 +198,7 @@ extern "C" int main(int argc, char** argv) {
if (epoll_fd < 0) {
err(1, "epoll_create");
}
auto epoll_closer = absl::MakeCleanup([epoll_fd] { close(epoll_fd); });
startPollThread(epoll_fd);
for (;;) {
@@ -213,9 +218,4 @@ extern "C" int main(int argc, char** argv) {
err(1, "epoll_ctl(ADD)");
}
}
close(sock);
unlink(path.c_str());
return 0;
}
-4
View File
@@ -33,10 +33,6 @@ func LoadSeccheckDataLocked(t *Task, mask seccheck.FieldMask, info *pb.ContextDa
if mask.Contains(seccheck.FieldCtxtTime) {
info.TimeNs = t.k.RealtimeClock().Now().Nanoseconds()
}
if t == nil {
return
}
if mask.Contains(seccheck.FieldCtxtThreadID) {
info.ThreadId = int32(t.k.tasks.Root.tids[t])
}
@@ -173,3 +173,8 @@ func (r *Remote) ExitNotifyParent(_ context.Context, _ seccheck.FieldSet, info *
r.write(info)
return nil
}
func (r *Remote) ContainerStart(_ context.Context, _ seccheck.FieldSet, info *pb.Start) error {
r.write(info)
return nil
}
+18
View File
@@ -21,6 +21,12 @@ import (
"gvisor.dev/gvisor/pkg/fd"
)
const (
// ContainerStartFieldEnv is an optional field to collect list of environment
// variables set for the container start process.
ContainerStartFieldEnv Field = iota
)
var points = map[string]PointDesc{}
var sinks = map[string]SinkDesc{}
@@ -146,6 +152,18 @@ func validateFields(fields []FieldDesc) error {
// These are all the points available in the system.
func init() {
// Points from the container namespace.
registerPoint(PointDesc{
ID: PointContainerStart,
Name: "container/start",
OptionalFields: []FieldDesc{
{
ID: ContainerStartFieldEnv,
Name: "env",
},
},
})
// Points from the sentry namespace.
registerPoint(PointDesc{
ID: PointClone,
+1
View File
@@ -8,6 +8,7 @@ proto_library(
name = "points",
srcs = [
"common.proto",
"container.proto",
"sentry.proto",
],
)
@@ -0,0 +1,27 @@
// Copyright 2022 The gVisor Authors.
//
// 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.
syntax = "proto3";
package gvisor.container;
import "pkg/sentry/seccheck/points/common.proto";
message Start {
gvisor.common.ContextData context_data = 1;
string id = 2;
string cwd = 3;
repeated string args = 4;
repeated string env = 5;
}
+17
View File
@@ -31,6 +31,7 @@ const (
PointClone Point = iota
PointExecve
PointExitNotifyParent
PointContainerStart
// Add new Points above this line.
pointLength
@@ -116,6 +117,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
ContainerStart(context.Context, FieldSet, *pb.Start) error
}
// CheckerDefaults may be embedded by implementations of Checker to obtain
@@ -139,6 +141,11 @@ func (CheckerDefaults) ExitNotifyParent(context.Context, FieldSet, *pb.ExitNotif
return nil
}
// ContainerStart implements Checker.ContainerStart.
func (CheckerDefaults) ContainerStart(context.Context, FieldSet, *pb.Start) error {
return nil
}
// PointReq indicates what Point a corresponding Checker runs at, and what
// information it requires at those Points.
type PointReq struct {
@@ -209,6 +216,16 @@ func (s *State) appendCheckerLocked(c Checker) {
s.registrationSeq.EndWrite()
}
// SendToCheckers iterates over all checkers and calls fn for each one of them.
func (s *State) SendToCheckers(fn func(c Checker) error) error {
for _, c := range s.getCheckers() {
if err := fn(c); err != nil {
return err
}
}
return nil
}
// GetFieldSet returns the FieldSet that has been configured for a given Point.
func (s *State) GetFieldSet(p Point) FieldSet {
s.registrationMu.RLock()
+1
View File
@@ -84,6 +84,7 @@ go_library(
"//pkg/sentry/platform",
"//pkg/sentry/seccheck",
"//pkg/sentry/seccheck/checkers/remote",
"//pkg/sentry/seccheck/points:points_go_proto",
"//pkg/sentry/socket/hostinet",
"//pkg/sentry/socket/netfilter",
"//pkg/sentry/socket/netlink",
+36
View File
@@ -48,6 +48,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/loader"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/seccheck"
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
"gvisor.dev/gvisor/pkg/sentry/socket/netfilter"
"gvisor.dev/gvisor/pkg/sentry/syscalls/linux/vfs2"
"gvisor.dev/gvisor/pkg/sentry/time"
@@ -642,6 +644,23 @@ func (l *Loader) run() error {
if err != nil {
return err
}
if seccheck.Global.Enabled(seccheck.PointContainerStart) {
evt := pb.Start{
Id: l.sandboxID,
Cwd: l.root.spec.Process.Cwd,
Args: l.root.spec.Process.Args,
}
fields := seccheck.Global.GetFieldSet(seccheck.PointContainerStart)
if fields.Local.Contains(seccheck.ContainerStartFieldEnv) {
evt.Env = l.root.spec.Process.Env
}
ctx := l.root.procArgs.NewContext(l.k)
_ = seccheck.Global.SendToCheckers(func(c seccheck.Checker) error {
return c.ContainerStart(ctx, fields, &evt)
})
}
}
ep.tg = l.k.GlobalInit()
@@ -770,6 +789,23 @@ func (l *Loader) startSubcontainer(spec *specs.Spec, conf *config.Config, cid st
if err != nil {
return err
}
if seccheck.Global.Enabled(seccheck.PointContainerStart) {
evt := pb.Start{
Id: cid,
Cwd: spec.Process.Cwd,
Args: spec.Process.Args,
}
fields := seccheck.Global.GetFieldSet(seccheck.PointContainerStart)
if fields.Local.Contains(seccheck.ContainerStartFieldEnv) {
evt.Env = spec.Process.Env
}
ctx := info.procArgs.NewContext(l.k)
_ = seccheck.Global.SendToCheckers(func(c seccheck.Checker) error {
return c.ContainerStart(ctx, fields, &evt)
})
}
l.k.StartProcess(ep.tg)
return nil
}