From d5c97f3de7ac3d5568bc641cc87a2edf37f8b9b5 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Thu, 26 Dec 2019 13:57:05 -0500 Subject: [PATCH] Avoid some crashes when importing a pool with corrupt metadata - Skip invalid DVAs when importing pools in readonly mode (in addition to when the config is untrusted). - Upon encountering a DVA with a null VDEV, fail gracefully instead of panicking with a NULL pointer dereference. Reviewed-by: Pavel Zakharov Reviewed-by: Brian Behlendorf Signed-off-by: Steve Mokris Closes #9022 --- module/zfs/vdev_mirror.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/module/zfs/vdev_mirror.c b/module/zfs/vdev_mirror.c index 552b83e00..3edd65c01 100644 --- a/module/zfs/vdev_mirror.c +++ b/module/zfs/vdev_mirror.c @@ -282,10 +282,11 @@ vdev_mirror_map_init(zio_t *zio) } /* - * If we do not trust the pool config, some DVAs might be - * invalid or point to vdevs that do not exist. We skip them. + * If the pool cannot be written to, then infer that some + * DVAs might be invalid or point to vdevs that do not exist. + * We skip them. */ - if (!spa_trust_config(spa)) { + if (!spa_writeable(spa)) { ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ); int j = 0; for (int i = 0; i < c; i++) { @@ -309,6 +310,13 @@ vdev_mirror_map_init(zio_t *zio) mc->mc_vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[c])); mc->mc_offset = DVA_GET_OFFSET(&dva[c]); + if (mc->mc_vd == NULL) { + kmem_free(mm, vdev_mirror_map_size( + mm->mm_children)); + zio->io_vsd = NULL; + zio->io_error = ENXIO; + return (NULL); + } } } else { /*