repo: Move fsverity bits to ostree-repo-verity.c
authorColin Walters <walters@verbum.org>
Thu, 7 Jan 2021 21:17:01 +0000 (21:17 +0000)
committerColin Walters <walters@verbum.org>
Mon, 11 Jan 2021 14:36:40 +0000 (14:36 +0000)
This file will get larger when we start doing more with fsverity.

Makefile-libostree.am
src/libostree/ostree-repo-commit.c
src/libostree/ostree-repo-private.h
src/libostree/ostree-repo-verity.c [new file with mode: 0644]
src/libostree/ostree-repo.c

index 02dbadedfe54cc0b62b426ebfa73bb0fefe3b625..7f9d7e671b7f40bf09fc0709a16608155c9a60de 100644 (file)
@@ -101,6 +101,7 @@ libostree_1_la_SOURCES = \
        src/libostree/ostree-repo-libarchive.c \
        src/libostree/ostree-repo-prune.c \
        src/libostree/ostree-repo-refs.c \
+       src/libostree/ostree-repo-verity.c \
        src/libostree/ostree-repo-traverse.c \
        src/libostree/ostree-repo-private.h \
        src/libostree/ostree-repo-file.c \
index 690075e1227512dab416a4ab7a1f96d2617d221c..9d5c6d3b28c8a6115e6c6a10f203cf76f7772ab2 100644 (file)
@@ -33,9 +33,6 @@
 #include <sys/ioctl.h>
 #include <linux/fs.h>
 #include <ext2fs/ext2_fs.h>
-#ifdef HAVE_LINUX_FSVERITY_H
-#include <linux/fsverity.h>
-#endif
 
 #include "otutil.h"
 #include "ostree.h"
@@ -190,113 +187,6 @@ ot_security_smack_reset_fd (int fd)
 #endif
 }
 
