From f84e9a85d1e5716745780537fce0e6c51fa2f1fb Mon Sep 17 00:00:00 2001 From: Shambhavi Srivastava Date: Wed, 25 May 2022 13:31:29 -0700 Subject: [PATCH] Add Points to some syscalls Added a raw syscall points to all syscalls. Added schematized syscall points to the following syscalls: - Chdir - Fchdir - Setgid - Setuid - Setsid - Setresuid - Setresgid PiperOrigin-RevId: 451001973 --- examples/seccheck/server.cc | 3 + pkg/sentry/seccheck/metadata_amd64.go | 13 ++++ pkg/sentry/seccheck/metadata_arm64.go | 12 +++ pkg/sentry/seccheck/points/common.proto | 3 + pkg/sentry/seccheck/points/syscall.proto | 25 +++++++ pkg/sentry/syscalls/linux/linux64.go | 28 +++---- pkg/sentry/syscalls/linux/points.go | 93 ++++++++++++++++++++++++ pkg/sentry/syscalls/linux/vfs2/vfs2.go | 8 +- 8 files changed, 167 insertions(+), 18 deletions(-) diff --git a/examples/seccheck/server.cc b/examples/seccheck/server.cc index d8567d7fe..5e31891d5 100644 --- a/examples/seccheck/server.cc +++ b/examples/seccheck/server.cc @@ -92,6 +92,9 @@ std::vector dispatchers = { unpackSyscall<::gvisor::syscall::Connect>, unpackSyscall<::gvisor::syscall::Execve>, unpackSyscall<::gvisor::syscall::Socket>, + unpackSyscall<::gvisor::syscall::Chdir>, + unpackSyscall<::gvisor::syscall::Setid>, + unpackSyscall<::gvisor::syscall::Setresid>, }; void unpack(absl::string_view buf) { diff --git a/pkg/sentry/seccheck/metadata_amd64.go b/pkg/sentry/seccheck/metadata_amd64.go index 2fcf23398..1a194e40d 100644 --- a/pkg/sentry/seccheck/metadata_amd64.go +++ b/pkg/sentry/seccheck/metadata_amd64.go @@ -66,6 +66,19 @@ func init() { Name: "envv", }, }) + addSyscallPoint(80, "chdir", nil) + addSyscallPoint(81, "fchdir", []FieldDesc{ + { + ID: FieldSyscallPath, + Name: "fd_path", + }, + }) + + addSyscallPoint(105, "setuid", nil) + addSyscallPoint(106, "setgid", nil) + addSyscallPoint(112, "setsid", nil) + addSyscallPoint(117, "setresuid", nil) + addSyscallPoint(119, "setresgid", nil) const lastSyscallInTable = 441 for i := 0; i <= lastSyscallInTable; i++ { diff --git a/pkg/sentry/seccheck/metadata_arm64.go b/pkg/sentry/seccheck/metadata_arm64.go index 1d051840c..fd93761d1 100644 --- a/pkg/sentry/seccheck/metadata_arm64.go +++ b/pkg/sentry/seccheck/metadata_arm64.go @@ -59,6 +59,18 @@ func init() { Name: "envv", }, }) + addSyscallPoint(49, "chdir", nil) + addSyscallPoint(50, "fchdir", []FieldDesc{ + { + ID: FieldSyscallPath, + Name: "fd_path", + }, + }) + addSyscallPoint(146, "setuid", nil) + addSyscallPoint(144, "setgid", nil) + addSyscallPoint(157, "setsid", nil) + addSyscallPoint(147, "setresuid", nil) + addSyscallPoint(149, "setresgid", nil) const lastSyscallInTable = 441 for i := 0; i <= lastSyscallInTable; i++ { diff --git a/pkg/sentry/seccheck/points/common.proto b/pkg/sentry/seccheck/points/common.proto index 880f8096d..a5c2bdd2b 100644 --- a/pkg/sentry/seccheck/points/common.proto +++ b/pkg/sentry/seccheck/points/common.proto @@ -110,5 +110,8 @@ enum MessageType { MESSAGE_SYSCALL_CONNECT = 10; MESSAGE_SYSCALL_EXECVE = 11; MESSAGE_SYSCALL_SOCKET = 12; + MESSAGE_SYSCALL_CHDIR = 13; + MESSAGE_SYSCALL_SETID = 14; + MESSAGE_SYSCALL_SETRESID = 15; } // LINT.ThenChange(../../../../examples/seccheck/server.cc) diff --git a/pkg/sentry/seccheck/points/syscall.proto b/pkg/sentry/seccheck/points/syscall.proto index acf0eabae..88d2c8b22 100644 --- a/pkg/sentry/seccheck/points/syscall.proto +++ b/pkg/sentry/seccheck/points/syscall.proto @@ -92,3 +92,28 @@ message Socket { int32 type = 5; int32 protocol = 6; } + +message Chdir { + gvisor.common.ContextData context_data = 1; + Exit exit = 2; + uint64 sysno = 3; + int64 fd = 4; + string fd_path = 5; + string pathname = 6; +} + +message Setresid { + gvisor.common.ContextData context_data = 1; + Exit exit = 2; + uint64 sysno = 3; + uint32 rgid = 4; + uint32 egid = 5; + uint32 sgid = 6; +} + +message Setid { + gvisor.common.ContextData context_data = 1; + Exit exit = 2; + uint64 sysno = 3; + uint32 id = 4; +} diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 9f410eeda..b4716bdd1 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -132,8 +132,8 @@ var AMD64 = &kernel.SyscallTable{ 77: syscalls.Supported("ftruncate", Ftruncate), 78: syscalls.Supported("getdents", Getdents), 79: syscalls.Supported("getcwd", Getcwd), - 80: syscalls.Supported("chdir", Chdir), - 81: syscalls.Supported("fchdir", Fchdir), + 80: syscalls.SupportedPoint("chdir", Chdir, PointChdir), + 81: syscalls.SupportedPoint("fchdir", Fchdir, PointFchdir), 82: syscalls.Supported("rename", Rename), 83: syscalls.Supported("mkdir", Mkdir), 84: syscalls.Supported("rmdir", Rmdir), @@ -157,21 +157,21 @@ var AMD64 = &kernel.SyscallTable{ 102: syscalls.Supported("getuid", Getuid), 103: syscalls.PartiallySupported("syslog", Syslog, "Outputs a dummy message for security reasons.", nil), 104: syscalls.Supported("getgid", Getgid), - 105: syscalls.Supported("setuid", Setuid), - 106: syscalls.Supported("setgid", Setgid), + 105: syscalls.SupportedPoint("setuid", Setuid, PointSetuid), + 106: syscalls.SupportedPoint("setgid", Setgid, PointSetgid), 107: syscalls.Supported("geteuid", Geteuid), 108: syscalls.Supported("getegid", Getegid), 109: syscalls.Supported("setpgid", Setpgid), 110: syscalls.Supported("getppid", Getppid), 111: syscalls.Supported("getpgrp", Getpgrp), - 112: syscalls.Supported("setsid", Setsid), + 112: syscalls.SupportedPoint("setsid", Setsid, PointSetsid), 113: syscalls.Supported("setreuid", Setreuid), 114: syscalls.Supported("setregid", Setregid), 115: syscalls.Supported("getgroups", Getgroups), 116: syscalls.Supported("setgroups", Setgroups), - 117: syscalls.Supported("setresuid", Setresuid), + 117: syscalls.SupportedPoint("setresuid", Setresuid, PointSetresuid), 118: syscalls.Supported("getresuid", Getresuid), - 119: syscalls.Supported("setresgid", Setresgid), + 119: syscalls.SupportedPoint("setresgid", Setresgid, PointSetresgid), 120: syscalls.Supported("getresgid", Getresgid), 121: syscalls.Supported("getpgid", Getpgid), 122: syscalls.ErrorWithEvent("setfsuid", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/260"}), // TODO(b/112851702) @@ -479,8 +479,8 @@ var ARM64 = &kernel.SyscallTable{ 46: syscalls.Supported("ftruncate", Ftruncate), 47: syscalls.PartiallySupported("fallocate", Fallocate, "Not all options are supported.", nil), 48: syscalls.Supported("faccessat", Faccessat), - 49: syscalls.Supported("chdir", Chdir), - 50: syscalls.Supported("fchdir", Fchdir), + 49: syscalls.SupportedPoint("chdir", Chdir, PointChdir), + 50: syscalls.SupportedPoint("fchdir", Fchdir, PointFchdir), 51: syscalls.Supported("chroot", Chroot), 52: syscalls.PartiallySupported("fchmod", Fchmod, "Options S_ISUID and S_ISGID not supported.", nil), 53: syscalls.Supported("fchmodat", Fchmodat), @@ -574,12 +574,12 @@ var ARM64 = &kernel.SyscallTable{ 141: syscalls.PartiallySupported("getpriority", Getpriority, "Stub implementation.", nil), 142: syscalls.CapError("reboot", linux.CAP_SYS_BOOT, "", nil), 143: syscalls.Supported("setregid", Setregid), - 144: syscalls.Supported("setgid", Setgid), + 144: syscalls.SupportedPoint("setgid", Setgid, PointSetgid), 145: syscalls.Supported("setreuid", Setreuid), - 146: syscalls.Supported("setuid", Setuid), - 147: syscalls.Supported("setresuid", Setresuid), + 146: syscalls.SupportedPoint("setuid", Setuid, PointSetuid), + 147: syscalls.SupportedPoint("setresuid", Setresuid, PointSetresuid), 148: syscalls.Supported("getresuid", Getresuid), - 149: syscalls.Supported("setresgid", Setresgid), + 149: syscalls.SupportedPoint("setresgid", Setresgid, PointSetresgid), 150: syscalls.Supported("getresgid", Getresgid), 151: syscalls.ErrorWithEvent("setfsuid", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/260"}), // TODO(b/112851702) 152: syscalls.ErrorWithEvent("setfsgid", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/260"}), // TODO(b/112851702) @@ -587,7 +587,7 @@ var ARM64 = &kernel.SyscallTable{ 154: syscalls.Supported("setpgid", Setpgid), 155: syscalls.Supported("getpgid", Getpgid), 156: syscalls.Supported("getsid", Getsid), - 157: syscalls.Supported("setsid", Setsid), + 157: syscalls.SupportedPoint("setsid", Setsid, PointSetsid), 158: syscalls.Supported("getgroups", Getgroups), 159: syscalls.Supported("setgroups", Setgroups), 160: syscalls.Supported("uname", Uname), diff --git a/pkg/sentry/syscalls/linux/points.go b/pkg/sentry/syscalls/linux/points.go index 3eefbb0d8..bedfeb899 100644 --- a/pkg/sentry/syscalls/linux/points.go +++ b/pkg/sentry/syscalls/linux/points.go @@ -19,6 +19,7 @@ import ( "google.golang.org/protobuf/proto" "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/hostarch" "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/sentry/seccheck" pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto" @@ -264,3 +265,95 @@ func PointExecveat(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.Context return p, pb.MessageType_MESSAGE_SYSCALL_EXECVE } + +// pointChdirHelper converts chdir(2) and fchdir(2) syscall to proto. +func pointChdirHelper(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo, fd int64, path hostarch.Addr) (proto.Message, pb.MessageType) { + p := &pb.Chdir{ + ContextData: cxtData, + Sysno: uint64(info.Sysno), + Fd: fd, + } + + if path > 0 { + pathname, err := t.CopyInString(path, linux.PATH_MAX) + if err == nil { + p.Pathname = pathname + } + } + + if fields.Local.Contains(seccheck.FieldSyscallPath) { + p.FdPath = getFilePath(t, int32(p.Fd)) + } + + p.Exit = newExitMaybe(info) + + return p, pb.MessageType_MESSAGE_SYSCALL_CHDIR +} + +// PointChdir calls pointChdirHelper to convert chdir(2) syscall to proto. +func PointChdir(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + path := info.Args[0].Pointer() + return pointChdirHelper(t, fields, cxtData, info, linux.AT_FDCWD, path) +} + +// PointFchdir calls pointChdirHelper to convert fchdir(2) syscall to proto. +func PointFchdir(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + fd := int64(info.Args[0].Int()) + path := info.Args[1].Pointer() + return pointChdirHelper(t, fields, cxtData, info, fd, path) +} + +// pointSetidHelper converts setuid(2) and setgid(2) syscall to proto. +func pointSetidHelper(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo, id uint32) (proto.Message, pb.MessageType) { + p := &pb.Setid{ + ContextData: cxtData, + Sysno: uint64(info.Sysno), + Id: id, + } + + p.Exit = newExitMaybe(info) + + return p, pb.MessageType_MESSAGE_SYSCALL_SETID +} + +// PointSetuid calls pointSetidHelper to convert setuid(2) syscall to proto. +func PointSetuid(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + id := uint32(info.Args[0].Uint()) + return pointSetidHelper(t, fields, cxtData, info, id) +} + +// PointSetgid calls pointSetidHelper to convert setgid(2) syscall to proto. +func PointSetgid(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + id := uint32(info.Args[0].Uint()) + return pointSetidHelper(t, fields, cxtData, info, id) +} + +// PointSetsid calls pointSetidHelper to convert setsid(2) syscall to proto. +func PointSetsid(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + return pointSetidHelper(t, fields, cxtData, info, 0) +} + +// pointSetresidHelper converts setresuid(2) and setresgid(2) syscall to proto. +func pointSetresidHelper(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + p := &pb.Setresid{ + ContextData: cxtData, + Sysno: uint64(info.Sysno), + Rgid: uint32(info.Args[0].Uint()), + Egid: uint32(info.Args[1].Uint()), + Sgid: uint32(info.Args[2].Uint()), + } + + p.Exit = newExitMaybe(info) + + return p, pb.MessageType_MESSAGE_SYSCALL_SETRESID +} + +// PointSetresuid calls pointSetresidHelper to convert setresuid(2) syscall to proto. +func PointSetresuid(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + return pointSetresidHelper(t, fields, cxtData, info) +} + +// PointSetresgid calls pointSetresidHelper to convert setresgid(2) syscall to proto. +func PointSetresgid(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) { + return pointSetresidHelper(t, fields, cxtData, info) +} diff --git a/pkg/sentry/syscalls/linux/vfs2/vfs2.go b/pkg/sentry/syscalls/linux/vfs2/vfs2.go index 9c22a0e7a..122bf87be 100644 --- a/pkg/sentry/syscalls/linux/vfs2/vfs2.go +++ b/pkg/sentry/syscalls/linux/vfs2/vfs2.go @@ -69,8 +69,8 @@ func Override() { s.Table[77] = syscalls.Supported("ftruncate", Ftruncate) s.Table[78] = syscalls.Supported("getdents", Getdents) s.Table[79] = syscalls.Supported("getcwd", Getcwd) - s.Table[80] = syscalls.Supported("chdir", Chdir) - s.Table[81] = syscalls.Supported("fchdir", Fchdir) + s.Table[80] = syscalls.SupportedPoint("chdir", Chdir, linux.PointChdir) + s.Table[81] = syscalls.SupportedPoint("fchdir", Fchdir, linux.PointFchdir) s.Table[82] = syscalls.Supported("rename", Rename) s.Table[83] = syscalls.Supported("mkdir", Mkdir) s.Table[84] = syscalls.Supported("rmdir", Rmdir) @@ -210,8 +210,8 @@ func Override() { s.Table[46] = syscalls.Supported("ftruncate", Ftruncate) s.Table[47] = syscalls.PartiallySupported("fallocate", Fallocate, "Not all options are supported.", nil) s.Table[48] = syscalls.Supported("faccessat", Faccessat) - s.Table[49] = syscalls.Supported("chdir", Chdir) - s.Table[50] = syscalls.Supported("fchdir", Fchdir) + s.Table[49] = syscalls.SupportedPoint("chdir", Chdir, linux.PointChdir) + s.Table[50] = syscalls.SupportedPoint("fchdir", Fchdir, linux.PointFchdir) s.Table[51] = syscalls.Supported("chroot", Chroot) s.Table[52] = syscalls.Supported("fchmod", Fchmod) s.Table[53] = syscalls.Supported("fchmodat", Fchmodat)