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 <pavel.zakharov@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Steve Mokris <smokris@softpixel.com>
Closes #9022
This commit is contained in:
Steve Mokris 2019-12-26 13:57:05 -05:00 committed by Tony Hutter
parent 5b8f560713
commit da6a7f0239

View File

@ -282,10 +282,11 @@ vdev_mirror_map_init(zio_t *zio)
} }
/* /*
* If we do not trust the pool config, some DVAs might be * If the pool cannot be written to, then infer that some
* invalid or point to vdevs that do not exist. We skip them. * 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); ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
int j = 0; int j = 0;
for (int i = 0; i < c; i++) { 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_vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[c]));
mc->mc_offset = DVA_GET_OFFSET(&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 { } else {
/* /*