summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/socket/rpcinet
diff options
context:
space:
mode:
authorBrian Geffon <bgeffon@google.com>2018-06-06 15:52:29 -0700
committerShentubot <shentubot@google.com>2018-06-06 15:53:26 -0700
commit79fef54eb1b9e941e2c910f90b65f3cfe94e18c4 (patch)
tree27271ed00212533e0715f4b7d23cd4bd4fe4b250 /pkg/sentry/socket/rpcinet
parent0c34b460f21d6f756b6402688203cfc5e533caa1 (diff)
Add support for rpcinet ioctl(2).
This change will add support for ioctls that have previously been supported by netstack. LINE_LENGTH_IGNORE PiperOrigin-RevId: 199544114 Change-Id: I3769202c19502c3b7d05e06ea9552acfd9255893
Diffstat (limited to 'pkg/sentry/socket/rpcinet')
-rw-r--r--pkg/sentry/socket/rpcinet/socket.go63
-rw-r--r--pkg/sentry/socket/rpcinet/syscall_rpc.proto14
2 files changed, 68 insertions, 9 deletions
diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go
index 74cb84927..3356f7804 100644
--- a/pkg/sentry/socket/rpcinet/socket.go
+++ b/pkg/sentry/socket/rpcinet/socket.go
@@ -56,6 +56,10 @@ type socketOperations struct {
// Verify that we actually implement socket.Socket.
var _ = socket.Socket(&socketOperations{})
+const (
+ sizeOfIfReq = 40
+)
+
// New creates a new RPC socket.
func newSocketFile(ctx context.Context, stack *Stack, family int, skType int, protocol int) (*fs.File, *syserr.Error) {
id, c := stack.rpcConn.NewRequest(pb.SyscallRequest{Args: &pb.SyscallRequest_Socket{&pb.SocketRequest{Family: int64(family), Type: int64(skType | syscall.SOCK_NONBLOCK), Protocol: int64(protocol)}}}, false /* ignoreResult */)
@@ -290,7 +294,11 @@ func (s *socketOperations) Accept(t *kernel.Task, peerRequested bool, flags int,
return 0, nil, 0, syserr.FromError(err)
}
- return fd, payload.Address.Address, payload.Address.Length, nil
+ if peerRequested {
+ return fd, payload.Address.Address, payload.Address.Length, nil
+ }
+
+ return fd, nil, 0, nil
}
// Bind implements socket.Socket.Bind.
@@ -385,9 +393,60 @@ func (s *socketOperations) GetSockName(t *kernel.Task) (interface{}, uint32, *sy
return addr.Address, addr.Length, nil
}
+func rpcIoctl(t *kernel.Task, fd, cmd uint32, arg []byte) ([]byte, error) {
+ stack := t.NetworkContext().(*Stack)
+
+ id, c := stack.rpcConn.NewRequest(pb.SyscallRequest{Args: &pb.SyscallRequest_Ioctl{&pb.IOCtlRequest{Fd: fd, Cmd: cmd, Arg: arg}}}, false /* ignoreResult */)
+ <-c
+
+ res := stack.rpcConn.Request(id).Result.(*pb.SyscallResponse_Ioctl).Ioctl.Result
+ if e, ok := res.(*pb.IOCtlResponse_ErrorNumber); ok {
+ return nil, syscall.Errno(e.ErrorNumber)
+ }
+
+ return res.(*pb.IOCtlResponse_Value).Value, nil
+}
+
// Ioctl implements fs.FileOperations.Ioctl.
func (s *socketOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) {
- return 0, syserror.ENOTTY
+ t := ctx.(*kernel.Task)
+
+ cmd := uint32(args[1].Int())
+ arg := args[2].Pointer()
+
+ var buf []byte
+ switch cmd {
+ // The following ioctls take 4 byte argument parameters.
+ case syscall.TIOCINQ, syscall.TIOCOUTQ:
+ buf = make([]byte, 4)
+ // The following ioctls have args which are sizeof(struct ifreq).
+ case syscall.SIOCGIFINDEX, syscall.SIOCGIFNETMASK, syscall.SIOCGIFHWADDR, syscall.SIOCGIFNAME, syscall.SIOCGIFFLAGS:
+ buf = make([]byte, sizeOfIfReq)
+ default:
+ return 0, syserror.ENOTTY
+ }
+
+ _, err := io.CopyIn(ctx, arg, buf, usermem.IOOpts{
+ AddressSpaceActive: true,
+ })
+
+ if err != nil {
+ return 0, err
+ }
+
+ v, err := rpcIoctl(t, s.fd, cmd, buf)
+ if err != nil {
+ return 0, err
+ }
+
+ if len(v) != len(buf) {
+ return 0, syserror.EINVAL
+ }
+
+ _, err = io.CopyOut(ctx, arg, v, usermem.IOOpts{
+ AddressSpaceActive: true,
+ })
+ return 0, err
}
func rpcRecvMsg(t *kernel.Task, req *pb.SyscallRequest_Recvmsg) (*pb.RecvmsgResponse_ResultPayload, *syserr.Error) {
diff --git a/pkg/sentry/socket/rpcinet/syscall_rpc.proto b/pkg/sentry/socket/rpcinet/syscall_rpc.proto
index b845b1bce..996962aae 100644
--- a/pkg/sentry/socket/rpcinet/syscall_rpc.proto
+++ b/pkg/sentry/socket/rpcinet/syscall_rpc.proto
@@ -8,7 +8,7 @@ package syscall_rpc;
message SendmsgRequest {
uint32 fd = 1;
- bytes data = 2;
+ bytes data = 2 [ctype = CORD];
bytes address = 3;
bool more = 4;
bool end_of_record = 5;
@@ -24,13 +24,13 @@ message SendmsgResponse {
message IOCtlRequest {
uint32 fd = 1;
uint32 cmd = 2;
- uint64 arg = 3;
+ bytes arg = 3;
}
message IOCtlResponse {
oneof result {
uint32 error_number = 1;
- uint64 value = 2;
+ bytes value = 2;
}
}
@@ -63,7 +63,7 @@ message ReadRequest {
message ReadResponse {
oneof result {
uint32 error_number = 1;
- bytes data = 2;
+ bytes data = 2 [ctype = CORD];
}
}
@@ -74,13 +74,13 @@ message ReadFileRequest {
message ReadFileResponse {
oneof result {
uint32 error_number = 1;
- bytes data = 2;
+ bytes data = 2 [ctype = CORD];
}
}
message WriteRequest {
uint32 fd = 1;
- bytes data = 2;
+ bytes data = 2 [ctype = CORD];
}
message WriteResponse {
@@ -107,7 +107,7 @@ message AddressResponse {
message RecvmsgResponse {
message ResultPayload {
- bytes data = 1;
+ bytes data = 1 [ctype = CORD];
AddressResponse address = 2;
uint32 length = 3;
}