-/* Wrapper around the fsverity ioctl, compressing the result to
- * "success, unsupported or error".  This is used for /boot where
- * we enable verity if supported.
- * */
-gboolean
-_ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf,
-                            _OstreeFeatureSupport fsverity_requested,
-                            gboolean    *supported,
-                            GError     **error)
-{
-  /* Set this by default to simplify the code below */
-  if (supported)
-    *supported = FALSE;
-
-  if (fsverity_requested == _OSTREE_FEATURE_NO)
-    return TRUE;
-
-#ifdef HAVE_LINUX_FSVERITY_H
-  GLNX_AUTO_PREFIX_ERROR ("fsverity", error);
-
-  /* fs-verity requires a read-only file descriptor */
-  if (!glnx_tmpfile_reopen_rdonly (tmpf, error))
-    return FALSE;
-
-  struct fsverity_enable_arg arg = { 0, };
-  arg.version = 1;
-  arg.hash_algorithm =  FS_VERITY_HASH_ALG_SHA256;  /* TODO configurable? */
-  arg.block_size = 4096; /* FIXME query */
-  arg.salt_size = 0; /* TODO store salt in ostree repo config */
-  arg.salt_ptr = 0;
-  arg.sig_size = 0; /* We don't currently expect use of in-kernel signature verification */
-  arg.sig_ptr = 0;
-
-  if (ioctl (tmpf->fd, FS_IOC_ENABLE_VERITY, &arg) < 0)
-    {
-      switch (errno)
-        {
-          case ENOTTY:
-          case EOPNOTSUPP:
-            return TRUE;
-          default:
-            return glnx_throw_errno_prefix (error, "ioctl(FS_IOC_ENABLE_VERITY)");
-        }
-    }
-  
-  if (supported)
-    *supported = TRUE;
-#endif
-  return TRUE;
-}
-
-/* Enable verity on a file, respecting the "wanted" and "supported" states.
- * The main idea here is to optimize out pointlessly calling the ioctl()
- * over and over in cases where it's not supported for the repo's filesystem,
- * as well as to support "opportunistic" use (requested and if filesystem supports).
- * */
-gboolean
-_ostree_tmpf_fsverity (OstreeRepo  *self,
-                       GLnxTmpfile *tmpf,
-                       GError    **error)
-{
-#ifdef HAVE_LINUX_FSVERITY_H
-  g_mutex_lock (&self->txn_lock);
-  _OstreeFeatureSupport fsverity_wanted = self->fs_verity_wanted;
-  _OstreeFeatureSupport fsverity_supported = self->fs_verity_supported;
-  g_mutex_unlock (&self->txn_lock);
-
-  switch (fsverity_wanted)
-    {
-      case _OSTREE_FEATURE_YES:
-        {
-          if (fsverity_supported == _OSTREE_FEATURE_NO)
-            return glnx_throw (error, "fsverity required but filesystem does not support it");
-        }
-        break;
-      case _OSTREE_FEATURE_MAYBE:
-        break;
-      case _OSTREE_FEATURE_NO:
-        return TRUE;
-    }
-
-  gboolean supported = FALSE;
-  if (!_ostree_tmpf_fsverity_core (tmpf, fsverity_wanted, &supported, error))
-    return FALSE;
-
-  if (!supported)
-    {
-      if (G_UNLIKELY (fsverity_wanted == _OSTREE_FEATURE_YES))
-        return glnx_throw (error, "fsverity required but filesystem does not support it");
-
-      /* If we got here, we must be trying "opportunistic" use of fs-verity */
-      g_assert_cmpint (fsverity_wanted, ==, _OSTREE_FEATURE_MAYBE);
-      g_mutex_lock (&self->txn_lock);
-      self->fs_verity_supported = _OSTREE_FEATURE_NO;
-      g_mutex_unlock (&self->txn_lock);
-      return TRUE;
-    }
-  
-  g_mutex_lock (&self->txn_lock);
-  self->fs_verity_supported = _OSTREE_FEATURE_YES;
-  g_mutex_unlock (&self->txn_lock);
-#else
-  g_assert_cmpint (self->fs_verity_wanted, !=, _OSTREE_FEATURE_YES);
-#endif
-  return TRUE;
-}
-
 /* Given an O_TMPFILE regular file, link it into place. */
 gboolean
 _ostree_repo_commit_tmpf_final (OstreeRepo        *self,
index 714fda8ba9cca2e9655f9145a767586950049cfb..6c01bc6bc4265a92b990910da7f76fd163d15cf7 100644 (file)
@@ -521,6 +521,8 @@ OstreeRepoAutoLock * _ostree_repo_auto_lock_push (OstreeRepo          *self,
 void          _ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, _ostree_repo_auto_lock_cleanup)
 
+gboolean _ostree_repo_parse_fsverity_config (OstreeRepo *self, GError **error);
+
 gboolean
 _ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf,
                             _OstreeFeatureSupport fsverity_requested,
diff --git a/src/libostree/ostree-repo-verity.c b/src/libostree/ostree-repo-verity.c
new file mode 100644 (file)
index 0000000..92b026e
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <sys/ioctl.h>
+
+#include "ostree-core-private.h"
+#include "ostree-repo-private.h"
+#include "otutil.h"
+#include "ot-fs-utils.h"
+#ifdef HAVE_LINUX_FSVERITY_H
+#include <linux/fsverity.h>
+#endif
+
+gboolean 
+_ostree_repo_parse_fsverity_config (OstreeRepo *self, GError **error)
+{
+  /* Currently experimental */
+  static const char fsverity_key[] = "ex-fsverity";
+  self->fs_verity_wanted = _OSTREE_FEATURE_NO;
+#ifdef HAVE_LINUX_FSVERITY_H
+  self->fs_verity_supported = _OSTREE_FEATURE_MAYBE;
+#else
+  self->fs_verity_supported = _OSTREE_FEATURE_NO;
+#endif
+  gboolean fsverity_required = FALSE;
+  if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "required",
+                                            FALSE, &fsverity_required, error))
+    return FALSE;
+  if (fsverity_required)
+    {
+      self->fs_verity_wanted = _OSTREE_FEATURE_YES;
+      if (self->fs_verity_supported == _OSTREE_FEATURE_NO)
+        return glnx_throw (error, "fsverity required, but libostree compiled without support");
+    }
+  else
+    {  
+      gboolean fsverity_opportunistic = FALSE;
+      if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "opportunistic",
+                                                FALSE, &fsverity_opportunistic, error))
+        return FALSE;
+      if (fsverity_opportunistic)
+        self->fs_verity_wanted = _OSTREE_FEATURE_MAYBE;
+    }
+
+  return TRUE;
+}
+
+
+/* Wrapper around the fsverity ioctl, compressing the result to
+ * "success, unsupported or error".  This is used for /boot where
+ * we enable verity if supported.
+ * */
+gboolean
+_ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf,
+                            _OstreeFeatureSupport fsverity_requested,
+                            gboolean    *supported,
+                            GError     **error)
+{
+  /* Set this by default to simplify the code below */
+  if (supported)
+    *supported = FALSE;
+
+  if (fsverity_requested == _OSTREE_FEATURE_NO)
+    return TRUE;
+
+#ifdef HAVE_LINUX_FSVERITY_H
+  GLNX_AUTO_PREFIX_ERROR ("fsverity", error);
+
+  /* fs-verity requires a read-only file descriptor */
+  if (!glnx_tmpfile_reopen_rdonly (tmpf, error))
+    return FALSE;
+
+  struct fsverity_enable_arg arg = { 0, };
+  arg.version = 1;
+  arg.hash_algorithm =  FS_VERITY_HASH_ALG_SHA256;  /* TODO configurable? */
+  arg.block_size = 4096; /* FIXME query */
+  arg.salt_size = 0; /* TODO store salt in ostree repo config */
+  arg.salt_ptr = 0;
+  arg.sig_size = 0; /* We don't currently expect use of in-kernel signature verification */
+  arg.sig_ptr = 0;
+
+  if (ioctl (tmpf->fd, FS_IOC_ENABLE_VERITY, &arg) < 0)
+    {
+      switch (errno)
+        {
+          case ENOTTY:
+          case EOPNOTSUPP:
+            return TRUE;
+          default:
+            return glnx_throw_errno_prefix (error, "ioctl(FS_IOC_ENABLE_VERITY)");
+        }
+    }
+  
+  if (supported)
+    *supported = TRUE;
+#endif
+  return TRUE;
+}
+
+/* Enable verity on a file, respecting the "wanted" and "supported" states.
+ * The main idea here is to optimize out pointlessly calling the ioctl()
+ * over and over in cases where it's not supported for the repo's filesystem,
+ * as well as to support "opportunistic" use (requested and if filesystem supports).
+ * */
+gboolean
+_ostree_tmpf_fsverity (OstreeRepo  *self,
+                       GLnxTmpfile *tmpf,
+                       GError    **error)
+{
+#ifdef HAVE_LINUX_FSVERITY_H
+  g_mutex_lock (&self->txn_lock);
+  _OstreeFeatureSupport fsverity_wanted = self->fs_verity_wanted;
+  _OstreeFeatureSupport fsverity_supported = self->fs_verity_supported;
+  g_mutex_unlock (&self->txn_lock);
+
+  switch (fsverity_wanted)
+    {
+      case _OSTREE_FEATURE_YES:
+        {
+          if (fsverity_supported == _OSTREE_FEATURE_NO)
+            return glnx_throw (error, "fsverity required but filesystem does not support it");
+        }
+        break;
+      case _OSTREE_FEATURE_MAYBE:
+        break;
+      case _OSTREE_FEATURE_NO:
+        return TRUE;
+    }
+
+  gboolean supported = FALSE;
+  if (!_ostree_tmpf_fsverity_core (tmpf, fsverity_wanted, &supported, error))
+    return FALSE;
+
+  if (!supported)
+    {
+      if (G_UNLIKELY (fsverity_wanted == _OSTREE_FEATURE_YES))
+        return glnx_throw (error, "fsverity required but filesystem does not support it");
+
+      /* If we got here, we must be trying "opportunistic" use of fs-verity */
+      g_assert_cmpint (fsverity_wanted, ==, _OSTREE_FEATURE_MAYBE);
+      g_mutex_lock (&self->txn_lock);
+      self->fs_verity_supported = _OSTREE_FEATURE_NO;
+      g_mutex_unlock (&self->txn_lock);
+      return TRUE;
+    }
+  
+  g_mutex_lock (&self->txn_lock);
+  self->fs_verity_supported = _OSTREE_FEATURE_YES;
+  g_mutex_unlock (&self->txn_lock);
+#else
+  g_assert_cmpint (self->fs_verity_wanted, !=, _OSTREE_FEATURE_YES);
+#endif
+  return TRUE;
+}
index 1c951b127f802551edacea8cf23339a031af666b..35b1a2b0c9ece837905648574ae2eb40f0da1bcc 100644 (file)
@@ -3017,33 +3017,8 @@ reload_core_config (OstreeRepo          *self,
       }
   }
 
