google / sanitizers

AddressSanitizer, ThreadSanitizer, MemorySanitizer
Other
11.5k stars 1.04k forks source link

Using ASan with multiprocess shared memory? #1112

Open Boddlnagg opened 5 years ago

Boddlnagg commented 5 years ago

Not a bug report, but a question: Is there a way to use ASan in a multiprocess scenario with a custom shared memory allocator? I've seen https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning, but I think that poisoning some memory that is mmapped by multiple processes will only affect the one process that's doing it, and the other processes won't be notified? Is there some special handling of fork in ASan?

I'm afraid the answer will be that it's not possible, but I still thought I'd ask ... any hint appreciated!

eugenis commented 5 years ago

There is no special handling for fork - shadow memory is CoW inherited by the child process, but future changes are not propagated.

I've never tried it, but in theory, if you map a shared memory region in the part of ASan shadow that corresponds to your program's shared memory, things should work as expected. Beware that asan shadow mapping is 8-to-1, which means that the "main" shared memory region need to be aligned to 8 pages in order for the shadow region to be page-aligned (and the same for size).

Note that shadow base address may change after exec().

On Thu, Jun 27, 2019 at 10:59 AM Patrick Reisert notifications@github.com wrote:

Not a bug report, but a question: Is there a way to use ASan in a multiprocess scenario with a custom shared memory allocator? I've seen https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning, but I think that poisoning some memory that is mmapped by multiple processes will only affect the one process that's doing it, and the other processes won't be notified? Is there some special handling of fork in ASan?

I'm afraid the answer will be that it's not possible, but I still thought I'd ask ... any hint appreciated!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/sanitizers/issues/1112?email_source=notifications&email_token=AADG4SSX4RJP55FSGP2NSSDP4T5Z3A5CNFSM4H36YX2KYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4G4EQ7GA, or mute the thread https://github.com/notifications/unsubscribe-auth/AADG4SWZLEHED3NJ3H7J2FLP4T5Z3ANCNFSM4H36YX2A .

Boddlnagg commented 5 years ago

Thank you! That gives me some hope that it might actually work. Just to make sure that I understand correctly, this is what I would need to do:

I stumbled upon https://groups.google.com/d/msg/address-sanitizer/w7wFo4Mnj9w/iYCBhrtiDwAJ which says that it should not be allowed to call mmap with MAP_FIXED for any of the adresses owned by ASan ... wouldn't that be a problem?

Note that shadow base address may change after exec().

Could you explain that some more? I thought the shadow adresses are always between 0x00007fff8000 and 0x10007fff7fff (on 64 bit)?

eugenis commented 5 years ago

On Fri, Jun 28, 2019 at 2:30 PM Patrick Reisert notifications@github.com wrote:

Thank you! That gives me some hope that it might actually work. Just to make sure that I understand correctly, this is what I would need to do:

Make sure that shared memory allocations are 8-page aligned, and their sizes are 8-page aligned Call mmap with MAP_FIXED for the corresponding shadow pages

I stumbled upon https://groups.google.com/d/msg/address-sanitizer/w7wFo4Mnj9w/iYCBhrtiDwAJ which says that it should not be allowed to call mmap with MAP_FIXED for any of the adresses owned by ASan ... wouldn't that be a problem?

You would be mapping memory for use by ASan. That's fine.

Note that shadow base address may change after exec().

Could you explain that some more? I thought the shadow addresses are always between 0x00007fff8000 and 0x10007fff7fff (on 64 bit)?

You are right, the address is constant on linux/x86_64. Anyway, if you do fork + exec, ASan will start from scratch in the child process, and the shadow thing will need to be mapped again.

One more catch, add ASAN_OPTIONS=clear_shadow_mmap_threshold=0, otherwise ASan may remap chunks of shadow back to anonymous memory (see the code in FastPoisonShadow).

And of course, you will need manual poisoning in the custom shared memory allocator. I.e. if you want to detect buffer overflows, you'd need to add redzones to all allocations and tell asan that they are inaccessible.