-
Notifications
You must be signed in to change notification settings - Fork 59
fix(asan): pointer used after free in autoref_ptr_test #361
fix(asan): pointer used after free in autoref_ptr_test #361
Conversation
autoref_ptr_test is mostly copied from chromium. Be sure we keep consistent with those codes unless they are confirmed incorrect. |
这个问题昨天我和贾硕一起看的,确实是有问题的。
在ScopedRefPtrToSelfPointerAssignment这个单测里,代码如下:
在执行到check->self_ptr = nullptr的时候,会调用ScopedRefPtrToSelf的=运算符重载:
在执行到label A的时候,此时执行了_obj->release_ref()将自己释放了。然后在执行到label B的时候,会发现使用了已经释放的对象的成员,所以就报错了 |
在我看来,合理的做法应当是修改ref_counter类,而不是改测试代码。这里的测试代码,就是为了测试在selfAssign情况下ref_counter能否正常工作。 修改如下:保证release_ref()在最后被调用,避免release自己后,再assign给自己
同理,其他类似函数也应当修改,譬如 |
这样改,return *this的时候会不会有问题呢?同样也是访问了已释放对象的成员(this) |
按理这样用也不对。但是返回解引用,但是没有操作数据,还是安全得多。如果使用者的方式没有问题的话,返回的引用就不应该再被使用,也就不会有问题。 |
最新版实现的真够简洁又隐晦的 |
ref_ptr& operator=(T* p) {
return *this = ref_ptr(p); // Call `ref_ptr& operator=(ref_ptr p)`.
}
ref_ptr& operator=(ref_ptr r) noexcept {
std::swap(ptr_, r.ptr_);
return *this;
} 为什么不用这种写法?这种写法同样可以保证一直到 |
b10f626
恩,我再改一下代码 |
It reports
heap-use-after-free
error that the pointerself_ptr_
is used after free inautoref_ptr_test.ScopedRefPtrToSelfPointerAssignment
when run test with AddressSanitizer tool.Coredump:
Related code:
rdsn/src/core/tests/autoref_ptr_test.cpp
Line 157 in b35cf26
rdsn/include/dsn/utility/autoref_ptr.h
Line 155 in 8095786
Solution
In the semantic of
shared_ptr::operator=
, ScopedRefPtrToSelf should be deleted after the call.Therefore we should not use
this
pointer after we callrelease_ref
, until the last linereturn *this
, because C++ compiler will run RVO to eliminate the return.