Merge pull request #24803 from DaanDeMeyer/repart-copy-deny-list

repart: Don't descend into directories assigned to other partitions
This commit is contained in:
Daan De Meyer
2022-11-11 13:19:58 +01:00
committed by GitHub
17 changed files with 501 additions and 295 deletions
+1 -17
View File
@@ -19,6 +19,7 @@
#include "pretty-print.h"
#include "recurse-dir.h"
#include "sort-util.h"
#include "stat-util.h"
#include "string-table.h"
#include "strv.h"
#include "terminal-util.h"
@@ -543,23 +544,6 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
return -strverscmp_improved(a->id, b->id);
}
static void inode_hash_func(const struct stat *q, struct siphash *state) {
siphash24_compress(&q->st_dev, sizeof(q->st_dev), state);
siphash24_compress(&q->st_ino, sizeof(q->st_ino), state);
}
static int inode_compare_func(const struct stat *a, const struct stat *b) {
int r;
r = CMP(a->st_dev, b->st_dev);
if (r != 0)
return r;
return CMP(a->st_ino, b->st_ino);
}
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(inode_hash_ops, struct stat, inode_hash_func, inode_compare_func, free);
static int config_check_inode_relevant_and_unseen(BootConfig *config, int fd, const char *fname) {
_cleanup_free_ char *d = NULL;
struct stat st;
+21 -5
View File
@@ -687,6 +687,7 @@ static int fd_copy_tree_generic(
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
const Set *denylist,
HardlinkContext *hardlink_context,
const char *display_path,
copy_progress_path_t progress_path,
@@ -877,6 +878,7 @@ static int fd_copy_directory(
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
const Set *denylist,
HardlinkContext *hardlink_context,
const char *display_path,
copy_progress_path_t progress_path,
@@ -979,6 +981,11 @@ static int fd_copy_directory(
return r;
}
if (set_contains(denylist, &buf)) {
log_debug("%s/%s is in the denylist, skipping", from, de->d_name);
continue;
}
if (S_ISDIR(buf.st_mode)) {
/*
* Don't descend into directories on other file systems, if this is requested. We do a simple
@@ -1011,7 +1018,10 @@ static int fd_copy_directory(
}
}
q = fd_copy_tree_generic(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, depth_left-1, override_uid, override_gid, copy_flags, hardlink_context, child_display_path, progress_path, progress_bytes, userdata);
q = fd_copy_tree_generic(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device,
depth_left-1, override_uid, override_gid, copy_flags, denylist,
hardlink_context, child_display_path, progress_path, progress_bytes,
userdata);
if (q == -EINTR) /* Propagate SIGINT/SIGTERM up instantly */
return q;
@@ -1082,6 +1092,7 @@ static int fd_copy_tree_generic(
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
const Set *denylist,
HardlinkContext *hardlink_context,
const char *display_path,
copy_progress_path_t progress_path,
@@ -1090,7 +1101,9 @@ static int fd_copy_tree_generic(
int r;
if (S_ISDIR(st->st_mode))
return fd_copy_directory(df, from, st, dt, to, original_device, depth_left-1, override_uid, override_gid, copy_flags, hardlink_context, display_path, progress_path, progress_bytes, userdata);
return fd_copy_directory(df, from, st, dt, to, original_device, depth_left-1, override_uid,
override_gid, copy_flags, denylist, hardlink_context, display_path,
progress_path, progress_bytes, userdata);
r = fd_copy_leaf(df, from, st, dt, to, override_uid, override_gid, copy_flags, hardlink_context, display_path, progress_bytes, userdata);
/* We just tried to copy a leaf node of the tree. If it failed because the node already exists *and* the COPY_REPLACE flag has been provided, we should unlink the node and re-copy. */
@@ -1113,6 +1126,7 @@ int copy_tree_at_full(
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
const Set *denylist,
copy_progress_path_t progress_path,
copy_progress_bytes_t progress_bytes,
void *userdata) {
@@ -1126,7 +1140,9 @@ int copy_tree_at_full(
if (fstatat(fdf, from, &st, AT_SYMLINK_NOFOLLOW) < 0)
return -errno;
r = fd_copy_tree_generic(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid, override_gid, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
r = fd_copy_tree_generic(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid,
override_gid, copy_flags, denylist, NULL, NULL, progress_path,
progress_bytes, userdata);
if (r < 0)
return r;
@@ -1188,7 +1204,7 @@ int copy_directory_fd_full(
COPY_DEPTH_MAX,
UID_INVALID, GID_INVALID,
copy_flags,
NULL, NULL,
NULL, NULL, NULL,
progress_path,
progress_bytes,
userdata);
@@ -1231,7 +1247,7 @@ int copy_directory_full(
COPY_DEPTH_MAX,
UID_INVALID, GID_INVALID,
copy_flags,
NULL, NULL,
NULL, NULL, NULL,
progress_path,
progress_bytes,
userdata);
+7 -5
View File
@@ -9,6 +9,8 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "set.h"
typedef enum CopyFlags {
COPY_REFLINK = 1 << 0, /* Try to reflink */
COPY_MERGE = 1 << 1, /* Merge existing trees with our new one to copy */
@@ -45,12 +47,12 @@ static inline int copy_file_atomic(const char *from, const char *to, mode_t mode
return copy_file_atomic_full(from, to, mode, chattr_flags, chattr_mask, copy_flags, NULL, NULL);
}
int copy_tree_at_full(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
static inline int copy_tree_at(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags) {
return copy_tree_at_full(fdf, from, fdt, to, override_uid, override_gid, copy_flags, NULL, NULL, NULL);
int copy_tree_at_full(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags, const Set *denylist, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
static inline int copy_tree_at(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags, const Set *denylist) {
return copy_tree_at_full(fdf, from, fdt, to, override_uid, override_gid, copy_flags, denylist, NULL, NULL, NULL);
}
static inline int copy_tree(const char *from, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags) {
return copy_tree_at_full(AT_FDCWD, from, AT_FDCWD, to, override_uid, override_gid, copy_flags, NULL, NULL, NULL);
static inline int copy_tree(const char *from, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags, const Set *denylist) {
return copy_tree_at_full(AT_FDCWD, from, AT_FDCWD, to, override_uid, override_gid, copy_flags, denylist, NULL, NULL, NULL);
}
int copy_directory_fd_full(int dirfd, const char *to, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
+12 -42
View File
@@ -688,7 +688,7 @@ static int dissect_image(
continue;
assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_ROOT_OF_ARCH(architecture);
designator = partition_root_of_arch(architecture);
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
@@ -713,7 +713,7 @@ static int dissect_image(
continue;
assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_OF(PARTITION_ROOT_OF_ARCH(architecture));
designator = partition_verity_of(partition_root_of_arch(architecture));
fstype = "DM_verity_hash";
rw = false;
@@ -733,7 +733,7 @@ static int dissect_image(
continue;
assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_SIG_OF(PARTITION_ROOT_OF_ARCH(architecture));
designator = partition_verity_sig_of(partition_root_of_arch(architecture));
fstype = "verity_hash_signature";
rw = false;
@@ -750,7 +750,7 @@ static int dissect_image(
continue;
assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_USR_OF_ARCH(architecture);
designator = partition_usr_of_arch(architecture);
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
@@ -774,7 +774,7 @@ static int dissect_image(
continue;
assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_OF(PARTITION_USR_OF_ARCH(architecture));
designator = partition_verity_of(partition_usr_of_arch(architecture));
fstype = "DM_verity_hash";
rw = false;
@@ -794,7 +794,7 @@ static int dissect_image(
continue;
assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_SIG_OF(PARTITION_USR_OF_ARCH(architecture));
designator = partition_verity_sig_of(partition_usr_of_arch(architecture));
fstype = "verity_hash_signature";
rw = false;
@@ -884,7 +884,7 @@ static int dissect_image(
* let the newest version win. This permits a simple A/B versioning
* scheme in OS images. */
if (!PARTITION_DESIGNATOR_VERSIONED(designator) ||
if (!partition_designator_is_versioned(designator) ||
strverscmp_improved(m->partitions[designator].label, label) >= 0)
continue;
@@ -2369,7 +2369,7 @@ int dissected_image_decrypt(
if (r < 0)
return r;
k = PARTITION_VERITY_OF(i);
k = partition_verity_of(i);
if (k >= 0) {
r = verity_partition(i, p, m->partitions + k, verity, flags | DISSECT_IMAGE_VERITY_SHARE, d);
if (r < 0)
@@ -2711,7 +2711,7 @@ int dissected_image_load_verity_sig_partition(
if (r == 0)
return 0;
d = PARTITION_VERITY_SIG_OF(verity->designator < 0 ? PARTITION_ROOT : verity->designator);
d = partition_verity_sig_of(verity->designator < 0 ? PARTITION_ROOT : verity->designator);
assert(d >= 0);
p = m->partitions + d;
@@ -3170,7 +3170,7 @@ bool dissected_image_verity_candidate(const DissectedImage *image, PartitionDesi
if (image->single_file_system)
return partition_designator == PARTITION_ROOT && image->has_verity;
return PARTITION_VERITY_OF(partition_designator) >= 0;
return partition_verity_of(partition_designator) >= 0;
}
bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignator partition_designator) {
@@ -3187,7 +3187,7 @@ bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignat
if (image->single_file_system)
return partition_designator == PARTITION_ROOT;
k = PARTITION_VERITY_OF(partition_designator);
k = partition_verity_of(partition_designator);
return k >= 0 && image->partitions[k].found;
}
@@ -3204,7 +3204,7 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
if (image->single_file_system)
return partition_designator == PARTITION_ROOT;
k = PARTITION_VERITY_SIG_OF(partition_designator);
k = partition_verity_sig_of(partition_designator);
return k >= 0 && image->partitions[k].found;
}
@@ -3306,34 +3306,6 @@ int mount_image_privately_interactively(
return 0;
}
static const char *const partition_designator_table[] = {
[PARTITION_ROOT] = "root",
[PARTITION_ROOT_SECONDARY] = "root-secondary",
[PARTITION_ROOT_OTHER] = "root-other",
[PARTITION_USR] = "usr",
[PARTITION_USR_SECONDARY] = "usr-secondary",
[PARTITION_USR_OTHER] = "usr-other",
[PARTITION_HOME] = "home",
[PARTITION_SRV] = "srv",
[PARTITION_ESP] = "esp",
[PARTITION_XBOOTLDR] = "xbootldr",
[PARTITION_SWAP] = "swap",
[PARTITION_ROOT_VERITY] = "root-verity",
[PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity",
[PARTITION_ROOT_OTHER_VERITY] = "root-other-verity",
[PARTITION_USR_VERITY] = "usr-verity",
[PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity",
[PARTITION_USR_OTHER_VERITY] = "usr-other-verity",
[PARTITION_ROOT_VERITY_SIG] = "root-verity-sig",
[PARTITION_ROOT_SECONDARY_VERITY_SIG] = "root-secondary-verity-sig",
[PARTITION_ROOT_OTHER_VERITY_SIG] = "root-other-verity-sig",
[PARTITION_USR_VERITY_SIG] = "usr-verity-sig",
[PARTITION_USR_SECONDARY_VERITY_SIG] = "usr-secondary-verity-sig",
[PARTITION_USR_OTHER_VERITY_SIG] = "usr-other-verity-sig",
[PARTITION_TMP] = "tmp",
[PARTITION_VAR] = "var",
};
static bool mount_options_relax_extension_release_checks(const MountOptions *options) {
if (!options)
return false;
@@ -3461,5 +3433,3 @@ int verity_dissect_and_mount(
return 0;
}
DEFINE_STRING_TABLE_LOOKUP(partition_designator, PartitionDesignator);
+1 -144
View File
@@ -6,6 +6,7 @@
#include "sd-id128.h"
#include "architecture.h"
#include "gpt.h"
#include "list.h"
#include "loop-util.h"
#include "macro.h"
@@ -41,147 +42,6 @@ struct DissectedPartition {
.mount_node_fd = -1, \
})
typedef enum PartitionDesignator {
PARTITION_ROOT,
PARTITION_ROOT_SECONDARY, /* Secondary architecture */
PARTITION_ROOT_OTHER,
PARTITION_USR,
PARTITION_USR_SECONDARY,
PARTITION_USR_OTHER,
PARTITION_HOME,
PARTITION_SRV,
PARTITION_ESP,
PARTITION_XBOOTLDR,
PARTITION_SWAP,
PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */
PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */
PARTITION_ROOT_OTHER_VERITY,
PARTITION_USR_VERITY,
PARTITION_USR_SECONDARY_VERITY,
PARTITION_USR_OTHER_VERITY,
PARTITION_ROOT_VERITY_SIG, /* PKCS#7 signature for root hash for the PARTITION_ROOT partition */
PARTITION_ROOT_SECONDARY_VERITY_SIG, /* ditto for the PARTITION_ROOT_SECONDARY partition */
PARTITION_ROOT_OTHER_VERITY_SIG,
PARTITION_USR_VERITY_SIG,
PARTITION_USR_SECONDARY_VERITY_SIG,
PARTITION_USR_OTHER_VERITY_SIG,
PARTITION_TMP,
PARTITION_VAR,
_PARTITION_DESIGNATOR_MAX,
_PARTITION_DESIGNATOR_INVALID = -EINVAL,
} PartitionDesignator;
static inline bool PARTITION_DESIGNATOR_VERSIONED(PartitionDesignator d) {
/* Returns true for all designators where we want to support a concept of "versioning", i.e. which
* likely contain software binaries (or hashes thereof) that make sense to be versioned as a
* whole. We use this check to automatically pick the newest version of these partitions, by version
* comparing the partition labels. */
return IN_SET(d,
PARTITION_ROOT,
PARTITION_ROOT_SECONDARY,
PARTITION_ROOT_OTHER,
PARTITION_USR,
PARTITION_USR_SECONDARY,
PARTITION_USR_OTHER,
PARTITION_ROOT_VERITY,
PARTITION_ROOT_SECONDARY_VERITY,
PARTITION_ROOT_OTHER_VERITY,
PARTITION_USR_VERITY,
PARTITION_USR_SECONDARY_VERITY,
PARTITION_USR_OTHER_VERITY,
PARTITION_ROOT_VERITY_SIG,
PARTITION_ROOT_SECONDARY_VERITY_SIG,
PARTITION_ROOT_OTHER_VERITY_SIG,
PARTITION_USR_VERITY_SIG,
PARTITION_USR_SECONDARY_VERITY_SIG,
PARTITION_USR_OTHER_VERITY_SIG);
}
static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) {
switch (p) {
case PARTITION_ROOT:
return PARTITION_ROOT_VERITY;
case PARTITION_ROOT_SECONDARY:
return PARTITION_ROOT_SECONDARY_VERITY;
case PARTITION_ROOT_OTHER:
return PARTITION_ROOT_OTHER_VERITY;
case PARTITION_USR:
return PARTITION_USR_VERITY;
case PARTITION_USR_SECONDARY:
return PARTITION_USR_SECONDARY_VERITY;
case PARTITION_USR_OTHER:
return PARTITION_USR_OTHER_VERITY;
default:
return _PARTITION_DESIGNATOR_INVALID;
}
}
static inline PartitionDesignator PARTITION_VERITY_SIG_OF(PartitionDesignator p) {
switch (p) {
case PARTITION_ROOT:
return PARTITION_ROOT_VERITY_SIG;
case PARTITION_ROOT_SECONDARY:
return PARTITION_ROOT_SECONDARY_VERITY_SIG;
case PARTITION_ROOT_OTHER:
return PARTITION_ROOT_OTHER_VERITY_SIG;
case PARTITION_USR:
return PARTITION_USR_VERITY_SIG;
case PARTITION_USR_SECONDARY:
return PARTITION_USR_SECONDARY_VERITY_SIG;
case PARTITION_USR_OTHER:
return PARTITION_USR_OTHER_VERITY_SIG;
default:
return _PARTITION_DESIGNATOR_INVALID;
}
}
static inline PartitionDesignator PARTITION_ROOT_OF_ARCH(Architecture arch) {
switch (arch) {
case native_architecture():
return PARTITION_ROOT;
#ifdef ARCHITECTURE_SECONDARY
case ARCHITECTURE_SECONDARY:
return PARTITION_ROOT_SECONDARY;
#endif
default:
return PARTITION_ROOT_OTHER;
}
}
static inline PartitionDesignator PARTITION_USR_OF_ARCH(Architecture arch) {
switch (arch) {
case native_architecture():
return PARTITION_USR;
#ifdef ARCHITECTURE_SECONDARY
case ARCHITECTURE_SECONDARY:
return PARTITION_USR_SECONDARY;
#endif
default:
return PARTITION_USR_OTHER;
}
}
typedef enum DissectImageFlags {
DISSECT_IMAGE_DEVICE_READ_ONLY = 1 << 0, /* Make device read-only */
DISSECT_IMAGE_DISCARD_ON_LOOP = 1 << 1, /* Turn on "discard" if on a loop device and file system supports it */
@@ -298,9 +158,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DecryptedImage*, decrypted_image_unref);
int dissected_image_relinquish(DissectedImage *m);
const char* partition_designator_to_string(PartitionDesignator d) _const_;
PartitionDesignator partition_designator_from_string(const char *name) _pure_;
int verity_settings_load(VeritySettings *verity, const char *image, const char *root_hash_path, const char *root_hash_sig_path);
void verity_settings_done(VeritySettings *verity);
+247 -50
View File
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "gpt.h"
#include "string-table.h"
#include "string-util.h"
#include "utf8.h"
@@ -14,13 +15,173 @@
#pragma message "Please define GPT partition types for your architecture."
#endif
bool partition_designator_is_versioned(PartitionDesignator d) {
/* Returns true for all designators where we want to support a concept of "versioning", i.e. which
* likely contain software binaries (or hashes thereof) that make sense to be versioned as a
* whole. We use this check to automatically pick the newest version of these partitions, by version
* comparing the partition labels. */
return IN_SET(d,
PARTITION_ROOT,
PARTITION_ROOT_SECONDARY,
PARTITION_ROOT_OTHER,
PARTITION_USR,
PARTITION_USR_SECONDARY,
PARTITION_USR_OTHER,
PARTITION_ROOT_VERITY,
PARTITION_ROOT_SECONDARY_VERITY,
PARTITION_ROOT_OTHER_VERITY,
PARTITION_USR_VERITY,
PARTITION_USR_SECONDARY_VERITY,
PARTITION_USR_OTHER_VERITY,
PARTITION_ROOT_VERITY_SIG,
PARTITION_ROOT_SECONDARY_VERITY_SIG,
PARTITION_ROOT_OTHER_VERITY_SIG,
PARTITION_USR_VERITY_SIG,
PARTITION_USR_SECONDARY_VERITY_SIG,
PARTITION_USR_OTHER_VERITY_SIG);
}
PartitionDesignator partition_verity_of(PartitionDesignator p) {
switch (p) {
case PARTITION_ROOT:
return PARTITION_ROOT_VERITY;
case PARTITION_ROOT_SECONDARY:
return PARTITION_ROOT_SECONDARY_VERITY;
case PARTITION_ROOT_OTHER:
return PARTITION_ROOT_OTHER_VERITY;
case PARTITION_USR:
return PARTITION_USR_VERITY;
case PARTITION_USR_SECONDARY:
return PARTITION_USR_SECONDARY_VERITY;
case PARTITION_USR_OTHER:
return PARTITION_USR_OTHER_VERITY;
default:
return _PARTITION_DESIGNATOR_INVALID;
}
}
PartitionDesignator partition_verity_sig_of(PartitionDesignator p) {
switch (p) {
case PARTITION_ROOT:
return PARTITION_ROOT_VERITY_SIG;
case PARTITION_ROOT_SECONDARY:
return PARTITION_ROOT_SECONDARY_VERITY_SIG;
case PARTITION_ROOT_OTHER:
return PARTITION_ROOT_OTHER_VERITY_SIG;
case PARTITION_USR:
return PARTITION_USR_VERITY_SIG;
case PARTITION_USR_SECONDARY:
return PARTITION_USR_SECONDARY_VERITY_SIG;
case PARTITION_USR_OTHER:
return PARTITION_USR_OTHER_VERITY_SIG;
default:
return _PARTITION_DESIGNATOR_INVALID;
}
}
PartitionDesignator partition_root_of_arch(Architecture arch) {
switch (arch) {
case native_architecture():
return PARTITION_ROOT;
#ifdef ARCHITECTURE_SECONDARY
case ARCHITECTURE_SECONDARY:
return PARTITION_ROOT_SECONDARY;
#endif
default:
return PARTITION_ROOT_OTHER;
}
}
PartitionDesignator partition_usr_of_arch(Architecture arch) {
switch (arch) {
case native_architecture():
return PARTITION_USR;
#ifdef ARCHITECTURE_SECONDARY
case ARCHITECTURE_SECONDARY:
return PARTITION_USR_SECONDARY;
#endif
default:
return PARTITION_USR_OTHER;
}
}
static const char *const partition_designator_table[] = {
[PARTITION_ROOT] = "root",
[PARTITION_ROOT_SECONDARY] = "root-secondary",
[PARTITION_ROOT_OTHER] = "root-other",
[PARTITION_USR] = "usr",
[PARTITION_USR_SECONDARY] = "usr-secondary",
[PARTITION_USR_OTHER] = "usr-other",
[PARTITION_HOME] = "home",
[PARTITION_SRV] = "srv",
[PARTITION_ESP] = "esp",
[PARTITION_XBOOTLDR] = "xbootldr",
[PARTITION_SWAP] = "swap",
[PARTITION_ROOT_VERITY] = "root-verity",
[PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity",
[PARTITION_ROOT_OTHER_VERITY] = "root-other-verity",
[PARTITION_USR_VERITY] = "usr-verity",
[PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity",
[PARTITION_USR_OTHER_VERITY] = "usr-other-verity",
[PARTITION_ROOT_VERITY_SIG] = "root-verity-sig",
[PARTITION_ROOT_SECONDARY_VERITY_SIG] = "root-secondary-verity-sig",
[PARTITION_ROOT_OTHER_VERITY_SIG] = "root-other-verity-sig",
[PARTITION_USR_VERITY_SIG] = "usr-verity-sig",
[PARTITION_USR_SECONDARY_VERITY_SIG] = "usr-secondary-verity-sig",
[PARTITION_USR_OTHER_VERITY_SIG] = "usr-other-verity-sig",
[PARTITION_TMP] = "tmp",
[PARTITION_VAR] = "var",
[PARTITION_USER_HOME] = "user-home",
[PARTITION_LINUX_GENERIC] = "linux-generic",
};
DEFINE_STRING_TABLE_LOOKUP(partition_designator, PartitionDesignator);
static const char *const partition_mountpoint_table[] = {
[PARTITION_ROOT] = "/\0",
[PARTITION_ROOT_SECONDARY] = "/\0",
[PARTITION_ROOT_OTHER] = "/\0",
[PARTITION_USR] = "/usr\0",
[PARTITION_USR_SECONDARY] = "/usr\0",
[PARTITION_USR_OTHER] = "/usr\0",
[PARTITION_HOME] = "/home\0",
[PARTITION_SRV] = "/srv\0",
[PARTITION_ESP] = "/efi\0/boot\0",
[PARTITION_XBOOTLDR] = "/boot\0",
[PARTITION_TMP] = "/var/tmp\0",
[PARTITION_VAR] = "/var\0",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(partition_mountpoint, PartitionDesignator);
#define _GPT_ARCH_SEXTET(arch, name) \
{ SD_GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .is_root = true }, \
{ SD_GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .is_root_verity = true }, \
{ SD_GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ARCHITECTURE_##arch, .is_root_verity_sig = true }, \
{ SD_GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .is_usr = true }, \
{ SD_GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .is_usr_verity = true }, \
{ SD_GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .is_usr_verity_sig = true }
{ SD_GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER }, \
{ SD_GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER_VERITY }, \
{ SD_GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER_VERITY_SIG }, \
{ SD_GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .designator = PARTITION_USR_OTHER }, \
{ SD_GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_USR_OTHER_VERITY }, \
{ SD_GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_USR_OTHER_VERITY_SIG }
const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(ALPHA, "alpha"),
@@ -43,26 +204,31 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(X86, "x86"),
_GPT_ARCH_SEXTET(X86_64, "x86-64"),
#ifdef SD_GPT_ROOT_NATIVE
{ SD_GPT_ROOT_NATIVE, "root", native_architecture(), .is_root = true },
{ SD_GPT_ROOT_NATIVE_VERITY, "root-verity", native_architecture(), .is_root_verity = true },
{ SD_GPT_ROOT_NATIVE_VERITY_SIG, "root-verity-sig", native_architecture(), .is_root_verity_sig = true },
{ SD_GPT_USR_NATIVE, "usr", native_architecture(), .is_usr = true },
{ SD_GPT_USR_NATIVE_VERITY, "usr-verity", native_architecture(), .is_usr_verity = true },
{ SD_GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig", native_architecture(), .is_usr_verity_sig = true },
{ SD_GPT_ROOT_NATIVE, "root", native_architecture(), .designator = PARTITION_ROOT },
{ SD_GPT_ROOT_NATIVE_VERITY, "root-verity", native_architecture(), .designator = PARTITION_ROOT_VERITY },
{ SD_GPT_ROOT_NATIVE_VERITY_SIG, "root-verity-sig", native_architecture(), .designator = PARTITION_ROOT_VERITY_SIG },
{ SD_GPT_USR_NATIVE, "usr", native_architecture(), .designator = PARTITION_USR },
{ SD_GPT_USR_NATIVE_VERITY, "usr-verity", native_architecture(), .designator = PARTITION_USR_VERITY },
{ SD_GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig", native_architecture(), .designator = PARTITION_USR_VERITY_SIG },
#endif
#ifdef SD_GPT_ROOT_SECONDARY
_GPT_ARCH_SEXTET(SECONDARY, "secondary"),
{ SD_GPT_ROOT_NATIVE, "root-secondary", native_architecture(), .designator = PARTITION_ROOT_SECONDARY },
{ SD_GPT_ROOT_NATIVE_VERITY, "root-secondary-verity", native_architecture(), .designator = PARTITION_ROOT_SECONDARY_VERITY },
{ SD_GPT_ROOT_NATIVE_VERITY_SIG, "root-secondary-verity-sig", native_architecture(), .designator = PARTITION_ROOT_SECONDARY_VERITY_SIG },
{ SD_GPT_USR_NATIVE, "usr-secondary", native_architecture(), .designator = PARTITION_USR_SECONDARY },
{ SD_GPT_USR_NATIVE_VERITY, "usr-secondary-verity", native_architecture(), .designator = PARTITION_USR_SECONDARY_VERITY },
{ SD_GPT_USR_NATIVE_VERITY_SIG, "usr-secondary-verity-sig", native_architecture(), .designator = PARTITION_USR_SECONDARY_VERITY_SIG },
#endif
{ SD_GPT_ESP, "esp", _ARCHITECTURE_INVALID },
{ SD_GPT_XBOOTLDR, "xbootldr", _ARCHITECTURE_INVALID },
{ SD_GPT_SWAP, "swap", _ARCHITECTURE_INVALID },
{ SD_GPT_HOME, "home", _ARCHITECTURE_INVALID },
{ SD_GPT_SRV, "srv", _ARCHITECTURE_INVALID },
{ SD_GPT_VAR, "var", _ARCHITECTURE_INVALID },
{ SD_GPT_TMP, "tmp", _ARCHITECTURE_INVALID },
{ SD_GPT_USER_HOME, "user-home", _ARCHITECTURE_INVALID },
{ SD_GPT_LINUX_GENERIC, "linux-generic", _ARCHITECTURE_INVALID },
{ SD_GPT_ESP, "esp", _ARCHITECTURE_INVALID, .designator = PARTITION_ESP },
{ SD_GPT_XBOOTLDR, "xbootldr", _ARCHITECTURE_INVALID, .designator = PARTITION_XBOOTLDR },
{ SD_GPT_SWAP, "swap", _ARCHITECTURE_INVALID, .designator = PARTITION_SWAP },
{ SD_GPT_HOME, "home", _ARCHITECTURE_INVALID, .designator = PARTITION_HOME },
{ SD_GPT_SRV, "srv", _ARCHITECTURE_INVALID, .designator = PARTITION_SRV },
{ SD_GPT_VAR, "var", _ARCHITECTURE_INVALID, .designator = PARTITION_VAR },
{ SD_GPT_TMP, "tmp", _ARCHITECTURE_INVALID, .designator = PARTITION_TMP },
{ SD_GPT_USER_HOME, "user-home", _ARCHITECTURE_INVALID, .designator = PARTITION_USER_HOME },
{ SD_GPT_LINUX_GENERIC, "linux-generic", _ARCHITECTURE_INVALID, .designator = PARTITION_LINUX_GENERIC },
{}
};
@@ -140,55 +306,86 @@ static GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) {
if (pt)
return *pt;
return (GptPartitionType) { .uuid = id, .arch = _ARCHITECTURE_INVALID };
return (GptPartitionType) {
.uuid = id,
.arch = _ARCHITECTURE_INVALID,
.designator = _PARTITION_DESIGNATOR_INVALID,
};
}
bool gpt_partition_type_is_root(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_root;
return IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_ROOT,
PARTITION_ROOT_SECONDARY,
PARTITION_ROOT_OTHER);
}
bool gpt_partition_type_is_root_verity(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_root_verity;
return IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_ROOT_VERITY,
PARTITION_ROOT_SECONDARY_VERITY,
PARTITION_ROOT_OTHER_VERITY);
}
bool gpt_partition_type_is_root_verity_sig(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_root_verity_sig;
return IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_ROOT_VERITY_SIG,
PARTITION_ROOT_SECONDARY_VERITY_SIG,
PARTITION_ROOT_OTHER_VERITY_SIG);
}
bool gpt_partition_type_is_usr(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_usr;
return IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_USR,
PARTITION_USR_SECONDARY,
PARTITION_USR_OTHER);
}
bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_usr_verity;
return IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_USR_VERITY,
PARTITION_USR_SECONDARY_VERITY,
PARTITION_USR_OTHER_VERITY);
}
bool gpt_partition_type_is_usr_verity_sig(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_usr_verity_sig;
return IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_USR_VERITY_SIG,
PARTITION_USR_SECONDARY_VERITY_SIG,
PARTITION_USR_OTHER_VERITY_SIG);
}
const char *gpt_partition_type_mountpoint_nulstr(sd_id128_t id) {
PartitionDesignator d = gpt_partition_type_from_uuid(id).designator;
if (d < 0)
return NULL;
return partition_mountpoint_to_string(d);
}
bool gpt_partition_type_knows_read_only(sd_id128_t id) {
return gpt_partition_type_is_root(id) ||
gpt_partition_type_is_usr(id) ||
sd_id128_in_set(id,
SD_GPT_HOME,
SD_GPT_SRV,
SD_GPT_VAR,
SD_GPT_TMP,
SD_GPT_XBOOTLDR) ||
gpt_partition_type_is_root_verity(id) || /* pretty much implied, but let's set the bit to make things really clear */
gpt_partition_type_is_usr_verity(id); /* ditto */
/* pretty much implied, but let's set the bit to make things really clear */
gpt_partition_type_is_root_verity(id) ||
gpt_partition_type_is_usr_verity(id) ||
IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_HOME,
PARTITION_SRV,
PARTITION_VAR,
PARTITION_TMP,
PARTITION_XBOOTLDR);
}
bool gpt_partition_type_knows_growfs(sd_id128_t id) {
return gpt_partition_type_is_root(id) ||
gpt_partition_type_is_usr(id) ||
sd_id128_in_set(id,
SD_GPT_HOME,
SD_GPT_SRV,
SD_GPT_VAR,
SD_GPT_TMP,
SD_GPT_XBOOTLDR);
IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_HOME,
PARTITION_SRV,
PARTITION_VAR,
PARTITION_TMP,
PARTITION_XBOOTLDR);
}
bool gpt_partition_type_knows_no_auto(sd_id128_t id) {
@@ -196,11 +393,11 @@ bool gpt_partition_type_knows_no_auto(sd_id128_t id) {
gpt_partition_type_is_root_verity(id) ||
gpt_partition_type_is_usr(id) ||
gpt_partition_type_is_usr_verity(id) ||
sd_id128_in_set(id,
SD_GPT_HOME,
SD_GPT_SRV,
SD_GPT_VAR,
SD_GPT_TMP,
SD_GPT_XBOOTLDR,
SD_GPT_SWAP);
IN_SET(gpt_partition_type_from_uuid(id).designator,
PARTITION_HOME,
PARTITION_SRV,
PARTITION_VAR,
PARTITION_TMP,
PARTITION_XBOOTLDR,
PARTITION_SWAP);
}
+45 -7
View File
@@ -10,6 +10,48 @@
/* maximum length of gpt label */
#define GPT_LABEL_MAX 36
typedef enum PartitionDesignator {
PARTITION_ROOT, /* Primary architecture */
PARTITION_ROOT_SECONDARY, /* Secondary architecture */
PARTITION_ROOT_OTHER, /* Any architecture not covered by the primary or secondary architecture. */
PARTITION_USR,
PARTITION_USR_SECONDARY,
PARTITION_USR_OTHER,
PARTITION_HOME,
PARTITION_SRV,
PARTITION_ESP,
PARTITION_XBOOTLDR,
PARTITION_SWAP,
PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */
PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */
PARTITION_ROOT_OTHER_VERITY,
PARTITION_USR_VERITY,
PARTITION_USR_SECONDARY_VERITY,
PARTITION_USR_OTHER_VERITY,
PARTITION_ROOT_VERITY_SIG, /* PKCS#7 signature for root hash for the PARTITION_ROOT partition */
PARTITION_ROOT_SECONDARY_VERITY_SIG, /* ditto for the PARTITION_ROOT_SECONDARY partition */
PARTITION_ROOT_OTHER_VERITY_SIG,
PARTITION_USR_VERITY_SIG,
PARTITION_USR_SECONDARY_VERITY_SIG,
PARTITION_USR_OTHER_VERITY_SIG,
PARTITION_TMP,
PARTITION_VAR,
PARTITION_USER_HOME,
PARTITION_LINUX_GENERIC,
_PARTITION_DESIGNATOR_MAX,
_PARTITION_DESIGNATOR_INVALID = -EINVAL,
} PartitionDesignator;
bool partition_designator_is_versioned(PartitionDesignator d);
PartitionDesignator partition_verity_of(PartitionDesignator p);
PartitionDesignator partition_verity_sig_of(PartitionDesignator p);
PartitionDesignator partition_root_of_arch(Architecture arch);
PartitionDesignator partition_usr_of_arch(Architecture arch);
const char* partition_designator_to_string(PartitionDesignator d) _const_;
PartitionDesignator partition_designator_from_string(const char *name) _pure_;
const char *gpt_partition_type_uuid_to_string(sd_id128_t id);
const char *gpt_partition_type_uuid_to_string_harder(
sd_id128_t id,
@@ -25,13 +67,7 @@ typedef struct GptPartitionType {
sd_id128_t uuid;
const char *name;
Architecture arch;
bool is_root:1;
bool is_root_verity:1;
bool is_root_verity_sig:1;
bool is_usr:1;
bool is_usr_verity:1;
bool is_usr_verity_sig:1;
PartitionDesignator designator;
} GptPartitionType;
extern const GptPartitionType gpt_partition_type_table[];
@@ -45,6 +81,8 @@ bool gpt_partition_type_is_usr(sd_id128_t id);
bool gpt_partition_type_is_usr_verity(sd_id128_t id);
bool gpt_partition_type_is_usr_verity_sig(sd_id128_t id);
const char *gpt_partition_type_mountpoint_nulstr(sd_id128_t id);
bool gpt_partition_type_knows_read_only(sd_id128_t id);
bool gpt_partition_type_knows_growfs(sd_id128_t id);
bool gpt_partition_type_knows_no_auto(sd_id128_t id);