aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2023-04-19 13:44:21 +0200
committerAmir Goldstein <amir73il@gmail.com>2023-08-12 19:02:38 +0300
commitae8cba4033bc16e8a07792428a48a50710cc0f3c (patch)
tree18a5cb911e62ee310a112312969fce8d48d45bf6 /fs/overlayfs
parent52a93d39b17dc7eb98b6aa3edb93943248e03b2f (diff)
downloadlinux-ae8cba4033bc16e8a07792428a48a50710cc0f3c.tar.gz
ovl: Add framework for verity support
This adds the scaffolding (docs, config, mount options) for supporting the new digest field in the metacopy xattr. This contains a fs-verity digest that need to match the fs-verity digest of the lowerdata file. The mount option "verity" specifies how this xattr is handled. If you enable verity ("verity=on") all existing xattrs are validated before use, and during metacopy we generate verity xattr in the upper metacopy file (if the source file has verity enabled). This means later accesses can guarantee that the same data is used. Additionally you can use "verity=require". In this mode all metacopy files must have a valid verity xattr. For this to work metadata copy-up must be able to create a verity xattr (so that later accesses are validated). Therefore, in this mode, if the lower data file doesn't have fs-verity enabled we fall back to a full copy rather than a metacopy. Actual implementation follows in a separate commit. Signed-off-by: Alexander Larsson <alexl@redhat.com> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Acked-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/overlayfs.h6
-rw-r--r--fs/overlayfs/ovl_entry.h1
-rw-r--r--fs/overlayfs/params.c61
3 files changed, 65 insertions, 3 deletions
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 9402591f12aae..34cc72f8fb6ad 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -70,6 +70,12 @@ enum {
OVL_XINO_ON,
};
+enum {
+ OVL_VERITY_OFF,
+ OVL_VERITY_ON,
+ OVL_VERITY_REQUIRE,
+};
+
/*
* The tuple (fh,uuid) is a universal unique identifier for a copy up origin,
* where:
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index 306e1ecdc96d3..e999c73fb0c39 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -10,6 +10,7 @@ struct ovl_config {
char *workdir;
bool default_permissions;
int redirect_mode;
+ int verity_mode;
bool index;
bool uuid;
bool nfs_export;
diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c
index a63160dbb0f95..575a60b76a6c3 100644
--- a/fs/overlayfs/params.c
+++ b/fs/overlayfs/params.c
@@ -55,6 +55,7 @@ enum {
Opt_userxattr,
Opt_xino,
Opt_metacopy,
+ Opt_verity,
Opt_volatile,
};
@@ -101,6 +102,23 @@ static int ovl_redirect_mode_def(void)
OVL_REDIRECT_NOFOLLOW;
}
+static const struct constant_table ovl_parameter_verity[] = {
+ { "off", OVL_VERITY_OFF },
+ { "on", OVL_VERITY_ON },
+ { "require", OVL_VERITY_REQUIRE },
+ {}
+};
+
+static const char *ovl_verity_mode(struct ovl_config *config)
+{
+ return ovl_parameter_verity[config->verity_mode].name;
+}
+
+static int ovl_verity_mode_def(void)
+{
+ return OVL_VERITY_OFF;
+}
+
#define fsparam_string_empty(NAME, OPT) \
__fsparam(fs_param_is_string, NAME, OPT, fs_param_can_be_empty, NULL)
@@ -116,6 +134,7 @@ const struct fs_parameter_spec ovl_parameter_spec[] = {
fsparam_flag("userxattr", Opt_userxattr),
fsparam_enum("xino", Opt_xino, ovl_parameter_xino),
fsparam_enum("metacopy", Opt_metacopy, ovl_parameter_bool),
+ fsparam_enum("verity", Opt_verity, ovl_parameter_verity),
fsparam_flag("volatile", Opt_volatile),
{}
};
@@ -572,6 +591,9 @@ static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param)
config->metacopy = result.uint_32;
ctx->set.metacopy = true;
break;
+ case Opt_verity:
+ config->verity_mode = result.uint_32;
+ break;
case Opt_volatile:
config->ovl_volatile = true;
break;
@@ -762,6 +784,18 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
config->ovl_volatile = false;
}
+ /* Resolve verity -> metacopy dependency */
+ if (config->verity_mode && !config->metacopy) {
+ /* Don't allow explicit specified conflicting combinations */
+ if (set.metacopy) {
+ pr_err("conflicting options: metacopy=off,verity=%s\n",
+ ovl_verity_mode(config));
+ return -EINVAL;
+ }
+ /* Otherwise automatically enable metacopy. */
+ config->metacopy = true;
+ }
+
/*
* This is to make the logic below simpler. It doesn't make any other
* difference, since redirect_dir=on is only used for upper.
@@ -769,13 +803,18 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
if (!config->upperdir && config->redirect_mode == OVL_REDIRECT_FOLLOW)
config->redirect_mode = OVL_REDIRECT_ON;
- /* Resolve metacopy -> redirect_dir dependency */
+ /* Resolve verity -> metacopy -> redirect_dir dependency */
if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) {
if (set.metacopy && set.redirect) {
pr_err("conflicting options: metacopy=on,redirect_dir=%s\n",
ovl_redirect_mode(config));
return -EINVAL;
}
+ if (config->verity_mode && set.redirect) {
+ pr_err("conflicting options: verity=%s,redirect_dir=%s\n",
+ ovl_verity_mode(config), ovl_redirect_mode(config));
+ return -EINVAL;
+ }
if (set.redirect) {
/*
* There was an explicit redirect_dir=... that resulted
@@ -812,7 +851,7 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
}
}
- /* Resolve nfs_export -> !metacopy dependency */
+ /* Resolve nfs_export -> !metacopy && !verity dependency */
if (config->nfs_export && config->metacopy) {
if (set.nfs_export && set.metacopy) {
pr_err("conflicting options: nfs_export=on,metacopy=on\n");
@@ -825,6 +864,14 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
*/
pr_info("disabling nfs_export due to metacopy=on\n");
config->nfs_export = false;
+ } else if (config->verity_mode) {
+ /*
+ * There was an explicit verity=.. that resulted
+ * in this conflict.
+ */
+ pr_info("disabling nfs_export due to verity=%s\n",
+ ovl_verity_mode(config));
+ config->nfs_export = false;
} else {
/*
* There was an explicit nfs_export=on that resulted
@@ -836,7 +883,7 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
}
- /* Resolve userxattr -> !redirect && !metacopy dependency */
+ /* Resolve userxattr -> !redirect && !metacopy && !verity dependency */
if (config->userxattr) {
if (set.redirect &&
config->redirect_mode != OVL_REDIRECT_NOFOLLOW) {
@@ -848,6 +895,11 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
pr_err("conflicting options: userxattr,metacopy=on\n");
return -EINVAL;
}
+ if (config->verity_mode) {
+ pr_err("conflicting options: userxattr,verity=%s\n",
+ ovl_verity_mode(config));
+ return -EINVAL;
+ }
/*
* Silently disable default setting of redirect and metacopy.
* This shall be the default in the future as well: these
@@ -909,5 +961,8 @@ int ovl_show_options(struct seq_file *m, struct dentry *dentry)
seq_puts(m, ",volatile");
if (ofs->config.userxattr)
seq_puts(m, ",userxattr");
+ if (ofs->config.verity_mode != ovl_verity_mode_def())
+ seq_printf(m, ",verity=%s",
+ ovl_verity_mode(&ofs->config));
return 0;
}