Skip to content

Commit 46f7dde

Browse files
hanidamlajmeta-codesync[bot]
authored andcommitted
WtStreamManager fix uaf
Summary: fixes a uaf when accessing a write handle that has been destroyed after dequeuing a fin Reviewed By: joanna-jo Differential Revision: D90117497 fbshipit-source-id: 15f087b82518df18b77f6cf0d320d245985069cf
1 parent 9bd8595 commit 46f7dde

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

third-party/proxygen/src/proxygen/lib/http/webtransport/WtStreamManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,8 @@ StreamData WtStreamManager::dequeue(WtWriteHandle& wh,
593593
connSendFc_.commit(len);
594594

595595
// Connection FC blocked if we have data but conn window is exhausted
596-
if (connSendFc_.getAvailable() == 0 &&
597-
writeHandle.bufferedSendData_.hasData()) {
596+
const bool hasData = !res.fin && writeHandle.bufferedSendData_.hasData();
597+
if (connSendFc_.getAvailable() == 0 && hasData) {
598598
connFcBlockedStreams_.insert(&wh);
599599
}
600600

third-party/proxygen/src/proxygen/lib/http/webtransport/test/WtStreamManagerTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,27 @@ TEST(WtStreamManager, WriteEgressHandle) {
351351
EXPECT_TRUE(dequeue.fin);
352352
}
353353

354+
TEST(WtStreamManager, DequeueWriteConnFcBlocked) {
355+
WtConfig config{.peerMaxStreamsUni = 1};
356+
WtSmEgressCb egressCb;
357+
WtSmIngressCb ingressCb;
358+
auto priorityQueue = std::make_unique<quic::HTTPPriorityQueue>();
359+
WtStreamManager streamManager{
360+
detail::WtDir::Client, config, egressCb, ingressCb, *priorityQueue};
361+
362+
auto uni = CHECK_NOTNULL(streamManager.createEgressHandle());
363+
// write kBufLen & fin into stream (fills egress buffer)
364+
constexpr auto kBufLen = 65'535;
365+
auto res = uni->writeStreamData(
366+
makeBuf(kBufLen), /*fin=*/true, /*byteEventCallback=*/nullptr);
367+
EXPECT_TRUE(res.hasValue() && *res == WebTransport::FCState::BLOCKED);
368+
369+
// we should be able to dequeue kBufLen data from one.writeHandle
370+
expectNextWritable(priorityQueue.get(), uni->getID());
371+
auto dequeue = streamManager.dequeue(*uni, /*atMost=*/kBufLen);
372+
EXPECT_TRUE(dequeue.data && dequeue.fin);
373+
}
374+
354375
TEST(WtStreamManager, BidiHandleCancellation) {
355376
WtConfig config{};
356377
WtSmEgressCb egressCb;

0 commit comments

Comments
 (0)