mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
gpt-auto-generator: add support for setting up verity partitions automatically
So far the gpt-auto-generator would only cover unprotected and encrypted partitions. Teach it handling of verity too.
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "fstab-util.h"
|
||||
#include "generator.h"
|
||||
#include "gpt.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "image-policy.h"
|
||||
#include "initrd-util.h"
|
||||
#include "mountpoint-util.h"
|
||||
@@ -184,6 +185,106 @@ static int add_cryptsetup(
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLE_EFI
|
||||
static int add_veritysetup(
|
||||
const char *id,
|
||||
const char *data_what,
|
||||
const char *hash_what,
|
||||
const char *mount_opts) {
|
||||
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
int r;
|
||||
|
||||
assert(id);
|
||||
assert(data_what);
|
||||
assert(hash_what);
|
||||
|
||||
_cleanup_free_ char *dd = NULL;
|
||||
r = unit_name_from_path(data_what, ".device", &dd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate data device unit name: %m");
|
||||
|
||||
_cleanup_free_ char *dh = NULL;
|
||||
r = unit_name_from_path(hash_what, ".device", &dh);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate hash device unit name: %m");
|
||||
|
||||
_cleanup_free_ char *e = unit_name_escape(id);
|
||||
if (!e)
|
||||
return log_oom();
|
||||
|
||||
_cleanup_free_ char *n = NULL;
|
||||
r = unit_name_build("systemd-veritysetup", e, ".service", &n);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
r = generator_open_unit_file(arg_dest, /* source= */ NULL, n, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = generator_write_veritysetup_unit_section(f, /* source= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fprintf(f,
|
||||
"Before=veritysetup.target\n"
|
||||
"BindsTo=%1$s %2$s\n"
|
||||
"After=%1$s %2$s\n",
|
||||
dd, dh);
|
||||
|
||||
r = generator_write_veritysetup_service_section(
|
||||
f,
|
||||
id,
|
||||
data_what,
|
||||
hash_what,
|
||||
/* roothash= */ NULL, /* NULL means: derive root hash from udev property ID_DISSECT_PART_ROOTHASH */
|
||||
"root-hash-signature=auto"); /* auto means: derive signature from udev property ID_DISSECT_PART_ROOTHASH_SIG */
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = fflush_and_check(f);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write file %s: %m", n);
|
||||
|
||||
r = generator_write_device_timeout(arg_dest, data_what, mount_opts, /* filtered= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = generator_write_device_timeout(arg_dest, hash_what, mount_opts, /* filtered= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = generator_add_symlink(arg_dest, dd, "wants", n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = generator_add_symlink(arg_dest, dh, "wants", n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_free_ char *dmname = NULL;
|
||||
dmname = strjoin("dev-mapper-", e, ".device");
|
||||
if (!dmname)
|
||||
return log_oom();
|
||||
|
||||
r = write_drop_in_format(
|
||||
arg_dest,
|
||||
dmname, 50, "job-timeout",
|
||||
"# Automatically generated by systemd-gpt-auto-generator\n\n"
|
||||
"[Unit]\n"
|
||||
"JobTimeoutSec=infinity"); /* the binary handles timeouts anyway */
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write device timeout drop-in: %m");
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Partition is Verity protected, but systemd-gpt-auto-generator was compiled without libcryptsetup support.");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int add_mount(
|
||||
const char *id,
|
||||
const char *what,
|
||||
@@ -757,6 +858,18 @@ static int add_root_mount(void) {
|
||||
r = add_root_cryptsetup();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* If a device /dev/disk/by-designator/root-verity or
|
||||
* /dev/disk/by-designator/root-verity-data appears, then make it pull in
|
||||
* systemd-cryptsetup@root.service, which sets it up, and causes /dev/disk/by-designator/root
|
||||
* to appear. */
|
||||
r = add_veritysetup(
|
||||
"root",
|
||||
"/dev/disk/by-designator/root-verity-data",
|
||||
"/dev/disk/by-designator/root-verity",
|
||||
arg_root_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Note that we do not need to enable systemd-remount-fs.service here. If /etc/fstab exists,
|
||||
@@ -793,7 +906,6 @@ static int add_root_mount(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int add_usr_mount(void) {
|
||||
#if ENABLE_EFI
|
||||
int r;
|
||||
@@ -828,6 +940,18 @@ static int add_usr_mount(void) {
|
||||
/* ret_device= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* If a device /dev/disk/by-designator/usr-verity or
|
||||
* /dev/disk/by-designator/usr-verity-data appears, then make it pull in
|
||||
* systemd-cryptsetup@usr.service, which sets it up, and causes /dev/disk/by-designator/usr
|
||||
* to appear. */
|
||||
r = add_veritysetup(
|
||||
"usr",
|
||||
"/dev/disk/by-designator/usr-verity-data",
|
||||
"/dev/disk/by-designator/usr-verity",
|
||||
arg_usr_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
_cleanup_free_ char *options = NULL;
|
||||
|
||||
@@ -1026,9 +1026,11 @@ int generator_write_veritysetup_service_section(
|
||||
if (!hash_what_escaped)
|
||||
return log_oom();
|
||||
|
||||
roothash_escaped = specifier_escape(roothash);
|
||||
if (!roothash_escaped)
|
||||
return log_oom();
|
||||
if (roothash) {
|
||||
roothash_escaped = specifier_escape(roothash);
|
||||
if (!roothash_escaped)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (options) {
|
||||
options_escaped = specifier_escape(options);
|
||||
@@ -1043,7 +1045,7 @@ int generator_write_veritysetup_service_section(
|
||||
"RemainAfterExit=yes\n"
|
||||
"ExecStart=" SYSTEMD_VERITYSETUP_PATH " attach '%s' '%s' '%s' '%s' '%s'\n"
|
||||
"ExecStop=" SYSTEMD_VERITYSETUP_PATH " detach '%s'\n",
|
||||
name_escaped, data_what_escaped, hash_what_escaped, roothash_escaped, strempty(options_escaped),
|
||||
name_escaped, data_what_escaped, hash_what_escaped, empty_to_dash(roothash_escaped), strempty(options_escaped),
|
||||
name_escaped);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user