[webkit-reviews] review granted: [Bug 201576] Make a ThreadSafeRefCounted object safe to ref & deref inside its destructor : [Attachment 380721] Fixed JSC tests
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Fri Oct 11 03:41:01 PDT 2019
Mark Lam <mark.lam at apple.com> has granted Ryosuke Niwa <rniwa at webkit.org>'s
request for review:
Bug 201576: Make a ThreadSafeRefCounted object safe to ref & deref inside its
destructor
https://bugs.webkit.org/show_bug.cgi?id=201576
Attachment 380721: Fixed JSC tests
https://bugs.webkit.org/attachment.cgi?id=380721&action=review
--- Comment #29 from Mark Lam <mark.lam at apple.com> ---
Comment on attachment 380721
--> https://bugs.webkit.org/attachment.cgi?id=380721
Fixed JSC tests
View in context: https://bugs.webkit.org/attachment.cgi?id=380721&action=review
r=me with the DropAllLocks VM shutdown check done in its constructor instead of
its client. The pre-existing refCount check there was trying to achieve the
same goal, but was unfortunately not effective enough.
>>>> Source/WTF/wtf/ThreadSafeRefCounted.h:89
>>>> + m_refCount = 1;
>>>
>>> I'm not sure how this achieves what the comment says.
https://bugs.webkit.org/show_bug.cgi?id=201576#c0 makes reference to doing the
same thing as webkit.org/b/195776, which in turn says to use String's
increment/decrement strategy of inc/dec'ing by an s_refCountIncrement of 2.
With String, setting refCount = 1 would prevent it from every decrementing to 0
again, thereby preventing a double free. In the case here, m_refCount is being
decremented by 1 each time. Setting m_refCount = 1 here doesn't prevent it
from being decremented to 0 again. Did you intend to change
ThreadSafeRefCountedBase to use a s_refCountIncrement of 2?
>>
>> I see that this has already been discussed in
https://bugs.webkit.org/show_bug.cgi?id=201576#c9, and
https://bugs.webkit.org/show_bug.cgi?id=201576#c17. I still don't see how this
prevents a double delete. Consider this scenario:
>>
>> 1. m_refCount == 1, and derefBase() is called in
ThreadSafeRefCounted::deref(): derefBase() sets m_refCount = 1 and returns true
i.e. deletion is executed.
>> 2. a bug occurs, and we call ThreadSafeRefCounted::deref() again:
derefBase() decs m_refCount to 0, sets it back to 1, and returns true again
i.e. double deletion is executed!
>>
>> Am I missing something here?
>
> This patch isn't intending to fix a bug that someone might be calling deref()
without ref(), or ref() on a potentially deleted object. This patch's sole
purpose is to prevent storing the object to a Ref / RefPtr inside object's
destructor not result in double delete. If someone is calling deref() before
calling ref() then it would result in UAF at some point regardless (e.g. such a
bug could keep deref()'ing an object until it gets deleted even if it had other
Ref/RefPtr to it).
OK, I see what I was missing: in the destructor, with m_refCount set to 1,
storing the object in any Ref/RefPtr will necessarily increment m_refCount
above 1, thereby ensuring that destruction of said Ref/RefPtr is guaranteed to
not decrement m_refCount down to 0. This (the decrement can only happen after
an increment) is what I was missing.
nit: maybe I was just too dense, or perhaps a little further clarification in
the ChangeLog (about how this ensures a non-zero refCount in the destructor
because assignment of this object to a Ref/RefPtr always sees an increment
before a decrement) may help.
More information about the webkit-reviews
mailing list