diff --git a/man/systemd-validatefs@.service.xml b/man/systemd-validatefs@.service.xml index 17f3da987d..9597b2ce9d 100644 --- a/man/systemd-validatefs@.service.xml +++ b/man/systemd-validatefs@.service.xml @@ -50,7 +50,7 @@ mounted to a location not matching any of the listed paths the validation check will fail. - user.validatefs.gpt_label: this extended attribute may contain a one + user.validatefs.gpt_label: this extended attribute may contain one or more free-form strings, separated by NUL bytes. If set, all backing partitions of the file system are checked against this list, and if any backing partition's label is not listed, the validation will fail. Note that there may be multiple backing partition in case of Verity setups, which combines a data diff --git a/src/validatefs/validatefs.c b/src/validatefs/validatefs.c index 8140167392..8dfe5073da 100644 --- a/src/validatefs/validatefs.c +++ b/src/validatefs/validatefs.c @@ -146,7 +146,6 @@ static char* validate_fields_gpt_type_uuid_as_string(const ValidateFields *f) { const char *id = gpt_partition_type_uuid_to_string(*u); if (id) (void) strextend(&joined, " (", id, ")"); - } return TAKE_PTR(joined); @@ -241,13 +240,62 @@ static int validate_mount_point(const char *path, const ValidateFields *f) { } _cleanup_free_ char *joined = strv_join(f->mount_point, ", "); - return log_error_errno( SYNTHETIC_ERRNO(EPERM), "File system is supposed to be mounted on one of %s only, but is mounted on %s, refusing.", strna(joined), path); } +static int validate_gpt_label(blkid_probe b, const ValidateFields *f) { + assert(b); + assert(f); + + if (strv_isempty(f->gpt_label)) + return 0; + + const char *v = NULL; + (void) blkid_probe_lookup_value(b, "PART_ENTRY_NAME", &v, /* ret_len= */ NULL); + + if (strv_contains(f->gpt_label, strempty(v))) + return 0; + + _cleanup_free_ char *joined = strv_join(f->gpt_label, "', '"); + return log_error_errno( + SYNTHETIC_ERRNO(EPERM), + "File system is supposed to be placed in a partition with labels '%s' only, but is placed in one labelled '%s', refusing.", + strna(joined), strempty(v)); +} + +static int validate_gpt_type(blkid_probe b, const ValidateFields *f) { + assert(b); + assert(f); + + if (f->n_gpt_type_uuid == 0) + return 0; + + const char *v = NULL; + (void) blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, /* ret_len= */ NULL); + + sd_id128_t id; + if (!v || sd_id128_from_string(v, &id) < 0) { + _cleanup_free_ char *joined = validate_fields_gpt_type_uuid_as_string(f); + return log_error_errno( + SYNTHETIC_ERRNO(EPERM), + "File system is supposed to be placed in a partition of type UUIDs %s only, but has no type, refusing.", + strna(joined)); + } + + FOREACH_ARRAY(u, f->gpt_type_uuid, f->n_gpt_type_uuid) + if (sd_id128_equal(*u, id)) + return 0; + + _cleanup_free_ char *joined = validate_fields_gpt_type_uuid_as_string(f); + return log_error_errno( + SYNTHETIC_ERRNO(EPERM), + "File system is supposed to be placed in a partition of type UUIDs %s only, but has type '%s', refusing.", + strna(joined), SD_ID128_TO_UUID_STRING(id)); +} + static int validate_gpt_metadata_one(sd_device *d, const char *path, const ValidateFields *f) { int r; @@ -288,50 +336,13 @@ static int validate_gpt_metadata_one(sd_device *d, const char *path, const Valid if (!streq_ptr(v, "gpt")) return log_error_errno(SYNTHETIC_ERRNO(EPERM), "File system is supposed to be on a GPT partition table, but is not, refusing."); - if (!strv_isempty(f->gpt_label)) { - v = NULL; - (void) blkid_probe_lookup_value(b, "PART_ENTRY_NAME", &v, /* ret_len= */ NULL); + r = validate_gpt_label(b, f); + if (r < 0) + return r; - if (!strv_contains(f->gpt_label, strempty(v))) { - _cleanup_free_ char *joined = strv_join(f->gpt_label, "', '"); - - return log_error_errno( - SYNTHETIC_ERRNO(EPERM), - "File system is supposed to be placed in a partition with labels '%s' only, but is placed in one labelled '%s', refusing.", - strna(joined), strempty(v)); - } - } - - if (f->n_gpt_type_uuid > 0) { - v = NULL; - (void) blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, /* ret_len= */ NULL); - - sd_id128_t id; - if (!v || sd_id128_from_string(v, &id) < 0) { - _cleanup_free_ char *joined = validate_fields_gpt_type_uuid_as_string(f); - - return log_error_errno( - SYNTHETIC_ERRNO(EPERM), - "File system is supposed to be placed in a partition of type UUIDs %s only, but has no type, refusing.", - strna(joined)); - } - - bool found = false; - FOREACH_ARRAY(u, f->gpt_type_uuid, f->n_gpt_type_uuid) - if (sd_id128_equal(*u, id)) { - found = true; - break; - } - - if (!found) { - _cleanup_free_ char *joined = validate_fields_gpt_type_uuid_as_string(f); - - return log_error_errno( - SYNTHETIC_ERRNO(EPERM), - "File system is supposed to be placed in a partition of type UUIDs %s only, but has type '%s', refusing.", - strna(joined), SD_ID128_TO_UUID_STRING(id)); - } - } + r = validate_gpt_type(b, f); + if (r < 0) + return r; return 0; }