Bug#1000421: dpkg-shlibdeps: Wrong minimum version requirement on libc6

2021-11-22 Thread Guillem Jover
Hi!

On Mon, 2021-11-22 at 22:49:43 +0100, Joachim Reichel wrote:
> Package: dpkg-dev
> Version: 1.20.9
> Severity: serious
> Control: affects -1 cppcheck

> dpkg-shlibdeps calculates too low minimum version requirements for cppcheck 
> on libc6 (see bug 1000146).
> 
> To reproduce, build cppcheck 2.6-1 in unstable chroot without cleaning up, 
> e.g., "dpkg-buildpackage -rfakeroot -us -uc".
> 
> $ grep Depends debian/cppcheck/DEBIAN/control
> Depends: libc6 (>= 2.29), [...]
> 
> But running the binary with libc6 2.31 fails with
> 
> cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by cppcheck)
> cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by 
> /usr/lib/x86_64-linux-gnu/libstdc++.so.6)
> cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by 
> /lib/x86_64-linux-gnu/libpthread.so.0)
> 
> I believe that is the case because a certain symbol in the .bss section is 
> ignored (this is the only symbol with 2.32 suffix):
> 
> $ objdump -w -T ./debian/cppcheck/usr/bin/cppcheck | grep 
> __libc_single_threaded
> 004670e0 gDO .bss   0001  GLIBC_2.32  
> __libc_single_threaded
> 
> $ nm -D ./debian/cppcheck/usr/bin/cppcheck | grep __libc_single_threaded
> 004670e0 B __libc_single_threaded@@GLIBC_2.32
> 
> $ dpkg-shlibdeps ./debian/cppcheck/usr/bin/cppcheck; cat debian/substvars
> shlibs:Depends=libc6 (>= 2.29), [...]
> 
> After hacking /usr/share/perl5/Dpkg/Shlibs/Objdump.pm:462 to read
> "defined => ($sect ne '*UND*') && ($sect ne '.bss')"
> (maybe not the right solution, just for demonstration):

Thanks for the investigation! But, I'm afraid that would mean
dpkg-gensymbols missing symbols on the generated .symbols file. Also
marking all such symbols from «.bss» would start emitting tons of
warnings for non-imported symbols, more so in cppcheck case as it is
built with -rdynamic (which exports those).

After some further checking, it seems newer binutils have started
qualifying symbols in copy relocation with the version string, which
the code was not matching (but i386 was not affected f.ex. as it does
not use copy relocations for those). The attached patch seems to work
on amd64, but I'll check tomorrow whether the same applies to other
arches and if they use the same symbol format. But at least it should
improve things and not cause regressions as it will try both formats.

Thanks,
Guillem
From a9c4f1806f1927a2da42712658f4cfdd37f73e50 Mon Sep 17 00:00:00 2001
From: Guillem Jover 
Date: Tue, 23 Nov 2021 02:26:50 +0100
Subject: [PATCH] Dpkg::Shlibs::Objdump: Fix apply_relocations to work with
 versioned symbols
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since at least binutils 2.28 copy relocations for versioned symbols have
the version appended after «@@». We were not taking this into account
which meant these did not match and did not get marked as undefined.

Try both the version qualified symbol and the bare symbol name to cope
with old and new formats.

Closes: #1000421
---
 scripts/Dpkg/Shlibs/Objdump.pm | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/scripts/Dpkg/Shlibs/Objdump.pm b/scripts/Dpkg/Shlibs/Objdump.pm
