Reject ambiguous ESP filesystem UUIDs before root formatting

This commit is contained in:
Codex
2026-10-13 21:51:14 +03:00
parent 8512d1d10b
commit 87003e92c6
2 changed files with 36 additions and 0 deletions
+8
View File
@@ -118,6 +118,14 @@ def partition_plan(request, probe, topo):
fail('ESP must be an existing FAT GPT EFI System Partition')
if not UUID.fullmatch(esp_node.get('uuid') or ''):
fail('ESP filesystem UUID missing')
# fstab resolves the ESP by filesystem UUID. Copies on any surviving
# device are ambiguous even when their GPT partition identities differ.
# Root's old filesystem is replaced before fstab is written.
copies = [path for path, node in topo.nodes.items()
if path not in {root, esp}
and (node.get('uuid') or '').lower() == esp_node['uuid'].lower()]
if copies:
fail('ESP filesystem UUID is ambiguous on surviving devices: ' + ', '.join(sorted(copies)))
# Equal GPT IDs anywhere would make later PARTUUID recovery ambiguous.
ids = [n.get('partuuid', '').lower() for n in topo.nodes.values() if n.get('partuuid')]
if len(ids) != len(set(ids)):
+28
View File
@@ -108,6 +108,23 @@ class PartitionGuardTests(unittest.TestCase):
def test_explicit_partitions_allow_unrelated_mounted_sibling(self):
self.assertEqual(i.validate_request(partition_request(), FakeProbe(partition_topology(sibling_mounted=True))), '/dev/vda2')
def test_duplicate_esp_uuid_on_surviving_devices_is_refused(self):
for location in ('sibling', 'other-disk'):
for copied_uuid in ('ABCD-1234', 'abcd-1234'):
topo = partition_topology()
if location == 'sibling':
copied = topo.nodes['/dev/vda3']
else:
copied = disk('/dev/vdb1', kind='part', pkname='/dev/vdb')
copied.update(start=2048, size=1024**3,
partuuid='bbbbbbbb-cccc-dddd-eeee-000000000001')
topo = topology(topo.nodes['/dev/vda'], disk('/dev/vdb', children=[copied]))
copied = topo.nodes['/dev/vdb1']
copied.update(fstype='vfat', uuid=copied_uuid,
parttype='c12a7328-f81f-11d2-ba4b-00a0c93ec93b')
with self.subTest(location=location, uuid=copied_uuid), self.assertRaisesRegex(i.InstallError, 'ESP filesystem UUID'):
i.validate_request(partition_request(), FakeProbe(topo))
def test_modes_and_confirmations_are_unambiguous(self):
for changes in ({'disk': '/dev/vda'}, {'esp_partition': None}, {'root_fs': 'xfs'},
{'confirm_erase': '/dev/vda'}, {'confirm_format': '/dev/vda3', 'execute': True}):
@@ -251,6 +268,17 @@ class PartitionPipelineTests(unittest.TestCase):
def install(self, runner):
i.install(self.request, runner, self.probe, self.root, 'test-password', io.StringIO())
def test_duplicate_fat_uuid_with_distinct_partuuid_stops_before_root_format(self):
copied = self.probe.topo.nodes['/dev/vda3']
copied.update(fstype='vfat', uuid='ABCD-1234',
parttype='c12a7328-f81f-11d2-ba4b-00a0c93ec93b')
self.assertNotEqual(copied['partuuid'], self.probe.topo.nodes['/dev/vda1']['partuuid'])
runner = FakeRunner(self.root)
with self.assertRaisesRegex(i.InstallError, 'ESP filesystem UUID'):
self.install(runner)
self.assertEqual(runner.calls, [])
self.assertFalse((self.root/'etc/fstab').exists())
def test_existing_mode_formats_root_only_and_records_owned_layout(self):
runner = FakeRunner(self.root)
self.install(runner)