This is an archive of the discontinued LLVM Phabricator instance.

[asan] Use private aliases for global variables (compiler-rt part).
ClosedPublic

Authored by m.ostapenko on Dec 18 2015, 8:23 AM.

Details

Summary

This is a compiler-rt part of this http://reviews.llvm.org/D15642 patch. Here, we change the way how we detect ODR violation. Instead of using __asan_region_is_poisoned(g->beg, g->size_with_redzone) on global address (that would be false now due to using private alias), we use new globally visible indicator symbol to perform the check.

Does this look like a reasonable approach?

Diff Detail

Repository
rL LLVM

Event Timeline

m.ostapenko retitled this revision from to [asan] Use private aliases for global variables (compiler-rt part)..
m.ostapenko updated this object.
m.ostapenko added reviewers: kcc, eugenis, samsonov.
m.ostapenko set the repository for this revision to rL LLVM.
m.ostapenko added subscribers: ygribov, llvm-commits.
kcc added inline comments.Dec 18 2015, 11:11 AM
test/asan/TestCases/Linux/local_alias.cc
1 ↗(On Diff #43231)

a comment, please

7 ↗(On Diff #43231)

name this more descriptively, e.g. BUILD_INSTRUMENTED_DSO and BUILD_UNINSTRUMENTED_DSO

15 ↗(On Diff #43231)

isn't this a real ODR which we now will fail to detect?

m.ostapenko added inline comments.Dec 18 2015, 11:32 AM
test/asan/TestCases/Linux/local_alias.cc
15 ↗(On Diff #43231)

Yes, we can't detect ODR violation here, because libfoo.so is sanitized and libbar.so is not. But how could we do it with existing approach? And anyway, this particular testcase fails with CHECK on x86 and with false positive global buffer overflow on x86_64. I think it's better to miss ODR violation than just miserably die :).

kcc added inline comments.Dec 18 2015, 11:35 AM
test/asan/TestCases/Linux/local_alias.cc
15 ↗(On Diff #43231)

With the current approach we do die, even though miserably. So, the bug is in fact detected.
Now we will miss it completely. Right?

m.ostapenko added inline comments.Dec 18 2015, 11:52 AM
test/asan/TestCases/Linux/local_alias.cc
15 ↗(On Diff #43231)

Right. But still, there's C code with semantic interposition that would fail here unconditionally.

ygribov added inline comments.Dec 18 2015, 11:55 AM
test/asan/TestCases/Linux/local_alias.cc
15 ↗(On Diff #43231)

Well, we'd really die accidentally. It could also lead to all sorts of misbehavior or even go undetected. So I'd rather not consider this a real existing feature.

On the contrary, we'll now detect errors in libraries dlopened with RTLD_DEEPBIND or linked with -Bsymbolic.

kcc added inline comments.Dec 18 2015, 1:29 PM
test/asan/TestCases/Linux/local_alias.cc
15 ↗(On Diff #43231)

I don't consider this as a blocker, just want to check my understanding.

Distinguish between two methods of ODR violation checking in runtime: old one (use __asan_region_is_poisoned) and new one (use odr indicators). This code looks scary, but it manages to preserve default behavior and enable new one if desired.

This is a draft implementation, for further design discussion.

I guess you need to update asan_init version.

lib/asan/asan_globals.cc
139 ↗(On Diff #45281)

"in case compiler instruments global variables through their local aliases"?

143 ↗(On Diff #45281)

s/registred/registered/, s/vioation/violation/

144 ↗(On Diff #45281)

You could simplify a bit by doing the easy case first and then early-exiting.

247 ↗(On Diff #45281)

What if indicator was set by a different module?

m.ostapenko added inline comments.Jan 20 2016, 5:58 AM
lib/asan/asan_globals.cc
247 ↗(On Diff #45281)

Well, if not consider concurrently running dlopen and dclose, this should never happen, because we have caught ODR violation, that happened before, no? If consider concurrency issues - yes, your nit is totally reasonable. Since original code seems not be thread safe, I didn't implement my changes to be thread safe either. So I wonder, if I should consider races here.

m.ostapenko updated this object.
m.ostapenko removed rL LLVM as the repository for this revision.

Addressing Yura's nits (except the last one, that I want to discuss a bit more).

ygribov added inline comments.Jan 20 2016, 1:08 PM
lib/asan/asan_globals.cc
143 ↗(On Diff #45407)

I think you forgot to set *odr_indicator to 1 here? Or rather to some descriptive enum value e.g. DEFINED. This would also simplify below description.

156 ↗(On Diff #45407)

s/posoned/poisoned/

176 ↗(On Diff #45407)

Some spelling suggestions: s/cheeply/cheaply/, s/try poison/try to poison an/

247 ↗(On Diff #45407)

Got it.

m.ostapenko added inline comments.Jan 20 2016, 1:33 PM
lib/asan/asan_globals.cc
143 ↗(On Diff #45407)

Yeah, thanks. Just remembered about this 5 minutes ago ☺.

176 ↗(On Diff #45407)

Ouch, thanks.

m.ostapenko set the repository for this revision to rL LLVM.

Fix an error with setting odr_indicator to 1 in CheckODRViolationViaIndicator + fix some spelling issues. I've also updated existing odr-violation.cc testcase to cover new functionality.

Ping. Actually, I think ODR indicators are quite independent from ASan (well, they still need to be registered on the very early stage, but all poisoning stuff can be skipped), perhaps we could move them out to separate module in the future?

samsonov edited edge metadata.Feb 2 2016, 10:35 AM

Sorry for the delays. Overall, this looks good. However, please note that this is an ABI-breaking change: you will need to update asan_init_version.h

lib/asan/asan_interface_internal.h
49 ↗(On Diff #45547)

Out of curiosity - why not make this new field last in the __asan_global structure?

However, please note that this is an ABI-breaking change: you will need to update asan_init_version.h

Right, thanks (though Yura had already pointed on this, but I forgot to make this change).

lib/asan/asan_interface_internal.h
49 ↗(On Diff #45547)

Yeah, you are right, will fix this.

m.ostapenko updated this revision to Diff 47008.Feb 5 2016, 3:33 AM
m.ostapenko edited edge metadata.

Updating according to Alexey's nits.

samsonov accepted this revision.Feb 5 2016, 2:30 PM
samsonov edited edge metadata.

LGTM

lib/asan/asan_globals.cc
139 ↗(On Diff #47008)

Why not UNREGISTERED/REGISTERED?

This revision is now accepted and ready to land.Feb 5 2016, 2:30 PM
m.ostapenko edited edge metadata.

Thanks! Uploading the diff to be committed.

This revision was automatically updated to reflect the committed changes.