WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
211201
Freezing of Gigacage and JSC Configs should be thread safe.
https://bugs.webkit.org/show_bug.cgi?id=211201
Summary
Freezing of Gigacage and JSC Configs should be thread safe.
Mark Lam
Reported
2020-04-29 13:16:19 PDT
If a client creates multiple VM instances in different threads concurrently, the following race can occur: Config::permanentlyFreeze() contains the following code: if (!g_jscConfig.isPermanentlyFrozen) // Point P1 g_jscConfig.isPermanentlyFrozen = true; // Point P2 Let's say there are 2 threads T1 and T2. 1. T1 creates a VM and gets to point P1, and sees that g_jscConfig.isPermanentlyFrozen is not set. T1 is about to execute P2 when it gets gets pre-empted. 2. T2 creates a VM and gets to point P1, and sees that g_jscConfig.isPermanentlyFrozen is not set. T2 proceeds to point P2 and sets g_jscConfig.isPermanentlyFrozen to true. T2 goes on to freeze the Config and makes it not writable. 3. T1 gets to run again, and proceeds to point P2. T1 tries to set g_jscConfig.isPermanentlyFrozen to true. But because the Config has been frozen against writes, the write to g_jscConfig.isPermanentlyFrozen results in a crash. This is a classic TOCTOU bug. The fix is simply to ensure that only one thread can enter Config::permanentlyFreeze() at a time. Ditto for Gigacage::permanentlyFreezeGigacageConfig(). <
rdar://problem/62597619
>
Attachments
proposed patch.
(4.66 KB, patch)
2020-04-29 13:25 PDT
,
Mark Lam
ysuzuki
: review+
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Mark Lam
Comment 1
2020-04-29 13:25:07 PDT
Created
attachment 397992
[details]
proposed patch.
Yusuke Suzuki
Comment 2
2020-04-29 13:27:50 PDT
Comment on
attachment 397992
[details]
proposed patch. View in context:
https://bugs.webkit.org/attachment.cgi?id=397992&action=review
> Source/JavaScriptCore/runtime/JSCConfig.cpp:58 > + static Lock configLock; > + LockHolder locker(configLock);
Why not using std::call_once?
> Source/bmalloc/bmalloc/Gigacage.cpp:122 > + static Mutex configLock; > + LockHolder locking(configLock); > +
Ditto.
Mark Lam
Comment 3
2020-04-29 13:32:33 PDT
Comment on
attachment 397992
[details]
proposed patch. View in context:
https://bugs.webkit.org/attachment.cgi?id=397992&action=review
>> Source/JavaScriptCore/runtime/JSCConfig.cpp:58 >> + LockHolder locker(configLock); > > Why not using std::call_once?
Because I want each call to permanentlyFreeze() to go thru the vm_protect and affirm that the setting is as we expect it. This is why there's a RELEASE_ASSERT on the result.
Yusuke Suzuki
Comment 4
2020-04-29 13:32:54 PDT
Comment on
attachment 397992
[details]
proposed patch. View in context:
https://bugs.webkit.org/attachment.cgi?id=397992&action=review
Discussed with Mark. We actually want to call this function multiple times, so std::call_once is not suitable. But while executing this function, this function breaks an invariant temporarily which is required by the call from the other thread. So guarding this with Lock is the appropriate way.
>> Source/JavaScriptCore/runtime/JSCConfig.cpp:58 >> + LockHolder locker(configLock); > > Why not using std::call_once?
Use `auto locker = holdLock(configLock)` in WTF.
Mark Lam
Comment 5
2020-04-29 13:40:23 PDT
Thanks for the review. (In reply to Yusuke Suzuki from
comment #4
)
> Use `auto locker = holdLock(configLock)` in WTF.
Applied. Landed in
r260913
: <
http://trac.webkit.org/r260913
>.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug