qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry <1885332@bugs.launchpad.net>
To: qemu-devel@nongnu.org
Subject: [Bug 1885332] Re: Error in user-mode calculation of ELF aux vector's AT_PHDR
Date: Sat, 11 Jul 2020 12:00:46 -0000	[thread overview]
Message-ID: <159446884647.13681.6408740332020546953.malone@gac.canonical.com> (raw)
In-Reply-To: 159320263008.26082.15752081078008046631.malonedeb@gac.canonical.com

When I switch to armv7 the issue goes away

$ cat Dockerfile.armv7 
FROM arm32v7/ubuntu
RUN apt-get update && \
    apt-get install -y \
    gcc make libpcre3-dev libreadline-dev git

RUN cd /home && git clone https://github.com/nginx/njs

RUN cd /home/njs && ./configure --cc-opt='-O0 -static -lm -lrt -pthread
-Wl,--whole-archive -lpthread -ltinfo -Wl,--no-whole-archive' && make
njs

$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
$ docker build -t njs/armv7 -f Dockerfile.armv7 .
$ docker run -v `pwd`:/m -ti njs/armv7 cp /home/njs/build/njs /m/njs-armv7

$ readelf -l ./njs-armv7

Elf file type is EXEC (Executable file)
Entry point 0x12fb9
There are 7 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x1be338 0x001ce338 0x001ce338 0x009b8 0x009b8 R   0x4
  LOAD           0x000000 0x00010000 0x00010000 0x1becf4 0x1becf4 R E 0x10000
  LOAD           0x1bedfc 0x001dedfc 0x001dedfc 0x17674 0x1c2cc RW  0x10000
  NOTE           0x000114 0x00010114 0x00010114 0x00044 0x00044 R   0x4
  TLS            0x1bedfc 0x001dedfc 0x001dedfc 0x00038 0x00060 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x1bedfc 0x001dedfc 0x001dedfc 0x0e204 0x0e204 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx 
   01     .note.ABI-tag .note.gnu.build-id .rel.dyn .init .iplt .text __libc_freeres_fn __libc_thread_freeres_fn .fini .rodata .stapsdt.base __libc_subfreeres __libc_IO_vtables __libc_atexit __libc_thread_subfreeres .ARM.extab .ARM.exidx .eh_frame 
   02     .tdata .init_array .fini_array .data.rel.ro .got .data .bss __libc_freeres_ptrs 
   03     .note.ABI-tag .note.gnu.build-id 
   04     .tdata .tbss 
   05     
   06     .tdata .init_array .fini_array .data.rel.ro 

$ readelf -h ./njs-armv7
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - GNU
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x12fb9
  Start of program headers:          52 (bytes into file)
  Start of section headers:          5696248 (bytes into file)
  Flags:                             0x5000400, Version5 EABI, hard-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         7
  Size of section headers:           40 (bytes)
  Number of section headers:         42
  Section header string table index: 41

$ qemu-arm -g 12345 ./njs-armv7 -c 'console.log("HH")'

$ gdb-multiarch ./njs-armv7 -ex 'source showstack.py'
ARGUMENTS
---------
argc = 3
arg 0 = ./njs-armv7
arg 1 = -c
arg 2 = console.log("HH")

...

AUX VECTOR
----------
AT_PHDR = 10034
AT_PHENT = 20
AT_PHNUM = 7
AT_PAGESZ = 1000
AT_BASE = 0
AT_FLAGS = 0
AT_ENTRY = 12fb9
AT_UID = 3e9
AT_EUID = 3e9
AT_GID = 3e9
AT_EGID = 3e9
AT_HWCAP = 1fb8d7
AT_CLKTCK = 64
AT_RANDOM = -104a0
AT_HWCAP2 = 1f
AT_NULL = 0

$ qemu-arm --version
qemu-arm version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.28)
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1885332

Title:
  Error in user-mode calculation of ELF aux vector's AT_PHDR

Status in QEMU:
  New

