Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3908,6 +3908,12 @@ def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetAnyX86>
let Documentation = [X86ForceAlignArgPointerDocs];
}

def SectionMemtag : InheritableAttr {
let Spellings = [ClangGCC<"section_memtag">];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe force_memtag? I don't think section_memtag is very meaningful if you don't know the context

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH, force_memtag may sound a bit too generic. Perhaps force_memtag_section or enable_memtag_section?
(If you still prefer force_memtag, that's fine)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could reuse force_memtag to e.g. force the stack instrumentation to not use stack safety analysis for a particular local variable and always tag it with MTE.

let Subjects = SubjectList<[GlobalVar]>;
let Documentation = [SectionMemtagDocs];
}

def NoSanitize : InheritableAttr {
let Spellings = [ClangGCC<"no_sanitize">];
let Args = [VariadicStringArgument<"Sanitizers">];
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -3655,6 +3655,16 @@ full list of supported sanitizer flags.
}];
}

def SectionMemtagDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
Use the ``section_memtag`` attribute on a global variable declaration that also
has the attribute section and the memory tag sanitizer is active to force the
global variable to be MTE tagged. Global variables under sections are not
tagged by default, so you need to explicitly opt-in using this attribute.
}];
}

def DisableSanitizerInstrumentationDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3823,6 +3823,10 @@ bool CodeGenModule::isInNoSanitizeList(SanitizerMask Kind,
return false;
}

bool CodeGenModule::userForcedSectionMemtag(llvm::GlobalVariable *GV) const {
return GV->getMetadata("section_memtag") != nullptr;
}

bool CodeGenModule::imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
StringRef Category) const {
const auto &XRayFilter = getContext().getXRayFilter();
Expand Down Expand Up @@ -6141,6 +6145,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
if (NeedsGlobalCtor || NeedsGlobalDtor)
EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);

if (D->hasAttr<SectionMemtagAttr>()) {
GV->setMetadata("section_memtag", llvm::MDNode::get(GV->getContext(), {}));
}
SanitizerMD->reportGlobal(GV, *D, NeedsGlobalCtor);

// Emit global variable debug information.
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,8 @@ class CodeGenModule : public CodeGenTypeCache {
SourceLocation Loc, QualType Ty,
StringRef Category = StringRef()) const;

bool userForcedSectionMemtag(llvm::GlobalVariable *GV) const;

/// Imbue XRay attributes to a function, applying the always/never attribute
/// lists in the process. Returns true if we did imbue attributes this way,
/// false otherwise.
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6455,6 +6455,10 @@ static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
Sanitizer == "memtag";
}

static void handleSectionMemtagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(SectionMemtagAttr::CreateImplicit(S.Context, AL));
}

static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!AL.checkAtLeastNumArgs(S, 1))
return;
Expand Down Expand Up @@ -7650,6 +7654,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_PtGuardedVar:
handlePtGuardedVarAttr(S, D, AL);
break;
case ParsedAttr::AT_SectionMemtag:
handleSectionMemtagAttr(S, D, AL);
break;
case ParsedAttr::AT_NoSanitize:
handleNoSanitizeAttr(S, D, AL);
break;
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CodeGen/memtag-globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

int global;
int __attribute__((__section__("my_section"))) section_global;
int __attribute__((__section__("my_section"))) __attribute__((section_memtag)) section_global_tagged;
int __attribute__((no_sanitize("memtag"))) attributed_global;
int __attribute__((disable_sanitizer_instrumentation)) disable_instrumentation_global;
int ignorelisted_global;
Expand All @@ -28,6 +29,11 @@ void func() {
// This DOES NOT mean we are instrumenting the section global,
// but we are ignoring it in AsmPrinter rather than in clang.
// CHECK: @{{.*}}section_global{{.*}} ={{.*}} sanitize_memtag

// In order to opt-in memory tagging in globals in sections,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also add to memtag-globals-asm.cpp?

// __attribute__((section_memtag)) must be used.
// CHECK: @{{.*}}section_global_tagged{{.*}} ={{.*}} sanitize_memtag,{{.*}} !section_memtag

// CHECK: @{{.*}}attributed_global{{.*}} =
// CHECK-NOT: sanitize_memtag
// CHECK: @{{.*}}disable_instrumentation_global{{.*}} =
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2633,7 +2633,8 @@ static bool shouldTagGlobal(const llvm::GlobalVariable &G) {
// To mitigate both these cases, and because specifying a section is rare
// outside of these two cases, disable MTE protection for globals in any
// section.
if (G.hasSection())
bool ForceSectionMemtag = G.getMetadata("section_memtag") != nullptr;
if (G.hasSection() && !ForceSectionMemtag)
return false;

return globalSize(G) > 0;
Expand Down
Loading