зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1475067: Faster handling of UNICODE_STRINGs in bootstrap blocklist; r=mhowell
This commit is contained in:
Родитель
fc3ec4ef85
Коммит
9f11895c62
|
@ -11,9 +11,19 @@
|
||||||
#include "mozilla/Types.h"
|
#include "mozilla/Types.h"
|
||||||
#include "mozilla/WindowsDllBlocklist.h"
|
#include "mozilla/WindowsDllBlocklist.h"
|
||||||
|
|
||||||
|
#define MOZ_LITERAL_UNICODE_STRING(s) \
|
||||||
|
{ \
|
||||||
|
/* Length of the string in bytes, less the null terminator */ \
|
||||||
|
sizeof(s) - sizeof(wchar_t), \
|
||||||
|
/* Length of the string in bytes, including the null terminator */ \
|
||||||
|
sizeof(s), \
|
||||||
|
/* Pointer to the buffer */ \
|
||||||
|
const_cast<wchar_t*>(s) \
|
||||||
|
}
|
||||||
|
|
||||||
#define DLL_BLOCKLIST_ENTRY(name, ...) \
|
#define DLL_BLOCKLIST_ENTRY(name, ...) \
|
||||||
{ L##name, __VA_ARGS__ },
|
{ MOZ_LITERAL_UNICODE_STRING(L##name), __VA_ARGS__ },
|
||||||
#define DLL_BLOCKLIST_CHAR_TYPE wchar_t
|
#define DLL_BLOCKLIST_STRING_TYPE UNICODE_STRING
|
||||||
|
|
||||||
// Restrict the blocklist definitions to Nightly-only for now
|
// Restrict the blocklist definitions to Nightly-only for now
|
||||||
#if defined(NIGHTLY_BUILD)
|
#if defined(NIGHTLY_BUILD)
|
||||||
|
@ -34,13 +44,13 @@ class MOZ_STATIC_CLASS MOZ_TRIVIAL_CTOR_DTOR NativeNtBlockSet final
|
||||||
{
|
{
|
||||||
NativeNtBlockSetEntry() = default;
|
NativeNtBlockSetEntry() = default;
|
||||||
~NativeNtBlockSetEntry() = default;
|
~NativeNtBlockSetEntry() = default;
|
||||||
NativeNtBlockSetEntry(const wchar_t* aName, uint64_t aVersion,
|
NativeNtBlockSetEntry(const UNICODE_STRING& aName, uint64_t aVersion,
|
||||||
NativeNtBlockSetEntry* aNext)
|
NativeNtBlockSetEntry* aNext)
|
||||||
: mName(aName)
|
: mName(aName)
|
||||||
, mVersion(aVersion)
|
, mVersion(aVersion)
|
||||||
, mNext(aNext)
|
, mNext(aNext)
|
||||||
{}
|
{}
|
||||||
const wchar_t* mName;
|
UNICODE_STRING mName;
|
||||||
uint64_t mVersion;
|
uint64_t mVersion;
|
||||||
NativeNtBlockSetEntry* mNext;
|
NativeNtBlockSetEntry* mNext;
|
||||||
};
|
};
|
||||||
|
@ -50,11 +60,12 @@ public:
|
||||||
NativeNtBlockSet() = default;
|
NativeNtBlockSet() = default;
|
||||||
~NativeNtBlockSet() = default;
|
~NativeNtBlockSet() = default;
|
||||||
|
|
||||||
void Add(const wchar_t* aName, uint64_t aVersion);
|
void Add(const UNICODE_STRING& aName, uint64_t aVersion);
|
||||||
void Write(HANDLE aFile);
|
void Write(HANDLE aFile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static NativeNtBlockSetEntry* NewEntry(const wchar_t* aName, uint64_t aVersion,
|
static NativeNtBlockSetEntry* NewEntry(const UNICODE_STRING& aName,
|
||||||
|
uint64_t aVersion,
|
||||||
NativeNtBlockSetEntry* aNextEntry);
|
NativeNtBlockSetEntry* aNextEntry);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -65,7 +76,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
NativeNtBlockSet::NativeNtBlockSetEntry*
|
NativeNtBlockSet::NativeNtBlockSetEntry*
|
||||||
NativeNtBlockSet::NewEntry(const wchar_t* aName, uint64_t aVersion,
|
NativeNtBlockSet::NewEntry(const UNICODE_STRING& aName, uint64_t aVersion,
|
||||||
NativeNtBlockSet::NativeNtBlockSetEntry* aNextEntry)
|
NativeNtBlockSet::NativeNtBlockSetEntry* aNextEntry)
|
||||||
{
|
{
|
||||||
HANDLE processHeap = mozilla::nt::RtlGetProcessHeap();
|
HANDLE processHeap = mozilla::nt::RtlGetProcessHeap();
|
||||||
|
@ -82,14 +93,13 @@ NativeNtBlockSet::NewEntry(const wchar_t* aName, uint64_t aVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NativeNtBlockSet::Add(const wchar_t* aName, uint64_t aVersion)
|
NativeNtBlockSet::Add(const UNICODE_STRING& aName, uint64_t aVersion)
|
||||||
{
|
{
|
||||||
::RtlAcquireSRWLockExclusive(&mLock);
|
::RtlAcquireSRWLockExclusive(&mLock);
|
||||||
|
|
||||||
for (NativeNtBlockSetEntry* entry = mFirstEntry; entry; entry = entry->mNext) {
|
for (NativeNtBlockSetEntry* entry = mFirstEntry; entry; entry = entry->mNext) {
|
||||||
// We just need to compare the string pointers, not the strings themselves,
|
if (::RtlEqualUnicodeString(&entry->mName, &aName, TRUE) &&
|
||||||
// as we always pass in the strings statically defined in the blocklist.
|
aVersion == entry->mVersion) {
|
||||||
if (aName == entry->mName && aVersion == entry->mVersion) {
|
|
||||||
::RtlReleaseSRWLockExclusive(&mLock);
|
::RtlReleaseSRWLockExclusive(&mLock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -118,8 +128,9 @@ NativeNtBlockSet::Write(HANDLE aFile)
|
||||||
|
|
||||||
MOZ_SEH_TRY {
|
MOZ_SEH_TRY {
|
||||||
for (auto entry = mFirstEntry; entry; entry = entry->mNext) {
|
for (auto entry = mFirstEntry; entry; entry = entry->mNext) {
|
||||||
int convOk = ::WideCharToMultiByte(CP_UTF8, 0, entry->mName, -1, buf,
|
int convOk = ::WideCharToMultiByte(CP_UTF8, 0, entry->mName.Buffer,
|
||||||
sizeof(buf), nullptr, nullptr);
|
entry->mName.Length / sizeof(wchar_t),
|
||||||
|
buf, sizeof(buf), nullptr, nullptr);
|
||||||
if (!convOk) {
|
if (!convOk) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -225,11 +236,11 @@ IsDllAllowed(const UNICODE_STRING& aLeafName, void* aBaseAddress)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNICODE_STRING testStr;
|
|
||||||
DECLARE_POINTER_TO_FIRST_DLL_BLOCKLIST_ENTRY(info);
|
DECLARE_POINTER_TO_FIRST_DLL_BLOCKLIST_ENTRY(info);
|
||||||
while (info->name) {
|
DECLARE_POINTER_TO_LAST_DLL_BLOCKLIST_ENTRY(end);
|
||||||
::RtlInitUnicodeString(&testStr, info->name);
|
|
||||||
if (::RtlEqualUnicodeString(&aLeafName, &testStr, TRUE)) {
|
while (info < end) {
|
||||||
|
if (::RtlEqualUnicodeString(&aLeafName, &info->name, TRUE)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +248,7 @@ IsDllAllowed(const UNICODE_STRING& aLeafName, void* aBaseAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t version;
|
uint64_t version;
|
||||||
if (info->name && !CheckBlockInfo(info, aBaseAddress, version)) {
|
if (info->name.Length && !CheckBlockInfo(info, aBaseAddress, version)) {
|
||||||
gBlockSet.Add(info->name, version);
|
gBlockSet.Add(info->name, version);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,13 @@ MatchUnicodeString(const UNICODE_STRING& aStr, bool (*aPredicate)(WCHAR))
|
||||||
inline bool
|
inline bool
|
||||||
Contains12DigitHexString(const UNICODE_STRING& aLeafName)
|
Contains12DigitHexString(const UNICODE_STRING& aLeafName)
|
||||||
{
|
{
|
||||||
|
// Quick check: If the string is too short, don't bother
|
||||||
|
// (We need at least 12 hex digits, one char for '.', and 3 for extension)
|
||||||
|
const USHORT kMinLen = (12 + 1 + 3) * sizeof(wchar_t);
|
||||||
|
if (aLeafName.Length < kMinLen) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t start, end;
|
uint16_t start, end;
|
||||||
if (!FindCharInUnicodeString(aLeafName, L'.', start)) {
|
if (!FindCharInUnicodeString(aLeafName, L'.', start)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -173,6 +180,13 @@ Contains12DigitHexString(const UNICODE_STRING& aLeafName)
|
||||||
inline bool
|
inline bool
|
||||||
IsFileNameAtLeast16HexDigits(const UNICODE_STRING& aLeafName)
|
IsFileNameAtLeast16HexDigits(const UNICODE_STRING& aLeafName)
|
||||||
{
|
{
|
||||||
|
// Quick check: If the string is too short, don't bother
|
||||||
|
// (We need 16 hex digits, one char for '.', and 3 for extension)
|
||||||
|
const USHORT kMinLen = (16 + 1 + 3) * sizeof(wchar_t);
|
||||||
|
if (aLeafName.Length < kMinLen) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t dotIndex;
|
uint16_t dotIndex;
|
||||||
if (!FindCharInUnicodeString(aLeafName, L'.', dotIndex)) {
|
if (!FindCharInUnicodeString(aLeafName, L'.', dotIndex)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -40,7 +40,7 @@ using namespace mozilla;
|
||||||
|
|
||||||
#define DLL_BLOCKLIST_ENTRY(name, ...) \
|
#define DLL_BLOCKLIST_ENTRY(name, ...) \
|
||||||
{ name, __VA_ARGS__ },
|
{ name, __VA_ARGS__ },
|
||||||
#define DLL_BLOCKLIST_CHAR_TYPE char
|
#define DLL_BLOCKLIST_STRING_TYPE const char*
|
||||||
#include "mozilla/WindowsDllBlocklistDefs.h"
|
#include "mozilla/WindowsDllBlocklistDefs.h"
|
||||||
|
|
||||||
// define this for very verbose dll load debug spew
|
// define this for very verbose dll load debug spew
|
||||||
|
|
|
@ -9,13 +9,15 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "mozilla/ArrayUtils.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
template <typename CharType>
|
template <typename StrType>
|
||||||
struct DllBlockInfoT {
|
struct DllBlockInfoT {
|
||||||
// The name of the DLL -- in LOWERCASE! It will be compared to
|
// The name of the DLL -- in LOWERCASE! It will be compared to
|
||||||
// a lowercase version of the DLL name only.
|
// a lowercase version of the DLL name only.
|
||||||
const CharType* name;
|
StrType name;
|
||||||
|
|
||||||
// If maxVersion is ALL_VERSIONS, we'll block all versions of this
|
// If maxVersion is ALL_VERSIONS, we'll block all versions of this
|
||||||
// dll. Otherwise, we'll block all versions less than or equal to
|
// dll. Otherwise, we'll block all versions less than or equal to
|
||||||
|
@ -73,22 +75,25 @@ MAKE_VERSION(uint16_t a, uint16_t b, uint16_t c, uint16_t d)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(DLL_BLOCKLIST_CHAR_TYPE)
|
#if !defined(DLL_BLOCKLIST_STRING_TYPE)
|
||||||
#error "You must define DLL_BLOCKLIST_CHAR_TYPE"
|
#error "You must define DLL_BLOCKLIST_STRING_TYPE"
|
||||||
#endif // !defined(DLL_BLOCKLIST_CHAR_TYPE)
|
#endif // !defined(DLL_BLOCKLIST_STRING_TYPE)
|
||||||
|
|
||||||
#define DLL_BLOCKLIST_DEFINITIONS_BEGIN \
|
#define DLL_BLOCKLIST_DEFINITIONS_BEGIN \
|
||||||
using DllBlockInfo = mozilla::DllBlockInfoT<DLL_BLOCKLIST_CHAR_TYPE>; \
|
using DllBlockInfo = mozilla::DllBlockInfoT<DLL_BLOCKLIST_STRING_TYPE>; \
|
||||||
static const DllBlockInfo gWindowsDllBlocklist[] = {
|
static const DllBlockInfo gWindowsDllBlocklist[] = {
|
||||||
|
|
||||||
#define ALL_VERSIONS DllBlockInfo::ALL_VERSIONS
|
#define ALL_VERSIONS DllBlockInfo::ALL_VERSIONS
|
||||||
#define UNVERSIONED DllBlockInfo::UNVERSIONED
|
#define UNVERSIONED DllBlockInfo::UNVERSIONED
|
||||||
|
|
||||||
#define DLL_BLOCKLIST_DEFINITIONS_END \
|
#define DLL_BLOCKLIST_DEFINITIONS_END \
|
||||||
{nullptr, 0} \
|
{} \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DECLARE_POINTER_TO_FIRST_DLL_BLOCKLIST_ENTRY(name) \
|
#define DECLARE_POINTER_TO_FIRST_DLL_BLOCKLIST_ENTRY(name) \
|
||||||
const DllBlockInfo* name = &gWindowsDllBlocklist[0]
|
const DllBlockInfo* name = &gWindowsDllBlocklist[0]
|
||||||
|
|
||||||
|
#define DECLARE_POINTER_TO_LAST_DLL_BLOCKLIST_ENTRY(name) \
|
||||||
|
const DllBlockInfo* name = &gWindowsDllBlocklist[mozilla::ArrayLength(gWindowsDllBlocklist) - 1]
|
||||||
|
|
||||||
#endif // mozilla_WindowsDllBlocklistCommon_h
|
#endif // mozilla_WindowsDllBlocklistCommon_h
|
||||||
|
|
Загрузка…
Ссылка в новой задаче