Fix SCM Rights reference leaks.

Control messages should be released on Read (which ignores the control message)
or zero-byte Send. Otherwise, open fds sent through the control messages will
be leaked.

PiperOrigin-RevId: 337110774
This commit is contained in:
Dean Deng
2020-10-14 09:54:05 -07:00
committed by gVisor bot
parent a7b7b7b980
commit fc1e653973
4 changed files with 18 additions and 6 deletions
+6 -2
View File
@@ -573,13 +573,17 @@ func (s *SocketOperations) Read(ctx context.Context, _ *fs.File, dst usermem.IOS
if dst.NumBytes() == 0 {
return 0, nil
}
return dst.CopyOutFrom(ctx, &EndpointReader{
r := &EndpointReader{
Ctx: ctx,
Endpoint: s.ep,
NumRights: 0,
Peek: false,
From: nil,
})
}
n, err := dst.CopyOutFrom(ctx, r)
// Drop control messages.
r.Control.Release(ctx)
return n, err
}
// RecvMsg implements the linux syscall recvmsg(2) for sockets backed by
+6 -2
View File
@@ -267,13 +267,17 @@ func (s *SocketVFS2) Read(ctx context.Context, dst usermem.IOSequence, opts vfs.
if dst.NumBytes() == 0 {
return 0, nil
}
return dst.CopyOutFrom(ctx, &EndpointReader{
r := &EndpointReader{
Ctx: ctx,
Endpoint: s.ep,
NumRights: 0,
Peek: false,
From: nil,
})
}
n, err := dst.CopyOutFrom(ctx, r)
// Drop control messages.
r.Control.Release(ctx)
return n, err
}
// PWrite implements vfs.FileDescriptionImpl.
+3 -1
View File
@@ -1052,7 +1052,9 @@ func sendSingleMsg(t *kernel.Task, s socket.Socket, file *fs.File, msgPtr userme
// Call the syscall implementation.
n, e := s.SendMsg(t, src, to, int(flags), haveDeadline, deadline, controlMessages)
err = handleIOError(t, n != 0, e.ToError(), syserror.ERESTARTSYS, "sendmsg", file)
if err != nil {
// Control messages should be released on error as well as for zero-length
// messages, which are discarded by the receiver.
if n == 0 || err != nil {
controlMessages.Release(t)
}
return uintptr(n), err
+3 -1
View File
@@ -1055,7 +1055,9 @@ func sendSingleMsg(t *kernel.Task, s socket.SocketVFS2, file *vfs.FileDescriptio
// Call the syscall implementation.
n, e := s.SendMsg(t, src, to, int(flags), haveDeadline, deadline, controlMessages)
err = slinux.HandleIOErrorVFS2(t, n != 0, e.ToError(), syserror.ERESTARTSYS, "sendmsg", file)
if err != nil {
// Control messages should be released on error as well as for zero-length
// messages, which are discarded by the receiver.
if n == 0 || err != nil {
controlMessages.Release(t)
}
return uintptr(n), err