Skip to content

Commit 3d31cfb

Browse files
committed
bug 1483905 - ensure the WebAuthnManager stays alive while WebAuthnTransactionChild is using it r=qdot
Differential Revision: https://phabricator.services.mozilla.com/D5305 --HG-- extra : rebase_source : 1c05f0cd33954fe0127e295b4c76eed40f75e6ef
1 parent df0661a commit 3d31cfb

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

dom/webauthn/WebAuthnTransactionChild.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ WebAuthnTransactionChild::RecvConfirmRegister(const uint64_t& aTransactionId,
2828
return IPC_FAIL_NO_REASON(this);
2929
}
3030

31-
mManager->FinishMakeCredential(aTransactionId, aResult);
31+
// We don't own the reference to mManager. We need to prevent its refcount
32+
// going to 0 while we call anything that can reach the call to
33+
// StopListeningForVisibilityEvents in WebAuthnManager::ClearTransaction
34+
// (often via WebAuthnManager::RejectTransaction).
35+
RefPtr<WebAuthnManagerBase> kungFuDeathGrip(mManager);
36+
kungFuDeathGrip->FinishMakeCredential(aTransactionId, aResult);
3237
return IPC_OK();
3338
}
3439

@@ -40,7 +45,12 @@ WebAuthnTransactionChild::RecvConfirmSign(const uint64_t& aTransactionId,
4045
return IPC_FAIL_NO_REASON(this);
4146
}
4247

43-
mManager->FinishGetAssertion(aTransactionId, aResult);
48+
// We don't own the reference to mManager. We need to prevent its refcount
49+
// going to 0 while we call anything that can reach the call to
50+
// StopListeningForVisibilityEvents in WebAuthnManager::ClearTransaction
51+
// (often via WebAuthnManager::RejectTransaction).
52+
RefPtr<WebAuthnManagerBase> kungFuDeathGrip(mManager);
53+
kungFuDeathGrip->FinishGetAssertion(aTransactionId, aResult);
4454
return IPC_OK();
4555
}
4656

@@ -52,7 +62,12 @@ WebAuthnTransactionChild::RecvAbort(const uint64_t& aTransactionId,
5262
return IPC_FAIL_NO_REASON(this);
5363
}
5464

55-
mManager->RequestAborted(aTransactionId, aError);
65+
// We don't own the reference to mManager. We need to prevent its refcount
66+
// going to 0 while we call anything that can reach the call to
67+
// StopListeningForVisibilityEvents in WebAuthnManager::ClearTransaction
68+
// (often via WebAuthnManager::RejectTransaction).
69+
RefPtr<WebAuthnManagerBase> kungFuDeathGrip(mManager);
70+
kungFuDeathGrip->RequestAborted(aTransactionId, aError);
5671
return IPC_OK();
5772
}
5873

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset=utf-8>
5+
</head>
6+
<body>
7+
<script type="text/javascript">
8+
window.addEventListener('load', function() {
9+
let o = [];
10+
o[0] = window.navigator;
11+
document.writeln('');
12+
// Since the USB token is enabled by default, this will pop up a notification that the
13+
// user can insert/interact with it. Since this is just a test, this won't happen. The
14+
// request will eventually time out.
15+
// Unfortunately the minimum timeout is 15 seconds.
16+
o[0].credentials.get({ publicKey: { challenge: new Uint8Array(128), timeout: 15000 } });
17+
o.forEach((n, i) => o[i] = null);
18+
});
19+
</script>
20+
</body>
21+
</html>

dom/webauthn/tests/mochitest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ support-files =
33
cbor.js
44
u2futil.js
55
pkijs/*
6+
get_assertion_dead_object.html
67
skip-if = !e10s
78
scheme = https
89

@@ -14,6 +15,7 @@ scheme = https
1415
[test_webauthn_no_token.html]
1516
[test_webauthn_make_credential.html]
1617
[test_webauthn_get_assertion.html]
18+
[test_webauthn_get_assertion_dead_object.html]
1719
[test_webauthn_override_request.html]
1820
[test_webauthn_store_credential.html]
1921
[test_webauthn_sameorigin.html]
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!DOCTYPE html>
2+
<meta charset=utf-8>
3+
<head>
4+
<title>Test for GetAssertion on dead object</title>
5+
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
6+
<script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
7+
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
8+
</head>
9+
<body>
10+
11+
<h1>Test for GetAssertion on dead object</h1>
12+
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1483905">Mozilla Bug 1483905</a>
13+
14+
<script class="testbody" type="text/javascript">
15+
"use strict";
16+
SimpleTest.waitForExplicitFinish();
17+
SimpleTest.requestFlakyTimeout(
18+
"Due to the nature of this test, there's no way for the window we're opening to signal " +
19+
"that it's done (the `document.writeln('')` is essential and basically clears any state " +
20+
"we could use). So, we have to wait at least 15 seconds for the webauthn call to time out.");
21+
let win = window.open("https://example.com/tests/dom/webauthn/tests/get_assertion_dead_object.html");
22+
setTimeout(() => {
23+
win.close();
24+
SimpleTest.finish();
25+
}, 20000);
26+
</script>
27+
28+
</body>
29+
</html>

0 commit comments

Comments
 (0)