mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add read/write syscalls to trace points
Closes #8092 PiperOrigin-RevId: 488719448
This commit is contained in:
committed by
gVisor bot
parent
9cf34dd35f
commit
e6f019594e
@@ -113,6 +113,7 @@ std::vector<Callback> dispatchers = {
|
||||
unpackSyscall<::gvisor::syscall::InotifyAddWatch>,
|
||||
unpackSyscall<::gvisor::syscall::InotifyRmWatch>,
|
||||
unpackSyscall<::gvisor::syscall::SocketPair>,
|
||||
unpackSyscall<::gvisor::syscall::Write>,
|
||||
};
|
||||
|
||||
void unpack(absl::string_view buf) {
|
||||
|
||||
@@ -24,6 +24,12 @@ func init() {
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(1, "write", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(2, "open", nil)
|
||||
addSyscallPoint(3, "close", []FieldDesc{
|
||||
{
|
||||
@@ -31,6 +37,30 @@ func init() {
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(17, "pread64", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(18, "pwrite64", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(19, "readv", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(20, "writev", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(41, "socket", nil)
|
||||
addSyscallPoint(42, "connect", []FieldDesc{
|
||||
{
|
||||
@@ -169,6 +199,30 @@ func init() {
|
||||
},
|
||||
})
|
||||
addSyscallPoint(53, "socketpair", nil)
|
||||
addSyscallPoint(295, "preadv", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(296, "pwritev", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(327, "preadv2", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(328, "pwritev2", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
|
||||
const lastSyscallInTable = 441
|
||||
for i := 0; i <= lastSyscallInTable; i++ {
|
||||
|
||||
@@ -24,6 +24,48 @@ func init() {
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(64, "write", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(65, "readv", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(66, "writev", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(67, "pread64", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(68, "pwrite64", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(69, "preadv", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(70, "pwritev", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(57, "close", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
@@ -145,6 +187,18 @@ func init() {
|
||||
},
|
||||
})
|
||||
addSyscallPoint(199, "socketpair", nil)
|
||||
addSyscallPoint(286, "preadv2", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
addSyscallPoint(287, "pwritev2", []FieldDesc{
|
||||
{
|
||||
ID: FieldSyscallPath,
|
||||
Name: "fd_path",
|
||||
},
|
||||
})
|
||||
|
||||
const lastSyscallInTable = 441
|
||||
for i := 0; i <= lastSyscallInTable; i++ {
|
||||
|
||||
@@ -131,5 +131,6 @@ enum MessageType {
|
||||
MESSAGE_SYSCALL_INOTIFY_ADD_WATCH = 31;
|
||||
MESSAGE_SYSCALL_INOTIFY_RM_WATCH = 32;
|
||||
MESSAGE_SYSCALL_SOCKETPAIR = 33;
|
||||
MESSAGE_SYSCALL_WRITE = 34;
|
||||
}
|
||||
// LINT.ThenChange(../../../../examples/seccheck/server.cc)
|
||||
|
||||
@@ -61,6 +61,21 @@ message Read {
|
||||
int64 fd = 4;
|
||||
string fd_path = 5;
|
||||
uint64 count = 6;
|
||||
bool has_offset = 7;
|
||||
int64 offset = 8;
|
||||
uint32 flags = 9;
|
||||
}
|
||||
|
||||
message Write {
|
||||
gvisor.common.ContextData context_data = 1;
|
||||
Exit exit = 2;
|
||||
uint64 sysno = 3;
|
||||
int64 fd = 4;
|
||||
string fd_path = 5;
|
||||
uint64 count = 6;
|
||||
bool has_offset = 7;
|
||||
int64 offset = 8;
|
||||
uint32 flags = 9;
|
||||
}
|
||||
|
||||
message Connect {
|
||||
@@ -267,7 +282,7 @@ message InotifyInit {
|
||||
int32 flags = 4;
|
||||
}
|
||||
|
||||
message InotifyAddWatch{
|
||||
message InotifyAddWatch {
|
||||
gvisor.common.ContextData context_data = 1;
|
||||
Exit exit = 2;
|
||||
uint64 sysno = 3;
|
||||
|
||||
@@ -53,7 +53,7 @@ var AMD64 = &kernel.SyscallTable{
|
||||
AuditNumber: linux.AUDIT_ARCH_X86_64,
|
||||
Table: map[uintptr]kernel.Syscall{
|
||||
0: syscalls.SupportedPoint("read", Read, PointRead),
|
||||
1: syscalls.Supported("write", Write),
|
||||
1: syscalls.SupportedPoint("write", Write, PointWrite),
|
||||
2: syscalls.SupportedPoint("open", Open, PointOpen),
|
||||
3: syscalls.SupportedPoint("close", Close, PointClose),
|
||||
4: syscalls.Supported("stat", Stat),
|
||||
@@ -69,10 +69,10 @@ var AMD64 = &kernel.SyscallTable{
|
||||
14: syscalls.Supported("rt_sigprocmask", RtSigprocmask),
|
||||
15: syscalls.Supported("rt_sigreturn", RtSigreturn),
|
||||
16: syscalls.Supported("ioctl", Ioctl),
|
||||
17: syscalls.Supported("pread64", Pread64),
|
||||
18: syscalls.Supported("pwrite64", Pwrite64),
|
||||
19: syscalls.Supported("readv", Readv),
|
||||
20: syscalls.Supported("writev", Writev),
|
||||
17: syscalls.SupportedPoint("pread64", Pread64, PointPread64),
|
||||
18: syscalls.SupportedPoint("pwrite64", Pwrite64, PointPwrite64),
|
||||
19: syscalls.SupportedPoint("readv", Readv, PointReadv),
|
||||
20: syscalls.SupportedPoint("writev", Writev, PointWritev),
|
||||
21: syscalls.Supported("access", Access),
|
||||
22: syscalls.SupportedPoint("pipe", Pipe, PointPipe),
|
||||
23: syscalls.Supported("select", Select),
|
||||
@@ -347,8 +347,8 @@ var AMD64 = &kernel.SyscallTable{
|
||||
292: syscalls.SupportedPoint("dup3", Dup3, PointDup3),
|
||||
293: syscalls.SupportedPoint("pipe2", Pipe2, PointPipe2),
|
||||
294: syscalls.PartiallySupportedPoint("inotify_init1", InotifyInit1, PointInotifyInit1, "inotify events are only available inside the sandbox.", nil),
|
||||
295: syscalls.Supported("preadv", Preadv),
|
||||
296: syscalls.Supported("pwritev", Pwritev),
|
||||
295: syscalls.SupportedPoint("preadv", Preadv, PointPreadv),
|
||||
296: syscalls.SupportedPoint("pwritev", Pwritev, PointPwritev),
|
||||
297: syscalls.Supported("rt_tgsigqueueinfo", RtTgsigqueueinfo),
|
||||
298: syscalls.ErrorWithEvent("perf_event_open", linuxerr.ENODEV, "No support for perf counters", nil),
|
||||
299: syscalls.Supported("recvmmsg", RecvMMsg),
|
||||
@@ -382,8 +382,8 @@ var AMD64 = &kernel.SyscallTable{
|
||||
// Syscalls implemented after 325 are "backports" from versions
|
||||
// of Linux after 4.4.
|
||||
326: syscalls.ErrorWithEvent("copy_file_range", linuxerr.ENOSYS, "", nil),
|
||||
327: syscalls.Supported("preadv2", Preadv2),
|
||||
328: syscalls.Supported("pwritev2", Pwritev2),
|
||||
327: syscalls.SupportedPoint("preadv2", Preadv2, PointPreadv2),
|
||||
328: syscalls.SupportedPoint("pwritev2", Pwritev2, PointPwritev2),
|
||||
329: syscalls.ErrorWithEvent("pkey_mprotect", linuxerr.ENOSYS, "", nil),
|
||||
330: syscalls.ErrorWithEvent("pkey_alloc", linuxerr.ENOSYS, "", nil),
|
||||
331: syscalls.ErrorWithEvent("pkey_free", linuxerr.ENOSYS, "", nil),
|
||||
@@ -495,13 +495,13 @@ var ARM64 = &kernel.SyscallTable{
|
||||
61: syscalls.Supported("getdents64", Getdents64),
|
||||
62: syscalls.Supported("lseek", Lseek),
|
||||
63: syscalls.SupportedPoint("read", Read, PointRead),
|
||||
64: syscalls.Supported("write", Write),
|
||||
65: syscalls.Supported("readv", Readv),
|
||||
66: syscalls.Supported("writev", Writev),
|
||||
67: syscalls.Supported("pread64", Pread64),
|
||||
68: syscalls.Supported("pwrite64", Pwrite64),
|
||||
69: syscalls.Supported("preadv", Preadv),
|
||||
70: syscalls.Supported("pwritev", Pwritev),
|
||||
64: syscalls.SupportedPoint("write", Write, PointWrite),
|
||||
65: syscalls.SupportedPoint("readv", Readv, PointReadv),
|
||||
66: syscalls.SupportedPoint("writev", Writev, PointWritev),
|
||||
67: syscalls.SupportedPoint("pread64", Pread64, PointPread64),
|
||||
68: syscalls.SupportedPoint("pwrite64", Pwrite64, PointPwrite64),
|
||||
69: syscalls.SupportedPoint("preadv", Preadv, PointPreadv),
|
||||
70: syscalls.SupportedPoint("pwritev", Pwritev, PointPwritev),
|
||||
71: syscalls.Supported("sendfile", Sendfile),
|
||||
72: syscalls.Supported("pselect", Pselect),
|
||||
73: syscalls.Supported("ppoll", Ppoll),
|
||||
@@ -703,8 +703,8 @@ var ARM64 = &kernel.SyscallTable{
|
||||
|
||||
// Syscalls after 284 are "backports" from versions of Linux after 4.4.
|
||||
285: syscalls.ErrorWithEvent("copy_file_range", linuxerr.ENOSYS, "", nil),
|
||||
286: syscalls.Supported("preadv2", Preadv2),
|
||||
287: syscalls.Supported("pwritev2", Pwritev2),
|
||||
286: syscalls.SupportedPoint("preadv2", Preadv2, PointPreadv2),
|
||||
287: syscalls.SupportedPoint("pwritev2", Pwritev2, PointPwritev2),
|
||||
288: syscalls.ErrorWithEvent("pkey_mprotect", linuxerr.ENOSYS, "", nil),
|
||||
289: syscalls.ErrorWithEvent("pkey_alloc", linuxerr.ENOSYS, "", nil),
|
||||
290: syscalls.ErrorWithEvent("pkey_free", linuxerr.ENOSYS, "", nil),
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/seccheck"
|
||||
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
func newExitMaybe(info kernel.SyscallInfo) *pb.Exit {
|
||||
@@ -58,6 +59,14 @@ func getFilePath(t *kernel.Task, fd int32) string {
|
||||
return path
|
||||
}
|
||||
|
||||
func getIovecSize(t *kernel.Task, addr hostarch.Addr, iovcnt int) uint64 {
|
||||
dst, err := t.IovecsIOSequence(addr, iovcnt, usermem.IOOpts{AddressSpaceActive: true})
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return uint64(dst.NumBytes())
|
||||
}
|
||||
|
||||
// PointOpen converts open(2) syscall to proto.
|
||||
func PointOpen(t *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Open{
|
||||
@@ -167,6 +176,173 @@ func PointRead(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_READ
|
||||
}
|
||||
|
||||
// PointPread64 converts pread64(2) syscall to proto.
|
||||
func PointPread64(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Read{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: uint64(info.Args[2].SizeT()),
|
||||
HasOffset: true,
|
||||
Offset: info.Args[3].Int64(),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_READ
|
||||
}
|
||||
|
||||
// PointReadv converts readv(2) syscall to proto.
|
||||
func PointReadv(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Read{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: getIovecSize(t, info.Args[1].Pointer(), int(info.Args[2].Int())),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_READ
|
||||
}
|
||||
|
||||
// PointPreadv converts preadv(2) syscall to proto.
|
||||
func PointPreadv(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Read{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: getIovecSize(t, info.Args[1].Pointer(), int(info.Args[2].Int())),
|
||||
HasOffset: true,
|
||||
Offset: info.Args[3].Int64(),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_READ
|
||||
}
|
||||
|
||||
// PointPreadv2 converts preadv2(2) syscall to proto.
|
||||
func PointPreadv2(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Read{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: getIovecSize(t, info.Args[1].Pointer(), int(info.Args[2].Int())),
|
||||
HasOffset: true,
|
||||
Offset: info.Args[3].Int64(),
|
||||
Flags: info.Args[5].Uint(),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_READ
|
||||
}
|
||||
|
||||
// PointWrite converts write(2) syscall to proto.
|
||||
func PointWrite(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Write{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: uint64(info.Args[2].SizeT()),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_WRITE
|
||||
}
|
||||
|
||||
// PointPwrite64 converts pwrite64(2) syscall to proto.
|
||||
func PointPwrite64(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Write{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: uint64(info.Args[2].SizeT()),
|
||||
HasOffset: true,
|
||||
Offset: info.Args[3].Int64(),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_WRITE
|
||||
}
|
||||
|
||||
// PointWritev converts writev(2) syscall to proto.
|
||||
func PointWritev(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Write{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: getIovecSize(t, info.Args[1].Pointer(), int(info.Args[2].Int())),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_WRITE
|
||||
}
|
||||
|
||||
// PointPwritev converts pwritev(2) syscall to proto.
|
||||
func PointPwritev(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Write{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: getIovecSize(t, info.Args[1].Pointer(), int(info.Args[2].Int())),
|
||||
HasOffset: true,
|
||||
Offset: info.Args[3].Int64(),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_WRITE
|
||||
}
|
||||
|
||||
// PointPwritev2 converts pwritev2(2) syscall to proto.
|
||||
func PointPwritev2(t *kernel.Task, fields seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Write{
|
||||
ContextData: cxtData,
|
||||
Sysno: uint64(info.Sysno),
|
||||
Fd: int64(info.Args[0].Int()),
|
||||
Count: getIovecSize(t, info.Args[1].Pointer(), int(info.Args[2].Int())),
|
||||
HasOffset: true,
|
||||
Offset: info.Args[3].Int64(),
|
||||
Flags: info.Args[5].Uint(),
|
||||
}
|
||||
if fields.Local.Contains(seccheck.FieldSyscallPath) {
|
||||
p.FdPath = getFilePath(t, int32(p.Fd))
|
||||
}
|
||||
|
||||
p.Exit = newExitMaybe(info)
|
||||
|
||||
return p, pb.MessageType_MESSAGE_SYSCALL_WRITE
|
||||
}
|
||||
|
||||
// PointSocket converts socket(2) syscall to proto.
|
||||
func PointSocket(_ *kernel.Task, _ seccheck.FieldSet, cxtData *pb.ContextData, info kernel.SyscallInfo) (proto.Message, pb.MessageType) {
|
||||
p := &pb.Socket{
|
||||
|
||||
@@ -108,6 +108,7 @@ func matchPoints(t *testing.T, msgs []test.Message) {
|
||||
pb.MessageType_MESSAGE_SYSCALL_RAW: {checker: checkSyscallRaw},
|
||||
pb.MessageType_MESSAGE_SYSCALL_READ: {checker: checkSyscallRead},
|
||||
pb.MessageType_MESSAGE_SYSCALL_SOCKET: {checker: checkSyscallSocket},
|
||||
pb.MessageType_MESSAGE_SYSCALL_WRITE: {checker: checkSyscallWrite},
|
||||
|
||||
// TODO(gvisor.dev/issue/4805): Add validation for these messages.
|
||||
pb.MessageType_MESSAGE_SYSCALL_ACCEPT: {checker: checkTODO},
|
||||
@@ -291,7 +292,44 @@ func checkSyscallRead(msg test.Message) error {
|
||||
}
|
||||
if p.Fd < 0 {
|
||||
// Although negative FD is possible, it doesn't happen in the test.
|
||||
return fmt.Errorf("reading negative FD: %d", p.Fd)
|
||||
return fmt.Errorf("read negative FD: %d", p.Fd)
|
||||
}
|
||||
if p.HasOffset {
|
||||
// Workload always uses 20 for read offsets (account for partial reads).
|
||||
if lower, upper := int64(20), int64(120); p.Offset < lower && p.Offset > upper {
|
||||
return fmt.Errorf("invalid offset, want: [%d, %d], got: %d", lower, upper, p.Offset)
|
||||
}
|
||||
} else if p.Offset != 0 {
|
||||
return fmt.Errorf("offset should be 0: %+v", &p)
|
||||
}
|
||||
if p.Flags != 0 && p.Flags != unix.RWF_HIPRI {
|
||||
return fmt.Errorf("invalid flag value, want: 0 || RWF_HIPRI, got: %+x", p.Flags)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkSyscallWrite(msg test.Message) error {
|
||||
p := pb.Write{}
|
||||
if err := proto.Unmarshal(msg.Msg, &p); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkContextData(p.ContextData); err != nil {
|
||||
return err
|
||||
}
|
||||
if p.Fd < 0 {
|
||||
// Although negative FD is possible, it doesn't happen in the test.
|
||||
return fmt.Errorf("write negative FD: %d", p.Fd)
|
||||
}
|
||||
if p.HasOffset {
|
||||
// Workload always uses 10 for write offsets (account for partial writes).
|
||||
if lower, upper := int64(10), int64(110); p.Offset < lower && p.Offset > upper {
|
||||
return fmt.Errorf("invalid offset, want: [%d, %d], got: %d", lower, upper, p.Offset)
|
||||
}
|
||||
} else if p.Offset != 0 {
|
||||
return fmt.Errorf("offset should be 0: %+v", &p)
|
||||
}
|
||||
if p.Flags != 0 && p.Flags != unix.RWF_HIPRI {
|
||||
return fmt.Errorf("invalid flag value, want: 0 || RWF_HIPRI, got: %+x", p.Flags)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -115,12 +115,88 @@ void runSocket() {
|
||||
}
|
||||
}
|
||||
|
||||
void runReadWrite() {
|
||||
const std::string path = "read-write.txt";
|
||||
auto fd_or = Open(path, O_RDWR | O_CREAT, 0644);
|
||||
if (!fd_or.ok()) {
|
||||
err(1, "open(O_CREAT): %s", fd_or.error().ToString().c_str());
|
||||
}
|
||||
auto cleaup = absl::MakeCleanup([path] { unlink(path.c_str()); });
|
||||
|
||||
auto fd = std::move(fd_or.ValueOrDie());
|
||||
|
||||
// Test different flavors of write.
|
||||
char msg[] = "hello world";
|
||||
if (WriteFd(fd.get(), msg, ABSL_ARRAYSIZE(msg)) < 0) {
|
||||
err(1, "write");
|
||||
}
|
||||
if (PwriteFd(fd.get(), msg, ABSL_ARRAYSIZE(msg), 10) < 0) {
|
||||
err(1, "pwrite");
|
||||
}
|
||||
|
||||
struct iovec write_vecs[] = {
|
||||
{
|
||||
.iov_base = msg,
|
||||
.iov_len = ABSL_ARRAYSIZE(msg),
|
||||
},
|
||||
{
|
||||
.iov_base = msg,
|
||||
.iov_len = ABSL_ARRAYSIZE(msg) / 2,
|
||||
},
|
||||
};
|
||||
if (writev(fd.get(), write_vecs, ABSL_ARRAYSIZE(write_vecs)) < 0) {
|
||||
err(1, "writev");
|
||||
}
|
||||
if (pwritev(fd.get(), write_vecs, ABSL_ARRAYSIZE(write_vecs), 10) < 0) {
|
||||
err(1, "pwritev");
|
||||
}
|
||||
if (pwritev2(fd.get(), write_vecs, ABSL_ARRAYSIZE(write_vecs), 10,
|
||||
RWF_HIPRI) < 0) {
|
||||
err(1, "pwritev2");
|
||||
}
|
||||
|
||||
// Rewind the file and test different flavors of read.
|
||||
if (lseek(fd.get(), 0, SEEK_SET) < 0) {
|
||||
err(1, "seek(0)");
|
||||
}
|
||||
char buf[1024];
|
||||
if (ReadFd(fd.get(), buf, ABSL_ARRAYSIZE(buf)) < 0) {
|
||||
err(1, "read");
|
||||
}
|
||||
if (PreadFd(fd.get(), buf, ABSL_ARRAYSIZE(buf), 20) < 0) {
|
||||
err(1, "read");
|
||||
}
|
||||
|
||||
// Reuse same buffer, since it's not using the result anyways.
|
||||
struct iovec read_vecs[] = {
|
||||
{
|
||||
.iov_base = buf,
|
||||
.iov_len = ABSL_ARRAYSIZE(msg),
|
||||
},
|
||||
{
|
||||
.iov_base = buf,
|
||||
.iov_len = ABSL_ARRAYSIZE(msg) / 2,
|
||||
},
|
||||
};
|
||||
if (readv(fd.get(), read_vecs, ABSL_ARRAYSIZE(read_vecs)) < 0) {
|
||||
err(1, "writev");
|
||||
}
|
||||
if (preadv(fd.get(), read_vecs, ABSL_ARRAYSIZE(read_vecs), 20) < 0) {
|
||||
err(1, "pwritev");
|
||||
}
|
||||
if (preadv2(fd.get(), read_vecs, ABSL_ARRAYSIZE(read_vecs), 20, RWF_HIPRI) <
|
||||
0) {
|
||||
err(1, "pwritev2");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace gvisor
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::gvisor::testing::runForkExecve();
|
||||
::gvisor::testing::runSocket();
|
||||
::gvisor::testing::runReadWrite();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user