diff options
author | Guillem Jover <guillem@debian.org> | 2018-04-08 22:38:27 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2018-05-04 04:13:19 +0200 |
commit | c972dfdcd85d92a39998b81a0fb23dc63935b137 (patch) | |
tree | 371321f2b76cb75456eb37ed37d22710952066e5 | |
parent | b9090a05af10b4f12adbc796fdc846c667ac7670 (diff) | |
download | dpkg-c972dfdcd85d92a39998b81a0fb23dc63935b137.tar.gz |
Dpkg::Shlibs::Objdump: Fix ELF program detection
An ELF executable is defined by whether the object has the EXEC_P flag
defined or an interpreter in the program header. The former applies to
statically linked programs, the latter to dynamically linked programs
and possibly some shared libraries that can be executed, such as the
ones provided by glibc.
This is now more relevant as PIE makes normal executables show up as
shared objects, so they do not contain the EXEC_P flag, and were not
being detected as executables.
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | scripts/Dpkg/Shlibs/Objdump.pm | 10 | ||||
-rw-r--r-- | scripts/t/Dpkg_Shlibs.t | 6 |
3 files changed, 14 insertions, 4 deletions
diff --git a/debian/changelog b/debian/changelog index 0d4410be9..5098e7f2d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -87,6 +87,8 @@ dpkg (1.19.1) UNRELEASED; urgency=medium signatures. Closes: #888787 - Dpkg::Deps: Turn virtualpkg tracking from an arrayyref into a hashref. - Dpkg::Vendor::Debian: Mark riscv64 as having gcc builtin PIE. + - Dpkg::Shlibs::Objdump: Fix ELF program detection, for PIE binaries and + executable libraries. * Documentation: - Update gettext minimal version in README. - Add a missing dot on the dpkg-buildflags(1) «lfs» feature paragraph. diff --git a/scripts/Dpkg/Shlibs/Objdump.pm b/scripts/Dpkg/Shlibs/Objdump.pm index 2694f596f..d0a7b56cb 100644 --- a/scripts/Dpkg/Shlibs/Objdump.pm +++ b/scripts/Dpkg/Shlibs/Objdump.pm @@ -270,6 +270,7 @@ sub reset { $self->{id} = ''; $self->{HASH} = ''; $self->{GNU_HASH} = ''; + $self->{INTERP} = 0; $self->{SONAME} = ''; $self->{NEEDED} = []; $self->{RPATH} = []; @@ -324,7 +325,7 @@ sub parse_objdump_output { $section = 'dyninfo'; next; } elsif (/^Program Header:/) { - $section = 'header'; + $section = 'program'; next; } elsif (/^Version definitions:/) { $section = 'verdef'; @@ -363,6 +364,10 @@ sub parse_objdump_output { $self->{RPATH} = [ split /:/, $rpath ]; } } + } elsif ($section eq 'program') { + if (/^\s*INTERP\s+/) { + $self->{INTERP} = 1; + } } elsif ($section eq 'none') { if (/^\s*.+:\s*file\s+format\s+(\S+)$/) { $self->{format} = $1; @@ -535,7 +540,8 @@ sub get_needed_libraries { sub is_executable { my $self = shift; - return exists $self->{flags}{EXEC_P} && $self->{flags}{EXEC_P}; + return (exists $self->{flags}{EXEC_P} && $self->{flags}{EXEC_P}) || + (exists $self->{INTERP} && $self->{INTERP}); } sub is_public_library { diff --git a/scripts/t/Dpkg_Shlibs.t b/scripts/t/Dpkg_Shlibs.t index 2310f4f1c..a271af587 100644 --- a/scripts/t/Dpkg_Shlibs.t +++ b/scripts/t/Dpkg_Shlibs.t @@ -21,7 +21,7 @@ use Test::Dpkg qw(:needs :paths); use Cwd; -plan tests => 148; +plan tests => 150; use Dpkg::Path qw(find_command); @@ -104,7 +104,7 @@ $obj->parse_objdump_output($objdump); close $objdump; ok($obj->is_public_library(), 'libc6 is a public library'); -ok(!$obj->is_executable(), 'libc6 is not an executable'); +ok($obj->is_executable(), 'libc6 is an executable'); is($obj->{SONAME}, 'libc.so.6', 'SONAME'); is($obj->{HASH}, '0x13d99c', 'HASH'); @@ -350,6 +350,8 @@ open $objdump, '<', "$datadir/objdump.glib-ia64" or die "$datadir/objdump.glib-ia64: $!"; $obj->parse_objdump_output($objdump); close $objdump; +ok($obj->is_public_library(), 'glib-ia64 is a public library'); +ok(!$obj->is_executable(), 'glib-ia64 is not an executable'); $sym = $obj->get_symbol('IA__g_free'); is_deeply( $sym, { name => 'IA__g_free', version => '', |