index 93319d1eb..43d786edd 100644
--- a/scripts/Dpkg/Shlibs/Objdump.pm
+++ b/scripts/Dpkg/Shlibs/Objdump.pm
@@ -488,9 +488,20 @@ sub apply_relocations {
 	# We want to mark as undefined symbols those which are currently
 	# defined but that depend on a copy relocation
 	next if not $sym->{defined};
-	next if not exists $self->{dynrelocs}{$sym->{name}};
-	if ($self->{dynrelocs}{$sym->{name}} =~ /^R_.*_COPY$/) {
+
+my @relocs;
+push @relocs, $sym->{name} . '@@' . $sym->{version} if $sym->{version};
+
+# Symbols that are not versioned, or versioned but linked with old
+# binutils do not have a version appended.
+push @relocs, $sym->{name};
+
+foreach my $reloc (@relocs) {
+next if not exists $self->{dynrelocs}{$reloc};
+next if not $self->{dynrelocs}{$reloc} =~ /^R_.*_COPY$/;
+
 	$sym->{defined} = 0;
+last;
 	}
 }
 }
-- 
2.34.0



Bug#1000421: dpkg-shlibdeps: Wrong minimum version requirement on libc6

2021-11-22 Thread Joachim Reichel
Package: dpkg-dev
Version: 1.20.9
Severity: serious
Control: affects -1 cppcheck

Hi,

dpkg-shlibdeps calculates too low minimum version requirements for cppcheck on 
libc6 (see bug 1000146).

To reproduce, build cppcheck 2.6-1 in unstable chroot without cleaning up, 
e.g., "dpkg-buildpackage -rfakeroot -us -uc".

$ grep Depends debian/cppcheck/DEBIAN/control
Depends: libc6 (>= 2.29), [...]

But running the binary with libc6 2.31 fails with

cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by cppcheck)
cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by 
/usr/lib/x86_64-linux-gnu/libstdc++.so.6)
cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by 
/lib/x86_64-linux-gnu/libpthread.so.0)

I believe that is the case because a certain symbol in the .bss section is 
ignored (this is the only symbol with 2.32 suffix):

$ objdump -w -T ./debian/cppcheck/usr/bin/cppcheck | grep __libc_single_threaded
004670e0 gDO .bss   0001  GLIBC_2.32  
__libc_single_threaded

$ nm -D ./debian/cppcheck/usr/bin/cppcheck | grep __libc_single_threaded
004670e0 B __libc_single_threaded@@GLIBC_2.32

$ dpkg-shlibdeps ./debian/cppcheck/usr/bin/cppcheck; cat debian/substvars
shlibs:Depends=libc6 (>= 2.29), [...]

After hacking /usr/share/perl5/Dpkg/Shlibs/Objdump.pm:462 to read
"defined => ($sect ne '*UND*') && ($sect ne '.bss')"
(maybe not the right solution, just for demonstration):

$ dpkg-shlibdeps ./debian/cppcheck/usr/bin/cppcheck; cat debian/substvars
shlibs:Depends=libc6 (>= 2.32), [...]

(Not really sure about the severity. I believe the resulting bugs in packagage 
using dpkg-shlipdeps are "serious".)

Best regards,
  Joachim

-- Package-specific info:
System tainted due to merged-usr-via-aliased-dirs.

-- System Information:
Debian Release: 11.1
  APT prefers stable-debug
  APT policy: (800, 'stable-debug'), (800, 'stable'), (500, 'stable-security')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.10.0-9-amd64 (SMP w/16 CPU threads)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, 
TAINT_UNSIGNED_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages dpkg-dev depends on:
ii  binutils  2.35.2-2
ii  bzip2 1.0.8-4
ii  libdpkg-perl  1.20.9
ii  make  4.3-4.1
ii  patch 2.7.6-7
ii  perl  5.32.1-4+deb11u2
ii  tar   1.34+dfsg-1
ii  xz-utils  5.2.5-2

Versions of packages dpkg-dev recommends:
ii  build-essential  12.9
ii  clang-11 [c-compiler]1:11.0.1-2
ii  fakeroot 1.25.3-1.1
ii  gcc [c-compiler] 4:10.2.1-1
ii  gcc-10 [c-compiler]  10.2.1-6
ii  gnupg2.2.27-2
ii  gpgv 2.2.27-2
ii  libalgorithm-merge-perl  0.08-3

Versions of packages dpkg-dev suggests:
ii  debian-keyring  2021.07.26

-- no debconf information