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

Bug#856975: lintian: add a check for wrong uses of Multi-Arch: foreign on shared libraries



Package: lintian
Version: 2.5.50.1
Severity: wishlist
Tags: patch
User: helmutg@debian.org
Usertags: rebootstrap

While working on cross building the Debian archive, I noticed a pattern.
A number of packages are marked Multi-Arch: foreign even though they
shouldn't be. If you look into the conflicts table of
https://bootstrap.debian.net/cross_all.html, you'll notice a number of
conflicts where both chains start with a -dev package. For instance,
src:kdepim-runtime has chains to libkf5service-bin via
libkf5akonadicontact-dev and libkf5textwidgets-dev. Why would both
chains (host and build arch) start with a -dev package? Because one of
them is wrongly marked Multi-Arch: foreign.

After a bit of research and fruitful discussion with Guillem Jover and
Johannes Schauer, we spot a subpattern. The following condition seems to
identify some wrong uses of Multi-Arch: foreign with high precision
(presently no known false positives):
 * A binary package is architecture-dependent (not Architecture: all).
 * It has Multi-Arch: foreign of course.
 * It ships a shared library in a public search path (i.e. a .so file,
   in most cases the symlink in a -dev package).
 * It does not ship any programs on $PATH.

The last condition filters a number of false positives that would
otherwise occur. Some tools ship private shared libraries or plugins on
the public library search path. Such use can be compatible with
Multi-Arch: foreign (e.g.  binutils-<triplet>).

Presently the check will identify the following binary packages (of sid
main amd64) and it is reported by the multiarch hinter[1]:

libcaffe-cpu-dev libfoma-dev libgexiv2-dev libgmsh-dev
libgtkdataboxmm-dev libimobiledevice-dev libjava-gmsh2
libkf5akonadicontact-dev libkf5akonadinotes-dev libkf5akonadisearch-dev
libkf5akonadisocialutils-dev libkf5alarmcalendar-dev libkf5blog-dev
libkf5calendarutils-dev libkf5gapi-dev libkf5gpgmepp-dev
libkf5identitymanagement-dev libkf5imap-dev libkf5kdelibs4support-dev
libkf5kontactinterface-dev libkf5mailtransport-dev libkf5mbox-dev
libkf5mime-dev libkf5pimtextedit-dev libkf5syndication-dev
libkf5tnef-dev liblognorm-dev libpocl-dev libpoclu-dev libquadrule-dev
libsnl-dev libsquirrel-dev libtet1.5-dev

In the attached patch, the new tag is called
multiarch-foreign-shared-library. Guillem Jover proposed
multiarch-foreign-with-shared-library instead, but since most hits are
primarily shared libraries, I currently prefer to stick with the shorter
name.

Johannes Schauer questioned the use of Certainty: wild-guess. I am not
sure what to put here as even empty-binary-package (which looks pretty
reliable to me) is marked as wild-guess. Thus I went conservative.

So please consider adding this new check for buster. Also excuse my bad
perl and tell me how to improve it.

Helmut

[1] https://wiki.debian.org/MultiArch/Hints
diff --minimal -Nru lintian-2.5.50.1/checks/files.desc lintian-2.5.50.1+nmu1/checks/files.desc
--- lintian-2.5.50.1/checks/files.desc	2016-12-01 21:31:08.000000000 +0100
+++ lintian-2.5.50.1+nmu1/checks/files.desc	2017-03-05 21:15:32.000000000 +0100
@@ -1729,3 +1729,14 @@
  not contain the actual directory itself.  Some tools do not cope
  very well with this case. Notably Lintian prior to 2.5.32 would
  crash on such packages.
