[pve-devel] [PATCH container 2/3] create: open templates as real root

Wolfgang Bumiller w.bumiller at proxmox.com
Mon Jun 26 09:32:59 CEST 2017


When creating an unprivileged container previously couldn't
open template files the unprivileged namespace did not have
access to. This fixes that.

Note that we cannot pass the file via stdin since tar will
then refuse to extract compressed archives automatically.
---
This fixes #1427 but I'd still like uploaded templates (and only
templates) to become world readable, so not marking it in the commit
message.

 src/PVE/LXC/Create.pm | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/PVE/LXC/Create.pm b/src/PVE/LXC/Create.pm
index 5b2e5b9..8b9e876 100644
--- a/src/PVE/LXC/Create.pm
+++ b/src/PVE/LXC/Create.pm
@@ -5,6 +5,7 @@ use warnings;
 use File::Basename;
 use File::Path;
 use Data::Dumper;
+use Fcntl;
 
 use PVE::Storage;
 use PVE::LXC;
@@ -62,7 +63,17 @@ sub restore_archive {
     my ($id_map, $rootuid, $rootgid) = PVE::LXC::parse_id_maps($conf);
     my $userns_cmd = PVE::LXC::userns_command($id_map);
 
-    my $cmd = [@$userns_cmd, 'tar', 'xpf', $archive, '--totals',
+    my $archive_fh;
+    my $tar_input_file = '-';
+    if ($archive ne '-') {
+	sysopen($archive_fh, $archive, O_RDONLY)
+	    or die "failed to open '$archive': $!\n";
+	$tar_input_file = '/proc/self/fd/'.fileno($archive_fh);
+	my $flags = $archive_fh->fcntl(Fcntl::F_GETFD(), 0);
+	$archive_fh->fcntl(Fcntl::F_SETFD(), $flags & ~(Fcntl::FD_CLOEXEC()));
+    }
+
+    my $cmd = [@$userns_cmd, 'tar', 'xpf', $tar_input_file, '--totals',
                @$PVE::LXC::COMMON_TAR_FLAGS,
                '-C', $rootdir];
 
@@ -79,9 +90,11 @@ sub restore_archive {
 	eval { PVE::Tools::run_command($cmd, input => "<&STDIN"); };
     } else {
 	print "extracting archive '$archive'\n";
-	eval { PVE::Tools::run_command($cmd); };
+	eval { PVE::Tools::run_command($cmd, input => '<&'.fileno($archive_fh)); };
     }
-    die $@ if $@ && !$no_unpack_error;
+    my $err = $@;
+    close($archive_fh) if defined $archive_fh;
+    die $err if $err && !$no_unpack_error;
 
     # if arch is set, we do not try to autodetect it
     return if defined($conf->{arch});
-- 
2.11.0





More information about the pve-devel mailing list