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

Johannes Schauer Marin Rodrigues josch at debian.org
Sat Jun 4 12:53:44 BST 2022


Hi,

let me put the two relevant lists back into the CC because the members of those
lists can probably give better input than I.

Quoting Guillem Jover (2022-05-28 19:09:10)
> On Wed, 2022-05-18 at 07:26:02 +0200, Johannes Schauer Marin Rodrigues wrote:
> > Package: dpkg
> > Version: 1.21.7
> > Severity: wishlist
> > Tags: patch
> > X-Debbugs-Cc: josch at debian.org
> 
> > 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.
> 
> Hmm right. To me it feels more like a taint flag though. The
> compilation and execution of the host program feels a bit meh, but
> there's certainly no other way to fetch that information otherwise.
> 
> > 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.
> 
> I'm attaching the slightly revised version with few fixes/changes.

Thanks!

> > >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
> 
> > +use File::Temp qw(tmpnam);
> 
> This function is marked as obsolete by POSIX, the File::Temp object
> provides a nice interface that can be used instead, perhaps you used
> it but were hit by ETXTBSY errors? (If so closing the descriptor fixes
> the issue, which is what I've done now.) This also means we do not
> need to cleanup the file as the object will do it on its destructor
> when going out of scope.

Yes, I used tmpnam because I got an error that we cannot execute the file as it
was still being written to. While tmpnam might be obsoleted by POSIX, I think
File::Temp uses its own implementation -- at least the docs suggest that it
does. Anyway, this is not really of any importance.

> > +    spawn(exec => [ debarch_to_gnutriplet(get_host_arch()) . '-gcc', '-x', 'c', '-o', $tmpname, '-' ],
> 
> I added honoring the CC envvar, but can potentially result in building
> for the build instead of host arch, as unfortunately we cannot rely on
> an "external build driver" setting a coherent build environment. So
> should probably go back to hardcoding it, but I'm thinking I should
> move all gcc hardcoding into a new vendor-hook that gets the default
> compiler name.

Yes, by ignoring CC I wanted to make sure that a d/rules cannot choose the
wrong compiler.

> > +    if ($? == 0 && $stdout eq "ok") {
> > +       $fields->{'Can-Execute-Host-Architecture'} = "true";
> > +    } else {
> > +       $fields->{'Can-Execute-Host-Architecture'} = "false";
> 
> I think a taint flag makes more sense. But it has the problem that
> then you might need to check the dpkg version used to see whether
> the check might have been performed, but I'm not sure whether that'd
> be a concern at all? (If its own field would be strongly favored then
> I think it should use the usual "yes"/"no" values used elsewhere.)

I don't have any strong opinion about this. I think I'd be fine with a taint
flag. If any tool wants to read this out in the future, I don't think that
checking the dpkg version is too much to ask for.

Thanks!

cheers, josch
-------------- 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/20220604/0bdcb1e1/attachment.sig>


More information about the Reproducible-builds mailing list