+
+Tag: multiarch-foreign-shared-library
+Severity: important
+Certainty: wild-guess
+Info: The package is architecture-dependent, ships a shared library in
+ a public library search path and is marked Multi-Arch: foreign. Typically,
+ shared libraries are marked Multi-Arch: same when possible. Sometimes, private
+ shared libraries are put into the public library search path to accomodate
+ programs in the same package, but this package does not contain any programs.
+ .
+ Please remove the Multi-Arch: foreign stanza.
diff --minimal -Nru lintian-2.5.50.1/checks/files.pm lintian-2.5.50.1+nmu1/checks/files.pm
--- lintian-2.5.50.1/checks/files.pm	2017-01-29 21:00:48.000000000 +0100
+++ lintian-2.5.50.1+nmu1/checks/files.pm	2017-03-05 21:22:01.000000000 +0100
@@ -259,7 +259,8 @@
 
 sub run {
     my ($pkg, $type, $info, $proc) = @_;
-    my ($is_python, $is_perl, $has_binary_perl_file);
+    my ($is_python, $is_perl, $has_binary_perl_file, $has_public_executable,
+        $has_public_shared_library);
     my @nonbinary_perl_files_in_lib;
     my %linked_against_libvga;
     my @devhelp;
@@ -274,7 +275,7 @@
     my $source_pkg = $proc->pkg_src;
     my $pkg_section = $info->field('section', '');
     my $arch = $info->field('architecture', '');
-    my $isma_same = $info->field('multi-arch', '') eq 'same';
+    my $multiarch = $info->field('multi-arch', 'no');
     my $ppkg = quotemeta($pkg);
 
     # get the last changelog timestamp
@@ -358,6 +359,7 @@
         $arch_dep_files = 1 if $fname !~ m,^usr/share/,o && $fname ne 'usr/';
 
         if (exists($PATH_DIRECTORIES{$file->dirname})) {
+            $has_public_executable = 1;
             tag 'file-name-in-PATH-is-not-ASCII', $file
               if $file->basename !~ m{\A [[:ascii:]]++ \Z}xsm;
         } elsif (!is_string_utf8_encoded($fname)) {
@@ -847,7 +849,6 @@
                             or index($block,'pkg-config')  > -1)
                       ) {
                         tag 'old-style-config-script',$file;
-                        my $multiarch = $info->field('multi-arch', 'no');
                         # could be ok but only if multi-arch: no
                         if($multiarch ne 'no' or $arch eq 'all') {
                             # check multi-arch path
@@ -1084,6 +1085,11 @@
             }
         }
 
+        if ($fname =~ m,(?:usr/)?lib/(?:([^/]+)/)?lib[^/]*\.so$,) {
+            $has_public_shared_library = 1
+              if (!defined($1) || $TRIPLETS->known($1));
+        }
+
         # ---------------- .pyc/.pyo (compiled Python files)
         #  skip any file installed inside a __pycache__ directory
         #  - we have a separate check for that directory.
@@ -1549,7 +1555,7 @@
                     }
                     close($fd);
                     if ($mtime != 0) {
-                        if ($isma_same && $file !~ m/\Q$arch\E/) {
+                        if ($multiarch eq 'same' && $file !~ m/\Q$arch\E/) {
                             tag 'gzip-file-is-not-multi-arch-same-safe',$file;
                         } else {
                             # see https://bugs.debian.org/762105
@@ -1932,6 +1938,12 @@
         tag 'package-mixes-misc-and-dpi-fonts';
     }
 
+    tag 'multiarch-foreign-shared-library'
+      if $arch ne 'all'
+          and $multiarch eq 'foreign'
+          and $has_public_shared_library
+          and !$has_public_executable;
+
     return;
 }
 
diff --minimal -Nru lintian-2.5.50.1/debian/changelog lintian-2.5.50.1+nmu1/debian/changelog
--- lintian-2.5.50.1/debian/changelog	2017-02-04 16:05:07.000000000 +0100
+++ lintian-2.5.50.1+nmu1/debian/changelog	2017-03-05 21:22:21.000000000 +0100
@@ -1,3 +1,10 @@
+lintian (2.5.50.1+nmu1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * New tag: multiarch-foreign-shared-library
+
+ -- Helmut Grohne <helmut@subdivi.de>  Sun, 05 Mar 2017 21:22:21 +0100
+
 lintian (2.5.50.1) unstable; urgency=medium
 
   * debian/copyright:

Reply to: