Package: perl
Version: 5.30.3-4
Severity: important
User: de...@kali.org
Usertags: origin-kali
X-Debbugs-Cc: debian-d...@lists.debian.org
Control: found -1 5.32.0-2

In Kali, any source package build started to fail with a mysterious
error:
> dpkg-buildpackage: error: dpkg-source -b . subprocess returned exit status 127

After quite some investigation, I tracked this down to perl exiting with
that error code in the middle of an eval statement that should have failed:
https://sources.debian.org/src/dpkg/1.20.5/scripts/Dpkg/Vendor.pm/#L166

The $name tried is "Kali" and we don't ship any Dpkg::Vendor::Kali. The
code should fallback to Dpkg::Vendor::Debian and this works a few times
but after multiples calls, at some point it no longer works and the
require statement in the eval block just never returns, it seems to crash
the perl interpreter.

You can easily reproduce this on an up-to-date testing or unstable system
with dpkg 1.20.5 (that version is failing, the former version we had
in Kali was 1.19.7 and it was not triggering this issue):

$ sudo tee /etc/dpkg/origins/kali >/dev/null <<END
> Vendor: Kali
> Vendor-URL: https://www.kali.org/
> Parent: debian
> Bugs: https://bugs.kali.org/
> END
$ sudo ln -sf kali /etc/dpkg/origins/default
$ apt source hello
[...]
$ cd hello-*
$ dpkg-buildpackage -S
[...]
 dpkg-source -b .
dpkg-source: info: using source format '3.0 (quilt)'
dpkg-source: info: building hello using existing ./hello_2.10.orig.tar.gz
dpkg-buildpackage: error: dpkg-source -b . subprocess returned exit status 127


Note that I only reproduce this with "3.0 (quilt)" source packages. Native
packages have different code paths likely involving fewer calls to
run_vendor_hook() and the problem can't be reproduced with such a source
package.

I can also reproduce the bug with version 5.32.0-2 available in
experimental.

FWIW I'm working around this issue in Kali with the attached patch but
this really smells like a bug in perl, thus I'm reporting it here.

Guillem, I believe the attached patch should be applied to dpkg in any
case as it's a small optimization that avoids running the evaled code too
often.

-- System Information:
Debian Release: bullseye/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (500, 
'oldstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.7.0-3-amd64 (SMP w/4 CPU threads)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages perl depends on:
ii  dpkg               1.20.5
ii  libperl5.30        5.30.3-4
ii  perl-base          5.30.3-4
ii  perl-modules-5.30  5.30.3-4

Versions of packages perl recommends:
ii  netbase  6.1

Versions of packages perl suggests:
pn  libtap-harness-archive-perl  <none>
ii  libterm-readline-gnu-perl    1.36-2+b1
ii  make                         4.3-4
ii  perl-doc                     5.30.3-4

-- no debconf information
>From 75631da697b9d2c5b3ff2c54bc225fc55d3ab9c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Hertzog?= <raph...@offensive-security.com>
Date: Thu, 3 Sep 2020 11:26:58 +0200
Subject: [PATCH] Work-around a perl crash during any package build

Somehow perl doesn't like the multiple execution of the eval code that tries
to "require Dpkg::Vendor::Kali;" and at some point perl just exits with
an error code of 127 when it tries to execute this line of code. When
it happens, the eval doesn't return.

To avoid the multiple execution of this code, we cache the result of the
lookup made on the parent vendor as the good result for the current
vendor as well.

There's likely some bug in perl here and somehow the update from
dpkg 1.19.7 to dpkg 1.20.5 started to trigger that bug.
---
 scripts/Dpkg/Vendor.pm | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/scripts/Dpkg/Vendor.pm b/scripts/Dpkg/Vendor.pm
index 196159156..5b8f66fd8 100644
--- a/scripts/Dpkg/Vendor.pm
+++ b/scripts/Dpkg/Vendor.pm
@@ -174,10 +174,12 @@ sub get_vendor_object {
 
     my $info = get_vendor_info($vendor);
     if (defined $info and defined $info->{'Parent'}) {
-        return get_vendor_object($info->{'Parent'});
+        $obj = get_vendor_object($info->{'Parent'});
     } else {
-        return get_vendor_object('Default');
+        $obj = get_vendor_object('Default');
     }
+    $OBJECT_CACHE{$vendor} = $obj;
+    return $obj;
 }
 
 =item run_vendor_hook($hookid, @params)
-- 
2.28.0

Reply via email to