[dpkg] 20/192: dpkg-shlibdeps: Preserve the order when scanning symbols/shlibs files
Ximin Luo
infinity0 at debian.org
Tue Oct 17 11:03:52 UTC 2017
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch pu/reproducible_builds
in repository dpkg.
commit 31f98198278ae0a70b5594680e05454a383ac175
Author: Guillem Jover <guillem at debian.org>
Date: Sun Apr 23 04:51:58 2017 +0200
dpkg-shlibdeps: Preserve the order when scanning symbols/shlibs files
The code was getting all the possible shared library pathnames for the
wanted SONAME, but was not preserving the order carefully constructed
in find_library(), so we were overwriting symbols/shlibs information
when parsing multiple entries, and selecting the symbols/shlibs files
randomly based on the perl hash order.
This causes regressions when multiple packages provide the same
SONAME on different directories. An example would be libc6:amd64
and libc6-amd64:i386.
Fixes: commit a927295c93fb7a17742441aa863aaffcf4a351b5
Closes: #860979
Reported-by: Helmut Grohne <helmut at subdivi.de>
---
debian/changelog | 4 +++
scripts/dpkg-shlibdeps.pl | 74 ++++++++++++++++++++++++++++++++---------------
2 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index cf9b5cc..92b2b27 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,10 @@ dpkg (1.18.24) UNRELEASED; urgency=medium
[ Guillem Jover ]
* Add missing symbols to the libdpkg map file.
+ * Fix dpkg-shlibdeps to preserve the Dpkg::Shlibs::find_library() order
+ when scanning symbols/shlibs files. This was causing generation of bogus
+ dependencies when multiple packages provide the same SONAME on different
+ directories. Regression introduced in dpkg 1.18.17. Closes: #860979
* Architecture support:
- Add support for ARM64 ILP32. Closes: #824742
Thanks to Wookey <wookey at wookware.org>.
diff --git a/scripts/dpkg-shlibdeps.pl b/scripts/dpkg-shlibdeps.pl
index 0978f33..f035093 100755
--- a/scripts/dpkg-shlibdeps.pl
+++ b/scripts/dpkg-shlibdeps.pl
@@ -191,6 +191,7 @@ foreach my $file (keys %exec) {
# Load symbols files for all needed libraries (identified by SONAME)
my %libfiles;
my %altlibfiles;
+ my %soname_libs;
my %soname_notfound;
my %alt_soname;
foreach my $soname (@sonames) {
@@ -209,6 +210,11 @@ foreach my $file (keys %exec) {
}
next;
}
+
+ # Track shared libraries for a given SONAME.
+ push @{$soname_libs{$soname}}, @libs;
+
+ # Track shared libraries for package mapping.
foreach my $lib (@libs) {
$libfiles{$lib} = $soname;
my $reallib = realpath($lib);
@@ -222,9 +228,11 @@ foreach my $file (keys %exec) {
my $symfile = Dpkg::Shlibs::SymbolFile->new();
my $dumplibs_wo_symfile = Dpkg::Shlibs::Objdump->new();
my @soname_wo_symfile;
- foreach my $lib (keys %libfiles) {
- my $soname = $libfiles{$lib};
+ SONAME: foreach my $soname (@sonames) {
+ # Select the first good entry from the ordered list that we got from
+ # find_library(), and skip to the next SONAME.
+ foreach my $lib (@{$soname_libs{$soname}}) {
if (none { $_ ne '' } @{$file2pkg->{$lib}}) {
# The path of the library as calculated is not the
# official path of a packaged file, try to fallback on
@@ -244,6 +252,7 @@ foreach my $file (keys %exec) {
}
# Load symbols/shlibs files from packages providing libraries
+ my $missing_wanted_shlibs_info = 0;
foreach my $pkg (@{$file2pkg->{$lib}}) {
my $symfile_path;
my $haslocaldep = 0;
@@ -273,6 +282,9 @@ foreach my $file (keys %exec) {
my $minver = $symfile->get_smallest_version($soname) || '';
update_dependency_version($dep, $minver);
debug(2, " Minimal version of ($dep) initialized with ($minver)");
+
+ # Found a symbols file for the SONAME.
+ next SONAME;
} else {
# No symbol file found, fall back to standard shlibs
debug(1, "Using shlibs+objdump for $soname (file $lib)");
@@ -284,31 +296,47 @@ foreach my $file (keys %exec) {
$alt_soname{$id} = $soname;
}
push @soname_wo_symfile, $soname;
+
# Only try to generate a dependency for libraries with a SONAME
- if ($libobj->is_public_library() and not
- add_shlibs_dep($soname, $pkg, $lib)) {
- # This failure is fairly new, try to be kind by
- # ignoring as many cases that can be safely ignored
- my $ignore = 0;
- # 1/ when the lib and the binary are in the same
- # package
- my $root_file = guess_pkg_root_dir($file);
- my $root_lib = guess_pkg_root_dir($lib);
- $ignore++ if defined $root_file and defined $root_lib
- and check_files_are_the_same($root_file, $root_lib);
- # 2/ when the lib is not versioned and can't be
- # handled by shlibs
- $ignore++ unless scalar(split_soname($soname));
- # 3/ when we have been asked to do so
- $ignore++ if $ignore_missing_info;
- error(g_('no dependency information found for %s ' .
- "(used by %s)\n" .
- 'Hint: check if the library actually comes ' .
- 'from a package.'), $lib, $file)
- unless $ignore;
+ if (not $libobj->is_public_library()) {
+ debug(1, "Skipping shlibs+objdump info for private library $lib");
+ next;
}
+
+ # If we found a shlibs file for the SONAME, skip to the next.
+ next SONAME if add_shlibs_dep($soname, $pkg, $lib);
+
+ $missing_wanted_shlibs_info = 1;
+
+ debug(1, "No shlibs+objdump info available, trying next package for $lib");
}
}
+
+ next if not $missing_wanted_shlibs_info;
+
+ # We will only reach this point, if we have found no symbols nor
+ # shlibs files for the given SONAME.
+
+ # This failure is fairly new, try to be kind by
+ # ignoring as many cases that can be safely ignored
+ my $ignore = 0;
+ # 1/ when the lib and the binary are in the same
+ # package
+ my $root_file = guess_pkg_root_dir($file);
+ my $root_lib = guess_pkg_root_dir($lib);
+ $ignore++ if defined $root_file and defined $root_lib
+ and check_files_are_the_same($root_file, $root_lib);
+ # 2/ when the lib is not versioned and can't be
+ # handled by shlibs
+ $ignore++ unless scalar split_soname($soname);
+ # 3/ when we have been asked to do so
+ $ignore++ if $ignore_missing_info;
+ error(g_('no dependency information found for %s ' .
+ "(used by %s)\n" .
+ 'Hint: check if the library actually comes ' .
+ 'from a package.'), $lib, $file)
+ unless $ignore;
+ }
}
# Scan all undefined symbols of the binary and resolve to a
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git
More information about the Reproducible-commits
mailing list