This is an archive of the discontinued LLVM Phabricator instance.

[gcov] Add nosanitize metadata to memory access instructions inserted by emitProfileNotes()
ClosedPublic

Authored by Enna1 on May 12 2023, 10:01 AM.

Details

Summary

This patch adds nosantize metadata to memory access instructions inserted by gcov emitProfileNotes(), making sanitizers skip these instructions when gcov and sanitizer are used together.

Diff Detail

Event Timeline

Enna1 created this revision.May 12 2023, 10:01 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 12 2023, 10:01 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
Enna1 published this revision for review.May 12 2023, 10:49 AM
Enna1 added reviewers: MaskRay, nickdesaulniers.
Enna1 added a subscriber: MTC.
Herald added a project: Restricted Project. · View Herald TranscriptMay 12 2023, 10:50 AM

Thanks for the patch! Why do we want to skip sanitizing these loads and stores?

Also, gocv is misspelled in the commit description, please fix that up.

llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
150–152

This looks the same as SanitizerMetadata::disableSanitizerForInstruction and ModuleSanitizerCoverage::SetNoSanitizeMetadata. Rather than define a third copy, why not declare it as a new method on Instruction and define it in llvm/lib/IR/Metadata.cpp, then use it in all three places?

925–936
Enna1 updated this revision to Diff 522445.May 15 2023, 11:01 PM

address review comments

Enna1 marked 2 inline comments as done.May 15 2023, 11:08 PM

Thanks for you review!

Why do we want to skip sanitizing these loads and stores?

When use asan and gcov together, asan will instrument the loads and stores inserted by gcov which increases the code size a lot.
As the loads and stores inserted by gcov are unlikey to have bugs, so I add nosanitize metadata to these loads and stores like we do in SanitizerCoverage.

Also, gocv is misspelled in the commit description, please fix that up.

Thanks for pointing this.

llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
150–152

Send https://reviews.llvm.org/D150632 which adds Instruction::setNoSanitizeMetadata() and use it in SanitizerMetadata and SanitizerCoverage as suggested.

Why do we want to skip sanitizing these loads and stores?

When use asan and gcov together, asan will instrument the loads and stores inserted by gcov which increases the code size a lot.
As the loads and stores inserted by gcov are unlikey to have bugs, so I add nosanitize metadata to these loads and stores like we do in SanitizerCoverage.

Hmm...that I'm less comfortable with approving. Personally, I feel that coverage and sanitizers don't mix well (perhaps due to such code size increases). If you want low overhead coverage, disable your sanitizers! Perhaps this makes more sense in the context of HWASAN where you might consider enabling a sanitizer always, even in production builds?

I guess I'm worried about __llvm_gcov_ctr becoming some kind of vector for attack.

Though, I guess you wouldn't ship coverage enabled in production.

llvm/test/Transforms/GCOVProfiling/nosanitize.ll
2

Is this run line necessary?

4

please add a comment about the intent of this test; something along the lines of "the intent of this test is to verify that the loads, stores, and atomicrmw adds for gcov are marked nosanitize.

Enna1 updated this revision to Diff 522887.May 16 2023, 8:10 PM
Enna1 marked 2 inline comments as done.

add comment about the intent of the test

Enna1 marked an inline comment as done.May 16 2023, 8:21 PM

Though, I guess you wouldn't ship coverage enabled in production.

Sure.

I guess I'm worried about __llvm_gcov_ctr becoming some kind of vector for attack.

__llvm_gcov_ctr global variable is not instrumented by asan, see https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp#L1184

Hmm...that I'm less comfortable with approving.

It's ok, if so, I can abandon this patch :)
Or maybe we can add an option gcov-nosanitize?

llvm/test/Transforms/GCOVProfiling/nosanitize.ll
2

Yes, it is for don't writing a.gcno in CWD. See other GCOVProfiling testcase (e.g. atomic-counter.ll, kcfi.ll)

MaskRay added inline comments.May 16 2023, 8:36 PM
llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
924–925

Define Instruction *Inst outside before if. Call Inst->setNoSanitizemetadata() just once after if.

Add a comment // Disable sanitizers to decrease size bloat. We don't expect sanitizers to catch interesting issues.

llvm/test/Transforms/GCOVProfiling/nosanitize.ll
3

; RUN: rm -rf %t && mkdir %t && cd %t clean up the directory which may be clobbered.

Though, I guess you wouldn't ship coverage enabled in production.

Sure.

I guess I'm worried about __llvm_gcov_ctr becoming some kind of vector for attack.

__llvm_gcov_ctr global variable is not instrumented by asan, see https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp#L1184

Hmm...that I'm less comfortable with approving.

It's ok, if so, I can abandon this patch :)
Or maybe we can add an option gcov-nosanitize?

I think this patch is fine. __llvm_gcov_ctr is an internal variable and accessing doesn't use indirection, so no risk of hijection.
I don't recommend mixing gcov and sanitizers (e.g. --coverage -fsanitize=hwaddress), but if a user does this, disabling instrumentation for __llvm_gcov_ctr provides some size benefit.

llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
924–925

It's either 1 or 2 instructions that need the metadata set.

The comment SGTM though that this is intentional/deliberate and not a bug.

Enna1 updated this revision to Diff 523342.May 18 2023, 4:54 AM

address review comments

Enna1 marked an inline comment as done.May 18 2023, 4:58 AM
Enna1 added inline comments.
llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
924–925

Define Instruction *Inst outside before if. Call Inst->setNoSanitizemetadata() just once after if.

There are 2 instructions in else block, so I think can not call Inst->setNoSanitizemetadata() just once after if.

MaskRay added inline comments.May 18 2023, 1:53 PM
llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
924–925

My idea is the factor out one instruction to apply Inst->setNoSanitizemetadata(). The else branch has one more instruction.

nickdesaulniers accepted this revision.May 18 2023, 1:55 PM
This revision is now accepted and ready to land.May 18 2023, 1:55 PM
Enna1 updated this revision to Diff 523728.May 19 2023, 4:17 AM

Update from MaskRay's comments.

This revision was landed with ongoing or failed builds.May 24 2023, 7:15 PM
This revision was automatically updated to reflect the committed changes.