Commit 72a98a7e authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

SocketPosix: Close socket before freeing write buffer.

SocketPosix::Close() was freeing the write buffer before destroying a
socket.  Unclear if this is the cause of the linked bug, but it seems
not a great thing to be doing.

Bug: 1005042
Change-Id: I2cc35154b6f9de8d272244456eeed5fb9465da4a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1810321Reviewed-by: default avatarEric Roman <eroman@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697718}
parent bffd61c4
...@@ -130,7 +130,10 @@ int SocketPosix::AdoptUnconnectedSocket(SocketDescriptor socket) { ...@@ -130,7 +130,10 @@ int SocketPosix::AdoptUnconnectedSocket(SocketDescriptor socket) {
} }
SocketDescriptor SocketPosix::ReleaseConnectedSocket() { SocketDescriptor SocketPosix::ReleaseConnectedSocket() {
StopWatchingAndCleanUp(); // It's not safe to release a socket with a pending write.
DCHECK(!write_buf_);
StopWatchingAndCleanUp(false /* close_socket */);
SocketDescriptor socket_fd = socket_fd_; SocketDescriptor socket_fd = socket_fd_;
socket_fd_ = kInvalidSocket; socket_fd_ = kInvalidSocket;
return socket_fd; return socket_fd;
...@@ -400,13 +403,7 @@ bool SocketPosix::HasPeerAddress() const { ...@@ -400,13 +403,7 @@ bool SocketPosix::HasPeerAddress() const {
void SocketPosix::Close() { void SocketPosix::Close() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
StopWatchingAndCleanUp(); StopWatchingAndCleanUp(true /* close_socket */);
if (socket_fd_ != kInvalidSocket) {
if (IGNORE_EINTR(close(socket_fd_)) < 0)
PLOG(ERROR) << "close() failed";
socket_fd_ = kInvalidSocket;
}
} }
void SocketPosix::DetachFromThread() { void SocketPosix::DetachFromThread() {
...@@ -544,7 +541,7 @@ void SocketPosix::WriteCompleted() { ...@@ -544,7 +541,7 @@ void SocketPosix::WriteCompleted() {
std::move(write_callback_).Run(rv); std::move(write_callback_).Run(rv);
} }
void SocketPosix::StopWatchingAndCleanUp() { void SocketPosix::StopWatchingAndCleanUp(bool close_socket) {
bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); bool ok = accept_socket_watcher_.StopWatchingFileDescriptor();
DCHECK(ok); DCHECK(ok);
ok = read_socket_watcher_.StopWatchingFileDescriptor(); ok = read_socket_watcher_.StopWatchingFileDescriptor();
...@@ -552,6 +549,16 @@ void SocketPosix::StopWatchingAndCleanUp() { ...@@ -552,6 +549,16 @@ void SocketPosix::StopWatchingAndCleanUp() {
ok = write_socket_watcher_.StopWatchingFileDescriptor(); ok = write_socket_watcher_.StopWatchingFileDescriptor();
DCHECK(ok); DCHECK(ok);
// These needs to be done after the StopWatchingFileDescriptor() calls, but
// before deleting the write buffer.
if (close_socket) {
if (socket_fd_ != kInvalidSocket) {
if (IGNORE_EINTR(close(socket_fd_)) < 0)
DPLOG(ERROR) << "close() failed";
socket_fd_ = kInvalidSocket;
}
}
if (!accept_callback_.is_null()) { if (!accept_callback_.is_null()) {
accept_socket_ = NULL; accept_socket_ = NULL;
accept_callback_.Reset(); accept_callback_.Reset();
......
...@@ -44,7 +44,8 @@ class NET_EXPORT_PRIVATE SocketPosix ...@@ -44,7 +44,8 @@ class NET_EXPORT_PRIVATE SocketPosix
// to be accepted, but must not be actually connected. // to be accepted, but must not be actually connected.
int AdoptUnconnectedSocket(SocketDescriptor socket); int AdoptUnconnectedSocket(SocketDescriptor socket);
// Releases ownership of |socket_fd_| to caller. // Releases ownership of |socket_fd_| to caller. There must be no pending
// write.
SocketDescriptor ReleaseConnectedSocket(); SocketDescriptor ReleaseConnectedSocket();
int Bind(const SockaddrStorage& address); int Bind(const SockaddrStorage& address);
...@@ -119,7 +120,8 @@ class NET_EXPORT_PRIVATE SocketPosix ...@@ -119,7 +120,8 @@ class NET_EXPORT_PRIVATE SocketPosix
int DoWrite(IOBuffer* buf, int buf_len); int DoWrite(IOBuffer* buf, int buf_len);
void WriteCompleted(); void WriteCompleted();
void StopWatchingAndCleanUp(); // |close_socket| indicates whether the socket should also be closed.
void StopWatchingAndCleanUp(bool close_socket);
SocketDescriptor socket_fd_; SocketDescriptor socket_fd_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment