- even if the user is root, they might not have permission to mount
- check for CAP_SYS_ADMIN and unshare --mount before proceeding
- allow one to disable the check with --skip=check/canmount
- this is useful in container environments like docker
# It's possible to be root but not be able to mount anything.
# This is for example the case when running under docker.
# Mounting needs CAP_SYS_ADMIN which might not be available.
#
# We test for CAP_SYS_ADMIN using the capget syscall.
# We cannot use cap_get_proc from sys/capability.h because Perl.
# We don't use capsh because we don't want to depend on libcap2-bin
my $hdrp = pack(
"Li", # __u32 followed by int
$_LINUX_CAPABILITY_VERSION_3, # available since Linux 2.6.26
0 # caps of this process
);
my $datap = pack("LLLLLL", 0, 0, 0, 0, 0, 0); # six __u32
0 == syscall &SYS_capget, $hdrp, $datap
or error "capget failed: $!";
my ($effective, undef) = unpack "LLLLLL", $datap;
if (($effective >> $CAP_SYS_ADMIN) & 1 == 1) {
# we have CAP_SYS_ADMIN, and thus can mount
$options->{canmount} = 1;
} else {
error "root mode requires mount which requires CAP_SYS_ADMIN";
}
# To test whether we can use mount without actually trying to mount
# something we try unsharing the mount namespace. If this is allowed,
# then we are also allowed to mount.
if (0 == system 'unshare --mount true 2>/dev/null') {
$options->{canmount} = 1;
} else {
# if we cannot unshare the mount namespace as root, then we also
# cannot mount
error "root mode requires mount but unshare --mount failed";
}
}
my @architectures = ();
my @architectures = ();
foreach my $archs (@{ $options->{architectures} }) {
foreach my $archs (@{ $options->{architectures} }) {
foreach my $arch (split /[,\s]+/, $archs) {
foreach my $arch (split /[,\s]+/, $archs) {
@ -6123,7 +6175,8 @@ the B<proot> mode is used if the proot binary exists.
This mode directly executes chroot and is the same mode of operation as is
This mode directly executes chroot and is the same mode of operation as is
used by debootstrap. It is the only mode that can directly create a directory
used by debootstrap. It is the only mode that can directly create a directory
chroot with the right permissions. If the chroot directory is not accessible
chroot with the right permissions. If the chroot directory is not accessible
by the _apt user, then apt sandboxing will be automatically disabled.
by the _apt user, then apt sandboxing will be automatically disabled. This mode
needs to be able to mount and thus requires C<SYS_CAP_ADMIN>.
=item B<unshare>
=item B<unshare>
@ -6426,6 +6479,8 @@ Upon startup, several checks are carried out, like:
=item * which mode to use and whether prerequisites are met
=item * which mode to use and whether prerequisites are met
=item * if you are root, check whether you have the ability to mount. This check requires the C<unshare> program from the C<util-linux> package and can be disabled by using B<--skip=check/canmount>.
=item * whether the requested architecture can be executed (requires arch-test) using qemu binfmt_misc support. This requires arch-test and can be disabled using B<--skip=check/qemu>
=item * whether the requested architecture can be executed (requires arch-test) using qemu binfmt_misc support. This requires arch-test and can be disabled using B<--skip=check/qemu>
=item * how the apt sources can be assembled from I<SUITE>, I<MIRROR> and B<--components> and/or from standard input as deb822 or one-line format and whether the required GPG keys exist.
=item * how the apt sources can be assembled from I<SUITE>, I<MIRROR> and B<--components> and/or from standard input as deb822 or one-line format and whether the required GPG keys exist.