From: Lennart Poettering Date: Mon, 2 Jun 2025 17:27:33 +0000 (+0200) Subject: repart: try harder to find verity-sig partitions for CopyBlocks=auto X-Git-Tag: v258-rc1~368^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d3a6606cea2929c209e7da3118dafc8d29b0ce19;p=thirdparty%2Fsystemd.git repart: try harder to find verity-sig partitions for CopyBlocks=auto verity-sig partitions are not kernel concepts, hence dm-verity won't link them for us from the slaves/ subdir in sysfs. Hence let's instead look up the partition via udev's database. Hence: when we search for the data+verity+verity-sig partitions then search for the first two as usual, but search for the latter by looking up the udev props on the first two, and then following the paths provided therein. Fixes: #34835 --- diff --git a/src/repart/repart.c b/src/repart/repart.c index 5fe195c033d..b8bfeb87e8b 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -7250,6 +7250,82 @@ static int resolve_copy_blocks_auto_candidate( return true; } +static int resolve_copy_blocks_auto_candidate_harder( + dev_t start_devno, + GptPartitionType partition_type, + dev_t restrict_devno, + dev_t *ret_found_devno, + sd_id128_t *ret_uuid) { + + _cleanup_(sd_device_unrefp) sd_device *d = NULL, *nd = NULL; + int r; + + /* A wrapper around resolve_copy_blocks_auto_candidate(), but looks for verity/verity-sig associated + * partitions, too. i.e. if the input is a data or verity partition, will try to find the + * verity/verity-sig partition for it, based on udev metadata. */ + + const char *property; + if (partition_designator_is_verity(partition_type.designator)) + property = "ID_DISSECT_PART_VERITY_DEVICE"; + else if (partition_designator_is_verity_sig(partition_type.designator)) + property = "ID_DISSECT_PART_VERITY_SIG_DEVICE"; + else + goto not_found; + + r = sd_device_new_from_devnum(&d, 'b', start_devno); + if (r < 0) + return log_error_errno(r, "Failed to allocate device object for " DEVNUM_FORMAT_STR ": %m", DEVNUM_FORMAT_VAL(start_devno)); + + const char *node; + r = sd_device_get_property_value(d, property, &node); + if (r == -ENOENT) { + log_debug_errno(r, "Property %s not set on " DEVNUM_FORMAT_STR ", skipping.", property, DEVNUM_FORMAT_VAL(start_devno)); + goto not_found; + } + if (r < 0) + return log_error_errno(r, "Failed to read property %s from device " DEVNUM_FORMAT_STR ": %m", property, DEVNUM_FORMAT_VAL(start_devno)); + + r = sd_device_new_from_devname(&nd, node); + if (ERRNO_IS_NEG_DEVICE_ABSENT(r)) { + log_debug_errno(r, "Device %s referenced in %s property not found, skipping: %m", node, property); + goto not_found; + } + if (r < 0) + return log_error_errno(r, "Failed to allocate device object for '%s': %m", node); + + r = device_in_subsystem(nd, "block"); + if (r < 0) + return log_error_errno(r, "Failed to determine if '%s' is a block device: %m", node); + if (r == 0) { + log_debug("Device referenced by %s property of %s does not refer to block device, refusing.", property, node); + goto not_found; + } + + dev_t found_devno = 0; + r = sd_device_get_devnum(nd, &found_devno); + if (r < 0) + return log_error_errno(r, "Failed to get device number for '%s': %m", node); + + r = resolve_copy_blocks_auto_candidate(found_devno, partition_type, restrict_devno, ret_uuid); + if (r < 0) + return r; + if (r == 0) + goto not_found; + + if (ret_found_devno) + *ret_found_devno = found_devno; + + return 1; + +not_found: + if (ret_found_devno) + *ret_found_devno = 0; + if (ret_uuid) + *ret_uuid = SD_ID128_NULL; + + return 0; +} + static int find_backing_devno( const char *path, const char *root, @@ -7391,7 +7467,7 @@ static int resolve_copy_blocks_auto( return r; if (r > 0) { /* We found a matching one! */ - if (found != 0) + if (found != 0 && found != sl) return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Multiple matching partitions found for partition type %s, refusing.", partition_designator_to_string(type.designator)); @@ -7399,6 +7475,20 @@ static int resolve_copy_blocks_auto( found = sl; found_uuid = u; } + + dev_t harder_devno = 0; + r = resolve_copy_blocks_auto_candidate_harder(sl, type, restrict_devno, &harder_devno, &u); + if (r < 0) + return r; + if (r > 0) { + /* We found a matching one! */ + if (found != 0 && found != harder_devno) + return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), + "Multiple matching partitions found, refusing."); + + found = harder_devno; + found_uuid = u; + } } } else if (errno != ENOENT) return log_error_errno(errno, "Failed open %s: %m", p);