HEADSUP: Memory corruption issue with ZFS users using L2ARC [Fwd: svn commit: r287283 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs]

From: Xin Li <delphij_at_delphij.net>
Date: Sat, 29 Aug 2015 03:03:23 -0700
Hi,

Please note that -CURRENT in revision range of [r286951, 287283),
approximately 9 days ago until now, are affected by a buffer overrun
issue that may cause data corruption (!) which may manifest itself as
random panics that relates to NULL pointer deference (e.g. Kernel Trap
12 with <4K fault address), or strange UMA related panics.

Systems that do not have L2ARC devices are not affected by this problem.
 The affected code is L2ARC specific.

For those who are using L2ARC devices -- it's not clear to me how bad
the corruption could affect the on disk data for ZFS.  If you are
running -CURRENT and have L2ARC, please be sure to examine if you have
any data loss.

Cheers,


-------- Forwarded Message --------
Subject: svn commit: r287283 -
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Date: Sat, 29 Aug 2015 09:22:33 +0000 (UTC)
From: Xin LI <delphij_at_FreeBSD.org>
To: src-committers_at_freebsd.org, svn-src-all_at_freebsd.org,
svn-src-head_at_freebsd.org

Author: delphij
Date: Sat Aug 29 09:22:32 2015
New Revision: 287283
URL: https://svnweb.freebsd.org/changeset/base/287283

Log:
  Fix a buffer overrun which may lead to data corruption, introduced in
  r286951 by reinstating changes in r274628.

  In l2arc_compress_buf(), we allocate a buffer to stash away the compressed
  data in 'cdata', allocated of l2hdr->b_asize bytes.

  We then ask zio_compress_data() to compress the buffer,
b_l1hdr.b_tmp_cdata,
  which is of l2hdr->b_asize bytes, and have the compressed size (or
original
  size, if compress didn't gain enough) stored in csize.

  To pad the buffer to fit the optimal write size, we round up the
compressed
  size to L2 device's vdev_ashift.

  Illumos code rounds up the size by at most SPA_MINBLOCKSIZE.  Because we
  know csize <= b_asize, and b_asize is integer multiple of
SPA_MINBLOCKSIZE,
  we are guaranteed that the rounded up csize would be <= b_asize. However,
  this is not necessarily true when we round up to 1 << vdev_ashift, because
  it could be larger than SPA_MINBLOCKSIZE.

  So, in the worst case scenario, we are overwriting at most

  	(1 << vdev_ashift - SPA_MINBLOCKSIZE)

  bytes of memory next to the compressed data buffer.

  Andriy's original change in r274628 reorganized the code a little bit,
  by moving the padding to after we determined that the compression was
  beneficial.  At which point, we would check rounded size against the
  allocated buffer size, and the buffer overrun would not be possible.

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c


Cheers,


Received on Sat Aug 29 2015 - 08:03:24 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:59 UTC