diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-12-23 17:38:12 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-02-07 12:21:29 +0100 |
commit | 41488e1f7acf5f4b5e11ff992a05ee1baa537d54 (patch) | |
tree | ffe49f452a10501be1e500218184e32480770eaa | |
parent | 78ebe98061eb527f17691929f470f262a7ab2c8f (diff) |
dissect: try to read roothash value off user.verity.roothash xattr of image file
This slightly extends the roothash loading logic to first check for a
user.verity.roothash extended attribute on the image file. If it exists,
it is used as Verity root hash and the ".roothash" file is not used.
This should improve the chance that the roothash is retained when the
file is moved around, as the data snippet is attached directly to the
image file. The field is still detached from the file payload however,
in order to make sure it may be trusted independently.
This does not replace the ".roothash" file loading, it simply adds a
second way to retrieve the data.
Extended attributes are often a poor choice for storing metadata like
this as it is usually difficult to discover for admins and users, and
hard to fix if it ever gets out of sync. However, in this case I think
it's safe as verity implies read-only access, and thus there's little
chance of it to get out of sync.
-rw-r--r-- | man/systemd-nspawn.xml | 10 | ||||
-rw-r--r-- | src/shared/dissect-image.c | 36 |
2 files changed, 29 insertions, 17 deletions
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index f6b3f57fc7..b8cae62818 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -257,9 +257,13 @@ <listitem><para>Takes a data integrity (dm-verity) root hash specified in hexadecimal. This option enables data integrity checks using dm-verity, if the used image contains the appropriate integrity data (see above). The specified hash must match the root hash of integrity data, and is usually at least 256bits (and hence 64 - hexadecimal characters) long (in case of SHA256 for example). If this option is not specified, but a file with - the <filename>.roothash</filename> suffix is found next to the image file, bearing otherwise the same name the - root hash is read from it and automatically used.</para></listitem> + formatted hexadecimal characters) long (in case of SHA256 for example). If this option is not specified, but + the image file carries the <literal>user.verity.roothash</literal> extended file attribute (see <citerefentry + project='man-pages'><refentrytitle>xattr</refentrytitle><manvolnum>7</manvolnum></citerefentry>), then the root + hash is read from it, also as formatted hexadecimal characters. If the extended file attribute is not found (or + not supported by the underlying file system), but a file with the <filename>.roothash</filename> suffix is + found next to the image file, bearing otherwise the same name the root hash is read from it and automatically + used (again, as formatted hexadecimal characters).</para></listitem> </varlistentry> <varlistentry> diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index f3cd663602..66ddf3a872 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -40,6 +40,7 @@ #include "string-util.h" #include "strv.h" #include "udev-util.h" +#include "xattr-util.h" static int probe_filesystem(const char *node, char **ret_fstype) { #ifdef HAVE_BLKID @@ -1092,7 +1093,6 @@ int decrypted_image_relinquish(DecryptedImage *d) { 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; @@ -1107,22 +1107,30 @@ int root_hash_load(const char *image, void **ret, size_t *ret_size) { return 0; } - fn = newa(char, strlen(image) + strlen(".roothash") + 1); - n = stpcpy(fn, image); - e = endswith(fn, ".raw"); - if (e) - n = e; + r = getxattr_malloc(image, "user.verity.roothash", &text, true); + if (r < 0) { + char *fn, *e, *n; - strcpy(n, ".roothash"); + if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT)) + return r; - r = read_one_line_file(fn, &text); - if (r == -ENOENT) { - *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; } - if (r < 0) - return r; r = unhexmem(text, strlen(text), &k, &l); if (r < 0) |