image-info: mount partitions in correct order when analysing image
image-info's code which analysed image with multiple partitions was not correctly working with more than two partitions, which had to be the root '/' and EFI partition '/boot/efi'. The consequence was that SELinux labels on paths which were mounted incorrectly could have been reported as incorrect. Modify `append_partitions()` to first read the fstab entries and then mount all partitions using their UUID in the correct order. Only then analyze the image filesystem tree. Regenerate affected image test cases. Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
parent
972515ad84
commit
aed3bf785c
3 changed files with 36 additions and 75 deletions
|
|
@ -10795,7 +10795,6 @@
|
||||||
},
|
},
|
||||||
"rpm-verify": {
|
"rpm-verify": {
|
||||||
"changed": {
|
"changed": {
|
||||||
"/boot": ".M.......",
|
|
||||||
"/etc/chrony.conf": "S.5....T.",
|
"/etc/chrony.conf": "S.5....T.",
|
||||||
"/etc/dnf/plugins/product-id.conf": "..5....T.",
|
"/etc/dnf/plugins/product-id.conf": "..5....T.",
|
||||||
"/etc/dnf/plugins/subscription-manager.conf": "..5....T.",
|
"/etc/dnf/plugins/subscription-manager.conf": "..5....T.",
|
||||||
|
|
@ -10814,34 +10813,9 @@
|
||||||
"/var/spool/anacron/cron.monthly": ".M.......",
|
"/var/spool/anacron/cron.monthly": ".M.......",
|
||||||
"/var/spool/anacron/cron.weekly": ".M......."
|
"/var/spool/anacron/cron.weekly": ".M......."
|
||||||
},
|
},
|
||||||
"missing": [
|
"missing": []
|
||||||
"/boot/efi",
|
|
||||||
"/boot/efi/EFI",
|
|
||||||
"/boot/efi/EFI/BOOT",
|
|
||||||
"/boot/efi/EFI/BOOT/BOOTAA64.EFI",
|
|
||||||
"/boot/efi/EFI/BOOT/fbaa64.efi",
|
|
||||||
"/boot/efi/EFI/redhat",
|
|
||||||
"/boot/efi/EFI/redhat",
|
|
||||||
"/boot/efi/EFI/redhat/BOOTAA64.CSV",
|
|
||||||
"/boot/efi/EFI/redhat/fonts",
|
|
||||||
"/boot/efi/EFI/redhat/grubaa64.efi",
|
|
||||||
"/boot/efi/EFI/redhat/mmaa64.efi",
|
|
||||||
"/boot/efi/EFI/redhat/shim.efi",
|
|
||||||
"/boot/efi/EFI/redhat/shimaa64-redhat.efi",
|
|
||||||
"/boot/efi/EFI/redhat/shimaa64.efi",
|
|
||||||
"/boot/grub2",
|
|
||||||
"/boot/grub2/grubenv",
|
|
||||||
"/boot/loader/entries"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"selinux": {
|
"selinux": {
|
||||||
"context-mismatch": [
|
|
||||||
{
|
|
||||||
"actual": "unconfined_u:object_r:unlabeled_t:s0",
|
|
||||||
"expected": "system_u:object_r:boot_t:s0",
|
|
||||||
"filename": "/boot"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"policy": {
|
"policy": {
|
||||||
"SELINUX": "enforcing",
|
"SELINUX": "enforcing",
|
||||||
"SELINUXTYPE": "targeted"
|
"SELINUXTYPE": "targeted"
|
||||||
|
|
|
||||||
|
|
@ -10835,7 +10835,6 @@
|
||||||
},
|
},
|
||||||
"rpm-verify": {
|
"rpm-verify": {
|
||||||
"changed": {
|
"changed": {
|
||||||
"/boot": ".M.......",
|
|
||||||
"/etc/chrony.conf": "S.5....T.",
|
"/etc/chrony.conf": "S.5....T.",
|
||||||
"/etc/dnf/plugins/product-id.conf": "..5....T.",
|
"/etc/dnf/plugins/product-id.conf": "..5....T.",
|
||||||
"/etc/dnf/plugins/subscription-manager.conf": "..5....T.",
|
"/etc/dnf/plugins/subscription-manager.conf": "..5....T.",
|
||||||
|
|
@ -10857,34 +10856,10 @@
|
||||||
"/var/spool/anacron/cron.weekly": ".M......."
|
"/var/spool/anacron/cron.weekly": ".M......."
|
||||||
},
|
},
|
||||||
"missing": [
|
"missing": [
|
||||||
"/boot/efi",
|
|
||||||
"/boot/efi/EFI",
|
|
||||||
"/boot/efi/EFI/BOOT",
|
|
||||||
"/boot/efi/EFI/BOOT/BOOTAA64.EFI",
|
|
||||||
"/boot/efi/EFI/BOOT/fbaa64.efi",
|
|
||||||
"/boot/efi/EFI/redhat",
|
|
||||||
"/boot/efi/EFI/redhat",
|
|
||||||
"/boot/efi/EFI/redhat/BOOTAA64.CSV",
|
|
||||||
"/boot/efi/EFI/redhat/fonts",
|
|
||||||
"/boot/efi/EFI/redhat/grubaa64.efi",
|
|
||||||
"/boot/efi/EFI/redhat/mmaa64.efi",
|
|
||||||
"/boot/efi/EFI/redhat/shim.efi",
|
|
||||||
"/boot/efi/EFI/redhat/shimaa64-redhat.efi",
|
|
||||||
"/boot/efi/EFI/redhat/shimaa64.efi",
|
|
||||||
"/boot/grub2",
|
|
||||||
"/boot/grub2/grubenv",
|
|
||||||
"/boot/loader/entries",
|
|
||||||
"/etc/yum.repos.d/redhat-rhui.repo"
|
"/etc/yum.repos.d/redhat-rhui.repo"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"selinux": {
|
"selinux": {
|
||||||
"context-mismatch": [
|
|
||||||
{
|
|
||||||
"actual": "unconfined_u:object_r:unlabeled_t:s0",
|
|
||||||
"expected": "system_u:object_r:boot_t:s0",
|
|
||||||
"filename": "/boot"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"policy": {
|
"policy": {
|
||||||
"SELINUX": "enforcing",
|
"SELINUX": "enforcing",
|
||||||
"SELINUXTYPE": "targeted"
|
"SELINUXTYPE": "targeted"
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import errno
|
||||||
import functools
|
import functools
|
||||||
import glob
|
import glob
|
||||||
import mimetypes
|
import mimetypes
|
||||||
|
import operator
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
|
@ -1812,44 +1813,55 @@ def append_filesystem(report, tree, *, is_ostree=False):
|
||||||
print("EFI partition", file=sys.stderr)
|
print("EFI partition", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
def partition_is_esp(partition):
|
|
||||||
return partition["type"] == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
|
|
||||||
|
|
||||||
|
|
||||||
def find_esp(partitions):
|
|
||||||
for i, p in enumerate(partitions):
|
|
||||||
if partition_is_esp(p):
|
|
||||||
return p, i
|
|
||||||
return None, 0
|
|
||||||
|
|
||||||
|
|
||||||
def append_partitions(report, device, loctl):
|
def append_partitions(report, device, loctl):
|
||||||
partitions = report["partitions"]
|
partitions = report["partitions"]
|
||||||
esp, esp_id = find_esp(partitions)
|
|
||||||
|
|
||||||
with contextlib.ExitStack() as cm:
|
with contextlib.ExitStack() as cm:
|
||||||
|
# open each partition as a loop device
|
||||||
devices = {}
|
devices = {}
|
||||||
|
device_idx_by_part_uuid = {}
|
||||||
for n, part in enumerate(partitions):
|
for n, part in enumerate(partitions):
|
||||||
start, size = part["start"], part["size"]
|
start, size = part["start"], part["size"]
|
||||||
dev = cm.enter_context(loop_open(loctl, device, offset=start, size=size))
|
dev = cm.enter_context(loop_open(loctl, device, offset=start, size=size))
|
||||||
devices[n] = dev
|
devices[n] = dev
|
||||||
read_partition(dev, part)
|
read_partition(dev, part)
|
||||||
|
if part["uuid"]:
|
||||||
|
device_idx_by_part_uuid[part["uuid"].upper()] = n
|
||||||
|
|
||||||
|
# find partition with fstab and read it
|
||||||
|
fstab = []
|
||||||
for n, part in enumerate(partitions):
|
for n, part in enumerate(partitions):
|
||||||
if not part["fstype"]:
|
if not part["fstype"]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
with mount(devices[n]) as tree:
|
with mount(devices[n]) as tree:
|
||||||
if esp and os.path.exists(f"{tree}/boot/efi"):
|
if os.path.exists(f"{tree}/etc/fstab"):
|
||||||
with mount_at(devices[esp_id], f"{tree}/boot/efi", options=['umask=077']):
|
fstab.extend(read_fstab(tree))
|
||||||
append_filesystem(report, tree)
|
break
|
||||||
# situation when /boot is on a separate partition
|
# sort the fstab entries by the mountpoint
|
||||||
elif esp and os.path.exists(f"{tree}/efi"):
|
fstab = sorted(fstab, key=operator.itemgetter(1))
|
||||||
with mount_at(devices[esp_id], f"{tree}/efi", options=['umask=077']):
|
|
||||||
append_filesystem(report, tree)
|
# mount all partitions to ther respective mount points
|
||||||
else:
|
root_tree = ""
|
||||||
append_filesystem(report, tree)
|
for n, fstab_entry in enumerate(fstab):
|
||||||
|
part_uuid = fstab_entry[0].split("=")[1].upper()
|
||||||
|
part_device = devices[device_idx_by_part_uuid[part_uuid]]
|
||||||
|
part_mountpoint = fstab_entry[1]
|
||||||
|
part_fstype = fstab_entry[2]
|
||||||
|
part_options = fstab_entry[3].split(",")
|
||||||
|
|
||||||
|
# the first mount point should be root
|
||||||
|
if n == 0:
|
||||||
|
if part_mountpoint != "/":
|
||||||
|
raise RuntimeError("The first mountpoint in sorted fstab entries is not '/'")
|
||||||
|
root_tree = cm.enter_context(mount(part_device))
|
||||||
|
continue
|
||||||
|
|
||||||
|
cm.enter_context(mount_at(part_device, f"{root_tree}{part_mountpoint}", options=part_options, extra=["-t", part_fstype]))
|
||||||
|
|
||||||
|
if not root_tree:
|
||||||
|
raise RuntimeError("The root filesystem tree is not mounted")
|
||||||
|
|
||||||
|
append_filesystem(report, root_tree)
|
||||||
|
|
||||||
|
|
||||||
def analyse_image(image):
|
def analyse_image(image):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue