When the "fix_hmac" argument is used, dm-integrity is supposed to check the superblock with the journal_mac. However, there was a logic bug in the code - the code only checked the superblock mac if the bit SB_FLAG_FIXED_HMAC was set in the superblock. So, the attacker could clear this bit and bypass the checking trivially.
This commit changes dm-integrity so that when the user specified the "fix_hmac" flag and the superblock doesn't have the bit SB_FLAG_FIXED_HMAC set, the activation is aborted with an error. Unfortunatelly, there's a bug in the integritysetup tool that when using the 'open' command it passes the "fix_hmac" argument to the kernel even if the user specified --integrity-legacy-hmac. The bug will be fixed in the upcoming 2.8.7 release. Signed-off-by: Mikulas Patocka <[email protected]> Reported-by: Shukai Ni <[email protected]> --- drivers/md/dm-integrity.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) Index: linux-2.6/drivers/md/dm-integrity.c =================================================================== --- linux-2.6.orig/drivers/md/dm-integrity.c 2026-07-09 21:07:04.000000000 +0200 +++ linux-2.6/drivers/md/dm-integrity.c 2026-07-09 21:10:32.000000000 +0200 @@ -5128,6 +5128,20 @@ static int dm_integrity_ctr(struct dm_ta ti->error = "Journal mac mismatch"; goto bad; } + if (ic->fix_hmac && !(ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_HMAC)) && ic->journal_mac_alg.key_string) { + /* + * If this happens, it may be either because someone tampered + * with the device or it may be due to a bug in the + * integritysetup tool. + * + * In the latter case, upgrade to integritysetup 2.8.7 and use + * the argument --integrity-legacy-hmac when using the open + * command. + */ + r = -EINVAL; + ti->error = "fix_hmac is on the command line but not in the superblock"; + goto bad; + } get_provided_data_sectors(ic); if (!ic->provided_data_sectors) {
