From ed8df6e70fab2a24d60d0a45d639b85f3c3abfa1 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Sat, 2 Nov 2019 09:22:20 +0000 Subject: [PATCH] MFC r354119: loader: rs_alloc() may return NULL rs_alloc() in zfs reader code may return NULL, so we need to check the return value and error out if needed. --- stand/libsa/zfs/zfsimpl.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c index 3d14b811ab3..d15818c0b29 100644 --- a/stand/libsa/zfs/zfsimpl.c +++ b/stand/libsa/zfs/zfsimpl.c @@ -840,12 +840,17 @@ vdev_indirect_remap(vdev_t *vd, uint64_t offset, uint64_t asize, void *arg) list_t stack; spa_t *spa = vd->spa; zio_t *zio = arg; + remap_segment_t *rs; list_create(&stack, sizeof (remap_segment_t), offsetof(remap_segment_t, rs_node)); - for (remap_segment_t *rs = rs_alloc(vd, offset, asize, 0); - rs != NULL; rs = list_remove_head(&stack)) { + rs = rs_alloc(vd, offset, asize, 0); + if (rs == NULL) { + printf("vdev_indirect_remap: out of memory.\n"); + zio->io_error = ENOMEM; + } + for ( ; rs != NULL; rs = list_remove_head(&stack)) { vdev_t *v = rs->rs_vd; uint64_t num_entries = 0; /* vdev_indirect_mapping_t *vim = v->v_mapping; */ @@ -853,6 +858,9 @@ vdev_indirect_remap(vdev_t *vd, uint64_t offset, uint64_t asize, void *arg) vdev_indirect_mapping_duplicate_adjacent_entries(v, rs->rs_offset, rs->rs_asize, &num_entries); + if (num_entries == 0) + zio->io_error = ENOMEM; + for (uint64_t i = 0; i < num_entries; i++) { vdev_indirect_mapping_entry_phys_t *m = &mapping[i]; uint64_t size = DVA_GET_ASIZE(&m->vimep_dst); @@ -865,9 +873,18 @@ vdev_indirect_remap(vdev_t *vd, uint64_t offset, uint64_t asize, void *arg) vdev_t *dst_v = vdev_lookup_top(spa, dst_vdev); if (dst_v->v_read == vdev_indirect_read) { - list_insert_head(&stack, - rs_alloc(dst_v, dst_offset + inner_offset, - inner_size, rs->rs_split_offset)); + remap_segment_t *o; + + o = rs_alloc(dst_v, dst_offset + inner_offset, + inner_size, rs->rs_split_offset); + if (o == NULL) { + printf("vdev_indirect_remap: " + "out of memory.\n"); + zio->io_error = ENOMEM; + break; + } + + list_insert_head(&stack, o); } vdev_indirect_gather_splits(rs->rs_split_offset, dst_v, dst_offset + inner_offset, -- 2.45.0