On Fri, Feb 15, 2013 at 11:45:15AM +0400, Konstantin Serebryany wrote: > On Thu, Feb 14, 2013 at 4:19 PM, Jakub Jelinek <ja...@redhat.com> wrote: > > On Thu, Feb 14, 2013 at 03:55:47PM +0400, Konstantin Serebryany wrote: > >> The patch seems to work on a simple test. Let me digest it. > >> I am trying to understand if there are problems with it other than the > >> added complexity (which is what I don't like the most). > > > > Yes, it is some added complexity, but not too much, and something that can > > be tested regularly that it works. > > The complexity I am afraid of is not only in the code, but also at the > time of execution. > We and our users sometimes have to stare at the /proc/self/maps. > A mapping with 1 (ZeroBase) or 3 (default) asan sections is ok, but > 6 extra asan sections becomes nearly incomprehensible, at least for me. > > So, how about having kMidMemBeg as a variable, set as __asan_init. > Only if something is mapped around 0x003X00000000 we set it to non-zero.
That is fine for me. Note that ASAN_FIXED_MAPPING 1 might not work well, e.g. for shadow offset of 1ULL << 44, there the prelink library range falls into the low memory and thus kMidMemBeg should be 0. > http://llvm-reviews.chandlerc.com/D411 (still needs some cleanup) One cleanup might be avoid calling MemoryRangeIsAvailable unnecessarily too many times. Guess if you move: uptr shadow_start = kLowShadowBeg; if (kLowShadowBeg) shadow_start -= GetMmapGranularity(); uptr shadow_end = kHighShadowEnd; bool shadow_avail = MemoryRangeIsAvailable(shadow_start, shadow_end); before the #if ASAN_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING if (!MemoryRangeIsAvailable(kLowShadowBeg, kHighShadowEnd)) { kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0; kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x3fffffffffULL : 0; } #endif code, you can just use shadow_avail there and later. Every MemoryRangeIsAvailable reads /proc/self/maps again, right? Also, on ppc64 the prelink library area is: 0x8001000000LL to 0x8100000000LL if we want to e.g. handle flexible mapping there (perhaps better use 0x8000000000L as kMidMemBeg then), guess for 32-bit architectures it is irrelevant, there is not much point in using shadow offsets other than the default high one (which is high enough) or 0 (then you need PIE, and thus prelink info is ignored both by the kernel and dynamic linker). > Unfortunately, the test does not work if gold is the system linker. > Any suggestion on how to make the test work with either linker? That is the question to Ian, if gold can do that at all. As I said before, you can try something like: #include <sys/mman.h> struct A { A (); void *ptr; }; void *ptr; __attribute__((no_address_safety_analysis)) A::A () { ptr = mmap ((void *) 0x3600000000UL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } A __attribute__((init_priority (1))) a; int main () { if (a.ptr != MAP_FAILED) { char *ptr = (char *) a.ptr; __asan_poison_memory_region (ptr, 4096); __asan_poison_memory_region (ptr + 61440, 4096); ptr[4096] = 23; } } and similar (and/or test that accessing the poisoned memory fails etc.). For gcc you want to compile with -w, so that it doesn't warn about the reserved init_priority, not sure what clang would do. Jakub