Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/seccheck/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ std::vector<Callback> dispatchers = {
unpackSyscall<::gvisor::syscall::InotifyRmWatch>,
unpackSyscall<::gvisor::syscall::SocketPair>,
unpackSyscall<::gvisor::syscall::Write>,
unpack<::gvisor::sentry::MmapInfo>,
};

void unpack(absl::string_view buf) {
Expand Down
6 changes: 6 additions & 0 deletions pkg/sentry/seccheck/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
PointExecve
PointExitNotifyParent
PointTaskExit
PointMmap

// Add new Points above this line.
pointLengthBeforeSyscalls
Expand Down Expand Up @@ -303,6 +304,11 @@ func genericInit() {
Name: "sentry/task_exit",
ContextFields: defaultContextFields,
})
registerPoint(PointDesc{
ID: PointMmap,
Name: "sentry/mmap",
ContextFields: defaultContextFields,
})
}

var initOnce sync.Once
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/seccheck/points/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,6 @@ enum MessageType {
MESSAGE_SYSCALL_INOTIFY_RM_WATCH = 32;
MESSAGE_SYSCALL_SOCKETPAIR = 33;
MESSAGE_SYSCALL_WRITE = 34;
MESSAGE_SENTRY_MMAP = 35;
}
// LINT.ThenChange(../../../../examples/seccheck/server.cc)
12 changes: 12 additions & 0 deletions pkg/sentry/seccheck/points/sentry.proto
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,15 @@ message TaskExit {
// by wait*().
int32 exit_status = 2;
}

message MmapInfo {
gvisor.common.ContextData context_data = 1;

string mapped_path = 2;
uint64 mapped_ino = 3;
uint32 mapped_mode = 4;
uint32 mapped_uid = 5;
uint32 mapped_gid = 6;

bool is_initial_mmap = 7;
}
6 changes: 6 additions & 0 deletions pkg/sentry/seccheck/seccheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ type Sink interface {
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
Mmap(context.Context, FieldSet, *pb.MmapInfo) error

ContainerStart(context.Context, FieldSet, *pb.Start) error

Expand Down Expand Up @@ -169,6 +170,11 @@ func (SinkDefaults) TaskExit(context.Context, FieldSet, *pb.TaskExit) error {
return nil
}

// Mmap implements Sink.Mmap.
func (SinkDefaults) Mmap(context.Context, FieldSet, *pb.MmapInfo) error {
return nil
}

// RawSyscall implements Sink.RawSyscall.
func (SinkDefaults) RawSyscall(context.Context, FieldSet, *pb.Syscall) error {
return nil
Expand Down
6 changes: 6 additions & 0 deletions pkg/sentry/seccheck/sinks/remote/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ func (r *remote) TaskExit(_ context.Context, _ seccheck.FieldSet, info *pb.TaskE
return nil
}

// Mmap implements seccheck.Sink.
func (r *remote) Mmap(_ context.Context, _ seccheck.FieldSet, info *pb.MmapInfo) error {
r.write(info, pb.MessageType_MESSAGE_SENTRY_MMAP)
return nil
}

// ContainerStart implements seccheck.Sink.
func (r *remote) ContainerStart(_ context.Context, _ seccheck.FieldSet, info *pb.Start) error {
r.write(info, pb.MessageType_MESSAGE_CONTAINER_START)
Expand Down
58 changes: 58 additions & 0 deletions pkg/sentry/syscalls/linux/sys_mmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/mm"
"gvisor.dev/gvisor/pkg/sentry/seccheck"
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
"gvisor.dev/gvisor/pkg/sentry/vfs"
)

// Brk implements linux syscall brk(2).
Expand Down Expand Up @@ -81,6 +84,7 @@ func Mmap(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *
}
}()

var mappedFile *vfs.FileDescription
if !anon {
// Convert the passed FD to a file reference.
file := t.GetFile(fd)
Expand Down Expand Up @@ -122,6 +126,7 @@ func Mmap(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *
if err := file.ConfigureMMap(t, &opts); err != nil {
return 0, nil, err
}
mappedFile = file
} else if shared {
// Back shared anonymous mappings with an anonymous tmpfs file.
opts.Offset = 0
Expand All @@ -133,10 +138,17 @@ func Mmap(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *
if err := file.ConfigureMMap(t, &opts); err != nil {
return 0, nil, err
}
mappedFile = file
} else {
opts.NameMut = memmap.NameMutAnon
}

if opts.Perms.Execute {
if err := traceMmap(t, mappedFile); err != nil {
return 0, nil, err
}
}

rv, err := t.MemoryManager().MMap(t, opts)
return uintptr(rv), nil, err
}
Expand Down Expand Up @@ -349,3 +361,49 @@ func Munlockall(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uint
Mode: memmap.MLockNone,
})
}

