commit 14fb585c62e74b861d9241cbb3986fa56f002520
parent 71e2ef9a1036dbe535ec98e6e7cf266476b4d172
Author: Kershaw Chang <kershaw@mozilla.com>
Date: Thu, 20 Nov 2025 13:30:06 +0000
Bug 1966501 - Check fd is open before use, r=necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D272901
Diffstat:
5 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/netwerk/base/nsIUDPSocket.idl b/netwerk/base/nsIUDPSocket.idl
@@ -273,6 +273,13 @@ interface nsIUDPSocket : nsISupports
*/
[noscript, notxpcom] void enableWritePoll();
+ /**
+ * isSocketClosed
+ *
+ * @return true when the socket is already closed.
+ */
+ [noscript, notxpcom] boolean isSocketClosed();
+
/**
* addOutputBytes
*
diff --git a/netwerk/base/nsUDPSocket.cpp b/netwerk/base/nsUDPSocket.cpp
@@ -1222,6 +1222,8 @@ void nsUDPSocket::EnableWritePoll() {
mPollFlags = (PR_POLL_WRITE | PR_POLL_READ | PR_POLL_EXCEPT);
}
+bool nsUDPSocket::IsSocketClosed() { return mFD == nullptr; }
+
NS_IMETHODIMP
nsUDPSocket::SendBinaryStream(const nsACString& aHost, uint16_t aPort,
nsIInputStream* aStream) {
diff --git a/netwerk/protocol/http/Http3ConnectUDPStream.cpp b/netwerk/protocol/http/Http3ConnectUDPStream.cpp
@@ -266,6 +266,8 @@ int64_t Http3ConnectUDPStream::GetFileDescriptor() { return -1; }
void Http3ConnectUDPStream::EnableWritePoll() {}
+bool Http3ConnectUDPStream::IsSocketClosed() { return mSendState == SEND_DONE; }
+
void Http3ConnectUDPStream::AddOutputBytes(uint32_t aBytes) {}
void Http3ConnectUDPStream::AddInputBytes(uint32_t aBytes) {}
diff --git a/netwerk/protocol/http/Http3Session.cpp b/netwerk/protocol/http/Http3Session.cpp
@@ -439,6 +439,11 @@ nsresult Http3Session::ProcessInput(nsIUDPSocket* socket) {
LOG(("Http3Session::ProcessInput writer=%p [this=%p state=%d]",
mUdpConn.get(), this, mState));
+ if (!socket || socket->IsSocketClosed()) {
+ MOZ_DIAGNOSTIC_ASSERT(false, "UDP socket should still be open");
+ return NS_ERROR_UNEXPECTED;
+ }
+
if (mUseNSPRForIO) {
while (true) {
nsTArray<uint8_t> data;
@@ -1091,6 +1096,11 @@ nsresult Http3Session::ProcessOutput(nsIUDPSocket* socket) {
LOG(("Http3Session::ProcessOutput reader=%p, [this=%p]", mUdpConn.get(),
this));
+ if (!socket || socket->IsSocketClosed()) {
+ MOZ_DIAGNOSTIC_ASSERT(false, "UDP socket should still be open");
+ return NS_ERROR_UNEXPECTED;
+ }
+
if (mUseNSPRForIO) {
mSocket = socket;
nsresult rv = mHttp3Connection->ProcessOutputAndSendUseNSPRForIO(
diff --git a/netwerk/protocol/http/HttpConnectionUDP.cpp b/netwerk/protocol/http/HttpConnectionUDP.cpp
@@ -619,6 +619,9 @@ void HttpConnectionUDP::Close(nsresult reason, bool aIsShutdown) {
socket->Close();
}
+ MOZ_DIAGNOSTIC_ASSERT(!mHttp3Session || mHttp3Session->IsClosed(),
+ "Http3Session should already be closed");
+
for (const auto& trans : mQueuedHttpConnectTransaction) {
trans->Close(reason);
}
@@ -718,7 +721,7 @@ nsresult HttpConnectionUDP::OnHeadersAvailable(nsAHttpTransaction* trans,
// response headers so that it will be ready to receive the new response.
if (mIsReused &&
((PR_IntervalNow() - mHttp3Session->LastWriteTime()) < k1000ms)) {
- Close(NS_ERROR_NET_RESET);
+ CloseTransaction(mHttp3Session, NS_ERROR_NET_RESET);
*reset = true;
return NS_OK;
}
@@ -1127,7 +1130,9 @@ NS_IMETHODIMP HttpConnectionUDP::OnPacketReceived(nsIUDPSocket* aSocket) {
NS_IMETHODIMP HttpConnectionUDP::OnStopListening(nsIUDPSocket* aSocket,
nsresult aStatus) {
- CloseTransaction(mHttp3Session, aStatus);
+ // At this point, the UDP socket has already been closed. Set aIsShutdown to
+ // true to ensure that mHttp3Session is also closed.
+ CloseTransaction(mHttp3Session, aStatus, true);
return NS_OK;
}