Fwd: Bug#1011191: dpkg: let buildinfo record whether host architecture binaries can be executed when cross-compiling

Johannes Schauer Marin Rodrigues josch at debian.org
Wed May 18 06:29:53 BST 2022


Hi,

sorry, I forgot to X-Debbugs-CC the reproducible builds mailing list. Fixing
this now with forwarding the message I sent to #1011191.

Thanks!

cheers, josch

Forwarded message from Johannes Schauer Marin Rodrigues (2022-05-18 07:26:02):
> Package: dpkg
> Version: 1.21.7
> Severity: wishlist
> Tags: patch
> X-Debbugs-Cc: josch at debian.org
> 
> Hi,
> 
> when cross compiling, one property of the build system that can
> influence the contents of the generate binary packages is whether or not
> the host architecture can be executed. While some platforms can natively
> execute others (like amd64 can execute i386), other combinations are
> more surprising. When installing the qemu-user-static package on a
> system with binfmt-support, then foreign architecture binaries for all
> architectures qemu supports will suddenly become executable. This is
> especially tricky because this will also transparently affect chroot
> builds with sbuild and neither schroot nor unshare isolation can prevent
> the emulation from happening. The only ways to stop automatic emulation
> are uninstalling qemu-user-static on the outside of the build chroot,
> writing 0 to /proc/sys/fs/binfmt_misc/qemu-$arch or running the build
> with QEMU_VERSION=1 (unreliable). Since transparent foreign architecture
> emulation is easily present on a developer's machine and thus
> influencing the build (even when done inside a chroot) it would be
> useful to record whether or not foreign architecture binaries can be
> executed in the buildinfo file.
> 
> I attached a proof-of-concept patch that does exactly that. Since we
> cannot rely on arch-test being installed in the build environment, this
> approach cross compiles a small true.c executable for the host
> architecture. This should always work because gcc is build-essential.
> The binary outputs a small string instead of just relying on the exit
> code to guard against QEMU_VERSION=1 "disabling" of emulation. The field
> 'Can-Execute-Host-Architecture is only added when cross-compiling, i.e
> when host and build architectures mismatch.
> 
> Thanks!
> 
> cheers, josch
-------------- next part --------------
>From 62179358b57d09fc8c6bb7a59deb128c67cbe522 Mon Sep 17 00:00:00 2001
From: Johannes Schauer Marin Rodrigues <josch at mister-muffin.de>
Date: Wed, 18 May 2022 07:11:39 +0200
Subject: [PATCH] dpkg-genbuildinfo: when cross-compiling add
 Can-Execute-Host-Architecture field

---
 scripts/dpkg-genbuildinfo.pl | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/scripts/dpkg-genbuildinfo.pl b/scripts/dpkg-genbuildinfo.pl
index e05fce048..a296a7314 100755
--- a/scripts/dpkg-genbuildinfo.pl
+++ b/scripts/dpkg-genbuildinfo.pl
@@ -28,13 +28,14 @@ use warnings;
 use List::Util qw(any);
 use Cwd;
 use File::Basename;
+use File::Temp qw(tmpnam);
 use POSIX qw(:fcntl_h :locale_h strftime);
 
 use Dpkg ();
 use Dpkg::Gettext;
 use Dpkg::Checksums;
 use Dpkg::ErrorHandling;
-use Dpkg::Arch qw(get_build_arch get_host_arch debarch_eq);
+use Dpkg::Arch qw(get_build_arch get_host_arch debarch_eq debarch_to_gnutriplet);
 use Dpkg::Build::Types;
 use Dpkg::Build::Info qw(get_build_env_allowed);
 use Dpkg::BuildOptions;
@@ -46,6 +47,8 @@ use Dpkg::Control;
 use Dpkg::Changelog::Parse;
 use Dpkg::Deps;
 use Dpkg::Dist::Files;
+use Dpkg::Exit qw(push_exit_handler);
+use Dpkg::IPC;
 use Dpkg::Lock;
 use Dpkg::Version;
 use Dpkg::Vendor qw(get_current_vendor run_vendor_hook);
@@ -455,6 +458,33 @@ $fields->{'Installed-Build-Depends'} = collect_installed_builddeps($control);
 
 $fields->{'Environment'} = "\n" . cleansed_environment();
 
+if (get_host_arch() ne $fields->{'Build-Architecture'}) {
+    # if we are cross-compiling, record whether it was possible to execute the
+    # host architecture by cross-compiling and executing a small host-arch
+    # binary
+
+    my $tmpname = tmpnam();
+    push_exit_handler(sub { unlink($tmpname) });
+    my ($stdout, $stderr) = ('', '');
+    my $testprog = 'int main(){write(1,"ok",2);return 0;}';
+    spawn(exec => [ debarch_to_gnutriplet(get_host_arch()) . '-gcc', '-x', 'c', '-o', $tmpname, '-' ],
+       wait_child => 1, nocheck => 1,
+       to_string => \$stdout,
+       error_to_string => \$stderr,
+       from_string => \$testprog);
+    if ($?) {
+       print { *STDOUT } $stdout;
+       print { *STDERR } $stderr;
+       subprocerr("gcc -x c -");
+    }
+    spawn(exec => [ $tmpname ], error_to_file => '/dev/null', 'to_string' => \$stdout, wait_child => 1, nocheck => 1);
+    if ($? == 0 && $stdout eq "ok") {
+       $fields->{'Can-Execute-Host-Architecture'} = "true";
+    } else {
+       $fields->{'Can-Execute-Host-Architecture'} = "false";
+    }
+}
+
 # Generate the buildinfo filename.
 if ($stdout) {
     # Nothing to do.
-- 
2.35.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: signature
URL: <http://alioth-lists.debian.net/pipermail/reproducible-builds/attachments/20220518/673a5f44/attachment.sig>


More information about the Reproducible-builds mailing list