Bug 208978 - [JSC] Use CacheableIdentifier in ByValInfo
Summary: [JSC] Use CacheableIdentifier in ByValInfo
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-03-12 00:23 PDT by Yusuke Suzuki
Modified: 2020-03-12 11:34 PDT (History)
11 users (show)

See Also:


Attachments
Patch (19.39 KB, patch)
2020-03-12 00:41 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (23.18 KB, patch)
2020-03-12 01:35 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (23.18 KB, patch)
2020-03-12 02:28 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (23.22 KB, patch)
2020-03-12 03:58 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (23.41 KB, patch)
2020-03-12 11:23 PDT, Yusuke Suzuki
saam: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2020-03-12 00:23:09 PDT
ByValInfo is also destroyed in CodeBlock::finalizeUnconditionally. And this function does not have AtomStringTable.
We must not destroy String here.
Comment 1 Yusuke Suzuki 2020-03-12 00:24:53 PDT
<rdar://problem/60289819>
Comment 2 Yusuke Suzuki 2020-03-12 00:41:48 PDT
Created attachment 393346 [details]
Patch
Comment 3 Yusuke Suzuki 2020-03-12 00:42:12 PDT
Comment on attachment 393346 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393346&action=review

> Source/JavaScriptCore/heap/Heap.cpp:1508
> +        auto* previous = Thread::current().setCurrentAtomStringTable(nullptr);
> +        auto scopeExit = makeScopeExit([&] {
> +            Thread::current().setCurrentAtomStringTable(previous);
> +        });

Should we do that only for debug builds?
Comment 4 Yusuke Suzuki 2020-03-12 01:35:55 PDT
Created attachment 393349 [details]
Patch
Comment 5 Yusuke Suzuki 2020-03-12 02:28:46 PDT
Created attachment 393350 [details]
Patch
Comment 6 Yusuke Suzuki 2020-03-12 03:38:35 PDT
jsc-i386 seems requiring clean build
Comment 7 Yusuke Suzuki 2020-03-12 03:58:51 PDT
Created attachment 393357 [details]
Patch
Comment 8 Saam Barati 2020-03-12 10:44:59 PDT
Comment on attachment 393357 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393357&action=review

> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:7580
> +                identifierNumber = m_graph.identifiers().ensure(byValInfo->cachedId.uid());

you need to freeze this cell regardless, no? Otherwise, potential UAF if the byValInfo gets cleared

> Source/JavaScriptCore/jit/JITPropertyAccess.cpp:1295
> +        slowCases.append(branchPtr(NotEqual, scratch, TrustedImmPtr(byValInfo->cachedId.uid())));

why is this not a possible UAF? Is it because we only ever set cacheable identifier once?

> Source/JavaScriptCore/runtime/CacheableIdentifier.h:99
> +    uintptr_t m_bits { 0 };

why?
Comment 9 Keith Miller 2020-03-12 10:57:46 PDT
I was under the impression that finalizeUnconditionally happened on the mutator thread? Why is the atomic string table not initialized there?
Comment 10 Keith Miller 2020-03-12 10:58:52 PDT
(In reply to Keith Miller from comment #9)
> I was under the impression that finalizeUnconditionally happened on the
> mutator thread? Why is the atomic string table not initialized there?

Oh nvm, should have read the updated ChangeLog...
Comment 11 Saam Barati 2020-03-12 10:58:59 PDT
(In reply to Keith Miller from comment #9)
> I was under the impression that finalizeUnconditionally happened on the
> mutator thread? Why is the atomic string table not initialized there?

finalizeUnconditionally happens with the mutator stopped. Not necessarily on the mutator.

I suppose a different implementation could be to swap in the mutator's atomic string table?

But I kinda like cacheable identifier more.
Comment 12 Yusuke Suzuki 2020-03-12 11:18:57 PDT
Comment on attachment 393357 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393357&action=review

>> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:7580
>> +                identifierNumber = m_graph.identifiers().ensure(byValInfo->cachedId.uid());
> 
> you need to freeze this cell regardless, no? Otherwise, potential UAF if the byValInfo gets cleared

Oops, right.

>> Source/JavaScriptCore/jit/JITPropertyAccess.cpp:1295
>> +        slowCases.append(branchPtr(NotEqual, scratch, TrustedImmPtr(byValInfo->cachedId.uid())));
> 
> why is this not a possible UAF? Is it because we only ever set cacheable identifier once?

Yes.

>> Source/JavaScriptCore/runtime/CacheableIdentifier.h:99
>> +    uintptr_t m_bits { 0 };
> 
> why?

Otherwise, `CacheableIdentifier value;`'s m_bits is undefined.
Comment 13 Yusuke Suzuki 2020-03-12 11:23:33 PDT
Created attachment 393393 [details]
Patch
Comment 14 Saam Barati 2020-03-12 11:23:36 PDT
Comment on attachment 393357 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393357&action=review

>>> Source/JavaScriptCore/jit/JITPropertyAccess.cpp:1295
>>> +        slowCases.append(branchPtr(NotEqual, scratch, TrustedImmPtr(byValInfo->cachedId.uid())));
>> 
>> why is this not a possible UAF? Is it because we only ever set cacheable identifier once?
> 
> Yes.

Can we document this inside ByValInfo's header as a requirement?

>>> Source/JavaScriptCore/runtime/CacheableIdentifier.h:99
>>> +    uintptr_t m_bits { 0 };
>> 
>> why?
> 
> Otherwise, `CacheableIdentifier value;`'s m_bits is undefined.

why not delete the default constructor? Do we use it? (Sorry, I wrote this assuming it was deleted, but maybe it isn't)
Comment 15 Saam Barati 2020-03-12 11:23:56 PDT
Comment on attachment 393393 [details]
Patch

r=me
Comment 16 Yusuke Suzuki 2020-03-12 11:26:01 PDT
Comment on attachment 393357 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=393357&action=review

Thanks!

>>>> Source/JavaScriptCore/jit/JITPropertyAccess.cpp:1295
>>>> +        slowCases.append(branchPtr(NotEqual, scratch, TrustedImmPtr(byValInfo->cachedId.uid())));
>>> 
>>> why is this not a possible UAF? Is it because we only ever set cacheable identifier once?
>> 
>> Yes.
> 
> Can we document this inside ByValInfo's header as a requirement?

Yeah, I've just documented.

>>>> Source/JavaScriptCore/runtime/CacheableIdentifier.h:99
>>>> +    uintptr_t m_bits { 0 };
>>> 
>>> why?
>> 
>> Otherwise, `CacheableIdentifier value;`'s m_bits is undefined.
> 
> why not delete the default constructor? Do we use it? (Sorry, I wrote this assuming it was deleted, but maybe it isn't)

ByValInfo is using this right now to make the initial one `nullptr`.
Comment 17 Yusuke Suzuki 2020-03-12 11:34:14 PDT
Committed r258344: <https://trac.webkit.org/changeset/258344>