From 510e9666777e90131d451ae13f38fa9c91e93ec9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 14 May 2025 11:30:52 +0200 Subject: [PATCH] validatefs: split out validate_fields_check() into three functions Just some basic refactoring, no actual code changes --- src/validatefs/validatefs.c | 204 ++++++++++++++++++++---------------- 1 file changed, 115 insertions(+), 89 deletions(-) diff --git a/src/validatefs/validatefs.c b/src/validatefs/validatefs.c index 8cc595932e8..fa8784cdf5d 100644 --- a/src/validatefs/validatefs.c +++ b/src/validatefs/validatefs.c @@ -181,115 +181,141 @@ static int validate_fields_read(int fd, ValidateFields *ret) { return r; } -static int validate_fields_check(int fd, const char *path, const ValidateFields *f) { +static int validate_mount_point(const char *path, const ValidateFields *f) { + assert(path); + assert(f); + + if (strv_isempty(f->mount_point)) + return 0; + + bool good = false; + + STRV_FOREACH(i, f->mount_point) { + _cleanup_free_ char *jj = NULL; + const char *j; + + if (arg_root) { + jj = path_join(arg_root, *i); + if (!jj) + return log_oom(); + + j = jj; + } else + j = *i; + + if (path_equal(path, j)) { + good = true; + break; + } + } + + if (!good) { + _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); + } + + return 0; +} + +static int validate_gpt_metadata(int fd, const char *path, const ValidateFields *f) { int r; assert(fd >= 0); assert(path); assert(f); - if (!strv_isempty(f->mount_point)) { - bool good = false; + if (!f->gpt_label && sd_id128_is_null(f->gpt_type_uuid)) + return 0; - STRV_FOREACH(i, f->mount_point) { - _cleanup_free_ char *jj = NULL; - const char *j; + _cleanup_(sd_device_unrefp) sd_device *d = NULL; + r = block_device_new_from_fd(fd, BLOCK_DEVICE_LOOKUP_ORIGINATING|BLOCK_DEVICE_LOOKUP_BACKING, &d); + if (r < 0) + return log_error_errno(r, "Failed to find block device backing '%s': %m", path); - if (arg_root) { - jj = path_join(arg_root, *i); - if (!jj) - return log_oom(); + _cleanup_close_ int block_fd = sd_device_open(d, O_RDONLY|O_CLOEXEC|O_NONBLOCK); + if (block_fd < 0) + return log_error_errno(block_fd, "Failed to open block device backing '%s': %m", path); - j = jj; - } else - j = *i; + _cleanup_(blkid_free_probep) blkid_probe b = blkid_new_probe(); + if (!b) + return log_oom(); - if (path_equal(path, j)) { - good = true; - break; - } - } + errno = 0; + r = blkid_probe_set_device(b, block_fd, 0, 0); + if (r != 0) + return log_error_errno(errno_or_else(ENOMEM), "Failed to set up block device prober for '%s': %m", path); + + (void) blkid_probe_enable_superblocks(b, 1); + (void) blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_LABEL); + (void) blkid_probe_enable_partitions(b, 1); + (void) blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS); + + errno = 0; + r = blkid_do_safeprobe(b); + if (r == _BLKID_SAFEPROBE_ERROR) + return log_error_errno(errno_or_else(EIO), "Failed to probe block device of '%s': %m", path); + if (r == _BLKID_SAFEPROBE_AMBIGUOUS) + return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Found multiple file system labels on block device '%s'.", path); + if (r == _BLKID_SAFEPROBE_NOT_FOUND) + return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Found no file system label on block device '%s'.", path); + + assert(r == _BLKID_SAFEPROBE_FOUND); + + const char *v = NULL; + (void) blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, /* ret_len= */ NULL); + 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 (f->gpt_label) { + v = NULL; + (void) blkid_probe_lookup_value(b, "PART_ENTRY_NAME", &v, /* ret_len= */ NULL); + + if (!streq(f->gpt_label, strempty(v))) + return log_error_errno( + SYNTHETIC_ERRNO(EPERM), + "File system is supposed to be placed in a partition with label '%s' only, but is placed in one labelled '%s', refusing.", + f->gpt_label, strempty(v)); + } - if (!good) { - _cleanup_free_ char *joined = strv_join(f->mount_point, ", "); + if (!sd_id128_is_null(f->gpt_type_uuid)) { + v = NULL; + (void) blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, /* ret_len= */ NULL); + sd_id128_t id = SD_ID128_NULL; + if (!v || sd_id128_from_string(v, &id) < 0) 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); - } + "File system is supposed to be placed in a partition of type UUID '%s' only, but has no type, refusing.", + SD_ID128_TO_UUID_STRING(f->gpt_type_uuid)); + + if (!sd_id128_equal(f->gpt_type_uuid, id)) + return log_error_errno( + SYNTHETIC_ERRNO(EPERM), + "File system is supposed to be placed in a partition of type UUID '%s' only, but has type '%s', refusing.", + SD_ID128_TO_UUID_STRING(f->gpt_type_uuid), SD_ID128_TO_UUID_STRING(id)); } - if (f->gpt_label || !sd_id128_is_null(f->gpt_type_uuid)) { - _cleanup_(sd_device_unrefp) sd_device *d = NULL; + return 0; +} - r = block_device_new_from_fd(fd, BLOCK_DEVICE_LOOKUP_ORIGINATING|BLOCK_DEVICE_LOOKUP_BACKING, &d); - if (r < 0) - return log_error_errno(r, "Failed to find block device backing '%s': %m", path); - - _cleanup_close_ int block_fd = sd_device_open(d, O_RDONLY|O_CLOEXEC|O_NONBLOCK); - if (block_fd < 0) - return log_error_errno(block_fd, "Failed to open block device backing '%s': %m", path); - - _cleanup_(blkid_free_probep) blkid_probe b = blkid_new_probe(); - if (!b) - return log_oom(); - - errno = 0; - r = blkid_probe_set_device(b, block_fd, 0, 0); - if (r != 0) - return log_error_errno(errno_or_else(ENOMEM), "Failed to set up block device prober for '%s': %m", path); - - (void) blkid_probe_enable_superblocks(b, 1); - (void) blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_LABEL); - (void) blkid_probe_enable_partitions(b, 1); - (void) blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS); - - errno = 0; - r = blkid_do_safeprobe(b); - if (r == _BLKID_SAFEPROBE_ERROR) - return log_error_errno(errno_or_else(EIO), "Failed to probe block device of '%s': %m", path); - if (r == _BLKID_SAFEPROBE_AMBIGUOUS) - return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Found multiple file system labels on block device '%s'.", path); - if (r == _BLKID_SAFEPROBE_NOT_FOUND) - return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Found no file system label on block device '%s'.", path); - - assert(r == _BLKID_SAFEPROBE_FOUND); - - const char *v = NULL; - (void) blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, /* ret_len= */ NULL); - 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 (f->gpt_label) { - v = NULL; - (void) blkid_probe_lookup_value(b, "PART_ENTRY_NAME", &v, /* ret_len= */ NULL); - - if (!streq(f->gpt_label, strempty(v))) - return log_error_errno( - SYNTHETIC_ERRNO(EPERM), - "File system is supposed to be placed in a partition with label '%s' only, but is placed in one labelled '%s', refusing.", - f->gpt_label, strempty(v)); - } +static int validate_fields_check(int fd, const char *path, const ValidateFields *f) { + int r; - if (!sd_id128_is_null(f->gpt_type_uuid)) { - v = NULL; - (void) blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, /* ret_len= */ NULL); + assert(fd >= 0); + assert(path); + assert(f); - sd_id128_t id = SD_ID128_NULL; - if (!v || sd_id128_from_string(v, &id) < 0) - return log_error_errno( - SYNTHETIC_ERRNO(EPERM), - "File system is supposed to be placed in a partition of type UUID '%s' only, but has no type, refusing.", - SD_ID128_TO_UUID_STRING(f->gpt_type_uuid)); + r = validate_mount_point(path, f); + if (r < 0) + return r; - if (!sd_id128_equal(f->gpt_type_uuid, id)) - return log_error_errno( - SYNTHETIC_ERRNO(EPERM), - "File system is supposed to be placed in a partition of type UUID '%s' only, but has type '%s', refusing.", - SD_ID128_TO_UUID_STRING(f->gpt_type_uuid), SD_ID128_TO_UUID_STRING(id)); - } - } + r = validate_gpt_metadata(fd, path, f); + if (r < 0) + return r; log_info("File system '%s' passed validation constraints, proceeding.", path); return 0; -- 2.47.3