Commit 82627927 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Wen Zhiwei
Browse files

dm-verity: restart or panic on an I/O error

stable inclusion
from stable-v6.6.54
commit bd24f30f5068df603b7d352243e15718e5c3add2
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAZ3K2

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=bd24f30f5068df603b7d352243e15718e5c3add2



--------------------------------

commit e6a3531dd542cb127c8de32ab1e54a48ae19962b upstream.

Maxim Suhanov reported that dm-verity doesn't crash if an I/O error
happens. In theory, this could be used to subvert security, because an
attacker can create sectors that return error with the Write Uncorrectable
command. Some programs may misbehave if they have to deal with EIO.

This commit fixes dm-verity, so that if "panic_on_corruption" or
"restart_on_corruption" was specified and an I/O error happens, the
machine will panic or restart.

This commit also changes kernel_restart to emergency_restart -
kernel_restart calls reboot notifiers and these reboot notifiers may wait
for the bio that failed. emergency_restart doesn't call the notifiers.

Reported-by: default avatarMaxim Suhanov <dfirblog@gmail.com>
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarWen Zhiwei <wenzhiwei@kylinos.cn>
parent c2b20f14
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -264,8 +264,10 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type,
	if (v->mode == DM_VERITY_MODE_LOGGING)
		return 0;

	if (v->mode == DM_VERITY_MODE_RESTART)
		kernel_restart("dm-verity device corrupted");
	if (v->mode == DM_VERITY_MODE_RESTART) {
		pr_emerg("dm-verity device corrupted\n");
		emergency_restart();
	}

	if (v->mode == DM_VERITY_MODE_PANIC)
		panic("dm-verity device corrupted");
@@ -689,6 +691,23 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
	if (!static_branch_unlikely(&use_tasklet_enabled) || !io->in_tasklet)
		verity_fec_finish_io(io);

	if (unlikely(status != BLK_STS_OK) &&
	    unlikely(!(bio->bi_opf & REQ_RAHEAD)) &&
	    !verity_is_system_shutting_down()) {
		if (v->mode == DM_VERITY_MODE_RESTART ||
		    v->mode == DM_VERITY_MODE_PANIC)
			DMERR_LIMIT("%s has error: %s", v->data_dev->name,
					blk_status_to_str(status));

		if (v->mode == DM_VERITY_MODE_RESTART) {
			pr_emerg("dm-verity device corrupted\n");
			emergency_restart();
		}

		if (v->mode == DM_VERITY_MODE_PANIC)
			panic("dm-verity device corrupted");
	}

	bio_endio(bio);
}