bosswnx commented on issue #67428:
URL: https://github.com/apache/doris/issues/67428#issuecomment-5506340466
Thanks for the thorough triage — the ownership analysis matches ours, and
the **attribution boundary correction is accepted**: I verified that neither
#66191 nor #66899 touches the flush-task lifetime code (`delta_writer` /
`memtable_writer` / `memtable_flush_executor` / the `rowset_builder` ownership
paths — #66191 only adds tablet-state checks and a migration lock in
`GroupRowsetBuilder::init`; #66899 only adds tests and a segment-flusher format
change). The UAF is timing-sensitive and probabilistic; the new suites merely
widen the exposure.
Per the "Missing evidence" request, the complete three ASAN stacks from
build 1036154 (PR #67402, base `952bfcbb40fa`) are attached below — full
frames, not selected ones.
**READ of size 8 (thread T1919, mf_normal):**
```
==48480==ERROR: AddressSanitizer: heap-use-after-free on address
0x7d3e73b61f30
READ of size 8 at 0x7d3e73b61f30 thread T1919 (mf_normal [work)
#0
std::__shared_ptr<doris::segment_v2::SegmentAllocatedLsnMap>::operator bool()
const shared_ptr_base.h:1677:16
#2 doris::RowsetWriterContext::remove_segment_allocated_lsns(long)
be/src/storage/rowset/rowset_writer_context.h:202:9
#3 doris::SharedMemtable::~SharedMemtable()
be/src/load/memtable/memtable_flush_executor.cpp:124:21
#7 doris::PartOfGroupMemtableFlushTask::~PartOfGroupMemtableFlushTask()
be/src/load/memtable/memtable_flush_executor.cpp:82:7
#13 doris::ThreadPool::dispatch_thread() be/src/util/threadpool.cpp:628:23
```
**Freed by thread T1919 (end of run()):**
```
#4 doris::FlushToken::~FlushToken()
be/src/load/memtable/memtable_flush_executor.h:92:7
#8 doris::PartOfGroupMemtableFlushTask::run()
be/src/load/memtable/memtable_flush_executor.cpp:100:5
```
**Allocated by thread T640 (brpc_heavy, stream-load ingest path):**
```
#1 doris::RowsetFactory::create_empty_group_rowset_writer(...)
be/src/storage/rowset/rowset_factory.cpp:100
#2 doris::GroupRowsetBuilder::init()
be/src/storage/rowset_builder.cpp:570:5
#4 doris::DeltaWriter::write(...)
be/src/load/delta_writer/delta_writer.cpp:177:9
#15 doris::PInternalService::tablet_writer_add_block ...
internal_service.cpp:526
```
On the suggested focused rerun around #66899/#66191: agreed it would cleanly
separate "coverage" from "timing change", but since neither PR modified the
lifetime code and the fix does not depend on that attribution, I'll skip the
bisection unless a maintainer wants it.
A fix is ready following the recommended approach: `SharedMemtable` owns
`std::shared_ptr<SegmentAllocatedLsnMap>` captured at submission, insert/remove
through the map directly, non-null map standing in for `need_allocated_lsn()`,
plus ASAN unit tests covering (a) the last token/writer owner released while a
group flush task finishes, (b) a queued subtask running after its weak token
expired, and (c) cancellation, with LSN-entry cleanup asserted on the success
and flush-error paths. Verified in both directions under ASAN: without the fix
the new tests abort with this exact use-after-free; with the fix the
memtable-flush-executor tests pass 8/8. PR to follow shortly.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]