Skip to content

Commit e2405bd

Browse files
kenrbmibrunin
authored andcommitted
[Backport] CVE-2024-9955: Use after free in Web Authentication
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/5900439: Clear pending write socket data state before sending it `EnclaveWebSocketClient` should not modify member variables after calling `InternalWrite`. Fixed: 370133761 Change-Id: Id29639790583d15bfa82e261ffcd40867a006dd0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5900439 Reviewed-by: Adam Langley <[email protected]> Commit-Queue: Ken Buchanan <[email protected]> Auto-Submit: Ken Buchanan <[email protected]> Cr-Commit-Position: refs/heads/main@{#1362071} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/597920 Reviewed-by: Michal Klocek <[email protected]>
1 parent e161a13 commit e2405bd

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

chromium/device/fido/enclave/enclave_websocket_client.cc

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "device/fido/enclave/enclave_websocket_client.h"
66

77
#include <limits>
8+
#include <utility>
89

910
#include "components/device_event_log/device_event_log.h"
1011
#include "device/fido/fido_constants.h"
@@ -90,6 +91,7 @@ void EnclaveWebSocketClient::Write(base::span<const uint8_t> data) {
9091
data.size() > std::numeric_limits<uint32_t>::max()) {
9192
FIDO_LOG(ERROR) << "Invalid WebSocket write.";
9293
ClosePipe(SocketStatus::kError);
94+
// `this` may have been deleted at this point.
9395
return;
9496
}
9597

@@ -103,6 +105,7 @@ void EnclaveWebSocketClient::Write(base::span<const uint8_t> data) {
103105
}
104106

105107
InternalWrite(data);
108+
// `this` may have been deleted at this point.
106109
}
107110

108111
void EnclaveWebSocketClient::Connect() {
@@ -144,6 +147,7 @@ void EnclaveWebSocketClient::InternalWrite(base::span<const uint8_t> data) {
144147
if (result != MOJO_RESULT_OK) {
145148
FIDO_LOG(ERROR) << "Failed to write to WebSocket.";
146149
ClosePipe(SocketStatus::kError);
150+
// `this` may have been deleted at this point.
147151
}
148152
}
149153

@@ -160,6 +164,7 @@ void EnclaveWebSocketClient::OnFailure(const std::string& message,
160164
<< net_error << ", " << response_code;
161165

162166
ClosePipe(SocketStatus::kError);
167+
// `this` may have been deleted at this point.
163168
}
164169

165170
void EnclaveWebSocketClient::OnConnectionEstablished(
@@ -194,8 +199,9 @@ void EnclaveWebSocketClient::OnConnectionEstablished(
194199
state_ = State::kOpen;
195200

196201
if (pending_write_data_) {
197-
InternalWrite(*pending_write_data_);
198-
pending_write_data_ = absl::nullopt;
202+
auto write_data = std::exchange(pending_write_data_, std::nullopt).value();
203+
InternalWrite(write_data);
204+
// `this` may have been deleted at this point.
199205
}
200206
}
201207

@@ -211,6 +217,7 @@ void EnclaveWebSocketClient::OnDataFrame(
211217
if (data_len == 0) {
212218
if (finish) {
213219
ProcessCompletedResponse();
220+
// `this` may have been deleted at this point.
214221
}
215222
return;
216223
}
@@ -224,13 +231,15 @@ void EnclaveWebSocketClient::OnDataFrame(
224231
FIDO_LOG(ERROR) << "Invalid WebSocket frame (type: "
225232
<< static_cast<int>(type) << ", len: " << data_len << ")";
226233
ClosePipe(SocketStatus::kError);
234+
// `this` may have been deleted at this point.
227235
return;
228236
}
229237

230238
pending_read_data_.resize(new_size);
231239
pending_read_finished_ = finish;
232240
client_receiver_.Pause();
233241
ReadFromDataPipe(MOJO_RESULT_OK, mojo::HandleSignalsState());
242+
// `this` may have been deleted at this point.
234243
}
235244

236245
void EnclaveWebSocketClient::OnDropChannel(bool was_clean,
@@ -240,6 +249,7 @@ void EnclaveWebSocketClient::OnDropChannel(bool was_clean,
240249
CHECK(state_ == State::kOpen || state_ == State::kConnecting);
241250

242251
ClosePipe(SocketStatus::kSocketClosed);
252+
// `this` may have been deleted at this point.
243253
}
244254

245255
void EnclaveWebSocketClient::OnClosingHandshake() {}
@@ -268,6 +278,7 @@ void EnclaveWebSocketClient::ReadFromDataPipe(MojoResult,
268278
client_receiver_.Resume();
269279
if (pending_read_finished_) {
270280
ProcessCompletedResponse();
281+
// `this` may have been deleted at this point.
271282
}
272283
}
273284
} else if (result == MOJO_RESULT_SHOULD_WAIT) {
@@ -276,6 +287,7 @@ void EnclaveWebSocketClient::ReadFromDataPipe(MojoResult,
276287
FIDO_LOG(ERROR) << "Reading WebSocket frame failed: "
277288
<< static_cast<int>(result);
278289
ClosePipe(SocketStatus::kError);
290+
// `this` may have been deleted at this point.
279291
}
280292
}
281293

@@ -301,6 +313,7 @@ void EnclaveWebSocketClient::ClosePipe(SocketStatus status) {
301313

302314
void EnclaveWebSocketClient::OnMojoPipeDisconnect() {
303315
ClosePipe(SocketStatus::kSocketClosed);
316+
// `this` may have been deleted at this point.
304317
}
305318

306319
} // namespace device::enclave

chromium/device/fido/enclave/enclave_websocket_client.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ class EnclaveWebSocketClient : public network::mojom::WebSocketHandshakeClient,
8181
};
8282

8383
void Connect();
84+
85+
// All of the methods below have the potential to invoke the response
86+
// callback, which can destroy this object. No data members should be
87+
// accessed after calling one.
8488
void InternalWrite(base::span<const uint8_t> data);
8589
void ReadFromDataPipe(MojoResult, const mojo::HandleSignalsState&);
8690
void ProcessCompletedResponse();

0 commit comments

Comments
 (0)