From: Lennart Poettering Date: Tue, 5 Feb 2019 17:17:01 +0000 (+0100) Subject: bootspec: also split out XBOOTLDR partition blkid code into its own function X-Git-Tag: v242-rc1~218^2~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ad95aa44d62b2a0f9784df3293e45bf4bf53b788;p=thirdparty%2Fsystemd.git bootspec: also split out XBOOTLDR partition blkid code into its own function --- diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index 4b4eed0c4c5..cfae1cc0b36 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -680,61 +680,26 @@ found: return 0; } -static int verify_xbootldr( - const char *p, +static int verify_xbootldr_blkid( + dev_t devid, bool searching, - bool unprivileged_mode, sd_id128_t *ret_uuid) { + + sd_id128_t uuid = SD_ID128_NULL; + #if HAVE_BLKID _cleanup_(blkid_free_probep) blkid_probe b = NULL; _cleanup_free_ char *node = NULL; const char *v; -#endif - struct stat st, st2; - const char *t2; - sd_id128_t uuid = SD_ID128_NULL; - bool relax_checks; int r; - assert(p); - - relax_checks = getenv_bool("SYSTEMD_RELAX_XBOOTLDR_CHECKS") > 0; - - if (stat(p, &st) < 0) - return log_full_errno((searching && errno == ENOENT) || - (unprivileged_mode && errno == EACCES) ? LOG_DEBUG : LOG_ERR, errno, - "Failed to determine block device node of \"%s\": %m", p); - - if (major(st.st_dev) == 0) - return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, - SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), - "Block device node of \"%s\" is invalid.", p); - - t2 = strjoina(p, "/.."); - r = stat(t2, &st2); - if (r < 0) - return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno, - "Failed to determine block device node of parent of \"%s\": %m", p); - - if (st.st_dev == st2.st_dev) - return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, - SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), - "Directory \"%s\" is not the root of the XBOOTLDR file system.", p); - - /* In a container we don't have access to block devices, skip this part of the verification, we trust - * the container manager set everything up correctly on its own. Also skip the following verification - * for non-root user. */ - if (detect_container() > 0 || unprivileged_mode || relax_checks) - goto finish; - -#if HAVE_BLKID - r = device_path_make_major_minor(S_IFBLK, st.st_dev, &node); + r = device_path_make_major_minor(S_IFBLK, devid, &node); if (r < 0) return log_error_errno(r, "Failed to format major/minor device path: %m"); errno = 0; b = blkid_new_probe_from_filename(node); if (!b) - return log_error_errno(errno ?: SYNTHETIC_ERRNO(ENOMEM), "Failed to open file system \"%s\": %m", p); + return log_error_errno(errno ?: SYNTHETIC_ERRNO(ENOMEM), "Failed to open file system \"%s\": %m", node); blkid_probe_enable_partitions(b, 1); blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS); @@ -742,60 +707,109 @@ static int verify_xbootldr( errno = 0; r = blkid_do_safeprobe(b); if (r == -2) - return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" is ambiguous.", p); + return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" is ambiguous.", node); else if (r == 1) - return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" does not contain a label.", p); + return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" does not contain a label.", node); else if (r != 0) - return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe file system \"%s\": %m", p); + return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe file system \"%s\": %m", node); errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL); if (r != 0) - return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition scheme \"%s\": %m", p); + return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition scheme of \"%s\": %m", node); if (streq(v, "gpt")) { errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL); if (r != 0) - return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition type UUID \"%s\": %m", p); + return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition type UUID of \"%s\": %m", node); if (!streq(v, "bc13c2ff-59e6-4262-a352-b275fd6f7172")) return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, searching ? SYNTHETIC_ERRNO(EADDRNOTAVAIL) : SYNTHETIC_ERRNO(ENODEV), - "File system \"%s\" has wrong type for extended boot loader partition.", p); + "File system \"%s\" has wrong type for extended boot loader partition.", node); errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL); if (r != 0) - return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition entry UUID \"%s\": %m", p); + return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition entry UUID of \"%s\": %m", node); r = sd_id128_from_string(v, &uuid); if (r < 0) - return log_error_errno(r, "Partition \"%s\" has invalid UUID \"%s\".", p, v); + return log_error_errno(r, "Partition \"%s\" has invalid UUID \"%s\".", node, v); } else if (streq(v, "dos")) { errno = 0; r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL); if (r != 0) - return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition type UUID \"%s\": %m", p); + return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition type UUID of \"%s\": %m", node); if (!streq(v, "0xea")) return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, searching ? SYNTHETIC_ERRNO(EADDRNOTAVAIL) : SYNTHETIC_ERRNO(ENODEV), - "File system \"%s\" has wrong type for extended boot loader partition.", p); + "File system \"%s\" has wrong type for extended boot loader partition.", node); } else return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, searching ? SYNTHETIC_ERRNO(EADDRNOTAVAIL) : SYNTHETIC_ERRNO(ENODEV), - "File system \"%s\" is not on a GPT or DOS partition table.", p); - + "File system \"%s\" is not on a GPT or DOS partition table.", node); #endif -finish: if (ret_uuid) *ret_uuid = uuid; return 0; } +static int verify_xbootldr( + const char *p, + bool searching, + bool unprivileged_mode, + sd_id128_t *ret_uuid) { + + struct stat st, st2; + bool relax_checks; + const char *t2; + int r; + + assert(p); + + relax_checks = getenv_bool("SYSTEMD_RELAX_XBOOTLDR_CHECKS") > 0; + + if (stat(p, &st) < 0) + return log_full_errno((searching && errno == ENOENT) || + (unprivileged_mode && errno == EACCES) ? LOG_DEBUG : LOG_ERR, errno, + "Failed to determine block device node of \"%s\": %m", p); + + if (major(st.st_dev) == 0) + return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, + SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), + "Block device node of \"%s\" is invalid.", p); + + t2 = strjoina(p, "/.."); + r = stat(t2, &st2); + if (r < 0) + return log_full_errno(unprivileged_mode && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno, + "Failed to determine block device node of parent of \"%s\": %m", p); + + if (st.st_dev == st2.st_dev) + return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, + SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), + "Directory \"%s\" is not the root of the XBOOTLDR file system.", p); + + /* In a container we don't have access to block devices, skip this part of the verification, we trust + * the container manager set everything up correctly on its own. Also skip the following verification + * for non-root user. */ + if (detect_container() > 0 || unprivileged_mode || relax_checks) + goto finish; + + return verify_xbootldr_blkid(st.st_dev, searching, ret_uuid); + +finish: + if (ret_uuid) + *ret_uuid = SD_ID128_NULL; + + return 0; +} + int find_xbootldr_and_warn( const char *path, bool unprivileged_mode,