summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillem Jover <guillem@debian.org>2018-04-08 22:38:27 +0200
committerGuillem Jover <guillem@debian.org>2018-05-04 04:13:19 +0200
commitc972dfdcd85d92a39998b81a0fb23dc63935b137 (patch)
tree371321f2b76cb75456eb37ed37d22710952066e5
parentb9090a05af10b4f12adbc796fdc846c667ac7670 (diff)
downloaddpkg-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/changelog2
-rw-r--r--scripts/Dpkg/Shlibs/Objdump.pm10
-rw-r--r--scripts/t/Dpkg_Shlibs.t6
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 => '',