This is an archive of the discontinued LLVM Phabricator instance.

[UBSAN] Suppress an error report with given type information
ClosedPublic

Authored by byoungyoung on Jul 28 2014, 5:58 PM.

Details

Reviewers
samsonov
rsmith
Summary

For UBSan vptr, suppress an error report with given type information.

The suppression list is provided with the file (UBSAN_OPTIONS=suppressions=SUPP_FILENAME), and an error report is suppressed if the type of an actual object is in the suppression list.

Diff Detail

Event Timeline

byoungyoung retitled this revision from to [UBSAN] Suppress an error report with given type information.
byoungyoung updated this object.
byoungyoung edited the test plan for this revision. (Show Details)
byoungyoung added reviewers: samsonov, rsmith.
byoungyoung added a subscriber: Unknown Object (MLST).
samsonov edited subscribers, added: Unknown Object (MLST); removed: Unknown Object (MLST).Jul 29 2014, 7:44 PM
samsonov added subscribers: earthdok, dvyukov.
samsonov edited edge metadata.Jul 29 2014, 8:16 PM

Sergey, Dmitry

Is there a reason that "suppressions" flag is not in sanitizer_common, and we have separate methods for accessing/parsing suppression context in LSan/TSan? Does it make sense to have this code in sanitizer_common instead?

For example, now we work on adding suppressions to UBSan. Note that there is a "supported" mode where we run ASan+LSan+UBSan together. Having separate set of suppressions for LSan and UBSan would be really unconvenient.

lib/sanitizer_common/sanitizer_suppressions.cc
27

Let the bikeshedding begin. I'd actually vote to exclude tool name from suppression type. Currently suppression names seem to correspond to the error type ("leak", "race", "deadlock"). Let's stick to this way and use smth. like "vptr_check" or "invalid_cast".

lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
75

Actually update the test to include new suppression name, as this comment recommends.

