Bug#1122107: dpkg-shlibdeps: please consider symbol versions from '.gnu.version_r' section

Guillem Jover <[email protected]>
Newsgroups gmane.linux.debian.devel.dpkg.bugs
Message-ID <aTYfqOyiNgK0152D__46792.4584330589$1765154848$gmane$org@thunder.hadrons.org>
Hi!

On Sun, 2025-12-07 at 12:04:40 +0100, Aurelien Jarno wrote:
> Package: dpkg-dev
> Version: 1.22.21
> Severity: wishlist
> Control: block 1122038 by -1

> When symbol versioning is in use, the '.gnu.version_r' section records
> all symbol version requirements declared by the binary for each of its
> shared library dependencies. At runtime, ld.so checks that all symbol
> versions are provided by the target library and refuse to run if a
> required symbol version is missing. 
> 
> On its side, dpkg-shlibdeps computes versioned dependencies only from
> the versions used by the symbols (from the '.dynsym' section).  This
> works fine as long as every symbol version required by the binary is
> also reference by at least one symbol.
> 
> Unfortunately, recent binutils and glibc versions started to use the
> symbol version requirements from section '.gnu.version_r' as ABI flags,
> meaning they do not have symbols associated with them. For instance the
> 'GLIBC_ABI_GNU_TLS' symbol on i386, which triggered the issue in bug
> #1122038. It is not seen by dpkg-shlibdeps, causing the generated
> dependency on libc6 to be lower than what is actually need at runtime,
> and the binary fails to start with older glibc.
> 
> Would it be possible for dpkg-shlibdeps to handle the requirements found
> in the '.gnu.version_r' section? In the above case it means that an
> entry for GLIBC_ABI_GNU_TLS in the '.gnu.version_r' section would match
> the ' GLIBC_ABI_GNU_TLS@GLIBC_ABI_GNU_TLS 2.42' in the symbols file.

Ah, hmm, that's unfortunate. The attached patch seems to fix this for
me (once I removed the workaround from the libc6:i386.symbols file
from the chroot. I've queued the patch for my next push, which will be
part of the 1.23.0 release.

Thanks,
Guillem
0001-Dpkg-Shlibs-Objdump-Object-Add-support-for-Version-R.patch (text/x-diff, 2.5 KB)
From ae5057e32f399759ea13f715e79e305747226fe2 Mon Sep 17 00:00:00 2001
From: Guillem Jover <[email protected]>
Date: Mon, 8 Dec 2025 01:23:23 +0100
Subject: [PATCH] Dpkg::Shlibs::Objdump::Object: Add support for "Version
 References" symbols

New binutils can emit dependencies on specific versions via the
DT_VERNEED tags in the .gnu.version_r section. But these dependencies
are not exposed in the Dynamic Symbol Table.

Inject those dependencies as if they were normal undefined symbols into
the object metadata.

Closes: #1122107
---
 scripts/Dpkg/Shlibs/Objdump/Object.pm | 36 +++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/scripts/Dpkg/Shlibs/Objdump/Object.pm b/scripts/Dpkg/Shlibs/Objdump/Object.pm
index cc635a24e..63e944ffd 100644
--- a/scripts/Dpkg/Shlibs/Objdump/Object.pm
+++ b/scripts/Dpkg/Shlibs/Objdump/Object.pm
@@ -109,6 +109,7 @@ sub parse_objdump_output {
     my ($self, $fh) = @_;
 
     my $section = 'none';
+    my $verneed_lib = undef;
     while (<$fh>) {
         s/\s*$//;
         next if length == 0;
@@ -164,6 +165,12 @@ sub parse_objdump_output {
                     $self->{RPATH} = [ split /:/, $rpath ];
                 }
             }
+        } elsif ($section eq 'verref') {
+            if (/^\s*required from ([^:]*):/) {
+                $verneed_lib = $1;
+            } elsif (/^\s*0x[[:xdigit:]]*\s*0x[[:xdigit:]]*\s*\d*\s*(.*)/) {
+                $self->add_verneed_symbol($verneed_lib, $1);
+            }
         } elsif ($section eq 'program') {
             if (/^\s*INTERP\s+/) {
                 $self->{INTERP} = 1;
@@ -307,6 +314,35 @@ sub apply_relocations {
     }
 }
 
+# Inject the version reference dependency as an undefined symbol into the
+# dynamic symbol information.
+#
+# We do not currently use the $solib name, which would denote a stronger
+# tighter dependency on a specific shared object, but for now this should
+# suffice.
+sub add_verneed_symbol($self, $solib, $name)
+{
+    my $symbol = {
+        name => $name,
+        version => $name,
+        section => '*UND*',
+        dynamic => 1,
+        debug => 0,
+        type => 'O',
+        weak => 0,
+        local => 0,
+        global => 1,
+        visibility => '',
+        hidden => '',
+        defined => 0,
+    };
+
+    # Register artificial symbol.
+    $self->add_dynamic_symbol($symbol);
+
+    return;
+}
+
 sub add_dynamic_symbol {
     my ($self, $symbol) = @_;
     $symbol->{objid} = $symbol->{soname} = $self->get_id();
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.