[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[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: