forked from OSchip/llvm-project
ASan+operator new[]: Add an option for more thorough operator new[] cookie poisoning
Summary: Right now clang is skipping array cookie poisoning for any operator new[] which is not part of the set of replaceable global allocation functions. This commit adds a flag to tell clang to poison all operator new[] cookies. A previous review was poisoning all array cookies unconditionally, but there is an edge case which would stop working under ASan (a custom operator new[] saves whatever pointer it returned, and then accesses it). This newer revision adds a command line argument to toggle this feature. Original revision: https://reviews.llvm.org/D41301 Compiler-rt test revision with an explanation of the edge case: https://reviews.llvm.org/D41664 Reviewers: rjmccall, kcc, rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D43013 llvm-svn: 324884
This commit is contained in:
parent
cd5eb00e8b
commit
4ba5817b8b
|
@ -898,6 +898,14 @@ def fno_sanitize_address_use_after_scope : Flag<["-"], "fno-sanitize-address-use
|
|||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable use-after-scope detection in AddressSanitizer">;
|
||||
def fsanitize_address_poison_class_member_array_new_cookie
|
||||
: Flag<[ "-" ], "fsanitize-address-poison-class-member-array-new-cookie">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable poisoning array cookies when using class member operator new[] in AddressSanitizer">;
|
||||
def fno_sanitize_address_poison_class_member_array_new_cookie
|
||||
: Flag<[ "-" ], "fno-sanitize-address-poison-class-member-array-new-cookie">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Disable poisoning array cookies when using class member operator new[] in AddressSanitizer">;
|
||||
def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable linker dead stripping of globals in AddressSanitizer">;
|
||||
|
|
|
@ -159,6 +159,9 @@ CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-
|
|||
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
|
||||
CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
|
||||
///< in AddressSanitizer
|
||||
CODEGENOPT(SanitizeAddressPoisonClassMemberArrayNewCookie, 1,
|
||||
0) ///< Enable poisoning operator new[] which is not a replaceable
|
||||
///< global allocation function in AddressSanitizer
|
||||
CODEGENOPT(SanitizeAddressGlobalsDeadStripping, 1, 0) ///< Enable linker dead stripping
|
||||
///< of globals in AddressSanitizer
|
||||
CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
|
||||
|
|
|
@ -1848,7 +1848,8 @@ Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
|
|||
|
||||
// Handle the array cookie specially in ASan.
|
||||
if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
|
||||
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
|
||||
(expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
|
||||
CGM.getCodeGenOpts().SanitizeAddressPoisonClassMemberArrayNewCookie)) {
|
||||
// The store to the CookiePtr does not need to be instrumented.
|
||||
CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
|
||||
llvm::FunctionType *FTy =
|
||||
|
|
|
@ -890,6 +890,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
|||
Opts.SanitizeCfiICallGeneralizePointers =
|
||||
Args.hasArg(OPT_fsanitize_cfi_icall_generalize_pointers);
|
||||
Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats);
|
||||
if (Arg *A = Args.getLastArg(
|
||||
OPT_fsanitize_address_poison_class_member_array_new_cookie,
|
||||
OPT_fno_sanitize_address_poison_class_member_array_new_cookie)) {
|
||||
Opts.SanitizeAddressPoisonClassMemberArrayNewCookie =
|
||||
A->getOption().getID() ==
|
||||
OPT_fsanitize_address_poison_class_member_array_new_cookie;
|
||||
}
|
||||
if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_after_scope,
|
||||
OPT_fno_sanitize_address_use_after_scope)) {
|
||||
Opts.SanitizeAddressUseAfterScope =
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - %s | FileCheck %s -check-prefix=PLAIN
|
||||
// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - -fsanitize=address %s | FileCheck %s -check-prefix=ASAN
|
||||
// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - -fsanitize=address -fsanitize-address-poison-class-member-array-new-cookie %s | FileCheck %s -check-prefix=ASAN-POISON-ALL-NEW-ARRAY
|
||||
|
||||
typedef __typeof__(sizeof(0)) size_t;
|
||||
namespace std {
|
||||
|
@ -8,6 +9,7 @@ namespace std {
|
|||
}
|
||||
void *operator new[](size_t, const std::nothrow_t &) throw();
|
||||
void *operator new[](size_t, char *);
|
||||
void *operator new[](size_t, int, int);
|
||||
|
||||
struct C {
|
||||
int x;
|
||||
|
@ -53,3 +55,10 @@ C *CallPlacementNew() {
|
|||
}
|
||||
// ASAN-LABEL: CallPlacementNew
|
||||
// ASAN-NOT: __asan_poison_cxx_array_cookie
|
||||
|
||||
C *CallNewWithArgs() {
|
||||
// ASAN-LABEL: CallNewWithArgs
|
||||
// ASAN-NOT: call void @__asan_poison_cxx_array_cookie
|
||||
// ASAN-POISON-ALL-NEW-ARRAY: call void @__asan_poison_cxx_array_cookie
|
||||
return new (123, 456) C[20];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue