This is an archive of the discontinued LLVM Phabricator instance.

[DFSan] Add efficient fast16labels instrumentation mode.
ClosedPublic

Authored by morehouse on Jul 22 2020, 5:06 PM.

Details

Summary

Adds the -fast-16-labels flag, which enables efficient instrumentation
for DFSan when the user needs <=16 labels. The instrumentation
eliminates most branches and most calls to dfsan_union or
dfsan_union_load.

We also add a call into the runtime during preinit to enable
fast16labels mode there, since we may still call __dfsan_union[_load] in
rare cases.

Diff Detail

Event Timeline

morehouse created this revision.Jul 22 2020, 5:06 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJul 22 2020, 5:06 PM
Herald added subscribers: Restricted Project, hiraditya. · View Herald Transcript
kcc added a comment.Jul 22 2020, 6:39 PM

In what cases do we still call __dfsan_union?

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
184

please add the documentation.
Probably into this change, so that we review it together.

kcc added inline comments.Jul 22 2020, 6:42 PM
compiler-rt/lib/dfsan/dfsan.cpp
163

I wonder if we can get away w/o these flags.
Just assume that fast16mode works only when the fast16mode instrumentation is enabled.
(remember, fast16mode is currently experimental, we are free to change its behavior)

vitalybuka added inline comments.Jul 22 2020, 7:15 PM
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
1049

what we are going to do in __dfsan_fast16labels_preinit?

1291

have you considered a loop?

morehouse updated this revision to Diff 280286.Jul 23 2020, 4:17 PM
morehouse marked 6 inline comments as done.
  • Add documentation.
  • Remove fast16labels runtime flag.
Herald added a project: Restricted Project. · View Herald TranscriptJul 23 2020, 4:17 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
In D84371#2168367, @kcc wrote:

In what cases do we still call __dfsan_union?

We still call __dfsan_union_load when we load sizes greater than 2 bytes but not divisible by 4. I actually am not sure what instruction sequence would hit this case, but it was already in DFSan so I left it there.

__dfsan_union_load then calls __dfsan_union.

compiler-rt/lib/dfsan/dfsan.cpp
163

SGTM. I only know of @Dor1s using it at the moment.

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
1049

This global is simply a pointer to dfsan_use_fast16labels() so that it runs during preinit. dfsan_use_fast16labels just enables fast16labels mode in the runtime.

1291

I think we should avoid loop overhead at least for the common case here (loading 8-16 bytes of shadow).

I think it's also possible to hit this case with vector instructions, but vanilla DFSan currently doesn't use a loop in that case either. If we want to use a loop for vector loads, I think we should do it in a different patch.

morehouse updated this revision to Diff 280304.Jul 23 2020, 5:37 PM
  • Fix libfuzzer dataflow tests.
kcc added a comment.Jul 23 2020, 6:01 PM

Yep, cool.
LGTM from me, but please get another pair if eyes (Vitaly?)

clang/docs/DataFlowSanitizer.rst
182

maybe -dataflow-fast-16-labels?

201

perhaps unconfuse the test a bit by using other constants

i = 100;
j = 200;
k = 300;
vitalybuka added inline comments.Jul 23 2020, 8:50 PM
compiler-rt/lib/dfsan/dfsan.cpp
165–166

isn't better just create new set of callbacks?
e.g __dfsan_fast16_union
and then we don't need any flags or preinit array initialization

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
784

DFSanUseFast16LabelsFnTy and DFSanUseFast16LabelsFn is used one in one place
I'd make them local variables. in if (ClFast16Labels) of runOnModule

morehouse updated this revision to Diff 280485.Jul 24 2020, 9:14 AM
morehouse marked 5 inline comments as done.
  • Rename flag
  • Clarify doc example
  • Use temporary variables.
compiler-rt/lib/dfsan/dfsan.cpp
165–166

Should work for __dfsan_union and __dfsan_union_load, but what about all the other API functions the user can call directly? We wouldn't be able to warn in those cases.

vitalybuka accepted this revision.Jul 28 2020, 1:13 AM

LGTM either way

compiler-rt/lib/dfsan/dfsan.cpp
165–166

Should work for __dfsan_union and __dfsan_union_load, but what about all the other API functions the user can call directly? We wouldn't be able to warn in those cases.

Those calls are no-op, it would be nice, but it's not worth it.
You can avoid state variable fast16labels, and avoid preinit_array which time to time conflicts with other libs. Which looks more useful then warning.

This revision is now accepted and ready to land.Jul 28 2020, 1:13 AM
morehouse marked 2 inline comments as done.
  • Remove preinit stuff and API warnings; use custom union-load callback.
compiler-rt/lib/dfsan/dfsan.cpp
165–166

Thanks. Turns out we only need __dfsan_union_load_fast16labels, which makes things simpler.

This revision was landed with ongoing or failed builds.Jul 29 2020, 12:00 PM
This revision was automatically updated to reflect the committed changes.
morehouse added inline comments.Aug 14 2020, 1:35 PM
compiler-rt/lib/dfsan/dfsan.cpp
165–166

Turns out we might need a fast16 flag and preinit_array after all, since many of the custom wrappers call dfsan_union...

@vitalybuka Any ideas to avoid this?

morehouse added inline comments.Aug 14 2020, 5:11 PM
compiler-rt/lib/dfsan/dfsan.cpp
165–166

One idea: In fast16 mode, we never call dfsan_create_label, so probably we can just check whether any labels have been created, and if not compute the OR.