Menu

Invalid executable after using statifier on ffmpeg from Ubuntu 16.04

Help
Michael
2016-03-23
2017-06-20
  • Michael

    Michael - 2016-03-23

    Using statifier on the bundled ffmpeg with Ubuntu 16.04 (64 Bit), I got a 128 MB big executable (can be ok giving how many libs ffmpeg can use). Sadly, this file isn't executable:

    "
    execve("./ffmpeg-static", ["./ffmpeg-static"], [/ 96 vars /]) = -1 ENOEXEC (Exec format error)
    "

    file says:
    "
    ffmpeg-static: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, for GNU/Linux 2.6.32, BuildID[sha1]=e0f06c36f33a9b9c545989eaeaf33aa7168c1b75, stripped
    "

     
    • Valery Reznic

      Valery Reznic - 2016-03-24

      Hmm... Could you please upload ffmpef.static to here?

       
  • nh2

    nh2 - 2017-06-20

    For me statifying ffmpeg doesn't work (--verbose says Symbol '\''_dl_argc'\'' not found in the interpreter), but I've uploaded another executable that apparently has the same problem.

     
  • Valery Reznic

    Valery Reznic - 2017-06-22

    Good news - Thanks to your executable I was able to find out what problem is.

    readelf -h nix-instantiate-static
    ELF Header:
    Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
    Class: ELF64
    Data: 2's complement, little endian
    Version: 1 (current)
    OS/ABI: UNIX - System V
    ABI Version: 0
    Type: EXEC (Executable file)
    Machine: Advanced Micro Devices X86-64
    Version: 0x1
    Entry point address: 0x7f1ead9b21a0
    Start of program headers: 64 (bytes into file)
    Start of section headers: 4656 (bytes into file)
    Flags: 0x0
    Size of this header: 64 (bytes)
    Size of program headers: 56 (bytes)
    Number of program headers: 82
    Size of section headers: 64 (bytes)
    Number of section headers: 31
    Section header string table index: 28

    Statified executble has 82 program headers, size of each 56 bytes.
    Total 82 * 56 = 4592 > 4096 (PAGE_SIZE)

    Kernel unble to load executable where phrs took more then PAGE_SIZE, so it returns ENOEXEC.

    Bad news: nothing to do with the current statifier design.
    It may be possible change statified exe format and loader, so statifier's code will load
    all PT_LOAD segments instead of kernel, but such approch not without problems too:
    loader will be more complex, so it will took more space. If it will took more space
    may be will be no enough room for loader in the existing PT_LOAD segments.
    So another one should be created...

     
  • Valery Reznic

    Valery Reznic - 2017-06-24

    Ooops. I was wrong. Kernel able to run elf with total size of phdrs up to 64K.
    So problem is not the number of phdrs

     
  • Valery Reznic

    Valery Reznic - 2017-06-24

    I was right after all.
    In the kernel in the file fs/binfmt_elf.c

        /* Sanity check the number of program headers... */
        if (elf_ex->e_phnum < 1 ||
            elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr))
            goto out;
    
        /* ...and their total size. */
        size = sizeof(struct elf_phdr) * elf_ex->e_phnum;
        if (size > ELF_MIN_ALIGN)
            goto out;
    

    First check limit phdrs size to 64K, but second one - to the ELF_MIN_ALIGN.
    On the x86_64 system ELF_MIN_ALIGN is 4096.

    When I run your executable "as is" I get following

    bash: ./nix-instantiate-static: cannot execute binary file: Exec format error
    

    But after changing with binary editor number of phrs from 82 to 73 (0x49)
    73 * 56 = 4088 < 4096 I got "Segmentation fault". Obviously application should not work because part of it code and data was prevented from loading, but at least kernel
    was not refusing to run it.

    By the way, setting phdrs number one higher - 74 will result in the same

    bash: ./nix-instantiate-static: cannot execute binary file: Exec format error
    
     

Log in to post a comment.

MongoDB Logo MongoDB