Re: gcc versus clang issue for 32-bit binaries

From: Michael Tuexen <tuexen_at_freebsd.org>
Date: Wed, 10 Jun 2020 22:16:35 +0200
> On 10. Jun 2020, at 20:30, Damjan Jovanovic <damjan.jov_at_gmail.com> wrote:
> 
> MAP_FIXED is generally bad news, as it overwrites any prior mappings within the range of addresses being mapped to.
> 
> They should use MAP_FIXED | MAP_EXCL instead, which will fail if any mappings already exist in the range, and then maybe retry with another range if it fails. Linux and NetBSD have MAP_TRYFIXED instead, which does the retrying internally. Or at the very least, run mincore() on every page in the range to verify that nothing is mapped before using mmap() with MAP_FIXED.
It is used in syzkaller. Some go code generates C include files... So right now I might want
to stick with a value.
> 
> If there is no other way but to use a single hardcoded value, check /proc/<pid>/map for a number of different processes, 32 and 64 bit, and find an address range that isn't used often.
Thanks for the hint. I tried to find one. Let's see how good this guess is.

Best regards
Michael
> 
> Damjan
> 
> 
> On Wed, Jun 10, 2020 at 7:40 PM Michael Tuexen <tuexen_at_freebsd.org> wrote:
> > On 10. Jun 2020, at 18:59, Mark Johnston <markj_at_FreeBSD.org> wrote:
> > 
> > On Wed, Jun 10, 2020 at 06:41:50PM +0200, Michael Tuexen wrote:
> >> Dear all,
> >> 
> >> consider the following program test.c:
> >> 
> >> #include <sys/mman.h>
> >> #include <stdio.h>
> >> 
> >> int 
> >> main(void)
> >> {
> >>      void *p;
> >>      
> >>      p = mmap((void *)0x20000000, 0x1000000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
> >>      printf("p= %p\n", p);
> >>      return (0);
> >> }
> >> 
> >> On i386 the following happens:
> >> * when compiling it with cc and running it, it crashes.
> >> * when compiling it with gcc it runs fine.
> >> 
> >> On amd64 the following happens:
> >> * when compiling it with cc -m64 it runs fine.
> >> * when compiling it with cc -m32 is crashes.
> >> * when compiling it with gcc -m64 it runs fine.
> >> * when compiling it with gcc -m32 it runs fine.
> >> 
> >> So why does the above program crash when compiled for 32-bit when using clang, but runs fine when compiled with gcc.
> > 
> > The difference is between ld.bfd and ld.lld, which emit executables with
> > different entry point addresses.  cc -m32 -fuse-ld=bfd gives an
> > executable that does not crash.
> > 
> > When linked with lld, libc and ld-elf get mapped into the region
> > [0x20000000,0x21000000], so the program crashes when the libc.so mapping
> > is overwritten with that created by the mmap() call and the program
> > calls printf().
> > 
> >> I'm testing this on 32-bit and 64-bit head systems. gcc is from ports.
> >> 
> >> The reason I'm looking into it is that I want to get syzkaller working on 32-bit with clang.
> > 
> > Do you know why SYZ_DATA_OFFSET is hard-coded the way it is?  It looks
> > like it works more or less by accident, but at a glance I don't see why
> > it has to be a fixed mapping.
> I don't know, it comes from:
> https://github.com/google/syzkaller/blob/master/sys/targets/targets.go#L450
> 
> Do you have a value which can be used on FreeBSD? Then we can just change it...
> 
> Best regards
> Michael
> 
> _______________________________________________
> freebsd-current_at_freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe_at_freebsd.org"
Received on Wed Jun 10 2020 - 18:16:42 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:24 UTC