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

Reply via email to