зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1512504 - Remove now unused CFG test. r=tjr
Depends on D19615 Differential Revision: https://phabricator.services.mozilla.com/D19616 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ef3ad686ee
Коммит
2980c6fe0b
|
@ -1,164 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <io.h>
|
||||
#include <intrin.h>
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "WindowsCFGStatus.h"
|
||||
|
||||
// Inspired by
|
||||
// https://github.com/trailofbits/cfg-showcase/blob/master/cfg_icall.cpp
|
||||
|
||||
jmp_buf env;
|
||||
|
||||
#pragma optimize("", off)
|
||||
void not_entry_point() {
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
__nop();
|
||||
|
||||
longjmp(env, 1);
|
||||
return;
|
||||
}
|
||||
#pragma optimize("", on)
|
||||
|
||||
typedef void (*fn_ptr)();
|
||||
|
||||
/*
|
||||
* Tests for Microsoft's Control Flow Guard compiler security feature.
|
||||
* This function will crash if CFG is enabled, and return false if it is
|
||||
* not enabled.
|
||||
*
|
||||
* CFG protects indirect function calls and ensures they call a valid entry
|
||||
* point. We create a function pointer that calls an invalid entry point.
|
||||
* That invalid entry point is a nop sled.
|
||||
*
|
||||
* Jumping into the nop sled skips the preamble that a function normally
|
||||
* performs, so if we hit the return (ret) we would mess up the stack.
|
||||
* To 'return' from the function safely we jump back to our original
|
||||
* function - no preamble and no return.
|
||||
*
|
||||
* We use setjmp/longjmp because inline asm instructions aren't supported
|
||||
* in x64 by MSVC.
|
||||
*/
|
||||
MFBT_API bool CFG_DisabledOrCrash() {
|
||||
// setjmp returns 0 on the initial call and whatever value is given
|
||||
// to longjmp (here it is 1) when it is jumped back to.
|
||||
int val = setjmp(env);
|
||||
|
||||
if (val == 0) {
|
||||
fn_ptr slide_to_the_left = (fn_ptr)((uintptr_t)(not_entry_point) + 0x20);
|
||||
|
||||
// If CFG is enabled, we're going to crash on the next line
|
||||
slide_to_the_left();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_windowscfgstatus_h
|
||||
#define mozilla_windowscfgstatus_h
|
||||
|
||||
#if defined(_MSC_VER) && \
|
||||
(defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64))
|
||||
|
||||
# include <windows.h>
|
||||
# include "mozilla/Attributes.h"
|
||||
# include "mozilla/Types.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
* Tests for Microsoft's Control Flow Guard compiler security feature.
|
||||
* This function will crash if CFG is enabled.
|
||||
*
|
||||
* There is a dependency on the calling convention in
|
||||
* toolkit/xre/test/browser_checkcfgstatus.js so be sure to update that
|
||||
* if it changes.
|
||||
*
|
||||
* @returns false if CFG is not enabled. Crashes if CFG is enabled.
|
||||
* It will never return true.
|
||||
*/
|
||||
MFBT_API bool CFG_DisabledOrCrash();
|
||||
}
|
||||
|
||||
#endif // defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#endif // mozilla_windowscfgstatus_h
|
|
@ -90,7 +90,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT']:
|
|||
'arm.h',
|
||||
'mips.h',
|
||||
'SSE.h',
|
||||
'WindowsCFGStatus.h',
|
||||
'WindowsDllBlocklist.h',
|
||||
]
|
||||
|
||||
|
|
|
@ -2,7 +2,3 @@
|
|||
|
||||
[browser_checkdllblockliststate.js]
|
||||
skip-if = os != "win" || (os == "win" && os_version == "10.0") # Bug 1401250
|
||||
|
||||
[browser_checkcfgstatus.js]
|
||||
# CFG is only supported on MSVC-compiled Windows 10+, only run it there
|
||||
skip-if = cc_type != "msvc" || os != "win" || os_version == "6.1" || os_version == "6.3"
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Returns the id of the crash minidump.
|
||||
*
|
||||
* @param subject (nsISupports)
|
||||
* The subject passed through the ipc:content-shutdown
|
||||
* observer notification when a content process crash has
|
||||
* occurred.
|
||||
* @returns {String} The crash dump id.
|
||||
*/
|
||||
function getCrashDumpId(subject) {
|
||||
Assert.ok(subject instanceof Ci.nsIPropertyBag2,
|
||||
"Subject needs to be a nsIPropertyBag2 to clean up properly");
|
||||
|
||||
return subject.getPropertyAsAString("dumpID");
|
||||
}
|
||||
|
||||
// Calls a function that should crash when CFG is enabled
|
||||
add_task(async function test_cfg_enabled() {
|
||||
// On debug builds, crashing tabs results in much thinking, which
|
||||
// slows down the test and results in intermittent test timeouts,
|
||||
// so we'll pump up the expected timeout for this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
if (!gMultiProcessBrowser) {
|
||||
Assert.ok(false, "This test should only be run in multi-process mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: "http://example.com",
|
||||
}, async function(browser) {
|
||||
// First, sanity check...
|
||||
Assert.ok(browser.isRemoteBrowser,
|
||||
"This browser needs to be remote if this test is going to " +
|
||||
"work properly.");
|
||||
let contentProcessGone = TestUtils.topicObserved("ipc:content-shutdown");
|
||||
|
||||
ContentTask.spawn(browser, null, function() {
|
||||
// Until 1342564 is fixed, we need to disable this call or it will cause False Positives
|
||||
privateNoteIntentionalCrash();
|
||||
|
||||
const {ctypes} = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
|
||||
let mozglue = ctypes.open("mozglue.dll");
|
||||
let CFG_DisabledOrCrash = mozglue.declare("CFG_DisabledOrCrash", ctypes.default_abi, ctypes.bool);
|
||||
CFG_DisabledOrCrash();
|
||||
// ^-- this line should have crashed us. If we get to the next line, no bueno
|
||||
|
||||
Assert.ok(false, "This test should cause a crash when CFG is enabled. If it " +
|
||||
"does not, this false assertion will trigger. It means CFG is not enabled " +
|
||||
"and we have lost compiler hardening features.");
|
||||
});
|
||||
|
||||
// If we don't crash within 5 seconds, give up.
|
||||
let timeout = new Promise(resolve => setTimeout(resolve, 5000, [null]));
|
||||
|
||||
// We crash or timeout
|
||||
let [subject /* , data */] = await Promise.race([timeout, contentProcessGone]);
|
||||
|
||||
if (!subject) {
|
||||
// We timed out, or otherwise didn't crash properly
|
||||
Assert.ok(false, "This test should cause a crash when CFG is enabled. We didn't " +
|
||||
"observe a crash. This specific assertion should be redundant to a false assertion " +
|
||||
"immediately prior to it. If it occurs alone, then something strange has occured " +
|
||||
"and CFG status and this test should be investigated.");
|
||||
} else {
|
||||
// We crashed properly, clean up...
|
||||
info("Content process is gone!");
|
||||
|
||||
// If we don't clean up the minidump, the harness will complain.
|
||||
let dumpID = getCrashDumpId(subject);
|
||||
|
||||
Assert.ok(dumpID == "", "There should NOT be a dumpID, but we have one: " + dumpID);
|
||||
}
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче