diff --git a/qubes/backup.py b/qubes/backup.py index 6335b212b..a337c7721 100644 --- a/qubes/backup.py +++ b/qubes/backup.py @@ -28,6 +28,7 @@ import itertools import logging import os +from pathlib import Path import pwd import shutil import stat @@ -452,6 +453,15 @@ def get_files_to_backup(self): if 0 in [vm.qid for vm in self.vms_for_backup]: local_user = grp.getgrnam("qubes").gr_mem[0] home_dir = pwd.getpwnam(local_user).pw_dir + + # Checking if target is not user home directory in dom0 + if self.target_dir in ["", "~"] or Path( + self.target_dir + ).is_relative_to(home_dir): + raise qubes.exc.QubesException( + "Can not backup dom0 home directory to itself!" + ) + # Home dir should have only user-owned files, so fix it now # to prevent permissions problems - some root-owned files can # left after 'sudo bash' and similar commands diff --git a/qubes/tests/integ/backup.py b/qubes/tests/integ/backup.py index 1837e025c..f902227fa 100644 --- a/qubes/tests/integ/backup.py +++ b/qubes/tests/integ/backup.py @@ -29,6 +29,8 @@ import sys import asyncio +import grp +import pwd import qubes import qubes.backup @@ -198,7 +200,9 @@ def make_backup(self, vms, target=None, expect_failure=False, **kwargs): if target is None: target = self.backupdir try: - backup = qubes.backup.Backup(self.app, vms, **kwargs) + backup = qubes.backup.Backup( + self.app, vms, target_dir=target, **kwargs + ) except qubes.exc.QubesException as e: if not expect_failure: self.fail("QubesException during backup_prepare: %s" % str(e)) @@ -207,7 +211,6 @@ def make_backup(self, vms, target=None, expect_failure=False, **kwargs): if "passphrase" not in kwargs: backup.passphrase = "qubes" - backup.target_dir = target try: self.loop.run_until_complete(backup.backup_do()) @@ -575,6 +578,21 @@ def test_100_backup_dom0_no_restore(self): self.make_backup([self.app.domains[0]]) # TODO: think of some safe way to test restore... + def test_101_backup_dom0_to_dom0_home(self): + # Assure backing up dom0 to dom0 home itself is refused... + local_user = grp.getgrnam("qubes").gr_mem[0] + home_dir = pwd.getpwnam(local_user).pw_dir + with self.assertRaises(qubes.exc.QubesException): + self.make_backup( + [self.app.domains[0]], target=home_dir, expect_failure=True + ) + with self.assertRaises(qubes.exc.QubesException): + self.make_backup( + [self.app.domains[0]], + target=os.path.join(home_dir, "somedir"), + expect_failure=True, + ) + def test_200_restore_over_existing_directory(self): """ Regression test for #1386