Fix dm-verity FEC calculation if stored in the same image with hashes.

FEC (Forward Error Correction) data should cover the whole data area,
hashes (Merkle tree) and optionally additional metadata (located after hash area).

Unfortunately, if FEC data is stored in the same file as hash, the calculation
wrongly used the whole file size thus overlaps with FEC area itself.
This produces unusable and too large FEC data.

(There is not a problem if FEC image is a separate image.)

This patch fixes the problem, introducing FEC blocks calculation as:

 -If hash device is in a separate image, metadata covers the whole rest of the image after hash area.
  (Unchanged behaviour.)

 -If hash and FEC device is in the image, metadata ends on the FEC area offset.

This should probably fix several issues reported with FEC wrong calculations.

Fixes: #554
This commit is contained in:
Milan Broz
2021-02-13 18:55:36 +01:00
parent 0dfeb304cc
commit 4359973586
6 changed files with 75 additions and 30 deletions

View File

@@ -122,9 +122,8 @@ struct dm_target {
const char *root_hash_sig_key_desc;
uint64_t hash_offset; /* hash offset in blocks (not header) */
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
uint64_t fec_offset; /* FEC offset in blocks (not header) */
uint64_t fec_blocks; /* size of FEC device (in hash blocks) */
uint64_t fec_blocks; /* FEC blocks covering data + hash + padding (foreign metadata)*/
struct crypt_params_verity *vp;
} verity;
struct {
@@ -191,8 +190,8 @@ int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg
uint32_t tag_size, uint32_t sector_size);
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
struct device *data_device, struct device *hash_device, struct device *fec_device,
const char *root_hash, uint32_t root_hash_size, const char *root_hash_sig_key_desc,
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp);
const char *root_hash, uint32_t root_hash_size, const char* root_hash_sig_key_desc,
uint64_t hash_offset_block, uint64_t fec_blocks, struct crypt_params_verity *vp);
int dm_integrity_target_set(struct crypt_device *cd,
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
struct device *meta_device,