blob: ff79a4d903f8446bff9837e46bb88c3993ea6792 [file] [edit]
<!-- webkit-test-runner [ IPCTestingAPIEnabled=true IgnoreInvalidMessageWhenIPCTestingAPIEnabled=false ] -->
<!doctype html>
<html><head>
<title>Media containment: rogue CreateMediaPlayer of a contained engine must terminate WebContent</title>
<script src="../resources/ipc.js"></script>
<script src="fuzz_tools.js"></script>
<script>
if (window.testRunner) {
testRunner.waitUntilDone();
testRunner.dumpAsText();
}
window.onload = function() {
var out = document.getElementById('out');
function fail(msg) {
out.textContent = msg;
if (window.testRunner) testRunner.notifyDone();
}
if (!window.IPC) {
// No IPC testing API → nothing to test. Match empty expectation.
out.textContent = "";
if (window.testRunner) testRunner.notifyDone();
return;
}
// Engines that GPU's RemoteMediaPlayerManagerProxy::createMediaPlayer must reject.
// AVFoundation (0) and WirelessPlayback (10) are the only allowed engines;
// AVFoundationMSE (1) corresponds to MediaPlayerPrivateMediaSourceAVFObjC,
// and CocoaWebM (9) corresponds to MediaPlayerPrivateWebM.
var blockedEngines = [
{ id: 1, name: 'AVFoundationMSE' },
{ id: 9, name: 'CocoaWebM' },
];
var sent = [];
$F.GPUOutgoingHandler[IPC.messages.RemoteMediaPlayerManagerProxy_CreateMediaPlayer.name] = function(msg) {
// Use the legitimate CreateMediaPlayer payload as a template, modify
// the engine identifier (and a unique MediaPlayerIdentifier so GPU does
// not reject for ID collision), then resend.
var origBody = msg.buffer.slice(16);
for (var i = 0; i < blockedEngines.length; ++i) {
var engine = blockedEngines[i];
var body = origBody.slice(0);
var bodyArr = new Uint8Array(body);
var bodyView = new DataView(body);
bodyView.setUint32(0, 990001 + engine.id, true);
bodyView.setUint32(4, 0, true);
bodyArr[16] = engine.id;
try {
$F.enableListener = false;
IPC.sendMessage("GPU", msg.destinationID, IPC.messages.RemoteMediaPlayerManagerProxy_CreateMediaPlayer.name, bodyArr);
sent.push(engine.name);
} catch (e) {
} finally {
$F.enableListener = true;
}
}
};
var v = document.createElement('video');
document.body.appendChild(v);
v.src = 'http://127.0.0.1/test.mp4';
v.load();
// If GPU's MESSAGE_CHECK fires for the rogue CreateMediaPlayer it asks the
// UI to terminate this WebContent process. The kill is asynchronous and
// crosses three processes, so wait long enough for it to land. If we are
// still alive when the timer fires, MESSAGE_CHECK did not fire — emit FAIL
// listing every blocked engine that was successfully (rogue-)instantiated.
setTimeout(function() {
if (sent.length === 0)
fail("FAIL: never intercepted CreateMediaPlayer — could not exercise the bypass");
else
fail("FAIL: WebContent was not terminated after rogue CreateMediaPlayer for: " + sent.join(', '));
}, 5000);
};
</script></head>
<body>
<pre id="out"></pre>
</body></html>