func traceMmap(t *kernel.Task, file *vfs.FileDescription) error {
if !seccheck.Global.Enabled(seccheck.PointMmap) {
return nil
}
fields := seccheck.Global.GetFieldSet(seccheck.PointMmap)
info := &pb.MmapInfo{}
if file != nil {
info.MappedPath = file.MappedName(t)
statOpts := vfs.StatOptions{
Mask: linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_UID | linux.STATX_GID | linux.STATX_INO,
}
if stat, err := file.Stat(t, statOpts); err == nil {
if stat.Mask&(linux.STATX_TYPE|linux.STATX_MODE) == (linux.STATX_TYPE | linux.STATX_MODE) {
info.MappedMode = uint32(stat.Mode)
}
if stat.Mask&linux.STATX_UID != 0 {
info.MappedUid = stat.UID
}
if stat.Mask&linux.STATX_GID != 0 {
info.MappedGid = stat.GID
}
if stat.Mask&linux.STATX_INO != 0 {
info.MappedIno = stat.Ino
}
}
}
if exe := t.MemoryManager().Executable(); exe != nil {
if exe == file {
info.IsInitialMmap = true
} else {
statOpts := vfs.StatOptions{Mask: linux.STATX_INO}
if exeStat, err := exe.Stat(t, statOpts); err == nil && info.MappedIno != 0 && exeStat.Ino == info.MappedIno {
info.IsInitialMmap = true
}
}
exe.DecRef(t)
}
if !fields.Context.Empty() {
info.ContextData = &pb.ContextData{}
kernel.LoadSeccheckData(t, fields.Context, info.ContextData)
}
return seccheck.Global.SentToSinks(func(c seccheck.Sink) error {
return c.Mmap(t, fields, info)
})
}
12 changes: 12 additions & 0 deletions test/trace/trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func matchPoints(t *testing.T, msgs []test.Message) map[pb.MessageType]*checkers
pb.MessageType_MESSAGE_SENTRY_EXEC: {checker: checkSentryExec},
pb.MessageType_MESSAGE_SENTRY_EXIT_NOTIFY_PARENT: {checker: checkSentryExitNotifyParent},
pb.MessageType_MESSAGE_SENTRY_TASK_EXIT: {checker: checkSentryTaskExit},
pb.MessageType_MESSAGE_SENTRY_MMAP: {checker: checkSentryMmap},
pb.MessageType_MESSAGE_SYSCALL_CLOSE: {checker: checkSyscallClose},
pb.MessageType_MESSAGE_SYSCALL_CONNECT: {checker: checkSyscallConnect},
pb.MessageType_MESSAGE_SYSCALL_EXECVE: {checker: checkSyscallExecve},
Expand Down Expand Up @@ -263,6 +264,17 @@ func checkSentryTaskExit(msg test.Message) error {
return nil
}

func checkSentryMmap(msg test.Message) error {
p := pb.MmapInfo{}
if err := proto.Unmarshal(msg.Msg, &p); err != nil {
return err
}
if err := checkContextData(p.ContextData); err != nil {
return err
}
return nil
}

func checkSyscallRaw(msg test.Message) error {
p := pb.Syscall{}
if err := proto.Unmarshal(msg.Msg, &p); err != nil {
Expand Down
Loading