@ -29,7 +29,7 @@ use English;
use Getopt::Long;
use Getopt::Long;
use Pod::Usage;
use Pod::Usage;
use File::Copy;
use File::Copy;
use File::Path qw(make_path remove_tree );
use File::Path qw(make_path);
use File::Temp qw(tempfile tempdir);
use File::Temp qw(tempfile tempdir);
use File::Basename;
use File::Basename;
use File::Find;
use File::Find;
@ -3057,15 +3057,14 @@ sub run_cleanup() {
# apt since 1.6 creates the auxfiles directory. If apt inside the
# apt since 1.6 creates the auxfiles directory. If apt inside the
# chroot is older than that, then it will not know how to clean it.
# chroot is older than that, then it will not know how to clean it.
if (-e "$options->{root}/var/lib/apt/lists/auxfiles") {
if (-e "$options->{root}/var/lib/apt/lists/auxfiles") {
remove_tree("$options->{root}/var/lib/apt/lists/auxfiles",
0 == system(
{ error => \my $err });
'rm',
if (@$err) {
'--interactive=never',
for my $diag (@$err) {
'--recursive',
my ($file, $message) = %$diag;
'--preserve-root',
if ($file eq '') { warning "general error: $message"; }
'--one-file-system',
else { warning "problem unlinking $file: $message"; }
"$options->{root}/var/lib/apt/lists/auxfiles"
}
) or error "rm failed: $?";
}
}
}
}
}
@ -3135,15 +3134,11 @@ sub run_cleanup() {
next if $entry eq ".";
next if $entry eq ".";
next if $entry eq "..";
next if $entry eq "..";
warning "deleting files in /tmp: $entry";
warning "deleting files in /tmp: $entry";
remove_tree("$options->{root}/tmp/$entry",
0 == system(
{ error => \my $err });
'rm', '--interactive=never',
if (@$err) {
'--recursive', '--preserve-root',
for my $diag (@$err) {
'--one-file-system', "$options->{root}/tmp/$entry"
my ($file, $message) = %$diag;
) or error "rm failed: $?";
if ($file eq '') { warning "general error: $message"; }
else { warning "problem unlinking $file: $message"; }
}
}
}
}
closedir($dh);
closedir($dh);
}
}
@ -4519,8 +4514,11 @@ sub main() {
$ENV{PATH} = "/usr/sbin:/usr/bin:/sbin:/bin";
$ENV{PATH} = "/usr/sbin:/usr/bin:/sbin:/bin";
}
}
foreach my $tool ('dpkg', 'dpkg-deb', 'apt-get', 'apt-cache', 'apt-config',
foreach my $tool (
'tar') {
'dpkg', 'dpkg-deb', 'apt-get', 'apt-cache',
'apt-config', 'tar', 'rm', 'find',
'env'
) {
my $found = 0;
my $found = 0;
foreach my $path (split /:/, $ENV{PATH}) {
foreach my $path (split /:/, $ENV{PATH}) {
if (-f "$path/$tool" && -x _ ) {
if (-f "$path/$tool" && -x _ ) {
@ -5922,31 +5920,18 @@ sub main() {
# no risk of removing anything important.
# no risk of removing anything important.
$pid = get_unshare_cmd(
$pid = get_unshare_cmd(
sub {
sub {
# File::Path will produce the error "cannot stat initial
# change CWD to chroot directory because find tries to
# working directory" if the working directory cannot be
# chdir to the current directory which might not be
# accessed by the unprivileged unshared user. Thus, we
# accessible by the unshared user:
# first navigate to the parent of the root directory.
# find: Failed to restore initial working directory
chdir "$options->{root}/.."
0 == system('env', "--chdir=$options->{root}", 'find',
or error "unable to chdir() to parent directory of"
$options->{root}, '-mount',
. " $options->{root}: $!";
'-mindepth', '1', '-delete')
remove_tree($options->{root}, { error => \my $err });
or error "rm failed: $?";
if (@$err) {
# ignore failure in case the unshared user doesn't have the
for my $diag (@$err) {
# required permissions -- we attempt again later if
my ($file, $message) = %$diag;
# necessary
if ($file eq '') {
rmdir "$options->{root}";
warning "general error: $message";
} else {
# the unshared process might not have
# sufficient permissions to remove the root
# directory. We attempt its removal later, so
# don't warn if its removal fails now.
if ($file ne $options->{root}) {
warning
"problem unlinking $file: $message";
}
}
}
}
},
},
\@idmap
\@idmap
);
);
@ -5954,8 +5939,7 @@ sub main() {
$? == 0 or error "remove_tree failed";
$? == 0 or error "remove_tree failed";
# in unshare mode, the toplevel directory might've been created in
# in unshare mode, the toplevel directory might've been created in
# a directory that the unshared user cannot change and thus cannot
# a directory that the unshared user cannot change and thus cannot
# delete. If the root directory still exists after remove_tree
# delete. We attempt its removal again outside as the normal user.
# above, we attempt its removal again outside as the normal user.
if (-e $options->{root}) {
if (-e $options->{root}) {
rmdir "$options->{root}"
rmdir "$options->{root}"
or error "cannot rmdir $options->{root}: $!";
or error "cannot rmdir $options->{root}: $!";
@ -5973,7 +5957,7 @@ sub main() {
# be removed.
# be removed.
0 == system('rm', '--interactive=never', '--recursive',
0 == system('rm', '--interactive=never', '--recursive',
'--preserve-root', '--one-file-system', $options->{root})
'--preserve-root', '--one-file-system', $options->{root})
or error "rm failed: $! ";
or error "rm failed: $? ";
} else {
} else {
error "unknown mode: $options->{mode}";
error "unknown mode: $options->{mode}";
}
}