PyModule_AddIntConstant(m, "MNT_MS_ROOT_HASH", MNT_MS_ROOT_HASH);
PyModule_AddIntConstant(m, "MNT_MS_HASH_OFFSET", MNT_MS_HASH_OFFSET);
PyModule_AddIntConstant(m, "MNT_MS_ROOT_HASH_FILE", MNT_MS_ROOT_HASH_FILE);
+ PyModule_AddIntConstant(m, "MNT_MS_FEC_DEVICE", MNT_MS_FEC_DEVICE);
+ PyModule_AddIntConstant(m, "MNT_MS_FEC_OFFSET", MNT_MS_FEC_OFFSET);
+ PyModule_AddIntConstant(m, "MNT_MS_FEC_ROOTS", MNT_MS_FEC_ROOTS);
/*
* mount(2) MS_* masks (MNT_MAP_LINUX map)
const char *backing_file, *optstr;
char *val = NULL, *key = NULL, *root_hash_binary = NULL, *mapper_device = NULL,
*mapper_device_full = NULL, *backing_file_basename = NULL, *root_hash = NULL,
- *hash_device = NULL, *root_hash_file = NULL;
+ *hash_device = NULL, *root_hash_file = NULL, *fec_device = NULL;
size_t len, hash_size, keysize = 0;
struct crypt_params_verity crypt_params = {};
struct crypt_device *crypt_dev = NULL;
int rc = 0;
- uint64_t offset = 0;
+ /* Use the same default for FEC parity bytes as cryptsetup uses */
+ uint64_t offset = 0, fec_offset = 0, fec_roots = 2;
assert(cxt);
assert(cxt->fs);
rc = root_hash_file ? 0 : -ENOMEM;
}
+ /*
+ * verity.fecdevice=
+ */
+ if (rc == 0 && (cxt->user_mountflags & MNT_MS_FEC_DEVICE) &&
+ mnt_optstr_get_option(optstr, "verity.fecdevice", &val, &len) == 0 && val) {
+ fec_device = strndup(val, len);
+ rc = fec_device ? 0 : -ENOMEM;
+ }
+
+ /*
+ * verity.fecoffset=
+ */
+ if (rc == 0 && (cxt->user_mountflags & MNT_MS_FEC_OFFSET) &&
+ mnt_optstr_get_option(optstr, "verity.fecoffset", &val, &len) == 0) {
+ rc = mnt_parse_offset(val, len, &fec_offset);
+ if (rc) {
+ DBG(VERITY, ul_debugobj(cxt, "failed to parse verity.fecoffset="));
+ rc = -MNT_ERR_MOUNTOPT;
+ }
+ }
+
+ /*
+ * verity.fecroots=
+ */
+ if (rc == 0 && (cxt->user_mountflags & MNT_MS_FEC_ROOTS) &&
+ mnt_optstr_get_option(optstr, "verity.fecroots", &val, &len) == 0) {
+ rc = mnt_parse_offset(val, len, &fec_roots);
+ if (rc) {
+ DBG(VERITY, ul_debugobj(cxt, "failed to parse verity.fecroots="));
+ rc = -MNT_ERR_MOUNTOPT;
+ }
+ }
+
if (root_hash && root_hash_file) {
DBG(VERITY, ul_debugobj(cxt, "verity.roothash and verity.roothashfile are mutually exclusive"));
rc = -EINVAL;
memset(&crypt_params, 0, sizeof(struct crypt_params_verity));
crypt_params.hash_area_offset = offset;
- crypt_params.fec_area_offset = 0;
- crypt_params.fec_roots = 0;
- crypt_params.fec_device = NULL;
+ crypt_params.fec_area_offset = fec_offset;
+ crypt_params.fec_roots = fec_roots;
+ crypt_params.fec_device = fec_device;
crypt_params.flags = 0;
rc = crypt_load(crypt_dev, CRYPT_VERITY, &crypt_params);
if (rc < 0)
free(hash_device);
free(root_hash);
free(root_hash_file);
+ free(fec_device);
free(key);
return rc;
}
{ "verity.roothash=", MNT_MS_ROOT_HASH, MNT_NOHLPS | MNT_NOMTAB }, /* verity device root hash */
{ "verity.hashoffset=", MNT_MS_HASH_OFFSET, MNT_NOHLPS | MNT_NOMTAB }, /* verity device hash offset */
{ "verity.roothashfile=", MNT_MS_ROOT_HASH_FILE, MNT_NOHLPS | MNT_NOMTAB },/* verity device root hash (read from file) */
+ { "verity.fecdevice=", MNT_MS_FEC_DEVICE, MNT_NOHLPS | MNT_NOMTAB }, /* verity FEC device */
+ { "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 */
{ NULL, 0, 0 }
};
If the hash tree device is embedded in the source volume,
.I offset
(default: 0) is used by dm-verity to get to the tree.
+.TP
+\fBverity.fecdevice=\fP\,\fIpath\fP
+Path to the Forward Error Correction (FEC) device associated with the source volume to pass to dm-verity.
+Optional. Requires kernel built with CONFIG_DM_VERITY_FEC.
+.TP
+\fBverity.fecoffset=\fP\,\fIoffset\fP
+If the FEC device is embedded in the source volume,
+.I offset
+(default: 0) is used by dm-verity to get to the FEC area. Optional.
+.TP
+\fBverity.fecroots=\fP\,\fIvalue\fP
+Parity bytes for FEC (default: 2). Optional.
.RE
.PP
Supported since util-linux v2.35.