Bug description:
  
  I have an (admittedly strange) statically-linked ELF binary for Linux that runs just fine on top of the Linux kernel in QEMU full-system emulation, but crashes before main in user-mode emulation. Specifically, it crashes when initializing thread-local storage in glibc's _dl_aux_init, because it reads out a strange value from the AT_PHDR entry of the ELF aux vector.

  The binary has these program headers:

    Program Headers:
      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
      EXIDX          0x065874 0x00075874 0x00075874 0x00570 0x00570 R   0x4
      PHDR           0x0a3000 0x00900000 0x00900000 0x00160 0x00160 R   0x1000
      LOAD           0x0a3000 0x00900000 0x00900000 0x00160 0x00160 R   0x1000
      LOAD           0x000000 0x00010000 0x00010000 0x65de8 0x65de8 R E 0x10000
      LOAD           0x066b7c 0x00086b7c 0x00086b7c 0x02384 0x02384 RW  0x10000
      NOTE           0x000114 0x00010114 0x00010114 0x00044 0x00044 R   0x4
      TLS            0x066b7c 0x00086b7c 0x00086b7c 0x00010 0x00030 R   0x4
      GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x8
      GNU_RELRO      0x066b7c 0x00086b7c 0x00086b7c 0x00484 0x00484 R   0x1
      LOAD           0x07e000 0x00089000 0x00089000 0x03f44 0x03f44 R E 0x1000
      LOAD           0x098000 0x00030000 0x00030000 0x01000 0x01000 RW  0x1000

  If I build the Linux kernel with the following patch to the very end
  of create_elf_tables in fs/binfmt_elf.c

    /* Put the elf_info on the stack in the right place.  */
    elf_addr_t *my_auxv = (elf_addr_t *) mm->saved_auxv;
    int i;
    for (i = 0; i < 15; i++) {
      printk("0x%x = 0x%x", my_auxv[2*i], my_auxv[(2*i)+ 1]);
    }
    if (copy_to_user(sp, mm->saved_auxv, ei_index * sizeof(elf_addr_t)))
        return -EFAULT;
    return 0;

  and run it like this:

    qemu-system-arm \
      -M versatilepb \
      -nographic \
      -dtb ./dts/versatile-pb.dtb \
      -kernel zImage \
      -M versatilepb \
      -m 128M \
      -append "earlyprintk=vga,keep" \
      -initrd initramfs

  after I've built the kernel initramfs like this (where "init" is the
  binary in question):

    make ARCH=arm versatile_defconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all -j10
    cp "$1" arch/arm/boot/init
    cd arch/arm/boot
    echo init | cpio -o --format=newc > initramfs

  then I get the following output. This is the kernel's view of the aux
  vector for this binary:

    0x10 = 0x1d7
    0x6 = 0x1000
    0x11 = 0x64
    0x3 = 0x900000
    0x4 = 0x20
    0x5 = 0xb
    0x7 = 0x0
    0x8 = 0x0
    0x9 = 0x101b8
    0xb = 0x0
    0xc = 0x0
    0xd = 0x0
    0xe = 0x0
    0x17 = 0x0
    0x19 = 0xbec62fb5

  However, if I run "qemu-arm -g 12345 binary" and use GDB to peek at
  the aux vector at the beginning of __libc_start_init (for example,
  using this Python GDB API script: https://gist.github.com/langston-
  barrett/5573d64ae0c9953e2fa0fe26847a5e1e), then I see the following
  values:

    AT_PHDR = 0xae000
    AT_PHENT = 0x20
    AT_PHNUM = 0xb
    AT_PAGESZ = 0x1000
    AT_BASE = 0x0
    AT_FLAGS = 0x0
    AT_ENTRY = 0x10230
    AT_UID = 0x3e9
    AT_EUID = 0x3e9
    AT_GID = 0x3e9
    AT_EGID = 0x3e9
    AT_HWCAP = 0x1fb8d7
    AT_CLKTCK = 0x64
    AT_RANDOM = -0x103c0
    AT_HWCAP2 = 0x1f
    AT_NULL = 0x0

  The crucial difference is in AT_PHDR (0x3), which is indeed the
  virtual address of the PHDR segment when the kernel calculates it, but
  is not when QEMU calculates it.

  qemu-arm --version
  qemu-arm version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.26)

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1885332/+subscriptions


  parent reply	other threads:[~2020-07-11 12:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-26 20:17 [Bug 1885332] [NEW] Error in user-mode calculation of ELF aux vector's AT_PHDR Langston
2020-06-26 23:05 ` [Bug 1885332] " Langston
2020-06-29 17:09 ` Langston
2020-07-10 18:09 ` Dmitry
2020-07-10 18:14 ` Dmitry
2020-07-10 18:18 ` Dmitry
2020-07-10 18:28 ` Langston
2020-07-10 19:12 ` Dmitry
2020-07-11 12:00 ` Dmitry [this message]
2020-07-13 13:02 ` Dmitry
2021-05-07  3:03 ` Thomas Huth
2021-05-07 18:06 ` Langston
2021-05-12 11:02 ` Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=159446884647.13681.6408740332020546953.malone@gac.canonical.com \
    --to=1885332@bugs.launchpad.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).