summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorSteve Mokris <[email protected]>2019-12-26 13:57:05 -0500
committerBrian Behlendorf <[email protected]>2019-12-26 10:57:05 -0800
commitd5c97f3de7ac3d5568bc641cc87a2edf37f8b9b5 (patch)
tree330a3cf03dcf5487bff48d95cb3a42c6e8e29f87 /module/zfs
parentad353e214798619ef4244f84325eb48d8b1afdab (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
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/vdev_mirror.c14
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 {
/*