Comment #9 on issue 348 by [email protected]: asan does not always
detect access beyond mmaped page
https://code.google.com/p/address-sanitizer/issues/detail?id=348
On Tue, Sep 30, 2014 at 12:29:08PM +0000, [email protected]
wrote:
Comment #8 on issue 348 by [email protected]: asan does not always
detect access beyond mmaped page
https://code.google.com/p/address-sanitizer/issues/detail?id=348
>I've measured my running firefox:
> $ cat /proc/`pidof iceweasel`/maps | wc -l
I think this stat is low exactly because the kernel consolidates adjacent
mappings. For example, Chrome calls mmap() 600+ times during the first
seconds of startup, and many of those calls would've been merged into a
single region.
https://bugzilla.kernel.org/show_bug.cgi?id=67651 gives an idea of how the
number of mappings changes when adjacent mappings with similar permissions
aren't combined.
Thanks for pointers. Yes, merging VMAs is important for performance,
because the kernel does binary tree lookup `addr -> vma` on every
pagefault and minimizing #vma minimizes that tree and lookup time.
I can't say about Chrome, but for Firefox and Chromium number of mmap
_calls_ look like this:
for Firefox:
$ mmaps() {
> grep mmap $1 |grep -v MAP_FIXED |grep -v "mmap resumed"
> }
$ strace -tt -f -o x.log iceweasel
# go to yandex.ru, google.ru, lwn.net; exit
$ mmaps x.log |wc -l
744
for Chromium:
# as root
$ strace -tt -f -o y.log chromium --user-data-dir=`pwd`/userdata
# go to yandex.ru, google.ru, lwn.net; exit
$ mmaps y.log |wc -l
3523
it looks Chromium does more mmap calls, but let's look deeper
# Chromium: N(mmap calls) distribution with child pids
$ mmaps y.log |awk '{print $1}' |sort |uniq -c | sort -nr | head -20
1115 14292
909 14297
323 14317
287 14324
131 14365
118 14346
88 14321
83 14342
72 14389
39 14349
37 14401
35 14309
29 14313
26 14327
17 14316
17 14306
14 14415
14 14398
14 14376
9 14407
A-ha, N(mmap calls) per process is not that high - judging by pid, there is
1
or 2 processes which are maybe some managers (first two pids) and others
are workers with lower N(mmap calls) count.
Anyway
N(mmap calls) is limited to ~ < 1000 per process
I think this is rather low and is of the same order as resulting mapping
number. I.e.
My point about low mappings count also stand for low mmap calls.
For completeness, here is the same distribution for Firefox:
# Firefox: N(mmaps) distribution with child pids
$ mmaps x.log |awk '{print $1}' |sort |uniq -c | sort -nr | head -20
517 18401
38 18436
31 18406
31 18403
29 18453
29 18452
11 18421
9 18425
7 18446
7 18419
6 18467
5 18424
4 18431
3 18443
3 18437
3 18428
3 18422
2 18450
2 18402
1 18427
>So if a user creates special program which creates a lot of mappings
>he/she should probably be already aware of
> /proc/sys/vm/max_map_count
>knob and _that_ is the flag to tune to run such a program with additional
>mmap sanitizations.
Thanks, I wasn't aware of this. Indeed, sysctl vm.max_map_count=16777216
lets the program create far more mappings (although this probably affects
the performance).
Yes, as said above N(mmaps) increases pagefault lookup time and maybe
something else.
Please also note, that if we create red-zones for "before" and "after"
region, for two such larger regions with red-zones, chance are high the
kernel will allocate them adjacent, i.e.
red-before1 region1 ref-after1 ref-before2 region2 red-after2
so adjacent {after,before} pairs will be merged into one PROT_NONE
mapping by kernel.
That means the overhead will be ~ 1 PROT_NONE mapping for real mmap
without MAP_FIXED, not 2 PROT_NONE / mmap as I've mistakenly thought before.
>Could you please provide an example?
MAP_FIXED was my first thought. I was also thinking about doing something
like:
ptr = mmap(0, size, ...)
ptr2 = mmap(ptr + size, ...)
, but this isn't guaranteed to work (i.e. is one of the cases you want to
look for), so probably MAP_FIXED is the only interesting case.
And we do not add red-zones to MAP_FIXED for this reason.
>On munmap see to which region it belongs, and if original region (which
>could be later changed with MAP_FIXED mapping into it, but anyway) was
>originally mmaped with red-zone, and we are unmapping adjacent to
red-zone
>(either part), just adjust the red zone.
Sounds good
>And if kernel __NR_mmap is called with correct args directly overcoming
>interceptor, it will just unmap some region inside original larger
mapping
>with red-zones, so red-zones will stay, and since they are mapped with
>PROT_NONE, will catch later incorrect read/write access to them. The only
>problem here is that red-zone mapping are leaking if unmap is called
>directly.
We'll also need to remove the left part of the original larger mapping
from
ASan's mappings registry so that further munmap() calls do not attempt to
unmap that part's redzone (I'm talking about the right redzone, although
we
can possibly create both).
I now agree mmap() interception won't break much, although may increase
lookup time in the kernel structures handling the mappings.
That was my point. And the increase, if it is 1 protective VMA per real
mapping should be imho not high.
Thanks,
Kirill
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
--
You received this message because you are subscribed to the Google Groups
"address-sanitizer" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.