Package: dpkg,debhelper
Severity: wishlist

I'm reporting this feature request against both dpkg and debhelper because
I don't yet know whether it's feasible to implement in debhelper, and
if it's feasible in both places, I don't know which location is where
it *should* be implemented.

Problem statement
-----------------

Debian Policy ยง4.9 requires the build process of a package (defined in
terms of the "required targets" in d/rules) to limit its write accesses
to one of a few allowed locations:

- the unpacked source package being built
- /tmp
- /var/tmp
- $TMPDIR
- (https://bugs.debian.org/942051 points out that some other locations
  like /dev/shm should also be allowed)

This requirement exists as a way to "prevent source package builds
creating and depending on state outside of themselves, thus affecting
multiple independent rebuilds", which seems like a good goal.
To encourage maintainers not to violate this part of Policy, the
production sbuild instances set HOME=/nonexistent.

Many packages run general-purpose tools from their required targets,
particularly if they have build-time tests. These general-purpose tools,
or the libraries they use, frequently read and write locations such as
$HOME and the freedesktop.org (XDG) base directories[1].

The Policy requirement means that packages must either not use these
tools (which is often not feasible, particularly for packages that
*contain* these tools and wish to exercise them in build-time tests),
or set various environment variables (notably $HOME and $XDG_RUNTIME_DIR)
that have the effect of diverting those tools into a temporary directory.

glib2.0 is a good example of the boilerplate that needs to be added to
d/rules to achieve this:

> export HOME=$(CURDIR)/debian/build
> unexport XDG_CACHE_HOME
> unexport XDG_CONFIG_DIRS
> unexport XDG_CONFIG_HOME
> unexport XDG_DATA_HOME
> unexport XDG_DATA_DIRS
> export XDG_RUNTIME_DIR=$(CURDIR)/debian/tmp-xdg-runtime-dir
>
> override_dh_auto_build:
>       mkdir -p debian/tmp-xdg-runtime-dir
>
> override_dh_clean:
>       rm -rf $(CURDIR)/debian/build \
>              $(CURDIR)/debian/tmp-xdg-runtime-dir
>       dh_clean

(Even that isn't perfect. Strictly speaking, the XDG_RUNTIME_DIR ought
to be mode 0700.)

Pasting similar setup code into increasingly many packages as their
Policy violations are discovered does not seem like an ideal solution
when the problem could be solved centrally instead: instead of fighting
against these packages, we could relax the requirement to allow use of
$HOME, while ensuring that $HOME is set to a clean per-build directory.

Proposed solution
-----------------

Either dpkg-buildpackage should:

- create a fake home directory, perhaps debian/.temp-home/home, and set
  $HOME to point to it
- create a fake XDG_RUNTIME_DIR, perhaps debian/.temp-home/run, and set
  $XDG_RUNTIME_DIR to point to it
- delete those directories during cleaning
- either unset the other XDG_* so that their hard-coded defaults are used,
  or set them to known-good values, using the fake $HOME where applicable:
  - XDG_CACHE_HOME: $HOME/.cache or unset
  - XDG_CONFIG_HOME: $HOME/.config or unset
  - XDG_CONFIG_DIRS: /etc/xdg or unset
  - XDG_DATA_HOME: $HOME/.local/share or unset
  - XDG_DATA_DIRS: /usr/local/share:/usr/share or /usr/share or unset

or dh should do all of those in dh(1), and optionally in other dh_*
commands for the benefit of packages that do not use dh.

The production sbuild instances should continue to do the build as a
user whose "official" home directory (getent passwd $user | cut -d: -f6)
is /nonexistent or similar, to guard against packages that use the
home directory from the system passwd database and ignore $HOME
(such as dbus before 1.11.18 and GLib before 2.35.x).

Limitations of proposed solution
--------------------------------

If a package is built in an unclean environment that includes
variables other than those that are reset explicitly (for example with
PYTHONPATH=$HOME/.local/lib/python3), it will continue to read and/or
write the home directory. (Solved by using debuild or sbuild.)

If this is solved in dpkg-buildpackage, and a package is built by invoking
debian/rules directly, it might bypass this solution. (Solved by using
dpkg-buildpackage, or anything that wraps it, like debuild or sbuild.)

If the user specifically *wants* to write outside the build directory,
for example because they are using ccache with cached files in the
default ~/.ccache, it will no longer be sufficient to run "debuild
-ePATH=/usr/lib/ccache:$PATH"; the user will now also have to pass in
an explicit CCACHE_DIR. (Mitigation: they already need to do this for
increasingly many packages that have solved this problem locally, like
glib2.0.)

------

Where do the dpkg and debhelper maintainers think this ought to be solved?

Thanks,
    smcv

Reply via email to