From e3412306aa15917b6df03f32643f2f9f08c6cdee Mon Sep 17 00:00:00 2001 From: Boris Protopopov Date: Thu, 20 Mar 2014 16:55:09 -0700 Subject: [PATCH] Illumos #4089 NULL pointer dereference in arc_read() 4089 NULL pointer dereference in arc_read() Reviewed by: Matthew Ahrens Reviewed by: Saso Kiselkov Reviewed by: Garrett D'Amore Approved by: Dan McDonald References: https://www.illumos.org/issues/4089 illumos/illumos-gate@57815f6b95a743697e148327725b7f568e75e6ea Signed-off-by: Brian Behlendorf Issue #2171 Issue #2165 Closes #2198 Conflicts: module/zfs/arc.c --- module/zfs/arc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/module/zfs/arc.c b/module/zfs/arc.c index f8071d4e08a7..d6c3bede5e63 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -21,8 +21,9 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* @@ -3025,6 +3026,8 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, vdev_t *vd = NULL; uint64_t addr = -1; boolean_t devw = B_FALSE; + enum zio_compress b_compress = ZIO_COMPRESS_OFF; + uint64_t b_asize = 0; if (hdr == NULL) { /* this block is not in the cache */ @@ -3094,10 +3097,12 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, hdr->b_acb = acb; hdr->b_flags |= ARC_IO_IN_PROGRESS; - if (HDR_L2CACHE(hdr) && hdr->b_l2hdr != NULL && + if (hdr->b_l2hdr != NULL && (vd = hdr->b_l2hdr->b_dev->l2ad_vdev) != NULL) { devw = hdr->b_l2hdr->b_dev->l2ad_writing; addr = hdr->b_l2hdr->b_daddr; + b_compress = hdr->b_l2hdr->b_compress; + b_asize = hdr->b_l2hdr->b_asize; /* * Lock out device removal. */ @@ -3141,7 +3146,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, cb->l2rcb_bp = *bp; cb->l2rcb_zb = *zb; cb->l2rcb_flags = zio_flags; - cb->l2rcb_compress = hdr->b_l2hdr->b_compress; + cb->l2rcb_compress = b_compress; /* * l2arc read. The SCL_L2ARC lock will be @@ -3149,8 +3154,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, * Issue a null zio if the underlying buffer * was squashed to zero size by compression. */ - if (hdr->b_l2hdr->b_compress == - ZIO_COMPRESS_EMPTY) { + if (b_compress == ZIO_COMPRESS_EMPTY) { rzio = zio_null(pio, spa, vd, l2arc_read_done, cb, zio_flags | ZIO_FLAG_DONT_CACHE | @@ -3159,8 +3163,8 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, ZIO_FLAG_DONT_RETRY); } else { rzio = zio_read_phys(pio, vd, addr, - hdr->b_l2hdr->b_asize, - buf->b_data, ZIO_CHECKSUM_OFF, + b_asize, buf->b_data, + ZIO_CHECKSUM_OFF, l2arc_read_done, cb, priority, zio_flags | ZIO_FLAG_DONT_CACHE | ZIO_FLAG_CANFAIL | @@ -3169,8 +3173,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, } DTRACE_PROBE2(l2arc__read, vdev_t *, vd, zio_t *, rzio); - ARCSTAT_INCR(arcstat_l2_read_bytes, - hdr->b_l2hdr->b_asize); + ARCSTAT_INCR(arcstat_l2_read_bytes, b_asize); if (*arc_flags & ARC_NOWAIT) { zio_nowait(rzio);