My findings are slightly different, but I agree that Position Independent Executables confuse the mimetype mechanism.
In the most recent Raspbian Stretch image (Nov 29th 2017) gcc generates normal position-dependent code by default, but I can believe that somewhere the default has changed. Adding '-pie' to the GCC creates the position-independent version.
In this output, pdfoo is the normal position-dependent elf, and pifoo is position-independent:
Code: Select all
[email protected]:~ $ file pdfoo
pdfoo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=4595b7b91b4664bb34eea3a09fb3b27af4c0596a, not stripped
[email protected]:~ $ file -i pdfoo
pdfoo: application/x-executable; charset=binary
[email protected]:~ $ hexdump pdfoo | head -2
0000000 457f 464c 0101 0001 0000 0000 0000 0000
0000010 0002 0028 0001 0000 02e0 0001 0034 0000
[email protected]:~ $ file pifoo
pifoo: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=3c6fe8043dec1156c0b9b85e73ce48635e4f1cca, not stripped
[email protected]:~ $ file -i pifoo
pifoo: application/x-sharedlib; charset=binary
[email protected]:~ $ hexdump pifoo | head -2
0000000 457f 464c 0101 0001 0000 0000 0000 0000
0000010 0003 0028 0001 0000 0468 0000 0034 0000
The "file" utility uses a file of magic numbers to identify file types. The following section of the source shows how the decision is made: [ From
https://github.com/file/file/blob/a25f2 ... ir/elf#L44 ]
Code: Select all
0 name elf-le
>16 leshort 0 no file type,
!:mime application/octet-stream
>16 leshort 1 relocatable,
!:mime application/x-object
>16 leshort 2 executable,
!:mime application/x-executable
>16 leshort 3 shared object,
!:mime application/x-sharedlib
>16 leshort 4 core file
!:mime application/x-coredump
According to my limited understanding the 16-bit little-endian value at offset 16 determines the ELF sub-type. As you can see in the hex dumps above, pdfoo has 2 (executable) while pifoo has 3 (shared object).
The takeaway from this seems to be that while position-independent code may be better from a security perspective, the current implementation is a hack that confuses "file".