-  /* Currently experimental */
-  static const char fsverity_key[] = "ex-fsverity";
-  self->fs_verity_wanted = _OSTREE_FEATURE_NO;
-#ifdef HAVE_LINUX_FSVERITY_H
-  self->fs_verity_supported = _OSTREE_FEATURE_MAYBE;
-#else
-  self->fs_verity_supported = _OSTREE_FEATURE_NO;
-#endif
-  gboolean fsverity_required = FALSE;
-  if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "required",
-                                            FALSE, &fsverity_required, error))
+  if (!_ostree_repo_parse_fsverity_config (self, error))
     return FALSE;
-  if (fsverity_required)
-    {
-      self->fs_verity_wanted = _OSTREE_FEATURE_YES;
-      if (self->fs_verity_supported == _OSTREE_FEATURE_NO)
-        return glnx_throw (error, "fsverity required, but libostree compiled without support");
-    }
-  else
-    {  
-      gboolean fsverity_opportunistic = FALSE;
-      if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "opportunistic",
-                                                FALSE, &fsverity_opportunistic, error))
-        return FALSE;
-      if (fsverity_opportunistic)
-        self->fs_verity_wanted = _OSTREE_FEATURE_MAYBE;
-    }
   
   {
     g_clear_pointer (&self->collection_id, g_free);