This is an archive of the discontinued LLVM Phabricator instance.

[msan] Implement -msan-disable-checks.
ClosedPublic

Authored by glider on Dec 7 2021, 4:32 AM.

Details

Summary

[msan] Implement -msan-disable-checks.

To ease the deployment of KMSAN, we need a way to apply
attribute((no_sanitize("kernel-memory"))) to the whole source file.

Passing -msan-disable-checks=1 to the compiler will make it
treat every function in the file as if it was lacking the
sanitize_memory attribute.

Diff Detail

Event Timeline

glider created this revision.Dec 7 2021, 4:32 AM
glider requested review of this revision.Dec 7 2021, 4:32 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 7 2021, 4:32 AM
glider added inline comments.Dec 7 2021, 4:34 AM
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
312

This edit was suggested by clang-format, I am not particularly fond of it.

vitalybuka added inline comments.Dec 7 2021, 10:24 AM
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
312

I guess we need this because simple -fno-sanitize=memory will also remove shadow propagation?
What about SanitizerSpecialCaseList?

melver added inline comments.Dec 8 2021, 1:13 AM
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
310

When does something compiled with LTO apply sanitizer passes?

Perhaps, to make it more general, I'd call it "msan-no-sanitize-all" or "msan-no-sanitize-all-functions", whichever you think is clearer.

311

__no_sanitize is the kernel spelling, should this be just no_sanitize?

Also, regarding formatting, I think I'd solve it by rewording the description slightly.

I think in this case, since this is about MSan, simply saying "Apply no_sanitize to the whole file" is probably unambiguous enough, and will make for nicer formatting.

llvm/test/Instrumentation/MemorySanitizer/msan_no_sanitize_whole_file.ll
4

This is not fully "noinstr", right? I.e. "noinstr" is slightly misleading since we still want instrumentation, just no checks.

27

This can be a "CHECK" because both are supposed to have this, right?

48

Aren't INSTR and NOINSTR supposed to be identical in the NoSanitizeFn case? I.e. you could just use CHECK throughout?

glider updated this revision to Diff 392714.Dec 8 2021, 4:46 AM

Addressed review comments

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
310

IIUC, currently LTO works as follows:

  • kernel is built as usual, but with bitcode files instead of .o files;
  • these bitcode files are merged together, and additional optimization passes are ran on the resulting file.

Nobody ever tried this with KMSAN, but I would still expect it to work on a per-file basis.

But I agree not mentioning "file" is better. I'd go for "msan-no-sanitize-all" (we don't sanitize anything except functions anyway).

311

I actually failed to write "attribute((no_sanitize("memory")))" :)

But that's too verbose and might raise questions about the compatibility between "memory" and "kernel-memory", so perhaps just "no_sanitize" should be fine.

312

Yes, that's right, -fno-sanitize=memory doesn't work.

-fsanitize-ignorelist could be an option, but we want Makefiles to be the source of truth for the ignore lists.
Currently we disable KMSAN completely using the following syntax:

# One file in this dir: vclock_gettime.c
KMSAN_SANITIZE_vclock_gettime.o := n
# Either head32.c or head64.c, depending on $(BITS) exported from the parent Makefile
KMSAN_SANITIZE_head$(BITS).o := n
# All files in this directory and subdirectories
KMSAN_SANITIZE := n

The proposed flag will enable us to have the same syntax to disable shadow checking, but with -fsanitize-ignorelist we would need to generate the list on the fly, which might be tricky.

llvm/test/Instrumentation/MemorySanitizer/msan_no_sanitize_whole_file.ll
4

Changed to NOSANITIZE.

27

No. This instruction unpoisons the return value, which only happens in the "non-instrumented" case.

48

Right, thank you!

glider retitled this revision from [msan] Implement -msan-no-sanitize-whole-file. to [msan] Implement -msan-no-sanitize-all..Dec 8 2021, 5:16 AM
glider edited the summary of this revision. (Show Details)
melver accepted this revision.Dec 8 2021, 5:18 AM
melver added inline comments.
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
311

s/ClNoSanitizeWholeFile/ClNoSanitizeAll/ ?

This revision is now accepted and ready to land.Dec 8 2021, 5:18 AM
glider updated this revision to Diff 392740.Dec 8 2021, 6:21 AM

Fixed flag name

glider marked an inline comment as done.Dec 8 2021, 9:50 AM
vitalybuka accepted this revision.Dec 8 2021, 11:04 AM
vitalybuka added inline comments.
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
311

I don't see value in -all suffix on the flag applied to compilation unit. It's obvious that it's apply to "all"
"msan-no-sanitize-all" -> "msan-no-sanitize"

Maybe, but I am not sure: it's also a boolean flag why not just

static cl::opt<bool>
ClSanitize("msan-sanitize",
...
cl::init(true));

Are you going to add fronted flag? Usually they have -fsanitize-memory- prefix:
-fsanitize-memory-???? Also not sure what this could be.

-fsanitize-memory-ignore?

glider added inline comments.Dec 8 2021, 2:11 PM
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
311

I don't see value in -all suffix on the flag applied to compilation unit. It's obvious that it's apply to "all"
"msan-no-sanitize-all" -> "msan-no-sanitize"

I imagine this being read as "apply no_sanitize to all functions", and "msan-no-sanitize" actually sounds very much like -fnosanitize=memory. Perhaps we need a better name...

Maybe, but I am not sure: it's also a boolean flag why not just

static cl::opt<bool>
ClSanitize("msan-sanitize",
...
cl::init(true));

Are you going to add fronted flag? Usually they have -fsanitize-memory- prefix:
-fsanitize-memory-???? Also not sure what this could be.

Good question, it didn't come to my mind. Not necessarily needed for KMSAN, but as long as we have the backend flag, might be a good idea.

-fsanitize-memory-ignore?

-fsanitize-memory-ignore-all-checks, maybe?

(and -mllvm -msan-ignore-all-checks ?)

melver added inline comments.Dec 9 2021, 3:31 AM
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
311

Probably, like Vitaly pointed out, the "all" might be redundant.

The other question is, are checks "ignored", or "disabled".

Perhaps one of the following:

-fsanitize-memory-ignore-checks / -mllvm -msan-ignore-checks
-fsanitize-memory-disable-checks / -mllvm -msan-disable-checks

whichever you find to be clearest.

glider added inline comments.Dec 9 2021, 3:48 AM
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
311

Probably, like Vitaly pointed out, the "all" might be redundant.

The other question is, are checks "ignored", or "disabled".

Perhaps one of the following:

-fsanitize-memory-ignore-checks / -mllvm -msan-ignore-checks
-fsanitize-memory-disable-checks / -mllvm -msan-disable-checks

whichever you find to be clearest.

I think "disable" should be better.
I'll go ahead and rename the -mllvm flag then.

glider updated this revision to Diff 393140.Dec 9 2021, 6:39 AM

Rename the flag

glider retitled this revision from [msan] Implement -msan-no-sanitize-all. to [msan] Implement -msan-disable-checks..Dec 9 2021, 6:41 AM
glider edited the summary of this revision. (Show Details)
This revision was automatically updated to reflect the committed changes.