Re: gcc versus clang issue for 32-bit binaries

From: Damjan Jovanovic <damjan.jov_at_gmail.com>
Date: Wed, 10 Jun 2020 20:30:23 +0200
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_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 - 16:31:45 UTC

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