On Wed, Jun 23, 2021 at 02:14:48PM +0200, Fabian Grünbichler wrote:
> On June 22, 2021 2:18 pm, Wolfgang Bumiller wrote:
> > Signed-off-by: Wolfgang Bumiller <[email protected]>

(...)

> > +sub volume_export {
> > +    my (
> > +   $class,
> > +   $scfg,
> > +   $storeid,
> > +   $fh,
> > +   $volname,
> > +   $format,
> > +   $snapshot,
> > +   $base_snapshot,
> > +   $with_snapshots,
> > +    ) = @_;
> > +
> > +    if ($format ne 'btrfs') {
> > +   return PVE::Storage::Plugin::volume_export(@_);
> > +    }
> > +
> > +    die "format 'btrfs' only works on snapshots\n"
> > +   if !defined $snapshot;
> > +
> > +    die "'btrfs' format in incremental mode requires snapshots to be 
> > listed explicitly\n"
> > +   if defined($base_snapshot) && $with_snapshots && ref($with_snapshots) 
> > ne 'ARRAY';
> > +
> > +    my $volume_format = ($class->parse_volname($volname))[6];
> > +
> > +    die "btrfs-sending volumes of type $volume_format ('$volname') is not 
> > supported\n"
> > +   if $volume_format ne 'raw' && $volume_format ne 'subvol';
> 
> the three checks here are the same as in volume_export, maybe they could 
> go into a single export-helper?

we get nicer errors this way, though (and more easily placed in the code
when a user runs into them, since we don't use Carp ;-) )

(...)

> > +
> > +   # Now go through the remaining snapshots (if any)
> > +   foreach my $snap (@snapshots) {
> > +       $class->btrfs_cmd(['property', 'set', "$tmppath/$diskname\@$snap", 
> > 'ro', 'false']);
> > +       PVE::Tools::renameat2(
> > +           -1,
> > +           "$tmppath/$diskname\@$snap",
> > +           -1,
> > +           "$destination\@$snap",
> > +           &PVE::Tools::RENAME_NOREPLACE,
> > +       ) or die "failed to move received snapshot 
> > '$tmppath/$diskname\@$snap'"
> > +           . " into place at '$destination\@$snap' - $!\n";
> > +       eval { $class->btrfs_cmd(['property', 'set', "$destination\@$snap", 
> > 'ro', 'true']) };
> > +       warn "failed to make $destination\@$snap read-only - $!\n" if $@;
> > +   }
> > +    };
> > +    my $err = $@;
> > +
> > +    eval {
> > +   # Cleanup all the received snapshots we did not move into place, so we 
> > can remove the temp
> > +   # directory.
> > +   if ($dh) {
> > +       $dh->rewind;
> > +       while (defined(my $entry = $dh->read)) {
> > +           next if $entry eq '.' || $entry eq '..';
> > +           eval { $class->btrfs_cmd(['subvolume', 'delete', '--', 
> > "$tmppath/$entry"]) };
> > +           warn $@ if $@;
> > +       }
> > +       $dh->close; undef $dh;
> > +   }
> > +   if (!rmdir($tmppath)) {
> > +       warn "failed to remove temporary directory '$tmppath' - $!\n"
> > +   }
> > +    };
> > +    warn $@ if $@;
> > +    if ($err) {
> > +   # clean up if the directory ended up being empty after an error
> > +   rmdir($tmppath);
> > +   die $err;
> > +    }
> 
> I am a bit wary about this (also w.r.t. future btrfs features) - a 
> privileged container can do quite a lot of stuff with btrfs
> 
> - create snapshots from within container
> - set default subvolume
> - set properties
> - ... (the above is what I found in a few minutes without much BTRFS 
>   experience)
> 
> unprivileged containers can do the following
> - create new subvols
> - create new snapshots
> - set ro property
> 
> (same caveat of not looking too much at what else is possible, lots of 
> stuff does not work)
> 
> how do we guarantee that the send stream is not affected in a dangerous 
> fashion by an attacker inside the container?

Shouldn't be dangerous sine it's not recursive anyway.

However, we could just by default disable the corresponding ioctls via
seccomp for unprivileged containers...


_______________________________________________
pve-devel mailing list
[email protected]
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to