This is an automated email from the ASF dual-hosted git repository.

guangmingchen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new d95ede52 Bugfix: Butex returned to ObjectPool triggers 
use-after-poison (#3012)
d95ede52 is described below

commit d95ede52bd9fb01817162a50c5ba3c520ecdac1e
Author: Bright Chen <chenguangmin...@foxmail.com>
AuthorDate: Tue Jul 15 14:05:42 2025 +0800

    Bugfix: Butex returned to ObjectPool triggers use-after-poison (#3012)
---
 docs/cn/sanitizers.md             | 18 ++++++++++++++++++
 src/bthread/butex.cpp             | 11 +++++++++++
 src/bthread/execution_queue_inl.h |  2 +-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/docs/cn/sanitizers.md b/docs/cn/sanitizers.md
index 30135269..bdd32010 100644
--- a/docs/cn/sanitizers.md
+++ b/docs/cn/sanitizers.md
@@ -17,6 +17,24 @@ BUTIL_ASAN_POISON_MEMORY_REGION(addr, size);
 BUTIL_ASAN_UNPOISON_MEMORY_REGION(addr, size);
 ```
 
+如果某些对象池在设计上允许操作对象池中的对象,例如ExecutionQueue、Butex,则需要特化ObjectPoolWithASanPoison,表示不对这些对象池的对象内存进行poison/unpoison,例如:
+
+```c++
+namespace butil {
+// TaskNode::cancel() may access the TaskNode object returned to the 
ObjectPool<TaskNode>,
+// so ObjectPool<TaskNode> can not poison the memory region of TaskNode.
+template <>
+struct ObjectPoolWithASanPoison<bthread::TaskNode> : false_type {};
+} // namespace butil
+
+namespace butil {
+// Butex object returned to the ObjectPool<Butex> may be accessed,
+// so ObjectPool<Butex> can not poison the memory region of Butex.
+template <>
+struct ObjectPoolWithASanPoison<bthread::Butex> : false_type {};
+} // namespace butil
+```
+
 
其他问题:如果ASan报告中new/delete的调用栈不完整,可以通过设置`fast_unwind_on_malloc=0`回溯出完整的调用栈了。需要注意的是`fast_unwind_on_malloc=0`很耗性能。
 
 ## ThreadSanitizer(TSan)
diff --git a/src/bthread/butex.cpp b/src/bthread/butex.cpp
index c54198c6..aca12816 100644
--- a/src/bthread/butex.cpp
+++ b/src/bthread/butex.cpp
@@ -122,6 +122,17 @@ struct BAIDU_CACHELINE_ALIGNMENT Butex {
 BAIDU_CASSERT(offsetof(Butex, value) == 0, offsetof_value_must_0);
 BAIDU_CASSERT(sizeof(Butex) == BAIDU_CACHELINE_SIZE, 
butex_fits_in_one_cacheline);
 
+} // namespace bthread
+
+namespace butil {
+// Butex object returned to the ObjectPool<Butex> may be accessed,
+// so ObjectPool<Butex> can not poison the memory region of Butex.
+template <>
+struct ObjectPoolWithASanPoison<bthread::Butex> : false_type {};
+} // namespace butil
+
+namespace bthread {
+
 static void wakeup_pthread(ButexPthreadWaiter* pw) {
     // release fence makes wait_pthread see changes before wakeup.
     pw->sig.store(PTHREAD_SIGNALLED, butil::memory_order_release);
diff --git a/src/bthread/execution_queue_inl.h 
b/src/bthread/execution_queue_inl.h
index cf7d2ee5..ddf7bc6b 100644
--- a/src/bthread/execution_queue_inl.h
+++ b/src/bthread/execution_queue_inl.h
@@ -587,7 +587,7 @@ inline int ExecutionQueueBase::dereference() {
 }  // namespace bthread
 
 namespace butil {
-// `TaskNode::cancel' may access the TaskNode object returned to the 
ObjectPool<TaskNode>,
+// TaskNode::cancel() may access the TaskNode object returned to the 
ObjectPool<TaskNode>,
 // so ObjectPool<TaskNode> can not poison the memory region of TaskNode.
 template <>
 struct ObjectPoolWithASanPoison<bthread::TaskNode> : false_type {};


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org
For additional commands, e-mail: dev-h...@brpc.apache.org

Reply via email to