]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: try to read roothash value off user.verity.roothash xattr of image file
authorLennart Poettering <lennart@poettering.net>
Fri, 23 Dec 2016 16:38:12 +0000 (17:38 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 7 Feb 2017 11:21:29 +0000 (12:21 +0100)
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.

man/systemd-nspawn.xml
src/shared/dissect-image.c

index f6b3f57fc77a24b31eafdba291aa2d4561662267..b8cae62818db7199d3ff8e26cac8836721c8037a 100644 (file)
         <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>
index f3cd663602c34b06c7f9feba3c17453ac539fd33..66ddf3a8721093fa10224828dbe02329ec10377d 100644 (file)
@@ -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)