mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 10:08:41 +00:00
Bug 1440886 - Implement a static analysis checker to detect usage of PR_LoadLibrary and LoadLibraryA/LoadLibraryExA/LoadLibrary/LoadLibraryEx. r=Nika
MozReview-Commit-ID: CUjfeBeOdsk --HG-- extra : rebase_source : 633b900794cba24030c2b93d4d070d1447fff39b
This commit is contained in:
parent
87f933ff63
commit
c523c8faa9
@ -11,6 +11,9 @@ CHECK(DanglingOnTemporaryChecker, "dangling-on-temporary")
|
||||
CHECK(ExplicitImplicitChecker, "implicit-constructor")
|
||||
CHECK(ExplicitOperatorBoolChecker, "explicit-operator-bool")
|
||||
CHECK(KungFuDeathGripChecker, "kungfu-death-grip")
|
||||
#ifdef _WIN32
|
||||
CHECK(LoadLibraryUsageChecker, "load-library-usage")
|
||||
#endif
|
||||
CHECK(MustOverrideChecker, "must-override")
|
||||
CHECK(MustReturnFromCallerChecker, "must-return-from-caller")
|
||||
CHECK(MustUseChecker, "must-use")
|
||||
|
@ -11,6 +11,9 @@
|
||||
#include "DanglingOnTemporaryChecker.h"
|
||||
#include "ExplicitImplicitChecker.h"
|
||||
#include "ExplicitOperatorBoolChecker.h"
|
||||
#ifdef _WIN32
|
||||
#include "LoadLibraryUsageChecker.h"
|
||||
#endif
|
||||
#include "KungFuDeathGripChecker.h"
|
||||
#include "MustOverrideChecker.h"
|
||||
#include "MustReturnFromCallerChecker.h"
|
||||
|
34
build/clang-plugin/LoadLibraryUsageChecker.cpp
Normal file
34
build/clang-plugin/LoadLibraryUsageChecker.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/* 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 "LoadLibraryUsageChecker.h"
|
||||
#include "CustomMatchers.h"
|
||||
|
||||
// On MacOS the filesystem is UTF-8, on linux the canonical filename is 8-bit
|
||||
// string. On Windows data loss conversion will occur. This checker restricts
|
||||
// the use of ASCII file functions for loading libraries.
|
||||
|
||||
void LoadLibraryUsageChecker::registerMatchers(MatchFinder *AstMatcher) {
|
||||
AstMatcher->addMatcher(
|
||||
callExpr(
|
||||
allOf(isFirstParty(),
|
||||
callee(functionDecl(anyOf(
|
||||
allOf(isInSystemHeader(), anyOf(hasName("LoadLibraryA"),
|
||||
hasName("LoadLibraryExA"))),
|
||||
hasName("PR_LoadLibrary")))),
|
||||
unless(hasArgument(0, stringLiteral()))))
|
||||
.bind("funcCall"),
|
||||
this);
|
||||
}
|
||||
|
||||
void LoadLibraryUsageChecker::check(const MatchFinder::MatchResult &Result) {
|
||||
const CallExpr *FuncCall = Result.Nodes.getNodeAs<CallExpr>("funcCall");
|
||||
|
||||
if (FuncCall) {
|
||||
diag(FuncCall->getLocStart(),
|
||||
"Usage of ASCII file functions (such as %0) is forbidden.",
|
||||
DiagnosticIDs::Error)
|
||||
<< FuncCall->getDirectCallee()->getName();
|
||||
}
|
||||
}
|
18
build/clang-plugin/LoadLibraryUsageChecker.h
Normal file
18
build/clang-plugin/LoadLibraryUsageChecker.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* 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 LoadLibraryUsageChecker_h__
|
||||
#define LoadLibraryUsageChecker_h__
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
class LoadLibraryUsageChecker : public BaseCheck {
|
||||
public:
|
||||
LoadLibraryUsageChecker(StringRef CheckName, ContextType *Context = nullptr)
|
||||
: BaseCheck(CheckName, Context) {}
|
||||
void registerMatchers(MatchFinder *AstMatcher) override;
|
||||
void check(const MatchFinder::MatchResult &Result) override;
|
||||
};
|
||||
|
||||
#endif // !defined(LoadLibraryUsageChecker_h__)
|
@ -428,8 +428,11 @@ inline bool inThirdPartyPath(const Decl *D) {
|
||||
inline bool inThirdPartyPath(const Stmt *S, ASTContext *context) {
|
||||
SourceLocation Loc = S->getLocStart();
|
||||
const SourceManager &SM = context->getSourceManager();
|
||||
|
||||
return inThirdPartyPath(Loc, SM);
|
||||
auto ExpansionLoc = SM.getExpansionLoc(Loc);
|
||||
if (ExpansionLoc.isInvalid()) {
|
||||
return inThirdPartyPath(Loc, SM);
|
||||
}
|
||||
return inThirdPartyPath(ExpansionLoc, SM);
|
||||
}
|
||||
|
||||
/// Polyfill for CXXOperatorCallExpr::isInfixBinaryOp()
|
||||
|
@ -42,6 +42,11 @@ UNIFIED_SOURCES += [
|
||||
'VariableUsageHelpers.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
UNIFIED_SOURCES += [
|
||||
'LoadLibraryUsageChecker.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_MOZSEARCH_PLUGIN']:
|
||||
UNIFIED_SOURCES += [
|
||||
'mozsearch-plugin/FileOperations.cpp',
|
||||
|
20
build/clang-plugin/tests/TestLoadLibraryUsage.cpp
Normal file
20
build/clang-plugin/tests/TestLoadLibraryUsage.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <windows.h>
|
||||
#include "prlink.h"
|
||||
|
||||
void Func() {
|
||||
auto h1 = PR_LoadLibrary(nullptr); // expected-error {{Usage of ASCII file functions (such as PR_LoadLibrary) is forbidden.}}
|
||||
auto h2 = PR_LoadLibrary("C:\\Some\\Path");
|
||||
auto h3 = LoadLibraryA(nullptr); // expected-error {{Usage of ASCII file functions (such as LoadLibraryA) is forbidden.}}
|
||||
auto h4 = LoadLibraryA("C:\\Some\\Path");
|
||||
auto h5 = LoadLibraryExA(nullptr, nullptr, 0); // expected-error {{Usage of ASCII file functions (such as LoadLibraryExA) is forbidden.}}
|
||||
auto h6 = LoadLibraryExA("C:\\Some\\Path", nullptr, 0);
|
||||
|
||||
#ifndef UNICODE
|
||||
// LoadLibrary is a defnine for LoadLibraryA
|
||||
auto h7 = LoadLibrary(nullptr); // expected-error {{Usage of ASCII file functions (such as LoadLibraryA) is forbidden.}}
|
||||
auto h8 = LoadLibrary("C:\\Some\\Path");
|
||||
// LoadLibraryEx is a define for LoadLibraryExA
|
||||
auto h9 = LoadLibraryEx(nullptr, nullptr, 0); // expected-error {{Usage of ASCII file functions (such as LoadLibraryExA) is forbidden.}}
|
||||
auto h10 = LoadLibraryEx("C:\\Some\\Path", nullptr, 0);
|
||||
#endif
|
||||
}
|
@ -47,6 +47,11 @@ SOURCES += [
|
||||
'TestTrivialCtorDtor.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'TestLoadLibraryUsage.cpp',
|
||||
]
|
||||
|
||||
DisableStlWrapping()
|
||||
NoVisibilityFlags()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user