[SCM] Debian package checker branch, master, updated. 2.5.10-10-g701e44e
The following commit has been merged in the master branch:
commit 701e44e2b14308faaf22805172f7c1b42f71748c
Author: Niels Thykier <niels@thykier.net>
Date: Sun Apr 15 16:41:43 2012 +0200
coll/objdump-info: dctrl-ify the output
Instead of relying on making "readelf output look like objdump",
filter out the unneeded part and write the interesting data as
a dctrl formatted file.
As a side effect, merge apparently-truncated-elf-binary into
apparently-corrupted-elf-binary. Unlike objdump, readelf does not
really give a reliable way of distinguishing the two cases.
The patch also fixes a couple of references to objdump in the
tag description of two tags.
Signed-off-by: Niels Thykier <niels@thykier.net>
diff --git a/checks/binaries b/checks/binaries
index c7476c1..051d24f 100644
--- a/checks/binaries
+++ b/checks/binaries
@@ -131,16 +131,10 @@ foreach my $file (sort keys %{$info->objdump_info}) {
}
}
}
- foreach (@{$objdump->{NOTES}}) {
- if ($_ eq 'File format not recognized') {
- tag 'apparently-corrupted-elf-binary', $file;
- } elsif ($_ eq 'File truncated') {
- tag 'apparently-truncated-elf-binary', $file;
- } elsif ($_ eq 'Packed with UPX') {
- tag 'binary-file-compressed-with-upx', $file;
- } elsif ($_ eq 'Invalid operation') {
- tag 'binary-with-bad-dynamic-table', $file unless $file =~ m%^usr/lib/debug/%;
- }
+ tag 'binary-file-compressed-with-upx', $file if $objdump->{'UPX'};
+ tag 'apparently-corrupted-elf-binary', $file if $objdump->{'ERRORS'};
+ if ($objdump->{'BAD-DYNAMIC-TABLE'}) {
+ tag 'binary-with-bad-dynamic-table', $file unless $file =~ m%^usr/lib/debug/%;
}
}
@@ -291,11 +285,10 @@ foreach my $file ($info->sorted_index) {
tag 'library-in-debug-or-profile-should-not-be-stripped', $file;
} else {
# appropriately stripped, but is it stripped enough?
- if (exists $objdump->{NOTE_SECTION}) {
- tag 'binary-has-unneeded-section', "$file .note";
- }
- if (exists $objdump->{COMMENT_SECTION}) {
- tag 'binary-has-unneeded-section', "$file .comment";
+ foreach my $sect ('.note', '.comment') {
+ if (exists $objdump->{'SH'}->{$sect}) {
+ tag 'binary-has-unneeded-section', "$file $sect";
+ }
}
}
}
@@ -346,21 +339,21 @@ foreach my $file ($info->sorted_index) {
# Something other than detached debugging symbols in /usr/lib/debug paths.
if ($file =~ m,^usr/lib/debug/(?:lib\d*|s?bin|usr|opt|dev|emul)/,) {
- if (exists($objdump->{NEEDED})) {
+ if (scalar (@{ $objdump->{NEEDED} }) ) {
tag 'debug-file-should-use-detached-symbols', $file;
}
}
# Detached debugging symbols directly in /usr/lib/debug.
if ($file =~ m,^usr/lib/debug/[^/]+$,) {
- unless (exists($objdump->{NEEDED})
+ unless (scalar (@{ $objdump->{NEEDED} })
|| $fileinfo =~ m/statically linked/) {
tag 'debug-symbols-directly-in-usr-lib-debug', $file;
}
}
# statically linked?
- if (!exists($objdump->{NEEDED}) || !defined($objdump->{NEEDED})) {
+ if (! scalar (@{ $objdump->{NEEDED} }) ) {
if ($fileinfo =~ m/shared object/o) {
# Some exceptions: detached debugging information and the dynamic
# loader (which itself has no dependencies).
@@ -374,7 +367,8 @@ foreach my $file ($info->sorted_index) {
next if ($file =~ /[\.-]static$/);
next if ($pkg =~ /-static$/);
# klibc binaries appear to be static.
- next if ($objdump->{KLIBC});
+ next if (exists $objdump->{INTERP}
+ && $objdump->{INTERP} =~ m,/lib/klibc-\S+\.so,);
# Location of debugging symbols.
next if ($file =~ m%^usr/lib/debug/%);
# ldconfig must be static.
diff --git a/checks/binaries.desc b/checks/binaries.desc
index 9a81f60..c6f3e25 100644
--- a/checks/binaries.desc
+++ b/checks/binaries.desc
@@ -150,26 +150,24 @@ Info: The package name of a library package should usually reflect
Tag: binary-with-bad-dynamic-table
Severity: serious
Certainty: possible
-Info: This appears to be an ELF file but objdump -T cannot parse it.
- If it is external debugging symbols for another file, it should be
- installed under /usr/lib/debug.
+Info: This appears to be an ELF file. According to readelf, the
+ program headers suggests it should have a dynamic section, but
+ readelf cannot find it.
+ .
+ If it is meant to be external debugging symbols for another file,
+ it should be installed under /usr/lib/debug. Otherwise, this
+ could be a corrupt ELF file.
Tag: apparently-corrupted-elf-binary
Severity: normal
Certainty: possible
-Info: This appears to be an ELF file but objdump -T doesn't recognize it
- as valid. This may be a mistake or a corrupted file, you may need to
+Info: This appears to be an ELF file but readelf cannot parse it.
+ .
+ This may be a mistake or a corrupted file, you may need to
install binutils-multiarch on the system running lintian so that
non-native binaries are handled correctly, or it may be a
misidentification of a file as ELF that actually isn't.
-Tag: apparently-truncated-elf-binary
-Severity: normal
-Certainty: possible
-Info: This appears to be an ELF file, but objdump believes it is
- truncated. This may be a mistake or a corrupted file, or it may be a
- misidentification of a file as ELF that actually isn't.
-
Tag: missing-dependency-on-libc
Severity: serious
Certainty: possible
diff --git a/checks/shared-libs b/checks/shared-libs
index 835e8c9..f2209c0 100644
--- a/checks/shared-libs
+++ b/checks/shared-libs
@@ -74,7 +74,7 @@ my @devpkgs;
# 1st step: get info about shared libraries installed by this package
foreach my $file (sort keys %{$objdump}) {
$SONAME{$file} = $objdump->{$file}->{SONAME}[0]
- if defined $objdump->{$file}->{SONAME};
+ if scalar @{ $objdump->{$file}->{SONAME} };
}
foreach my $file ($info->sorted_index) {
@@ -154,13 +154,13 @@ for my $cur_file ($info->sorted_index) {
# executable stack. We can only warn about a missing section on some
# architectures. Only warn if there's an Architecture field; if
# that's missing, we'll already be complaining elsewhere.
- if (not defined $objdump->{$cur_file}->{STACK}) {
+ if (not defined $objdump->{$cur_file}->{'PH'}->{STACK}) {
if (defined $info->field('architecture')) {
my $arch = $info->field('architecture');
tag 'shlib-without-PT_GNU_STACK-section', $cur_file
if $stack_arches{$arch};
}
- } elsif ($objdump->{$cur_file}->{STACK} ne 'rw-') {
+ } elsif ($objdump->{$cur_file}->{'PH'}->{STACK}->{flags} ne 'rw-') {
tag 'shlib-with-executable-stack', $cur_file;
}
} elsif ($ldconfig_dirs->known(dirname($cur_file))
diff --git a/collection/objdump-info-helper b/collection/objdump-info-helper
index e816bb1..7485a45 100755
--- a/collection/objdump-info-helper
+++ b/collection/objdump-info-helper
@@ -58,10 +58,10 @@ if (scalar @ARGV == 1) {
# simply use xargs directly on readelf and just parse its output
# in the loop below.
$bin = $ARGV[0];
- print "-- $bin\n";
+ print "Filename: $bin\n";
system ("head \Q$bin\E | grep -q 'packed.*with.*UPX'");
- print "objdump: $bin: Packed with UPX" if $? == 0;
+ print "UPX: yes\n" if $? == 0;
}
while ( my $line = <$readelf> ) {
@@ -73,22 +73,25 @@ while ( my $line = <$readelf> ) {
finish_file();
$bin = $file;
- print "-- $bin\n";
+ print "Filename: $bin\n";
system ("head \Q$bin\E | grep -q 'packed.*with.*UPX'");
- print "objdump: $bin: Packed with UPX" if $? == 0;
- } elsif ($line =~ m/^readelf: Error: Unable to read in 0x[0-9a-fA-F]+ bytes of/) {
- print "objdump: $bin: File truncated\n" unless $truncated++;
+ print "UPX: yes\n" if $? == 0;
+ } elsif ($line =~ m/^readelf: Error: Unable to read in 0x[0-9a-fA-F]+ bytes of/ or
+ $line =~ m/^readelf: Error: .*: Failed to read .*(?:magic number|file header)/) {
+ # Various errors for corrupt / broken files. Note, readelf may spit out
+ # multiple errors per file, hench the "unless".
+ print "Broken: yes\n" unless $truncated++;
next;
} elsif ($line =~ m/^Program Headers:/) {
$section = 'PH';
- print "$line\n";
+ print "Program-Headers:\n";
} elsif ($line =~ m/^Section Headers:/) {
$section = 'SH';
- print "$line\n";
+ print "Section-Headers:\n";
} elsif ($line =~ m/^Dynamic section at offset .*:/) {
$section = 'DS';
- print "$line\n";
+ print "Dynamic-Section:\n";
} elsif ($line =~ m/^Version symbols section /) {
$section = 'VS';
} elsif ($line =~ m/^Symbol table '.dynsym'/) {
@@ -104,20 +107,37 @@ while ( my $line = <$readelf> ) {
next if $header eq 'Type';
my $newflags = '';
+ my $redo = 0;
+ my $extra = '';
$newflags .= ($flags =~ m/R/) ? 'r' : '-';
$newflags .= ($flags =~ m/W/) ? 'w' : '-';
$newflags .= ($flags =~ m/E/) ? 'x' : '-';
$program_headers{$header} = $newflags;
- print " $header off 0x0 X 0x0 X 0x0\n flags $newflags\n";
+
+ if ($header eq 'INTERP') {
+ # Check if the next line is the "requesting an interpreter"
+ # (readelf appears to always emit on the next line if at all)
+ my $next = <$readelf>;
+ if ($next =~ m,\[Requesting program interpreter:\s([^\]]+)\],) {
+ $extra .= " interp=$1";
+ } else {
+ # Nope, give it back
+ $redo = 1;
+ $line = $next;
+ }
+ }
+
+ print " $header flags=${newflags}$extra\n";
+
+ redo if $redo;
+ next;
+
} elsif ($line =~ m/^\s*\[(\d+)\]\s*(\S+)(?:\s|\Z)/
and $section eq 'SH') {
$sections[$1] = $2;
- # We need sections as well (i.e. for incomplete stripping)
- # - The 0 0 0 0 2**3 is just there to make it look like objdump output
- # (supposedly we don't even check for those extra fields in
- # L::Collect::Binary)
- print " $1 $2 0 0 0 0 2**3\n";
+ # We need sections as well (e.g. for incomplete stripping)
+ print " $1 $2\n";
} elsif ($line =~ m/^\s*0x(?:[0-9A-F]+)\s+\((.*?)\)\s+(\S.*)\Z/i
and $section eq 'DS') {
my ($type, $value) = ($1, $2);
@@ -148,9 +168,8 @@ while ( my $line = <$readelf> ) {
} elsif ($line =~ m/^There is no dynamic section in this file/
and exists $program_headers{DYNAMIC}) {
# The headers declare a dynamic section but it's
- # empty. Generate the same error as objdump,
- # the checks scripts special-case the string.
- print "\n\nobjdump: $bin: Invalid operation\n";
+ # empty.
+ print "Bad-Dynamic-Table: Yes\n";
}
}
@@ -164,7 +183,7 @@ exit 0;
sub finish_file {
if (@dyn_symbols) {
- print "DYNAMIC SYMBOL TABLE:\n";
+ print "Dynamic-Symbols:\n";
foreach my $dynsym (@dyn_symbols) {
my ($symnum, $seg, $sym, $ver) = @$dynsym;
@@ -192,9 +211,11 @@ sub finish_file {
$seg = $sections[$seg];
}
- print "00 XX $seg 000000 $ver $sym\n";
+ print " $seg $ver $sym\n";
}
}
+ # Add an newline to end the current paragraph
+ print "\n";
# reset variables
@sections = ();
diff --git a/collection/objdump-info.desc b/collection/objdump-info.desc
index 71e7df7..5bc5af0 100644
--- a/collection/objdump-info.desc
+++ b/collection/objdump-info.desc
@@ -3,5 +3,5 @@ Author: Christian Schwarz <schwarz@debian.org>
Info: This script runs objdump(1) over all binaries and object files of a
binary package.
Type: binary, udeb
-Version: 3
+Version: 4
Needs-Info: file-info, unpacked, index
diff --git a/debian/changelog b/debian/changelog
index de0e226..4fa2a86 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,8 +4,14 @@ lintian (2.5.11) UNRELEASED; urgency=low
+ Added:
- field-name-typo-in-dep5-copyright
+ Removed:
+ - apparently-truncated-elf-binary
- data.tar.xz-member-without-dpkg-pre-depends
+ * checks/binaries{,.desc}:
+ + [NT] Merge apparently-truncated-elf-binary into
+ apparently-corrupted-elf-binary.
+ + [NT] Remove some references to objdump in tag descriptions
+ as Lintian uses readelf.
* checks/deb-format{,.desc}:
+ [NT] Retire data.tar.xz tag. (Closes: #680391)
* checks/fields.desc:
@@ -23,6 +29,10 @@ lintian (2.5.11) UNRELEASED; urgency=low
+ [NT] Check for possible misspellings of known field
names. (Closes: #678639)
+ * collection/objdump-info{-helper,.desc}:
+ + [NT] Change the output format for the collection and
+ bump the version of the collection accordingly.
+
* data/doc-base/sections:
+ [NT] Update section list. (Closes: #678650)
@@ -34,6 +44,8 @@ lintian (2.5.11) UNRELEASED; urgency=low
methods that denotes the default value if a field is
missing. This avoid some boiler plate for callers
of the methods.
+ * lib/Lintian/Collect/Binary.pm:
+ + [NT] Bump API for objdump method.
-- Niels Thykier <niels@thykier.net> Tue, 10 Jul 2012 13:21:56 +0200
diff --git a/lib/Lintian/Collect/Binary.pm b/lib/Lintian/Collect/Binary.pm
index 5945cdc..64af868 100644
--- a/lib/Lintian/Collect/Binary.pm
+++ b/lib/Lintian/Collect/Binary.pm
@@ -28,7 +28,7 @@ use Lintian::Relation;
use Carp qw(croak);
use Parse::DebianChangelog;
-use Lintian::Util qw(fail open_gz);
+use Lintian::Util qw(fail open_gz parse_dpkg_control);
# Initialize a new binary package collect object. Takes the package name,
# which is currently unused.
@@ -171,71 +171,56 @@ sub objdump_info {
# sub objdump_info Needs-Info objdump-info
open my $fd, '-|', 'gzip', '-dc', "$base_dir/objdump-info.gz"
or fail "cannot open $base_dir/objdump-info.gz: $!";
- while (<$fd>) {
- chomp;
-
- next if m/^\s*$/o;
-
- if (m,^-- (?:\./)?(.+)$,) {
- if ($file) {
- $objdump_info{$file->{name}} = $file;
- }
- $file = { name => $1 };
- $dynsyms = 0;
- } elsif ($dynsyms) {
- # The (?:(\S+)\s+)? near the end is added because a number of optional fields
- # might be printed. The symbol name should be the last word.
- if (m/^[0-9a-fA-F]+.{6}\w\w?\s+(\S+)\s+[0-9a-zA-Z]+\s+(?:(\S+)\s+)?(\S+)$/){
- my ($foo, $sec, $sym) = ($1, $2, $3);
- $sec //= '';
- push @{$file->{SYMBOLS}}, [ $foo, $sec, $sym ];
+ foreach my $pg (parse_dpkg_control ($fd)) {
+ my %info = (
+ 'PH' => {},
+ 'SH' => {},
+ 'NOTES' => [],
+ 'NEEDED' => [],
+ 'RPATH' => {},
+ 'SONAME' => [],
+ );
+ $info{'ERRORS'} = lc ($pg->{'broken'}//'no') eq 'yes' ? 1 : 0;
+ $info{'UPX'} = lc ($pg->{'upx'}//'no') eq 'yes' ? 1 : 0;
+ $info{'BAD-DYNAMIC-TABLE'} = lc ($pg->{'bad-dynamic-table'}//'no') eq 'yes' ? 1 : 0;
+ foreach my $symd (split m/\s*\n\s*/, $pg->{'dynamic-symbols'}//'') {
+ next unless $symd;
+ if ($symd =~ m/^\s*(\S+)\s+(?:(\S+)\s+)?(\S+)$/){
+ # $ver is not always there
+ my ($sec, $ver, $sym) = ($1, $2, $3);
+ $ver //= '';
+ push @{ $info{'SYMBOLS'} }, [ $sec, $ver, $sym ];
}
- } else {
- if (m/^\s*NEEDED\s*(\S+)/o) {
- push @{$file->{NEEDED}}, $1;
- } elsif (m/^\s*RPATH\s*(\S+)/o) {
- my $rpath = $1;
- foreach my $r (split m/:/o, $rpath) {
- $file->{RPATH}{$r}++;
- }
- } elsif (m/^\s*SONAME\s*(\S+)/o) {
- push @{$file->{SONAME}}, $1;
- } elsif (m/^\s*\d+\s+\.comment\s+/o) {
- $file->{COMMENT_SECTION} = 1;
- } elsif (m/^\s*\d+\s+\.note\s+/o) {
- $file->{NOTE_SECTION} = 1;
- } elsif (m/^DYNAMIC SYMBOL TABLE:/) {
- $dynsyms = 1;
- } elsif (m/^objdump: .*?: File format not recognized$/) {
- push @{$file->{NOTES}}, 'File format not recognized';
- } elsif (m/^objdump: .*?: File truncated$/) {
- push @{$file->{NOTES}}, 'File truncated';
- } elsif (m/^objdump: .*?: Packed with UPX$/) {
- push @{$file->{NOTES}}, 'Packed with UPX';
- } elsif (m/objdump: .*?: Invalid operation$/) {
- # Don't anchor this regex since it can be interspersed with other
- # output and hence not on the beginning of a line.
- push @{$file->{NOTES}}, 'Invalid operation';
- } elsif (m/CXXABI/) {
- $file->{CXXABI} = 1;
- } elsif (m%Requesting program interpreter:\s+/lib/klibc-\S+\.so%) {
- $file->{KLIBC} = 1;
- } elsif (m/^\s*TEXTREL\s/o) {
- $file->{TEXTREL} = 1;
- } elsif (m/^\s*INTERP\s/) {
- $file->{INTERP} = 1;
- } elsif (m/^\s*STACK\s/) {
- $file->{STACK} = '0';
- } else {
- if (defined $file->{STACK} and $file->{STACK} eq '0') {
- m/\sflags\s+(\S+)/o;
- $file->{STACK} = $1;
+ }
+ foreach my $data (split m/\s*\n\s*/, $pg->{'section-headers'}//'') {
+ next unless $data;
+ my (undef, $section) = split m/\s++/, $data;
+ $info{'SH'}->{$section}++;
+ }
+ foreach my $data (split m/\s*\n\s*/, $pg->{'program-headers'}//'') {
+ next unless $data;
+ my ($header, @vals) = split m/\s++/, $data;
+ $info{'PH'}->{$header} = {};
+ foreach my $extra (@vals) {
+ my ($opt, $val) = split m/=/, $extra;
+ $info{'PH'}->{$header}->{$opt} = $val;
+ if ($opt eq 'interp' and $header eq 'INTERP') {
+ $info{'INTERP'} = $val;
}
}
}
- }
- if ($file) {
- $objdump_info{$file->{name}} = $file;
+ foreach my $data (split m/\s*\n\s*/, $pg->{'dynamic-section'}//'') {
+ next unless $data;
+ # Here we just need RPATH and NEEDS, so ignore the rest for now
+ my ($header, $val) = split m/\s++/, $data;
+ if ($header eq 'RPATH') {
+ $info{$header}->{$val} = 1;
+ } elsif ($header eq 'NEEDED' or $header eq 'SONAME') {
+ push @{ $info{$header} }, $val;
+ }
+ }
+
+ $objdump_info{$pg->{'filename'}} = \%info;
}
$self->{objdump_info} = \%objdump_info;
diff --git a/t/COVERAGE b/t/COVERAGE
index 7005c28..efbaf8e 100644
--- a/t/COVERAGE
+++ b/t/COVERAGE
@@ -1,9 +1,8 @@
Last generated 2012-07-10
-Coverage: 812/965 (84.15%), w. legacy tests: 917/965 (95.03%)
+Coverage: 812/964 (84.23%), w. legacy tests: 917/964 (95.12%)
The following tags are not tested by the test suite:
-binaries apparently-corrupted-elf-binary
binaries binary-file-compressed-with-upx
binaries library-not-linked-against-libc
binaries ocaml-custom-executable
diff --git a/t/tests/binaries-from-other-arch/desc b/t/tests/binaries-from-other-arch/desc
index 0d0e818..673a06a 100644
--- a/t/tests/binaries-from-other-arch/desc
+++ b/t/tests/binaries-from-other-arch/desc
@@ -4,5 +4,5 @@ Architecture: any
Version: 1.0
Description: Test package with a pseudo binary from a different architecture
Test-For:
- apparently-truncated-elf-binary
+ apparently-corrupted-elf-binary
binary-from-other-architecture
diff --git a/t/tests/binaries-from-other-arch/tags b/t/tests/binaries-from-other-arch/tags
index bf69c46..eed9159 100644
--- a/t/tests/binaries-from-other-arch/tags
+++ b/t/tests/binaries-from-other-arch/tags
@@ -1,4 +1,4 @@
E: binaries-from-other-arch: binary-from-other-architecture usr/bin/elfobject
E: binaries-from-other-arch: statically-linked-binary usr/bin/elfobject
-W: binaries-from-other-arch: apparently-truncated-elf-binary usr/bin/elfobject
+W: binaries-from-other-arch: apparently-corrupted-elf-binary usr/bin/elfobject
W: binaries-from-other-arch: binary-without-manpage usr/bin/elfobject
--
Debian package checker
Reply to: