file mis-identifies modern executables as application/x-sharedlib

Bug #1747711 reported by scruss on 2018-02-06
266
This bug affects 3 people
Affects Status Importance Assigned to Milestone
file (Ubuntu)
Undecided
Unassigned

Bug Description

file doesn't recognize modern PIE (Position Independent Executable) x86 executables as such, reporting them as “application/x-sharedlib”. Consequently, only non-PIE executables can be opened in graphical file managers such as nautilus. This may cause a minor (?) security risk if a commonly-published workaround is attempted.

Expected behaviour:

    $ echo "int main() { return 0; }" > foo.c
    $ gcc -o foo foo.c
    $ file foo
    foo: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6e7749f995a89a53f74ec29d3c16fcf3f56be90f, not stripped
    $ file --mime-type foo
    foo: application/x-executable

Actual behaviour:

    $ echo "int main() { return 0; }" > foo.c
    $ gcc -o foo foo.c
    $ file foo
    foo: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6e7749f995a89a53f74ec29d3c16fcf3f56be90f, not stripped
    $ file --mime-type foo
    foo: application/x-sharedlib

Workaround (unsafe?):

    $ echo "int main() { return 0; }" > foo.c
    $ gcc -o foo-nopie foo.c -no-pie
    $ file foo-nopie
    foo-nopie: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=3eb8c581f43c19997e3c828f5a9730dbdc794470, not stripped
    $ file --mime-type foo-nopie
    foo-nopie: application/x-executable

gcc now defaults to building with PIE enabled for security reasons.

Also affects: nautilus (and likely other graphical file managers like those on Lubuntu) - because nautilus uses mime-type to determine if a file is executable, double-click to run a program no longer works.

Also noted on: Gnome Bugs - https://bugzilla.gnome.org/show_bug.cgi?id=737849 (2014) - before PIE became the default build option.

This may be an upstream issue. This may not affect architectures outside x86.*

ProblemType: Bug
DistroRelease: Ubuntu 17.10
Package: file 1:5.32-1
ProcVersionSignature: Ubuntu 4.13.0-32.35-generic 4.13.13
Uname: Linux 4.13.0-32-generic x86_64
ApportVersion: 2.20.7-0ubuntu3.7
Architecture: amd64
CurrentDesktop: GNOME
Date: Tue Feb 6 11:21:20 2018
InstallationDate: Installed on 2017-05-11 (270 days ago)
InstallationMedia: Ubuntu-GNOME 17.04 "Zesty Zapus" - Release amd64 (20170412)
SourcePackage: file
UpgradeStatus: Upgraded to artful on 2017-10-21 (108 days ago)

scruss (scruss) wrote :
scruss (scruss) on 2018-02-08
information type: Private Security → Public Security
description: updated
tags: added: bionic
Brian Murray (brian-murray) wrote :

It is also an issue on bionic:

 $ schroot -u root -c bionic-amd64
(bionic-amd64)root@impulse:/tmp# echo "int main() { return 0; }" > foo.c
(bionic-amd64)root@impulse:/tmp# gcc -o foo foo.c
(bionic-amd64)root@impulse:/tmp# file foo
foo: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=5222fe7f5f12ee8d286b84f93c981cab98ad382a, not stripped

But not on xenial:

 $ schroot -u root -c xenial-amd64
(xenial-amd64)root@impulse:/tmp# echo "int main() { return 0; }" > foo.c
(xenial-amd64)root@impulse:/tmp# gcc -o foo foo.c
(xenial-amd64)root@impulse:/tmp# file foo
foo: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5a079b5be569b3e0527b9685f1c7811fb193d37c, not stripped

Using gcc from xenial and file from bionic though the file is identified as an executable so I don't think its file.

Kees Cook (kees) wrote :

This is (sort of) a bug in file. The problem is not being able to distinguish between shared objects and PIE binaries. (The latter have INTERP ELF sections and can be run directly.)

$ readelf -l /bin/true
...
Elf file type is EXEC (Executable file)
...
  INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c R 1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
...

$ readelf -l /usr/lib/x86_64-linux-gnu/libmagic.so.1.0.0
...
Elf file type is DYN (Shared object file)
...[no INTERP]...

$ readelf -l /usr/bin/ssh
...
Elf file type is DYN (Shared object file)
...
  INTERP 0x0000000000000238 0x0000000000000238 0x0000000000000238
                 0x000000000000001c 0x000000000000001c R 1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

So for mime types to distinguish, "file" needs to grow reporting of the INTERP presence.

This has become an issue in bionic due to PIE-by-default.

scruss (scruss) wrote :

I've had a discussion with Christos Zoulas, the root maintainer of ‘file’, and they will make the necessary changes in due course. Whether this will be noticed by all the forks and re-implementations such as xdgmime in Gnome, I don't know.

tags: added: rls-bb-incoming
Steve Langasek (vorlon) on 2018-02-22
tags: added: rls-bb-notfixing
removed: rls-bb-incoming
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in file (Ubuntu):
status: New → Confirmed
Chris Billington (cjbil1) wrote :

Has this been fixed upstream? Looking at the changelog, there has been a related change, but I'm not sure if it resolves the issue yet, it now says they're both executables.

https://github.com/file/file/blob/219846094c7593e27453e62855e61181089c48cf/ChangeLog

file 5.3.3:

python3.6: ELF 64-bit LSB pie executable x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.4.0, with debug_info, not stripped

libpython3.6m.so.1.0: ELF 64-bit LSB pie executable x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped

file 5.3.2:

python3.6: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.4.0, with debug_info, not stripped

libpython3.6m.so.1.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped

WHR (msl0000023508) wrote :

Looks like the upstream fix makes many dynamic libraries wrongly detected as 'pie executable's.
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=906727

WHR (msl0000023508) wrote :

And I don't think this is a bug because technically an ELF position independent executable IS a ELF shared object, right?

scruss (scruss) wrote :

What does "file --mime-type" return for dynamic libraries?

Yes, this is very much a bug. While ELF position independent executables are ELF shared objects, they weren't being recognized as executables by desktop launchers. So they wouldn't run.

Corey Bruce (cdfrosty) wrote :

Electron applications using Electron 4.0.0 beta/nightly are effected by this bug making it impossible for developers to create Linux applications and have it easily work using that version, doesn't effect applications developed Electron 3.0.6 latest but this is a seriously annoying bugs that will cause issues with Linux users and needs to be patched.

WHR (msl0000023508) wrote :

>>> Yes, this is very much a bug. While ELF position independent executables are ELF shared objects, they weren't being recognized as executables by desktop launchers. So they wouldn't run.

So those launchers should accept shared objects (application/x-sharedlib) as executables from now.

WHR (msl0000023508) wrote :

>>> So for mime types to distinguish, "file" needs to grow reporting of the INTERP presence.

Distinguish between shared libraries and PIC executables based on INTERP ELF header is not always correct. Consider following 2 exceptions:

GLIBC main library libc-2.24.so
This shared object has an INTERP header, which is /lib64/ld-linux-x86-64.so.2 in my system. However we usually considering it a shared library, not an executable.

GLIBC dynamic linker ld-2.24.so
This shared object doesn't have INTERP header because this object itself is an interpreter. It should be considered as an executable since it is useful to load and run GLIBC linked dynamic executables.

This indicates a clear boundary between shared libraries and PIC executables just does not exist.

To post a comment you must log in.
This report contains Public Security information  Edit
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.