Merge ~mitchellaugustin/curtin/+git/curtin-1:missing-ischroot-mitigation into curtin:master

Proposed by Mitchell Augustin
Status: Merged
Approved by: Dan Bungert
Approved revision: 935c59ff250d1b61d4e092f2fc0c06bcfd9ad991
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~mitchellaugustin/curtin/+git/curtin-1:missing-ischroot-mitigation
Merge into: curtin:master
Diff against target: 82 lines (+52/-2)
2 files modified
curtin/util.py (+4/-2)
tests/unittests/test_util.py (+48/-0)
Reviewer Review Type Date Requested Status
Dan Bungert Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+461730@code.launchpad.net

Commit message

Check to ensure ischroot exists before ChrootableTarget bind mount

Some systems (such as centos7) do not include /usr/bin/ischroot,
which will cause the bind mount to it in ChrootableTarget to fail.

Adding a check for this ensures that the file exists before
mounting and aborts the mount if it does not.

Description of the change

Check to ensure ischroot exists before ChrootableTarget bind mount

To post a comment you must log in.
Revision history for this message
Dan Bungert (dbungert) wrote :

Thanks, I think this is correct.
Do you mind adding a unittest case for that?

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Mitchell Augustin (mitchellaugustin) wrote :

CI passed after I committed the tests, so I went ahead and squashed that commit.

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Dan Bungert (dbungert) wrote :

Nice work!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/curtin/util.py b/curtin/util.py
2index 8be6d20..58ee7e1 100644
3--- a/curtin/util.py
4+++ b/curtin/util.py
5@@ -784,8 +784,10 @@ class ChrootableTarget(object):
6 ischroot_mount_path = paths.target_path(self.target,
7 '/usr/bin/ischroot')
8 true_exists = os.path.isfile(true_mount_path)
9- if true_exists and do_mount(true_mount_path, ischroot_mount_path,
10- opts='--bind'):
11+ ischroot_exists = os.path.isfile(ischroot_mount_path)
12+ both_exist = true_exists and ischroot_exists
13+ if both_exist and do_mount(true_mount_path, ischroot_mount_path,
14+ opts='--bind'):
15 self.umounts.append(ischroot_mount_path)
16
17 return self
18diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
19index 5dcef36..2dd63a7 100644
20--- a/tests/unittests/test_util.py
21+++ b/tests/unittests/test_util.py
22@@ -642,6 +642,7 @@ class TestChrootableTargetIsChrootBehavior(CiTestCase):
23 Assumptions:
24 - /usr/bin/true exists inside the target. (If it does not,
25 util.py does not attempt this bind mount)
26+ - /usr/bin/ischroot exists inside the target.
27
28 Notes:
29 - This test ignores any attempts to bind-mount anything other
30@@ -694,6 +695,53 @@ class TestChrootableTargetIsChrootBehavior(CiTestCase):
31 self.assertEqual(self.true_content, target_ischroot_file)
32
33
34+class TestChrootableTargetIsChrootBehaviorMissingFiles(CiTestCase):
35+ """Test ChrootableTargets do *not* mount ischroot if ischroot or
36+ true do not exist
37+
38+ The test checks to make sure that, in a ChrootableTarget that is
39+ missing /usr/bin/ischroot or /usr/bin/true:
40+ The ischroot->true bind mount is not attempted
41+
42+ Notes:
43+ - This test ignores any attempts to bind-mount anything other
44+ than files, as such mounts are out-of-scope for this test.
45+ """
46+
47+ def setUp(self):
48+ super(TestChrootableTargetIsChrootBehaviorMissingFiles, self).setUp()
49+ self.target = self.tmp_dir()
50+ self.truebin = os.path.join(self.target, 'usr/bin/true')
51+ self.ischrootbin = os.path.join(self.target, 'usr/bin/ischroot')
52+ os.makedirs(os.path.dirname(self.truebin))
53+ self.add_patch('curtin.util.do_mount', 'm_do_mount')
54+ # Patching subp is necessary here since subp calls are attempted
55+ # in ChrootableTarget.__exit__(), which will fail since
56+ # self.allowed_subp=False
57+ self.add_patch('curtin.util.subp', 'm_subp')
58+ self.umounts = []
59+
60+ def mymount(self, src, dst, opts):
61+ print('mymount(src=%s dst=%s, opts=%s)' % (src, dst, opts))
62+ if dst not in self.umounts:
63+ self.umounts.append(dst)
64+ else:
65+ return False
66+
67+ if os.path.isfile(src):
68+ util.write_file(dst, util.load_file(src))
69+ else:
70+ print("Ignoring non-file bind mounts for this test")
71+ return True
72+
73+ def test_chrootable_target_does_not_bind_if_files_missing(self):
74+ target_ischroot = os.path.join(self.target, 'usr/bin/ischroot')
75+
76+ self.m_do_mount.side_effect = self.mymount
77+ with util.ChrootableTarget(self.target) as chroot:
78+ self.assertFalse(target_ischroot in chroot.umounts)
79+
80+
81 class TestChrootableTargetResolvConf(CiTestCase):
82 """Test ChrootableTargets handles target /etc/resolv.conf gracefully"""
83

Subscribers

People subscribed via source and target branches