Bug 227540

Summary: [MacOS wk1] crypto/workers/subtle/hrsa-postMessage-worker.html is a flaky failure
Product: WebKit Reporter: ayumi_kojima
Component: WebCore Misc.Assignee: Chris Dumez <cdumez>
Status: RESOLVED FIXED    
Severity: Normal CC: achristensen, ayumi_kojima, beidson, bfulgham, cdumez, darin, ggaren, jcaptanis, jiewen_tan, katherine_cheney, tsavell, webkit-bot-watchers-bugzilla, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Mac (Intel)   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=229178
Attachments:
Description Flags
Patch
none
Patch
none
TestExpectations update
none
WIP Patch
none
Patch
none
Patch
none
Patch none

Description ayumi_kojima 2021-06-30 11:36:14 PDT
crypto/workers/subtle/hrsa-postMessage-worker.html

History: https://results.webkit.org/?suite=layout-tests&test=crypto%2Fworkers%2Fsubtle%2Fhrsa-postMessage-worker.html

This test appeared to be timing specific in its results reporting

--- /Volumes/Data/worker/bigsur-debug-tests-wk1/build/layout-test-results/crypto/workers/subtle/hrsa-postMessage-worker-expected.txt
+++ /Volumes/Data/worker/bigsur-debug-tests-wk1/build/layout-test-results/crypto/workers/subtle/hrsa-postMessage-worker-actual.txt
@@ -3,6 +3,14 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+PASS All checks passed in worker for public key
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSASSA-PKCS1-v1_5'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-256'
+PASS publicKey.usages is ['verify']
 PASS All checks passed in worker for private key
 PASS privateKey.type is 'private'
 PASS privateKey.extractable is false
@@ -11,14 +19,6 @@
 PASS bytesToHexString(privateKey.algorithm.publicExponent) is '010001'
 PASS privateKey.algorithm.hash.name is 'SHA-256'
 PASS privateKey.usages is ['sign']
-PASS All checks passed in worker for public key
-PASS publicKey.type is 'public'
-PASS publicKey.extractable is true
-PASS publicKey.algorithm.name is 'RSASSA-PKCS1-v1_5'
-PASS publicKey.algorithm.modulusLength is 2048
-PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
-PASS publicKey.algorithm.hash.name is 'SHA-256'
-PASS publicKey.usages is ['verify']
 PASS successfullyParsed is true
 
 TEST COMPLETE
Comment 1 Radar WebKit Bug Importer 2021-06-30 11:41:41 PDT
<rdar://problem/79977662>
Comment 2 ayumi_kojima 2021-06-30 14:24:53 PDT
Created attachment 432624 [details]
Patch
Comment 3 ayumi_kojima 2021-06-30 15:04:34 PDT
Created attachment 432631 [details]
Patch
Comment 4 ayumi_kojima 2021-06-30 15:22:08 PDT
Created attachment 432632 [details]
TestExpectations update
Comment 5 Truitt Savell 2021-06-30 15:25:11 PDT
Comment on attachment 432632 [details]
TestExpectations update

Clearing flags on attachment: 432632

Committed r279437 (239294@main): <https://commits.webkit.org/239294@main>
Comment 6 Chris Dumez 2021-07-02 12:46:12 PDT
This is not an issue with the test but rather is really bug in Crypto key deserialization:

38  0x16325d3ad WebCore::ScriptExecutionContext::Task::performTask(WebCore::ScriptExecutionContext&)
39  0x165a32f5d WebCore::WorkerRunLoop::Task::performTask(WebCore::WorkerOrWorkletGlobalScope*)
40  0x165a3249d WebCore::WorkerRunLoop::runInMode(WebCore::WorkerOrWorkletGlobalScope*, WebCore::ModePredicate const&, WebCore::WorkerRunLoop::WaitMode)
41  0x165a3291f WebCore::WorkerRunLoop::runInMode(WebCore::WorkerOrWorkletGlobalScope*, WTF::String const&, WebCore::WorkerRunLoop::WaitMode)
42  0x1659fa04a WebCore::WorkerGlobalScope::unwrapCryptoKey(WTF::Vector<unsigned char, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WTF::Vector<unsigned char, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc>&)
43  0x1635bfd3a WebCore::unwrapCryptoKey(JSC::JSGlobalObject*, WTF::Vector<unsigned char, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WTF::Vector<unsigned char, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc>&)
44  0x16359677d WebCore::CloneDeserializer::readTerminal()
45  0x163594179 WebCore::CloneDeserializer::deserialize()

The test sends 2 messages to the worker, the first one with the public key and the second one with the private key. When processing the first message on the worker thread and doing the deserialization of the public key, we call WorkerRunLoop::runInMode() which processes the pending message for the private key.

As a result, the MessageEvents are dispatched to the JS in the wrong order (private key first, then then public key) sometimes.
Comment 7 Chris Dumez 2021-07-02 12:50:25 PDT
The implementation here is wrong:
bool WorkerGlobalScope::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key)
{
    Ref<WorkerGlobalScope> protectedThis(*this);
    auto resultContainer = CryptoBooleanContainer::create();
    auto doneContainer = CryptoBooleanContainer::create();
    auto keyContainer = CryptoBufferContainer::create();
    thread().workerLoaderProxy().postTaskToLoader([resultContainer, wrappedKey, keyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(thread().workerLoaderProxy()))](ScriptExecutionContext& context) {
        resultContainer->setBoolean(context.unwrapCryptoKey(wrappedKey, keyContainer->buffer()));
        doneContainer->setBoolean(true);
        workerMessagingProxy->postTaskForModeToWorkerOrWorkletGlobalScope([](ScriptExecutionContext& context) {
            ASSERT_UNUSED(context, context.isWorkerGlobalScope());
        }, WorkerRunLoop::defaultMode());
    });

    auto waitResult = MessageQueueMessageReceived;
    while (!doneContainer->boolean() && waitResult != MessageQueueTerminated)
        waitResult = thread().runLoop().runInMode(this, WorkerRunLoop::defaultMode());

    if (doneContainer->boolean())
        key.swap(keyContainer->buffer());
    return resultContainer->boolean();
}

The runInMode() call means we'll process incoming events while we're in the middle of deserializing a crypto key and this is what can cause messages to get received out of order.
Comment 8 Chris Dumez 2021-07-02 13:01:40 PDT
Created attachment 432815 [details]
WIP Patch
Comment 9 Chris Dumez 2021-07-02 13:18:21 PDT
Created attachment 432816 [details]
Patch
Comment 10 Chris Dumez 2021-07-02 14:00:53 PDT
Created attachment 432820 [details]
Patch
Comment 11 Chris Dumez 2021-07-02 14:13:41 PDT
Created attachment 432821 [details]
Patch
Comment 12 Geoffrey Garen 2021-07-02 15:12:41 PDT
Comment on attachment 432821 [details]
Patch

r=me
Comment 13 EWS 2021-07-02 15:26:39 PDT
Committed r279518 (239369@main): <https://commits.webkit.org/239369@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 432821 [details].
Comment 14 youenn fablet 2021-08-19 00:29:15 PDT
*** Bug 229178 has been marked as a duplicate of this bug. ***