buildFHSUserEnv is meant primarily for running 3rd-party software
which is difficult to patch for NixOS. Such software is often built to
run from /opt. Currently, running such a software from FHS environment
is difficult for two reasons:
1. If the 3rd-party software is put into the Nix store via a simple
derivation (with e.g. installPhase = "dpkg-deb -x $src $out"), the
content of /opt directory of that derivation does not appear in the
FHSEnv even if the derivation is specified in targetPkgs. This is
why we change env.nix.
2. If using buildFHSUserEnvChroot and the host system has the /opt
directory, it always gets bind-mounted to the FHSEnv even if some
targetPkgs contain /opt (NB buildFHSUserEnvBubblewrap does not have
this problem). If that directory is not accessible for non-root
users (which is what docker's containerd does with /opt :-(), the
user running the FHSEnv cannot use it.
With the change in chrootenv.c, /opt is not bind-mounted to the
container, but instead created as user-modifiable symlink to
/host/opt (see the init attribute in
build-fhs-userenv/default.nix). If needed, the user can remove this
symlink and create an empty /opt directory which is under his/her
control.
If run as root we were leaking mounts to the parent namespace,
which lead to an error when removing the temporary mountroot.
To fix this we remount the whole tree as private as soon as we created
the new mountenamespace.
continuation of #109595
pkgconfig was aliased in 2018, however, it remained in
all-packages.nix due to its wide usage. This cleans
up the remaining references to pkgs.pkgsconfig and
moves the entry to aliases.nix.
python3Packages.pkgconfig remained unchanged because
it's the canonical name of the upstream package
on pypi.
I hate the thing too even though I made it, and rather just get rid of
it. But we can't do that yet. In the meantime, this brings us more
inline with autoconf and will make it slightly easier for me to write a
pkg-config wrapper, which we need.
Naive concatenation of $LD_LIBRARY_PATH can result in an empty
colon-delimited segment; this tells glibc to load libraries from the
current directory, which is definitely wrong, and may be a security
vulnerability if the current directory is untrusted. (See #67234, for
example.) Fix this throughout the tree.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
To avoid symlink loops to /host in nested chrootenvs we need to remove
one level of indirection. This is also what's generally expected of
/host contents.
* Remove unused argument from pivot_root;
* Factor out tmpdir creation into a separate function;
* Remove unused fstype from bind mount;
* Use unlink instead of a treewalk to remove empty temporary directory.
The problem with stacking chrootenv before was that CLONE_NEWUSER cannot
be used when a child uses chroot. So instead of that we use pivot_root
which replaces root in the whole namespace. This requires our new root
to be an actual fs so we mount tmpfs.
glibc 2.27 (and possibly other versions) can't handle an `nopenfd` value larger than 2^19 in `ntfw`, which is problematic if you've set the maximum number of fds per process to a value higher than that.
Changes:
* doesn't handle root user separately
* doesn't chdir("/") which makes using it seamless
* only bind mounts, doesn't symlink (i.e. files)
Incidentally, fixes #33106.
It's about two times shorter than the previous version, and much
easier to read/follow through. It uses GLib quite heavily, along with
RAII (available in GCC/Clang).
* Wrap LEN macro in parantheses
* Drop env_filter in favor of stateful environ_blacklist_filter,
use execvp instead of execvpe, don't explicitly use environ
* Add argument error logging wherever it makes sense
* Drop strjoin in favor of asprintf
* char* -> const char* where appropriate
* Handle stat errors
* Print user messages with fputs, not errorf
* Abstract away is_str_in (previously bind_blacklisted)
* Cleanup temporary directory on error
* Some minor syntactic and naming changes
Thanks to Jörg Thalheim and Tuomas Tynkkynen for the code review!
The `DISPLAY` environment variable is propagated into chroots built with
`buildFHSUserEnv`, but currently the `XAUTHORITY` variable is not. When
the latter is set, its value is usually necessary in order to connect to
the X server identified by the former.
This matters for users running gdm3, for example, who have `XAUTHORITY`
set to something like `/run/user/1000/gdm/Xauthority` instead of the X
default of `~/.Xauthority`, which doesn't exist in that setup.
Fixes #21532.