Support panic_on_corruption option form dm-verity.

The panic_on_corruption switch is available since kernel 5.9 (dm-verity 1.7.0).
This commit is contained in:
Milan Broz
2020-08-20 18:52:31 +02:00
parent f647333f49
commit 3c54d8a239
9 changed files with 42 additions and 7 deletions

View File

@@ -1103,6 +1103,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
/** use IV sector counted in sector_size instead of default 512 bytes sectors */
#define CRYPT_ACTIVATE_IV_LARGE_SECTORS (1 << 22)
/** dm-verity: panic_on_corruption flag - panic kernel on corruption */
#define CRYPT_ACTIVATE_PANIC_ON_CORRUPTION (1 << 23)
/**
* Active device runtime attributes

View File

@@ -205,6 +205,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
_dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
_dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
_dm_verity_checked = true;
}
@@ -693,14 +696,19 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
vp = tgt->u.verity.vp;
/* These flags are not compatible */
if ((flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) &&
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION))
flags &= ~CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
if ((flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) &&
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION))
(flags & (CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)))
flags &= ~CRYPT_ACTIVATE_IGNORE_CORRUPTION;
if (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION)
num_options++;
if (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION)
num_options++;
if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)
num_options++;
if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
num_options++;
if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
@@ -723,9 +731,10 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
*verity_verify_args = '\0';
if (num_options)
snprintf(features, sizeof(features)-1, " %d%s%s%s%s", num_options,
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s", num_options,
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
(flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
else
@@ -1638,6 +1647,10 @@ int dm_create_device(struct crypt_device *cd, const char *name,
!(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED))
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
if (r == -EINVAL && dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
!(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED))
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
if (r == -EINVAL && dmd->segment.type == DM_VERITY &&
dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED))
log_err(cd, _("Requested dm-verity FEC options are not supported."));
@@ -2178,6 +2191,8 @@ static int _dm_target_query_verity(struct crypt_device *cd,
*act_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
else if (!strcasecmp(arg, "restart_on_corruption"))
*act_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
else if (!strcasecmp(arg, "panic_on_corruption"))
*act_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
else if (!strcasecmp(arg, "ignore_zero_blocks"))
*act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
else if (!strcasecmp(arg, "check_at_most_once"))

View File

@@ -69,6 +69,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_BITLK_ELEPHANT_SUPPORTED (1 << 21) /* Elephant diffuser for BITLK supported */
#define DM_VERITY_SIGNATURE_SUPPORTED (1 << 22) /* Verity option root_hash_sig_key_desc supported */
#define DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is supported */
#define DM_VERITY_PANIC_CORRUPTION_SUPPORTED (1 << 24) /* dm-verity panic on corruption */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_SET = 1, TARGET_QUERY };

View File

@@ -40,8 +40,8 @@ Creates a mapping with <name> backed by device <data_device> and using
The <root_hash> is a hexadecimal string.
\fB<options>\fR can be [\-\-hash-offset, \-\-no-superblock,
\-\-ignore-corruption or \-\-restart-on-corruption, \-\-ignore-zero-blocks,
\-\-check-at-most-once, \-\-root-hash-signature]
\-\-ignore-corruption or \-\-restart-on-corruption, \-\-panic-on-corruption,
\-\-ignore-zero-blocks, \-\-check-at-most-once, \-\-root-hash-signature]
If option \-\-no-superblock is used, you have to use as the same options
as in initial format operation.
@@ -117,12 +117,13 @@ Use the provided UUID for format command instead of generating new one.
The UUID must be provided in standard UUID format,
e.g. 12345678-1234-1234-1234-123456789abc.
.TP
.B "\-\-ignore-corruption", "\-\-restart-on-corruption"
.B "\-\-ignore-corruption", "\-\-restart-on-corruption", "\-\-panic-on-corruption"
Defines what to do if data integrity problem is detected (data corruption).
Without these options kernel fails the IO operation with I/O error.
With \-\-ignore-corruption option the corruption is only logged.
With \-\-restart-on-corruption the kernel is restarted immediately.
With \-\-restart-on-corruption or \-\-panic-on-corruption the kernel
is restarted (panicked) immediately.
(You have to provide way how to avoid restart loops.)
\fBWARNING:\fR Use these options only for very specific cases.

View File

@@ -99,6 +99,7 @@
#define OPT_NEW_KEYFILE_OFFSET "new-keyfile-offset"
#define OPT_NEW_KEYFILE_SIZE "new-keyfile-size"
#define OPT_OFFSET "offset"
#define OPT_PANIC_ON_CORRUPTION "panic-on-corruption"
#define OPT_PBKDF "pbkdf"
#define OPT_PBKDF_FORCE_ITERATIONS "pbkdf-force-iterations"
#define OPT_PBKDF_MEMORY "pbkdf-memory"

View File

@@ -140,6 +140,8 @@ static int _activate(const char *dm_device,
activate_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
if (ARG_SET(OPT_RESTART_ON_CORRUPTION_ID))
activate_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
if (ARG_SET(OPT_PANIC_ON_CORRUPTION_ID))
activate_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
if (ARG_SET(OPT_IGNORE_ZERO_BLOCKS_ID))
activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
if (ARG_SET(OPT_CHECK_AT_MOST_ONCE_ID))
@@ -336,11 +338,13 @@ static int action_status(int arg)
if (cad.flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
CRYPT_ACTIVATE_PANIC_ON_CORRUPTION|
CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE))
log_std(" flags: %s%s%s%s\n",
log_std(" flags: %s%s%s%s%s\n",
(cad.flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? "ignore_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? "restart_on_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? "panic_on_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? "ignore_zero_blocks " : "",
(cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : "");
}
@@ -539,6 +543,11 @@ int main(int argc, const char **argv)
_("Option --ignore-corruption and --restart-on-corruption cannot be used together."),
poptGetInvocationName(popt_context));
if (ARG_SET(OPT_PANIC_ON_CORRUPTION_ID) && ARG_SET(OPT_RESTART_ON_CORRUPTION_ID))
usage(popt_context, EXIT_FAILURE,
_("Option --panic-on-corruption and --restart-on-corruption cannot be used together."),
poptGetInvocationName(popt_context));
if (ARG_SET(OPT_DEBUG_ID)) {
ARG_SET(OPT_VERBOSE_ID) = true;
crypt_set_debug_level(CRYPT_DEBUG_ALL);

View File

@@ -49,6 +49,8 @@ ARG(OPT_IGNORE_ZERO_BLOCKS, '\0', POPT_ARG_NONE, N_("Do not verify zeroed blocks
ARG(OPT_NO_SUPERBLOCK, '\0', POPT_ARG_NONE, N_("Do not use verity superblock"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_PANIC_ON_CORRUPTION, '\0', POPT_ARG_NONE, N_("Panic kernel if corruption is detected"), NULL, CRYPT_ARG_BOOL, {}, OPT_PANIC_ON_CORRUPTION_ACTIONS)
ARG(OPT_RESTART_ON_CORRUPTION, '\0', POPT_ARG_NONE, N_("Restart kernel if corruption is detected"), NULL, CRYPT_ARG_BOOL, {}, OPT_RESTART_ON_CORRUPTION_ACTIONS)
ARG(OPT_ROOT_HASH_SIGNATURE, '\0', POPT_ARG_STRING, N_("Path to root hash signature file"), NULL, CRYPT_ARG_STRING, {}, OPT_ROOT_HASH_SIGNATURE_ACTIONS)

View File

@@ -35,6 +35,7 @@
#define OPT_IGNORE_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_IGNORE_ZERO_BLOCKS_ACTIONS { OPEN_ACTION }
#define OPT_RESTART_ON_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_PANIC_ON_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_ROOT_HASH_SIGNATURE_ACTIONS { OPEN_ACTION }
enum {

View File

@@ -424,6 +424,9 @@ if check_version 1 3; then
if check_version 1 4; then
check_option 512 $HASH $SALT 1 sha256 "--check-at-most-once" "check_at_most_once"
fi
if check_version 1 7; then
check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption"
fi
fi
echo "Veritysetup [hash-offset bigger than 2G works] "