Date: Wed, 10 Jun 2020 20:30:23 +0200 From: Damjan Jovanovic <damjan.jov@gmail.com> To: Michael Tuexen <tuexen@freebsd.org> Cc: Mark Johnston <markj@freebsd.org>, "freebsd-current@FreeBSD.org" <freebsd-current@freebsd.org> Subject: Re: gcc versus clang issue for 32-bit binaries Message-ID: <CAJm2B-nh_cR1jwocahFuagcXGgkr0G1VfvxMDMLbKwGJMmcu8g@mail.gmail.com> In-Reply-To: <0281EB7A-B5DE-4D52-96DF-C7A2D6DC805C@freebsd.org> References: <128AB51F-0950-448F-8463-12C573C1AA38@freebsd.org> <20200610165908.GA81346@raichu> <0281EB7A-B5DE-4D52-96DF-C7A2D6DC805C@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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. 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. Damjan On Wed, Jun 10, 2020 at 7:40 PM Michael Tuexen <tuexen@freebsd.org> wrote: > > On 10. Jun 2020, at 18:59, Mark Johnston <markj@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@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-current > To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org" >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJm2B-nh_cR1jwocahFuagcXGgkr0G1VfvxMDMLbKwGJMmcu8g>