From ce02babfa6f55b1fd4b62875e6accfd39a4cdedd Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 2 Jul 2021 18:51:41 +0100 Subject: [PATCH] verity: add support for corruption action flag Add verity.oncorruption= to let users override the default kernel behaviour, using libcrypsetup's relevant flags. Signed-off-by: Luca Boccassi --- libmount/src/context_veritydev.c | 27 +++++++++++++++++++++++++-- libmount/src/libmount.h.in | 1 + libmount/src/optmap.c | 1 + sys-utils/mount.8.adoc | 3 +++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libmount/src/context_veritydev.c b/libmount/src/context_veritydev.c index 2878d9489c..185b57d73e 100644 --- a/libmount/src/context_veritydev.c +++ b/libmount/src/context_veritydev.c @@ -85,6 +85,7 @@ int mnt_context_setup_veritydev(struct libmnt_context *cxt) int rc = 0; /* Use the same default for FEC parity bytes as cryptsetup uses */ uint64_t offset = 0, fec_offset = 0, fec_roots = 2; + uint32_t crypt_activate_flags = CRYPT_ACTIVATE_READONLY; struct stat hash_sig_st; #ifdef CRYPTSETUP_VIA_DLOPEN /* To avoid linking libmount to libcryptsetup, and keep the default dependencies list down, use dlopen */ @@ -232,6 +233,28 @@ int mnt_context_setup_veritydev(struct libmnt_context *cxt) } } + /* + * verity.oncorruption= + */ + if (rc == 0 && (cxt->user_mountflags & MNT_MS_VERITY_ON_CORRUPTION) && + mnt_optstr_get_option(optstr, "verity.oncorruption", &val, &len) == 0) { + if (!strncmp(val, "ignore", len)) + crypt_activate_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION; + else if (!strncmp(val, "restart", len)) + crypt_activate_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION; + else if (!strncmp(val, "panic", len)) + /* Added by libcryptsetup v2.3.4 - ignore on lower versions, as with other optional features */ +#ifdef CRYPT_ACTIVATE_PANIC_ON_CORRUPTION + crypt_activate_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION; +#else + DBG(VERITY, ul_debugobj(cxt, "verity.oncorruption=panic not supported by libcryptsetup, ignoring")); +#endif + else { + DBG(VERITY, ul_debugobj(cxt, "failed to parse verity.oncorruption=")); + rc = -MNT_ERR_MOUNTOPT; + } + } + if (!rc && root_hash && root_hash_file) { DBG(VERITY, ul_debugobj(cxt, "verity.roothash and verity.roothashfile are mutually exclusive")); rc = -EINVAL; @@ -321,14 +344,14 @@ int mnt_context_setup_veritydev(struct libmnt_context *cxt) if (hash_sig) { #ifdef HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY rc = (*sym_crypt_activate_by_signed_key)(crypt_dev, mapper_device, root_hash_binary, hash_size, - hash_sig, hash_sig_size, CRYPT_ACTIVATE_READONLY); + hash_sig, hash_sig_size, crypt_activate_flags); #else rc = -EINVAL; DBG(VERITY, ul_debugobj(cxt, "verity.roothashsig=%s passed but libcryptsetup does not provide crypt_activate_by_signed_key()", hash_sig)); #endif } else rc = (*sym_crypt_activate_by_volume_key)(crypt_dev, mapper_device, root_hash_binary, hash_size, - CRYPT_ACTIVATE_READONLY); + crypt_activate_flags); /* * If the mapper device already exists, and if libcryptsetup supports it, get the root * hash associated with the existing one and compare it with the parameter passed by diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index 8ab01369ea..3bcf746828 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -917,6 +917,7 @@ extern int mnt_context_set_syscall_status(struct libmnt_context *cxt, int status #define MNT_MS_FEC_OFFSET (1 << 23) #define MNT_MS_FEC_ROOTS (1 << 24) #define MNT_MS_ROOT_HASH_SIG (1 << 25) +#define MNT_MS_VERITY_ON_CORRUPTION (1 << 26) /* * mount(2) MS_* masks (MNT_MAP_LINUX map) diff --git a/libmount/src/optmap.c b/libmount/src/optmap.c index 49e8113d21..6d0db2bf3a 100644 --- a/libmount/src/optmap.c +++ b/libmount/src/optmap.c @@ -191,6 +191,7 @@ static const struct libmnt_optmap userspace_opts_map[] = { "verity.fecoffset=", MNT_MS_FEC_OFFSET, MNT_NOHLPS | MNT_NOMTAB }, /* verity FEC area offset */ { "verity.fecroots=", MNT_MS_FEC_ROOTS, MNT_NOHLPS | MNT_NOMTAB }, /* verity FEC roots */ { "verity.roothashsig=", MNT_MS_ROOT_HASH_SIG, MNT_NOHLPS | MNT_NOMTAB }, /* verity device root hash signature file */ + { "verity.oncorruption=", MNT_MS_VERITY_ON_CORRUPTION, MNT_NOHLPS | MNT_NOMTAB }, /* verity: action the kernel takes on corruption */ { NULL, 0, 0 } }; diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc index a534586a71..f68a30df64 100644 --- a/sys-utils/mount.8.adoc +++ b/sys-utils/mount.8.adoc @@ -1405,6 +1405,9 @@ Parity bytes for FEC (default: 2). Optional. **verity.roothashsig=**__path__:: Path to *pkcs7*(1ssl) signature of root hash hex string. Requires crypt_activate_by_signed_key() from cryptsetup and kernel built with *CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG*. For device reuse, signatures have to be either used by all mounts of a device or by none. Optional. +**verity.oncorruption=**__ignore__|__restart__|__panic__:: +Instruct the kernel to ignore, reboot or panic when corruption is detected. By default the I/O operation simply fails. Requires Linux 4.1 or newer, and libcrypsetup 2.3.4 or newer. Optional. + Supported since util-linux v2.35. For example commands: -- 2.47.3