diff options
author | Steve Mokris <[email protected]> | 2019-12-26 13:57:05 -0500 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-12-26 10:57:05 -0800 |
commit | d5c97f3de7ac3d5568bc641cc87a2edf37f8b9b5 (patch) | |
tree | 330a3cf03dcf5487bff48d95cb3a42c6e8e29f87 | |
parent | ad353e214798619ef4244f84325eb48d8b1afdab (diff) |
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 <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Steve Mokris <[email protected]>
Closes #9022
-rw-r--r-- | module/zfs/vdev_mirror.c | 14 |
1 files 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 { /* |