lib/ubsan/ubsan_flags.cc
26 ↗(On Diff #11967)

Let's use empty string for consistency with another sanitizers defining this flag.

33 ↗(On Diff #11967)

I find this flag description confusing.

lib/ubsan/ubsan_handlers_cxx.cc
29

It probably makes more sense to put suppression context into ubsan_diag and implement proper set of methods to access it.

47

I believe you should put this check before acquiring the SourceLocation above. Otherwise, if two errors happen consecutively and have the same source location, and the first error is suppressed, then you won't report the second one. It would be nice to have a test for it.

51

Note that suppression context may not yet be initialized at this point (if InitIfNecessary() hasn't run yet, which is barely possible on Linux, where we use preinit_array, but probably may happen on other platforms).

lib/ubsan/ubsan_init.cc
32

It's sad to see the duplicated code here. Let me raise a discussion about having common suppression context in sanitizer_common.

+1 to Dima's email reply. (Let's move the flag to common flags, and drop "ubsan" from the suppression type.)

byoungyoung edited edge metadata.

Thanks Alexey for the detailed comments! This patch resolved the comments by Alexey.

samsonov added inline comments.Jul 30 2014, 2:08 PM
lib/ubsan/ubsan_diag.cc
313

No, I believe we must first move the code for initializing suppression context into sanitizer_common and make "suppressions" a common runtime flag. I will work on it soon. I've submitted the first patch for that in r214334.

lib/ubsan/ubsan_handlers_cxx.cc
38

// Check if error report is suppressed.

test/ubsan/TestCases/TypeCheck/vptr.cpp
15

Remove stray echo " "

175

LSan shouldn't be a problem after r214149 I've submitted recently.

samsonov added inline comments.Jul 30 2014, 3:02 PM
lib/ubsan/ubsan_diag.cc
313

I think this should be done as of r214344.

Resolved comments by Alexey. Please note this patch does NOT pass ubsan testcases, but I'm uploading this to ask why it fails.

The failing test is

Failing Tests (1):

UndefinedBehaviorSanitizer-AddressSanitizer :: TestCases/TypeCheck/vptr.cpp

with CHECK-LOC-SUPPRESS check. I've checked this case manually, and everything looks fine. But not sure why cmake test complains this specific case went wrong (only for UBSAN+ASAN).

samsonov added inline comments.Jul 31 2014, 12:16 PM
lib/ubsan/ubsan_diag.cc
21

Revise new #includes you need.

318

I'd prefer to skip check for suppressions common flag and assume that suppression context is always properly initialized (but can be empty).

322

just introduce SuppressionContext::InitIfNecessary()

326

As you're encapsulating access to SuppressionContext, you may provide a superior interface, so that callers of MatchSuppressions() won't have to know about the enum "SuppressionVptrCheck". E.g. you can introduce a simple function

bool __ubsan::TypeIsSuppressed(const char *TypeName);
329

you can plain if() here:

if (!SANITIZER_CAN_USE_PREINIT_ARRAY)
  InitIfNecessary();

please add a comment describing why you need this.

333

Collapse

if (condition)
  return true;
return false;

to

return condition;
lib/ubsan/ubsan_flags.cc
17 ↗(On Diff #12066)

accidental include?

lib/ubsan/ubsan_handlers_cxx.cc
39

you can save DTI.getMostDerivedTypeName() in a variable (it's called several times in this function).

test/ubsan/TestCases/TypeCheck/vptr.cpp
15

remove stray (echo " ")

The problem could be difference in environment options. E.g. UBSan+ASan tests setup ASAN_OPTIONS=detect_leaks=0 (which overrides the default). Note that it is important, as LSan also supports suppressions, and creates/parses suppression context only if detect_leaks is setup to true.

Thanks for the details comments, Alexey! Addressed the comments, and now it can pass ubsan tests.

samsonov added inline comments.Jul 31 2014, 5:39 PM
lib/ubsan/ubsan_diag.cc
317

You may now get rid of this function and call SuppressionContext::InitIfNecessary() from __ubsan::InitIfNecessary() directly.

lib/ubsan/ubsan_handlers_cxx.cc
37

why not create and pass MangledName around?

test/ubsan/TestCases/TypeCheck/vptr.cpp
15

echo ""; remains a mystery for me.

byoungyoung added inline comments.Jul 31 2014, 7:51 PM
lib/sanitizer_common/sanitizer_suppressions.cc
27

done

lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
75

Done

lib/ubsan/ubsan_diag.cc
313

When UBSan is running together with LSan, it seems LSan initializes SuppressionContext() before UBSan. I guess this has to be handled in the SuppressionContext(), but right now I simple implemented SuppressionContext::GetOrNull() to avoid the issue as I'm not sure whether my logic is correct.

317

I just wanted to keep the encapsulation as it would require ubsan_init to see SuppressionContext, but let me get rid of this wrapper function.

lib/ubsan/ubsan_flags.cc
26 ↗(On Diff #11967)

done

33 ↗(On Diff #11967)

I think I improved the description, but not sure whether it is clear enough :(

lib/ubsan/ubsan_handlers_cxx.cc
29

Done, now all suppressions are implemented in ubsan_diag

37

As the mangled name was not straight forward to us to blacklist (or suppress here), we actually wanted to bring up the discussion to see whether it's possible to use un-mangled name. But let me fix this as you suggest as it clearly breaks the consistency.

38

Done.

47

Ah! I've added the test but it may not be clean enough. Please comment if you have a better idea.

51

Can we safely assume that InitIfNecessary() is called if preinit_array is defined? Now InitIfNecessary() is enforced only if preinit_array is not defined. I think we may simply always call InitIfNecessary() as well because this matching function would not be invoked a lot (at least for vptr).

lib/ubsan/ubsan_init.cc
32

Thanks, let me leave the code as it is until then.

test/ubsan/TestCases/TypeCheck/vptr.cpp
15

Since running this test generates empty outputs, FileCheck complains about it. I may add one simple printf(), or is there any options for FileCheck to handle empty output cases?

15

Oh I misunderstood the meaning of stray :( Fixed now.

15

It seems my previous comments were not properly sent to you. These echo commands were prepended to generate non-empty outputs, because FileCheck complains otherwise due to the empty outputs.

16

Please note that these redundant options (ASAN_OPTIONS and UBSAN_OPTIONS) are given to pass both UBsan tests and UBsan + Asan tests. When UBSan+Asan is running, suppressions flag in UBSAN_OPTIONS is not parsed.

24

This check fails for UBSAN+ASAN while it worked fine when I manually tested. Could you please take a look why this fails?

24

Let me also keep debugging this issue in the meantime !

175

There were strange issues in testing UndefinedBehaviorSanitizer-AddressSanitizer, and let me describe more in the updated patch.

samsonov added inline comments.Aug 1 2014, 6:03 PM
lib/ubsan/ubsan_handlers_cxx.cc
37

I mean, use the "MangledName" object, which is a strong typedef for "const char *".
But, yes, I believe that we should eventually be able to blacklist/suppress *demangled* names. That's a different issue, though.

test/ubsan/TestCases/TypeCheck/vptr.cpp
15

Oh god. Consider the following approach: build the code with -fno-sanitize-recover and simply execute the binaries, without piping the output to FileCheck (i.e. just check that a binary executes successfully and returns zero exit code).

byoungyoung updated this revision to Diff 12184.Aug 4 2014, 5:19 PM

Sorry for the delay as I had troubles to access my computer. I hope this patch resolves your concerns.

lib/ubsan/ubsan_handlers_cxx.cc
37

Fixed as commented --- introduced MDTMangledName variable.

test/ubsan/TestCases/TypeCheck/vptr.cpp
15

Ughh... I didn't know what this "RUN" was actually doing and checking. I'm sorry for the mess.

samsonov accepted this revision.Aug 4 2014, 6:33 PM
samsonov edited edge metadata.

OK, landing this now.

This revision is now accepted and ready to land.Aug 4 2014, 6:33 PM

Landed (with a few modifications) as r214833. Thanks for working on this!

samsonov closed this revision.Aug 4 2014, 6:34 PM