<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">So, I'd argue that proper support for sanitized shared libraries<br>(primarily libc++, but not just libc++) would require loader change.<br>We could start by agreeing on and specifying a way a binary would<br>declare it's "sanitizer type" which could be used at runtime to change<br>the library lookup path.</blockquote><div><br></div><div>I think adding <a href="https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html">OS X style @rpath semantics</a> to the loader would be sufficient to support sanitizers and would be generally useful feature to have in the loader.</div><div>If we are serious about changing the loader those are the semantics I would suggest adding.</div><div><br></div><div><br></div><div> </div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Aug 17, 2016 at 1:12 PM, Craig, Ben via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 8/16/2016 7:35 PM, Evgenii Stepanov via cfe-dev wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So, I'd argue that proper support for sanitized shared libraries<br>
(primarily libc++, but not just libc++) would require loader change.<br>
We could start by agreeing on and specifying a way a binary would<br>
declare it's "sanitizer type" which could be used at runtime to change<br>
the library lookup path.<br>
</blockquote></span>
I don't think you need loader changes if you are willing to change the soname and use version tags.  I don't think loader changes will fix any of the pathological cases that soname and version tag trickery won't fix.<br>
<br>
Here's a brief proposal for a way to do this...<br>
* Give sanitized libraries a different file name.  For example, libc++-msan.so.<br>
* Give sanitized libraries a different soname.  For example, libc++-msan.so.1.<br>
* Put all symbols in libc++ under a version tag (LIBCPP_MSAN perhaps).  The "regular" build of libc++ will continue to use unversioned symbols.<br>
* Install the sanitized libc++ in the same directory as the regular libc++.<br>
* Change the clang driver so that -fsanitize=memory will cause the linker to pull in libc++-msan.so instead of libc++.so.  This will cause the DT_NEEDED to point at the msan version of libc++, and it will cause all the unresolved symbols to point to @LIBCPP_MSAN versions of the symbols.<br>
<br>
How this works in mixed envrionments...<br>
Case 1 (great!):<br>
* User builds an msan version of an executable (msan_tester).  If you point 'nm' at msan_tester, you will see that it has a lot of standard library symbols with @LIBCPP_MSAN on them.  'ldd' will tell you that msan_tester will pull in libc++-msan.so, but not libc++.so.<br>
* Suppose msan_tester does a dlopen and dlsym of a non-msan'd C++ library.  That C++ library was built against regular libc++. Regular libc++ gets loaded, but none of it's symbols will get put in the global symbol table, because libc++-msan.so got there first.<br>
* Happy day, only one version of libc++ is getting used (though two different ones got loaded).<br>
<br>
Case 2(boo!):<br>
* User builds an regular version of an executable (normal_tester)<br>
* normal_tester does a dlopen and dlsym of an msan'd C++ library. The msan'd C++ library is still going to bind against the libc++-msan.so version of the symbols.<br>
* Sad day.  Two versions of libc++ are being used.<br>
<br>
Note that changing the loader wouldn't fix case 2 either, at least as I understand the proposal.<div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Also, we can solve this for the case of -static-libstdc++ easily in<br>
the clang driver by looking under /msan/ subdirectory first. With<br>
that, we could replace the whole msan bootstrap instruction [1] with<br>
just "use -static-libstdc++".<br>
<br>
[1] <a href="https://github.com/google/sanitizers/wiki/MemorySanitizerBootstrappingClang" rel="noreferrer" target="_blank">https://github.com/google/sani<wbr>tizers/wiki/MemorySanitizerBoo<wbr>tstrappingClang</a><br>
<br>
<br>
On Mon, Aug 15, 2016 at 2:34 PM, Jonathan Roelofs<br>
<<a href="mailto:jonathan@codesourcery.com" target="_blank">jonathan@codesourcery.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
On 8/15/16 1:51 PM, Hal Finkel wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
----- Original Message -----<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
From: "Jonathan Roelofs" <<a href="mailto:jonathan@codesourcery.com" target="_blank">jonathan@codesourcery.com</a>> To: "Hal<br>
Finkel" <<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>> Cc: "Eric Fiselier" <<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>>,<br>
"clang developer list" <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>, "Chandler<br>
Carruth" <<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>>, "Kostya Serebryany"<br>
<<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>>, "Evgenii Stepanov" <<a href="mailto:eugenis@google.com" target="_blank">eugenis@google.com</a>> Sent:<br>
Monday, August 15, 2016 9:24:17 AM Subject: Re: [cfe-dev] Making<br>
MSAN Easier to Use: Providing a Sanitized Libc++<br>
<br>
<br>
<br>
On 8/14/16 7:31 PM, Hal Finkel wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
----- Original Message -----<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
From: "Jonathan Roelofs via cfe-dev" <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
To: "Eric Fiselier" <<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>>, "clang developer list"<br>
<<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>, "Chandler Carruth"<br>
<<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>>, "Kostya Serebryany" <<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>>,<br>
"Evgenii Stepanov" <<a href="mailto:eugenis@google.com" target="_blank">eugenis@google.com</a>> Sent: Sunday, August<br>
14, 2016 7:07:00 PM Subject: Re: [cfe-dev] Making MSAN Easier<br>
to Use: Providing a Sanitized   Libc++<br>
<br>
<br>
<br>
On 8/14/16 4:05 PM, Eric Fiselier via cfe-dev wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Sanitizers such as MSAN require the entire program to be<br>
instrumented, anything less leads to plenty of false<br>
positives. Unfortunately this can be difficult to achieve,<br>
especially for the C and C++ standard libraries. To work<br>
around this the sanitizers provide interceptors for common C<br>
functions, but the same solution doesn't work as well for the<br>
C++ STL. Instead users are forced to manually build and link<br>
a custom sanitized libc++. This is a huge PITA and I would<br>
like to improve the situation, not just for MSAN but all<br>
sanitizers. I'm working on a proposal to change this. The<br>
basis of my proposal is:<br>
<br>
Clang should install/provide multiple sanitized versions of<br>
Libc++ and a mechanism to easily link them, as if they were<br>
a Compiler-RT runtime.<br>
<br>
The goal of this proposal is:<br>
<br>
(1) Greatly reduce the number of false positives caused by<br>
using an un-sanitized STL. (2) Allow sanitizers to catch user<br>
bugs that occur within the STL library, not just its<br>
headers.<br>
<br>
The basic steps I would like to take to achieve this are:<br>
<br>
(1) Teach the compiler-rt CMake how to build and install<br>
each sanitized libc++ version along side its other runtimes.<br>
(2) Add options to the Clang driver to support linking/using<br>
these libraries.<br>
<br>
I think this proposal is likely to be contentious, so I<br>
would like to focus on the details it. Once I have some<br>
feedback on these details I'll put together a formal<br>
proposal, including a plan for implementing it. The details I<br>
would like input on are:<br>
<br>
(A) What kind and how many sanitized versions of libc++<br>
should we provide?<br>
<br>
------------------------------<wbr>------------------------------<wbr>------------------------------<wbr>---------------------<br>
<br>
<br>
<br>
</blockquote></blockquote></blockquote></blockquote></blockquote>
I think the minimum set would be Address (which includes Leak),<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Memory (With origin tracking?), Thread, and Undefined. Once<br>
we get into combinations of sanitizers things get more<br>
complicated. What other sanitizer combinations should we<br>
provide?<br>
<br>
(B) How should we handle UBSAN?<br>
------------------------------<wbr>---------------------<br>
<br>
UBSAN is really just a collection of sanitizers and<br>
providing sanitized versions of libc++ for every possible<br>
configuration is out of the question. Instead we should<br>
figure out what subset of UBSAN checks we want to enable in<br>
sanitized libc++ versions. I suspect we want to disable the<br>
following checks.<br>
<br>
* -fsanitize=vptr * -fsanitize=function *<br>
-fsanitize=float-divide-by-zer<wbr>o<br>
<br>
Additionally UBSAN can be combined with every other<br>
sanitizer group (ie Address, Memory, Thread). Do we want to<br>
provide a combination of UBSAN on/off for every group, or can<br>
we simply provide an over-sanitized version with UBSAN on?<br>
<br>
(C) How should the Clang driver expose the sanitized<br>
libraries to the users?<br>
<br>
------------------------------<wbr>------------------------------<wbr>------------------------------<wbr>-------------------<br>
<br>
<br>
<br>
</blockquote></blockquote></blockquote></blockquote></blockquote>
I would like to propose the driver option '-fsanitize-stdlib' and<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
'-fsanitize-stdlib=<sanitizer><wbr>'. The first version deduces<br>
the best sanitized version to use, the second allows it to<br>
be explicitly specified.<br>
<br>
A couple of other options are:<br>
<br>
* -fsanitize=foo:  Implicitly turn on a sanitized STL. Clang<br>
deduces which version. * -stdlib=libc++-<sanitizer>:<br>
Explicitly turn on and choose a sanitized STL.<br>
<br>
(D) Should sanitized libc++ versions override libc++.so?<br>
<br>
------------------------------<wbr>------------------------------<wbr>------------------------------<wbr>-<br>
<br>
<br>
<br>
</blockquote></blockquote></blockquote></blockquote></blockquote>
For example, what happens when a program links to both a sanitized<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
and non-sanitized libc++ version? Does the sanitized version<br>
replace the non-sanitized version, or should both versions<br>
be loaded into the program?<br>
<br>
Essentially I'm asking if the sanitized versions of libc++<br>
should have the "soname" libc++ so they can replace<br>
non-sanitized version, or if they should have a different<br>
"soname" so the linker treats them as a separate library.<br>
<br>
I haven't looked into the consequences of either approach in<br>
depth, but any input is appreciated.<br>
</blockquote>
<br>
In a sense, these are /just/ multilibs, so my inclination would<br>
be to make all the soname's the same, and just stick them in<br>
appropriately named subfolders relative to their normal<br>
location.<br>
</blockquote>
<br>
I'm not sure that's true; there's no property of the environment<br>
that determines which library path you need. As a practical<br>
matter, I can't set $PLATFORM and/or $LIB in my rpath and have<br>
ld.so do the right thing in this context. Moreover, it is really<br>
a property of how you compiled, so I think using an alternate<br>
library name is natural.<br>
</blockquote>
<br>
Multilibs solve exactly the problem of "it's a property of how you<br>
compiled". The thing that's subtly different here is that the<br>
usual thing that people do with multilibs is to provide ABI<br>
incompatible versions of the same library (which are made<br>
incompatible via compiler flags, -msoft-float, for example),<br>
whereas these libraries just so happen to be ABI compatible with<br>
their non-instrumented variants.<br>
<br>
I'm not sure I understand what you're saying about $PLATFORM and<br>
$LIB, but I /think/ it's a red herring: the compiler takes care of<br>
adding in the multilib suffixes where appropriate, so shouldn't the<br>
answer to "which library do I stick in the rpath?" include said<br>
suffix (when compiled with Eric's proposed flag)?<br>
</blockquote>
<br>
I'm not sure what color herring it is ;) -- I'm trying to understand<br>
the system you're proposing:<br>
<br>
1. User A compiles/installs Clang/LLVM/libc++ on system A in<br>
/local/clang, and so we get a /local/clang/lib/libc++.so and a<br>
/local/clang/lib/msan/libc++.s<wbr>o. User A compiles a program, foo, with<br>
msan enabled, and foo gets an rpath of /local/clang/lib/msan. User A<br>
also compiles another program, prod, without any sanitizers, and<br>
those get an rpath of /local/clang/lib.<br>
<br>
2. User B compiles/installs Clang/LLVM/libc++ on system B in<br>
/soft/clang, and so we get a /soft/clang/lib/libc++.so and a<br>
/soft/clang/lib/msan/libc++.so<wbr>. User A sends User B the executables<br>
foo and prod. Those executables have rpaths with /local/clang/...,<br>
but those don't help User B. User B has an environment with<br>
LD_LIBRARY_PATH=/soft/clang/li<wbr>b so that the executables compiled by<br>
User A will run.<br>
<br>
3. User B has no good option, because if LD_LIBRARY_PATH is set to<br>
/soft/clang/lib, then prod will behave as expected (i.e. not be<br>
sanitized), but foo will not. If LD_LIBRARY_PATH is set to<br>
/soft/clang/lib/msan, then foo will be sanitized as expected, but<br>
prod will run slower than usual.<br>
</blockquote>
<br>
Ahhh, I see. I was imagining this sort use case:<br>
<br>
first_guy$ cat lib.h<br>
extern void lib_func();<br>
<br>
first_guy$ cat lib.c<br>
#include "lib.h"<br>
<br>
#include <stdio.h><br>
<br>
void lib_func() {<br>
   printf("In %s\n", MESSAGE);<br>
}<br>
first_guy$ cat bin.c<br>
#include "lib.h"<br>
<br>
int main() {<br>
   lib_func();<br>
}<br>
first_guy$ mkdir -p lib/sanitized<br>
first_guy$ clang lib.c -shared -DMESSAGE="\"sanitized\"" -o<br>
lib/sanitized/library.so<br>
first_guy$ clang lib.c -shared -DMESSAGE="\"production\"" -o lib/library.so<br>
first_guy$ clang bin.c -lrary -Wl,-rpath,$PWD/lib -L./lib/sanitized/ -o<br>
sanitized<br>
first_guy$ clang bin.c -lrary -Wl,-rpath,$PWD/lib -L./lib/ -o production<br>
first_guy$ ./sanitized<br>
In sanitized<br>
first_guy$ ./production<br>
In production<br>
first_guy$ mkdir ../other_guy<br>
first_guy$ cd ../other_guy/<br>
other_guy$ cp ../first_guy/sanitized .<br>
other_guy$ cp ../first_guy/production .<br>
other_guy$ cp -r ../first_guy/lib .<br>
other_guy$ ./sanitized<br>
In sanitized<br>
other_guy$ ./production<br>
In production<br>
other_guy$ rm lib/library.so<br>
other_guy$ ln -s ../lib/sanitized/library.so lib/library.so<br>
other_guy$ ./production<br>
In sanitized<br>
other_guy$ ./sanitized<br>
In sanitized<br>
<br>
<br>
Jon<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
4. User B compiles programs to send to User A. User A then sets<br>
LD_LIBRARY_PATH to /local/clang/lib. User A has the same problem as<br>
User B, and moreover, if User A compiles using -W,--enable-new-dtags,<br>
then the linker will use DT_RUNPATH (instead of, or in addition to,<br>
DT_RPATH; effect is the same), which is the recommended default on<br>
many systems, the rpath scheme won't even work for User A on User A's<br>
own executables (because LD_LIBRARY_PATH overrides DT_RUNPATH).<br>
<br>
There are a few things, other than pure directory paths, that can<br>
appear in, or otherwise affect, LD_LIBRARY_PATH and<br>
DT_RPATH/DT_RUNPATH, but I don't think any of them help us here:<br>
<br>
1. Pseudo variables $ORIGIN, $LIB and $PLATFORM - These are expanded<br>
by ld.so based on properties of the current execution environment<br>
(e.g. whether you're loading a 32-bit or 64-bit executable, the<br>
hardware architecture).<br>
<br>
2. Hardware-capability strings - There are a fixed set of hardware<br>
capabilities, such as sse, sse2, altivec, etc. that are appended to<br>
the directory name to form alternate search paths.<br>
<br>
3. The multilib suffix. This, AFAIK, is baked into the dynamic<br>
loader. The path to the loader itself has the multilib suffix, and<br>
that's specified in PT_INTERP.<br>
<br>
Unfortunately, I don't think that any of these help us.<br>
<br>
-Hal<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Jon<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-Hal<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Jon<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Conclusion -----------------<br>
<br>
I hope my proposal and questions have made sense. Any and<br>
all input is appreciated. Please let me know if anything<br>
needs clarification.<br>
<br>
/Eric<br>
<br>
<br>
<br>
<br>
<br>
<br>
______________________________<wbr>_________________ cfe-dev<br>
mailing list <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br>
</blockquote>
-- Jon Roelofs <a href="mailto:jonathan@codesourcery.com" target="_blank">jonathan@codesourcery.com</a> CodeSourcery / Mentor<br>
Embedded ______________________________<wbr>_________________<br>
cfe-dev mailing list <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br>
</blockquote></blockquote>
-- Jon Roelofs <a href="mailto:jonathan@codesourcery.com" target="_blank">jonathan@codesourcery.com</a> CodeSourcery / Mentor<br>
Embedded<br>
<br>
</blockquote></blockquote>
--<br>
Jon Roelofs<br>
<a href="mailto:jonathan@codesourcery.com" target="_blank">jonathan@codesourcery.com</a><br>
CodeSourcery / Mentor Embedded<br>
</blockquote>
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</blockquote>
<br>
-- <br></div></div><span class="im HOEnZb">
Employee of Qualcomm Innovation Center, Inc.<br>
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project<br>
<br></span><div class="HOEnZb"><div class="h5">
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div>