core: add RootHash and RootVerity service parameters

Allow to explicitly pass root hash (explicitly or as a file) and verity
device/file as unit options. Take precedence over implicit checks.
This commit is contained in:
Luca Boccassi
2020-06-23 10:50:09 +02:00
committed by Lennart Poettering
parent 6fe01ced0e
commit 0389f4fa81
17 changed files with 262 additions and 25 deletions
+21
View File
@@ -13,6 +13,7 @@
#include "escape.h"
#include "exec-util.h"
#include "exit-status.h"
#include "fileio.h"
#include "hexdecoct.h"
#include "hostname-util.h"
#include "in-addr-util.h"
@@ -24,6 +25,7 @@
#include "nsflags.h"
#include "numa-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "rlimit-util.h"
#include "securebits-util.h"
@@ -849,6 +851,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
"ProtectHome",
"SELinuxContext",
"RootImage",
"RootVerity",
"RuntimeDirectoryPreserve",
"Personality",
"KeyringMode",
@@ -1415,6 +1418,24 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
return 1;
}
if (streq(field, "RootHash")) {
_cleanup_free_ void *roothash_decoded = NULL;
size_t roothash_decoded_size = 0;
/* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
if (path_is_absolute(eq))
return bus_append_string(m, "RootHashPath", eq);
/* We have a roothash to decode, eg: RootHash=012345789abcdef */
r = unhexmem(eq, strlen(eq), &roothash_decoded, &roothash_decoded_size);
if (r < 0)
return log_error_errno(r, "Failed to decode RootHash= '%s': %m", eq);
if (roothash_decoded_size < sizeof(sd_id128_t))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "RootHash= '%s' is too short: %m", eq);
return bus_append_byte_array(m, field, roothash_decoded, roothash_decoded_size);
}
return 0;
}
+22 -15
View File
@@ -1421,7 +1421,7 @@ int decrypted_image_relinquish(DecryptedImage *d) {
return 0;
}
int verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data) {
int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data) {
_cleanup_free_ char *verity_filename = NULL;
_cleanup_free_ void *roothash_decoded = NULL;
size_t roothash_decoded_size = 0;
@@ -1465,24 +1465,31 @@ int verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roo
_cleanup_free_ char *text = NULL;
assert(ret_roothash_size);
r = getxattr_malloc(image, "user.verity.roothash", &text, true);
if (r < 0) {
char *fn, *e, *n;
if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
if (root_hash_path) {
/* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
r = read_one_line_file(root_hash_path, &text);
if (r < 0)
return r;
} else {
r = getxattr_malloc(image, "user.verity.roothash", &text, true);
if (r < 0) {
char *fn, *e, *n;
fn = newa(char, strlen(image) + STRLEN(".roothash") + 1);
n = stpcpy(fn, image);
e = endswith(fn, ".raw");
if (e)
n = e;
if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
return r;
strcpy(n, ".roothash");
fn = newa(char, strlen(image) + STRLEN(".roothash") + 1);
n = stpcpy(fn, image);
e = endswith(fn, ".raw");
if (e)
n = e;
r = read_one_line_file(fn, &text);
if (r < 0 && r != -ENOENT)
return r;
strcpy(n, ".roothash");
r = read_one_line_file(fn, &text);
if (r < 0 && r != -ENOENT)
return r;
}
}
if (text) {
+1 -1
View File
@@ -100,6 +100,6 @@ 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 verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data);
int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data);
bool dissected_image_can_do_verity(const DissectedImage *image, unsigned partition_designator);
bool dissected_image_has_verity(const DissectedImage *image, unsigned partition_designator);