Skip to content

Commit c9f1324

Browse files
committed
Internal change.
PiperOrigin-RevId: 927390251
1 parent da03d3a commit c9f1324

5 files changed

Lines changed: 140 additions & 3 deletions

File tree

examples/seccheck/server.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ std::vector<Callback> dispatchers = {
125125
unpackSyscall<::gvisor::syscall::InotifyRmWatch>,
126126
unpackSyscall<::gvisor::syscall::SocketPair>,
127127
unpackSyscall<::gvisor::syscall::Write>,
128+
nullptr,
129+
unpackSyscall<::gvisor::syscall::Select>,
128130
};
129131

130132
void unpack(absl::string_view buf) {

pkg/sentry/seccheck/points/common.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,6 @@ enum MessageType {
134134
MESSAGE_SYSCALL_INOTIFY_RM_WATCH = 32;
135135
MESSAGE_SYSCALL_SOCKETPAIR = 33;
136136
MESSAGE_SYSCALL_WRITE = 34;
137+
MESSAGE_SYSCALL_SELECT = 36;
137138
}
138139
// LINT.ThenChange(../../../../examples/seccheck/server.cc)

pkg/sentry/seccheck/points/syscall.proto

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,14 @@ message SocketPair {
311311
int32 socket1 = 7;
312312
int32 socket2 = 8;
313313
}
314+
315+
message Select {
316+
gvisor.common.ContextData context_data = 1;
317+
Exit exit = 2;
318+
uint64 sysno = 3;
319+
int64 nfds = 4;
320+
repeated int64 read_fds = 5;
321+
int64 timeout_ms = 6;
322+
int64 write_nfds = 7;
323+
int64 except_nfds = 8;
324+
}

pkg/sentry/syscalls/linux/linux64.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ var AMD64 = &kernel.SyscallTable{
6565
20: syscalls.SupportedPoint("writev", Writev, PointWritev),
6666
21: syscalls.Supported("access", Access),
6767
22: syscalls.SupportedPoint("pipe", Pipe, PointPipe),
68-
23: syscalls.Supported("select", Select),
68+
23: syscalls.SupportedPoint("select", Select, PointSelect),
6969
24: syscalls.Supported("sched_yield", SchedYield),
7070
25: syscalls.Supported("mremap", Mremap),
7171
26: syscalls.PartiallySupported("msync", Msync, "Full data flush is not guaranteed at this time.", nil),
@@ -312,7 +312,7 @@ var AMD64 = &kernel.SyscallTable{
312312
267: syscalls.Supported("readlinkat", Readlinkat),
313313
268: syscalls.Supported("fchmodat", Fchmodat),
314314
269: syscalls.Supported("faccessat", Faccessat),
315-
270: syscalls.Supported("pselect6", Pselect6),
315+
270: syscalls.SupportedPoint("pselect6", Pselect6, PointPselect6),
316316
271: syscalls.Supported("ppoll", Ppoll),
317317
272: syscalls.PartiallySupported("unshare", Unshare, "Time, cgroup namespaces not supported.", nil),
318318
273: syscalls.Supported("set_robust_list", SetRobustList),
@@ -494,7 +494,7 @@ var ARM64 = &kernel.SyscallTable{
494494
69: syscalls.SupportedPoint("preadv", Preadv, PointPreadv),
495495
70: syscalls.SupportedPoint("pwritev", Pwritev, PointPwritev),
496496
71: syscalls.Supported("sendfile", Sendfile),
497-
72: syscalls.Supported("pselect6", Pselect6),
497+
72: syscalls.SupportedPoint("pselect6", Pselect6, PointPselect6),
498498
73: syscalls.Supported("ppoll", Ppoll),
499499
74: syscalls.SupportedPoint("signalfd4", Signalfd4, PointSignalfd4),
500500
75: syscalls.ErrorWithEvent("vmsplice", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/138"}), // TODO(b/29354098)

pkg/sentry/syscalls/linux/points.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,3 +992,126 @@ func PointSocketpair(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.Conte
992992
p.Exit = newExitMaybe(info)
993993
return p, pb.MessageType_MESSAGE_SYSCALL_SOCKETPAIR
994994
}
995+
996+
// PointSelect converts select(2) syscall to proto.
997+
func PointSelect(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
998+
nfds := int(info.Args[0].Int())
999+
p := &pb.Select{
1000+
ContextData: cxtData,
1001+
Sysno: uint64(info.Sysno),
1002+
Nfds: int64(nfds),
1003+
}
1004+
1005+
if nfds >= 0 && nfds <= fileCap {
1006+
nBytes := (nfds + 7) / 8
1007+
nBitsInLastPartialByte := nfds % 8
1008+
1009+
if r, err := CopyInFDSet(t, info.Args[1].Pointer(), nBytes, nBitsInLastPartialByte); err == nil {
1010+
var fd int64
1011+
for i := 0; i < nBytes; i++ {
1012+
rV := r[i]
1013+
m := byte(1)
1014+
for j := 0; j < 8; j++ {
1015+
if (rV & m) != 0 {
1016+
p.ReadFds = append(p.ReadFds, fd)
1017+
}
1018+
fd++
1019+
m <<= 1
1020+
}
1021+
}
1022+
}
1023+
1024+
if w, err := CopyInFDSet(t, info.Args[2].Pointer(), nBytes, nBitsInLastPartialByte); err == nil {
1025+
for i := 0; i < nBytes; i++ {
1026+
wV := w[i]
1027+
for wV != 0 {
1028+
wV &= (wV - 1)
1029+
p.WriteNfds++
1030+
}
1031+
}
1032+
}
1033+
1034+
if e, err := CopyInFDSet(t, info.Args[3].Pointer(), nBytes, nBitsInLastPartialByte); err == nil {
1035+
for i := 0; i < nBytes; i++ {
1036+
eV := e[i]
1037+
for eV != 0 {
1038+
eV &= (eV - 1)
1039+
p.ExceptNfds++
1040+
}
1041+
}
1042+
}
1043+
}
1044+
1045+
timeoutMs := int64(-1)
1046+
if timevalAddr := info.Args[4].Pointer(); timevalAddr != 0 {
1047+
var timeval linux.Timeval
1048+
if _, err := timeval.CopyIn(t, timevalAddr); err == nil {
1049+
if timeval.Sec >= 0 && timeval.Usec >= 0 {
1050+
timeoutMs = timeval.ToNsecCapped() / 1e6
1051+
}
1052+
}
1053+
}
1054+
p.TimeoutMs = timeoutMs
1055+
p.Exit = newExitMaybe(info)
1056+
return p, pb.MessageType_MESSAGE_SYSCALL_SELECT
1057+
}
1058+
1059+
// PointPselect6 converts pselect6(2) syscall to proto.
1060+
func PointPselect6(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
1061+
nfds := int(info.Args[0].Int())
1062+
p := &pb.Select{
1063+
ContextData: cxtData,
1064+
Sysno: uint64(info.Sysno),
1065+
Nfds: int64(nfds),
1066+
}
1067+
1068+
if nfds >= 0 && nfds <= fileCap {
1069+
nBytes := (nfds + 7) / 8
1070+
nBitsInLastPartialByte := nfds % 8
1071+
1072+
if r, err := CopyInFDSet(t, info.Args[1].Pointer(), nBytes, nBitsInLastPartialByte); err == nil {
1073+
var fd int64
1074+
for i := 0; i < nBytes; i++ {
1075+
rV := r[i]
1076+
m := byte(1)
1077+
for j := 0; j < 8; j++ {
1078+
if (rV & m) != 0 {
1079+
p.ReadFds = append(p.ReadFds, fd)
1080+
}
1081+
fd++
1082+
m <<= 1
1083+
}
1084+
}
1085+
}
1086+
1087+
if w, err := CopyInFDSet(t, info.Args[2].Pointer(), nBytes, nBitsInLastPartialByte); err == nil {
1088+
for i := 0; i < nBytes; i++ {
1089+
wV := w[i]
1090+
for wV != 0 {
1091+
wV &= (wV - 1)
1092+
p.WriteNfds++
1093+
}
1094+
}
1095+
}
1096+
1097+
if e, err := CopyInFDSet(t, info.Args[3].Pointer(), nBytes, nBitsInLastPartialByte); err == nil {
1098+
for i := 0; i < nBytes; i++ {
1099+
eV := e[i]
1100+
for eV != 0 {
1101+
eV &= (eV - 1)
1102+
p.ExceptNfds++
1103+
}
1104+
}
1105+
}
1106+
}
1107+
1108+
timeoutMs := int64(-1)
1109+
if timespecAddr := info.Args[4].Pointer(); timespecAddr != 0 {
1110+
if timeout, err := copyTimespecInToDuration(t, timespecAddr); err == nil && timeout >= 0 {
1111+
timeoutMs = timeout.Milliseconds()
1112+
}
1113+
}
1114+
p.TimeoutMs = timeoutMs
1115+
p.Exit = newExitMaybe(info)
1116+
return p, pb.MessageType_MESSAGE_SYSCALL_SELECT
1117+
}

0 commit comments

Comments
 (0)