Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added address sanitization feature for translating ML models to LLVM modules #4676

Merged
merged 18 commits into from
Feb 11, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ class LLVMAOTTargetBackend final : public TargetBackend {
return targetOp.emitError() << "failed to translate the MLIR LLVM "
"dialect to the native llvm::Module";
}
if (options_.sanitizerKind == LLVMTargetOptions::SanitizerKind::Address) {
for (auto &function : llvmModule->getFunctionList())
function.addFnAttr(llvm::Attribute::SanitizeAddress);
}

// Try to grab a linker tool based on the options (and target environment).
auto linkerTool = LinkerTool::getForTarget(targetTriple, options_);
Expand Down Expand Up @@ -340,6 +344,8 @@ class LLVMAOTTargetBackend final : public TargetBackend {
builder, debugDatabaseFilenameRef);
iree_DyLibExecutableDef_debug_database_embedded_add(builder,
debugDatabaseRef);
iree_DyLibExecutableDef_sanitized_kind_add(
builder, (unsigned char)options_.sanitizerKind);
hanhanW marked this conversation as resolved.
Show resolved Hide resolved
iree_DyLibExecutableDef_end_as_root(builder);

// Add the binary data to the target executable.
Expand Down
23 changes: 23 additions & 0 deletions iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"

namespace mlir {
namespace iree_compiler {
Expand Down Expand Up @@ -87,6 +88,28 @@ LogicalResult runLLVMIRPasses(const LLVMTargetOptions &options,
passBuilder.registerLoopAnalyses(loopAnalysisManager);
passBuilder.crossRegisterProxies(loopAnalysisManager, functionAnalysisManager,
cGSCCAnalysisManager, moduleAnalysisManager);

if (options.sanitizerKind == LLVMTargetOptions::SanitizerKind::Address) {
bool compileKernel = false;
bool recover = false;
bool useAfterScope = true;
bool moduleUseAfterScope = false;
bool useOdrIndicator = false;
hanhanW marked this conversation as resolved.
Show resolved Hide resolved
passBuilder.registerOptimizerLastEPCallback(
[compileKernel, recover, useAfterScope, moduleUseAfterScope,
useOdrIndicator](llvm::ModulePassManager &modulePassManager,
llvm::PassBuilder::OptimizationLevel Level) {
modulePassManager.addPass(
llvm::RequireAnalysisPass<llvm::ASanGlobalsMetadataAnalysis,
llvm::Module>());
modulePassManager.addPass(llvm::ModuleAddressSanitizerPass(
compileKernel, recover, moduleUseAfterScope, useOdrIndicator));
modulePassManager.addPass(
createModuleToFunctionPassAdaptor(llvm::AddressSanitizerPass(
compileKernel, recover, useAfterScope)));
});
}

if (options.optLevel != llvm::PassBuilder::OptimizationLevel::O0) {
llvm::ModulePassManager modulePassManager;
modulePassManager =
Expand Down
12 changes: 12 additions & 0 deletions iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ LLVMTargetOptions getLLVMTargetOptionsFromFlags() {
llvmTargetOptions.targetCPUFeatures = clTargetCPUFeatures;
}

static llvm::cl::opt<std::string> clSanitizerKind(
"iree-llvm-sanitize",
llvm::cl::desc("Specify LLVM sanitize feature such as 'address' ETC"),
llvm::cl::init(""));
if (clSanitizerKind == "address")
llvmTargetOptions.sanitizerKind = LLVMTargetOptions::SanitizerKind::Address;
else if (clSanitizerKind != "") {
llvm::errs() << "For now, you can use 'address' for llvm-sanitize, other "
"values are ignored\n";
clSanitizerKind = "";
}

hanhanW marked this conversation as resolved.
Show resolved Hide resolved
static llvm::cl::opt<std::string> clTargetABI(
"iree-llvm-target-abi",
llvm::cl::desc("LLVM target machine ABI; specify for -mabi"),
Expand Down
5 changes: 5 additions & 0 deletions iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ struct LLVMTargetOptions {
// and benchmarking
bool debugSymbols = true;

// Define and declare kinds of Sanitizer as enum
// the order in enum should be same as one in flat buffer schema
enum SanitizerKind { None = 0, Address };
hanhanW marked this conversation as resolved.
Show resolved Hide resolved
SanitizerKind sanitizerKind = SanitizerKind::None;

// Link any required runtime libraries into the produced binaries statically.
// This increases resulting binary size but enables the binaries to be used on
// any machine without requiring matching system libraries to be installed.
Expand Down
10 changes: 10 additions & 0 deletions iree/hal/local/loaders/legacy_library_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "iree/base/dynamic_library.h"
#include "iree/base/internal/file_io.h"
#include "iree/base/internal/file_path.h"
#include "iree/base/target_platform.h"
#include "iree/base/tracing.h"
#include "iree/hal/local/local_executable.h"

Expand Down Expand Up @@ -81,6 +82,15 @@ static iree_status_t iree_hal_dylib_executable_flatbuffer_verify(
"executable library_embedded is missing/empty");
}

if (iree_DyLibExecutableDef_sanitized_kind_get(executable_def) ==
hanhanW marked this conversation as resolved.
Show resolved Hide resolved
iree_Sanitizer_Address &&
!IREE_SANITIZER_ADDRESS) {
return iree_make_status(
IREE_STATUS_UNAVAILABLE,
"Dynamic library executable is compiled with ASAN support, but this "
"host application failed to enable ASAN to load this executable");
}
hanhanW marked this conversation as resolved.
Show resolved Hide resolved

return iree_ok_status();
}

Expand Down
29 changes: 21 additions & 8 deletions iree/schemas/dylib_executable_def.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
// limitations under the License.

namespace iree;
// Define kinds of sanitizers (the order in enum should be same as enum in LLVM
hanhanW marked this conversation as resolved.
Show resolved Hide resolved
// TargetOptions)
enum Sanitizer : ubyte {
None = 0,
Address
}

// 'Dynamic Library (dylib) Executable'.

Expand All @@ -21,15 +27,22 @@ file_extension "dlib";

// Dynamic library (.so/.dll/.dylib) executable module.
table DyLibExecutableDef {
// A map of entry points to string names with the same order as in the executable op.
entry_points:[string];
// An embedded (as opposed to external) dynamic library file.
// TODO(scotttodd): List of embedded files?
// TODO(scotttodd): Format of files, platform information (x86/arm/etc.)
library_embedded:[ubyte];
// A map of entry points to string names with the same order as in the
// executable op.
entry_points:
[string];
// An embedded (as opposed to external) dynamic library file.
// TODO(scotttodd): List of embedded files?
// TODO(scotttodd): Format of files, platform information (x86/arm/etc.)
library_embedded:
[ubyte];

debug_database_filename:string;
debug_database_embedded:[ubyte];
debug_database_filename:
string;
debug_database_embedded:
[ubyte];
sanitized_kind:
Sanitizer = None;
hanhanW marked this conversation as resolved.
Show resolved Hide resolved

// TODO(scotttodd): Relative file path from this flatbuffer file
}
Expand Down