summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-12-23 17:10:42 +0100
committerLennart Poettering <lennart@poettering.net>2017-02-07 12:21:28 +0100
commit78ebe98061eb527f17691929f470f262a7ab2c8f (patch)
tree59683606cfb85012fb77d4416a95ffa4144c0acd
parent915e6d1676cf73c4f927f3bbfa21ee82640b1832 (diff)
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.
-rw-r--r--src/core/namespace.c17
-rw-r--r--src/dissect/dissect.c8
-rw-r--r--src/nspawn/nspawn.c57
-rw-r--r--src/shared/dissect-image.c51
-rw-r--r--src/shared/dissect-image.h2
5 files changed, 84 insertions, 51 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 0ae5f704c7..75dca5b791 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -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) {
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index fd9db5ba87..59bd7d9e84 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -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);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 5594b87efa..213f50f796 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -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)) {
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 5fc2ce25f0..f3cd663602 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -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",
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index 26319bd8e7..cdb083be6f 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -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);