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
2 changes: 2 additions & 0 deletions examples/seccheck/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ std::vector<Callback> dispatchers = {
unpackSyscall<::gvisor::syscall::InotifyRmWatch>,
unpackSyscall<::gvisor::syscall::SocketPair>,
unpackSyscall<::gvisor::syscall::Write>,
nullptr,
unpackSyscall<::gvisor::syscall::Select>,
};

void unpack(absl::string_view buf) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/sentry/seccheck/metadata_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func archInit() {
},
})
addSyscallPoint(22, "pipe", nil)
addSyscallPoint(23, "select", nil)
addSyscallPoint(32, "dup", []FieldDesc{
{
ID: FieldSyscallPath,
Expand Down Expand Up @@ -149,6 +150,7 @@ func archInit() {
Name: "fd_path",
},
})
addSyscallPoint(270, "pselect6", nil)
addSyscallPoint(282, "signalfd", []FieldDesc{
{
ID: FieldSyscallPath,
Expand Down
1 change: 1 addition & 0 deletions pkg/sentry/seccheck/metadata_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func archInit() {
Name: "fd_path",
},
})
addSyscallPoint(72, "pselect6", nil)
addSyscallPoint(74, "signalfd4", []FieldDesc{
{
ID: FieldSyscallPath,
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_SYSCALL_SELECT = 36;
}
// LINT.ThenChange(../../../../examples/seccheck/server.cc)
12 changes: 12 additions & 0 deletions pkg/sentry/seccheck/points/syscall.proto
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,15 @@ message SocketPair {
int32 socket1 = 7;
int32 socket2 = 8;
}

message Select {
gvisor.common.ContextData context_data = 1;
Exit exit = 2;
uint64 sysno = 3;
int64 nfds = 4;
repeated int64 read_fds = 5;
int64 timeout_ms = 6;
repeated int64 write_fds = 7;
repeated int64 except_fds = 8;
}

6 changes: 3 additions & 3 deletions pkg/sentry/syscalls/linux/linux64.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ var AMD64 = &kernel.SyscallTable{
20: syscalls.SupportedPoint("writev", Writev, PointWritev),
21: syscalls.Supported("access", Access),
22: syscalls.SupportedPoint("pipe", Pipe, PointPipe),
23: syscalls.Supported("select", Select),
23: syscalls.SupportedPoint("select", Select, PointSelect),
24: syscalls.Supported("sched_yield", SchedYield),
25: syscalls.Supported("mremap", Mremap),
26: syscalls.PartiallySupported("msync", Msync, "Full data flush is not guaranteed at this time.", nil),
Expand Down Expand Up @@ -312,7 +312,7 @@ var AMD64 = &kernel.SyscallTable{
267: syscalls.Supported("readlinkat", Readlinkat),
268: syscalls.Supported("fchmodat", Fchmodat),
269: syscalls.Supported("faccessat", Faccessat),
270: syscalls.Supported("pselect6", Pselect6),
270: syscalls.SupportedPoint("pselect6", Pselect6, PointPselect6),
271: syscalls.Supported("ppoll", Ppoll),
272: syscalls.PartiallySupported("unshare", Unshare, "Time, cgroup namespaces not supported.", nil),
273: syscalls.Supported("set_robust_list", SetRobustList),
Expand Down Expand Up @@ -494,7 +494,7 @@ var ARM64 = &kernel.SyscallTable{
69: syscalls.SupportedPoint("preadv", Preadv, PointPreadv),
70: syscalls.SupportedPoint("pwritev", Pwritev, PointPwritev),
71: syscalls.Supported("sendfile", Sendfile),
72: syscalls.Supported("pselect6", Pselect6),
72: syscalls.SupportedPoint("pselect6", Pselect6, PointPselect6),
73: syscalls.Supported("ppoll", Ppoll),
74: syscalls.SupportedPoint("signalfd4", Signalfd4, PointSignalfd4),
75: syscalls.ErrorWithEvent("vmsplice", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/138"}), // TODO(b/29354098)
Expand Down
85 changes: 85 additions & 0 deletions pkg/sentry/syscalls/linux/points.go
Original file line number Diff line number Diff line change
Expand Up @@ -992,3 +992,88 @@ func PointSocketpair(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.Conte
p.Exit = newExitMaybe(info)
return p, pb.MessageType_MESSAGE_SYSCALL_SOCKETPAIR
}

func extractFDs(t *kernel.Task, addr hostarch.Addr, nBytes, nBitsInLastPartialByte int) []int64 {
if addr == 0 {
return nil
}
set, err := CopyInFDSet(t, addr, nBytes, nBitsInLastPartialByte)
if err != nil {
return nil
}
var fds []int64
var fd int64
for i := 0; i < nBytes; i++ {
v := set[i]
m := byte(1)
for j := 0; j < 8; j++ {
if (v & m) != 0 {
fds = append(fds, fd)
}
fd++
m <<= 1
}
}
return fds
}

// PointSelect converts select(2) syscall to proto.
func PointSelect(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
nfds := int(info.Args[0].Int())
p := &pb.Select{
ContextData: cxtData,
Sysno: uint64(info.Sysno),
Nfds: int64(nfds),
}

if nfds >= 0 && nfds <= fileCap {
nBytes := (nfds + 7) / 8
nBitsInLastPartialByte := nfds % 8

p.ReadFds = extractFDs(t, info.Args[1].Pointer(), nBytes, nBitsInLastPartialByte)
p.WriteFds = extractFDs(t, info.Args[2].Pointer(), nBytes, nBitsInLastPartialByte)
p.ExceptFds = extractFDs(t, info.Args[3].Pointer(), nBytes, nBitsInLastPartialByte)
}

timeoutMs := int64(-1)
if timevalAddr := info.Args[4].Pointer(); timevalAddr != 0 {
var timeval linux.Timeval
if _, err := timeval.CopyIn(t, timevalAddr); err == nil {
if timeval.Sec >= 0 && timeval.Usec >= 0 {
timeoutMs = timeval.ToNsecCapped() / 1e6
}
}
}
p.TimeoutMs = timeoutMs
p.Exit = newExitMaybe(info)
return p, pb.MessageType_MESSAGE_SYSCALL_SELECT
}

// PointPselect6 converts pselect6(2) syscall to proto.
func PointPselect6(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
nfds := int(info.Args[0].Int())
p := &pb.Select{
ContextData: cxtData,
Sysno: uint64(info.Sysno),
Nfds: int64(nfds),
}

if nfds >= 0 && nfds <= fileCap {
nBytes := (nfds + 7) / 8
nBitsInLastPartialByte := nfds % 8

p.ReadFds = extractFDs(t, info.Args[1].Pointer(), nBytes, nBitsInLastPartialByte)
p.WriteFds = extractFDs(t, info.Args[2].Pointer(), nBytes, nBitsInLastPartialByte)
p.ExceptFds = extractFDs(t, info.Args[3].Pointer(), nBytes, nBitsInLastPartialByte)
}

timeoutMs := int64(-1)
if timespecAddr := info.Args[4].Pointer(); timespecAddr != 0 {
if timeout, err := copyTimespecInToDuration(t, timespecAddr); err == nil && timeout >= 0 {
timeoutMs = timeout.Milliseconds()
}
}
p.TimeoutMs = timeoutMs
p.Exit = newExitMaybe(info)
return p, pb.MessageType_MESSAGE_SYSCALL_SELECT
}
Loading