mirror of
https://github.com/systemd/systemd.git
synced 2025-03-29 06:50:16 +03:00
core,nspawn,dissect: make nspawn's .roothash file search reusable
This makes nspawn's logic of automatically discovering the root hash of an image file generic, and then reuses it in systemd-dissect and in PID1's RootImage= logic, so that verity is automatically set up whenever we can.
This commit is contained in:
parent
915e6d1676
commit
78ebe98061
@ -883,8 +883,11 @@ int setup_namespace(
|
||||
DissectImageFlags dissect_image_flags) {
|
||||
|
||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
||||
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
|
||||
_cleanup_free_ void *root_hash = NULL;
|
||||
MountEntry *m, *mounts = NULL;
|
||||
size_t root_hash_size = 0;
|
||||
bool make_slave = false;
|
||||
unsigned n_mounts;
|
||||
int r = 0;
|
||||
@ -906,7 +909,15 @@ int setup_namespace(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dissect_image(loop_device->fd, NULL, 0, dissect_image_flags, &dissected_image);
|
||||
r = root_hash_load(root_image, &root_hash, &root_hash_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dissect_image(loop_device->fd, root_hash, root_hash_size, dissect_image_flags, &dissected_image);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dissected_image_decrypt(dissected_image, NULL, root_hash, root_hash_size, dissect_image_flags, &decrypted_image);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1038,6 +1049,10 @@ int setup_namespace(
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = decrypted_image_relinquish(decrypted_image);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
loop_device_relinquish(loop_device);
|
||||
|
||||
} else if (root_directory) {
|
||||
|
@ -191,6 +191,14 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!arg_root_hash) {
|
||||
r = root_hash_load(arg_image, &arg_root_hash, &arg_root_hash_size);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to read root hash file for %s: %m", arg_image);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
r = dissect_image(d->fd, arg_root_hash, arg_root_hash_size, arg_flags, &m);
|
||||
if (r == -ENOPKG) {
|
||||
log_error_errno(r, "Couldn't identify a suitable partition table or file system in %s.", arg_image);
|
||||
|
@ -3480,53 +3480,6 @@ static int run(int master,
|
||||
return 1; /* loop again */
|
||||
}
|
||||
|
||||
static int load_root_hash(const char *image) {
|
||||
_cleanup_free_ char *text = NULL, *fn = NULL;
|
||||
char *n, *e;
|
||||
void *k;
|
||||
size_t l;
|
||||
int r;
|
||||
|
||||
assert_se(image);
|
||||
|
||||
/* Try to load the root hash from a file next to the image file if it exists. */
|
||||
|
||||
if (arg_root_hash)
|
||||
return 0;
|
||||
|
||||
fn = new(char, strlen(image) + strlen(".roothash") + 1);
|
||||
if (!fn)
|
||||
return log_oom();
|
||||
|
||||
n = stpcpy(fn, image);
|
||||
e = endswith(fn, ".raw");
|
||||
if (e)
|
||||
n = e;
|
||||
|
||||
strcpy(n, ".roothash");
|
||||
|
||||
r = read_one_line_file(fn, &text);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to read %s, ignoring: %m", fn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unhexmem(text, strlen(text), &k, &l);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Invalid root hash: %s", text);
|
||||
if (l < sizeof(sd_id128_t)) {
|
||||
free(k);
|
||||
return log_error_errno(r, "Root hash too short: %s", text);
|
||||
}
|
||||
|
||||
arg_root_hash = k;
|
||||
arg_root_hash_size = l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
_cleanup_free_ char *console = NULL;
|
||||
@ -3742,9 +3695,13 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = load_root_hash(arg_image);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (!arg_root_hash) {
|
||||
r = root_hash_load(arg_image, &arg_root_hash, &arg_root_hash_size);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to load root hash file for %s: %m", arg_image);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mkdtemp(tmprootdir)) {
|
||||
|
@ -28,8 +28,10 @@
|
||||
#include "blkid-util.h"
|
||||
#include "dissect-image.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "gpt.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "mount-util.h"
|
||||
#include "path-util.h"
|
||||
#include "stat-util.h"
|
||||
@ -1087,6 +1089,55 @@ int decrypted_image_relinquish(DecryptedImage *d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int root_hash_load(const char *image, void **ret, size_t *ret_size) {
|
||||
_cleanup_free_ char *text = NULL;
|
||||
_cleanup_free_ void *k = NULL;
|
||||
char *fn, *e, *n;
|
||||
size_t l;
|
||||
int r;
|
||||
|
||||
assert(image);
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
|
||||
if (is_device_path(image)) {
|
||||
/* If we are asked to load the root hash for a device node, exit early */
|
||||
*ret = NULL;
|
||||
*ret_size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fn = newa(char, strlen(image) + strlen(".roothash") + 1);
|
||||
n = stpcpy(fn, image);
|
||||
e = endswith(fn, ".raw");
|
||||
if (e)
|
||||
n = e;
|
||||
|
||||
strcpy(n, ".roothash");
|
||||
|
||||
r = read_one_line_file(fn, &text);
|
||||
if (r == -ENOENT) {
|
||||
*ret = NULL;
|
||||
*ret_size = 0;
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unhexmem(text, strlen(text), &k, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (l < sizeof(sd_id128_t))
|
||||
return -EINVAL;
|
||||
|
||||
*ret = k;
|
||||
*ret_size = l;
|
||||
|
||||
k = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *const partition_designator_table[] = {
|
||||
[PARTITION_ROOT] = "root",
|
||||
[PARTITION_ROOT_SECONDARY] = "root-secondary",
|
||||
|
@ -94,3 +94,5 @@ int decrypted_image_relinquish(DecryptedImage *d);
|
||||
|
||||
const char* partition_designator_to_string(int i) _const_;
|
||||
int partition_designator_from_string(const char *name) _pure_;
|
||||
|
||||
int root_hash_load(const char *image, void **ret, size_t *ret_size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user