From owner-svn-src-all@FreeBSD.ORG Wed Oct 19 23:44:38 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9F406106566C; Wed, 19 Oct 2011 23:44:38 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 848E18FC13; Wed, 19 Oct 2011 23:44:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9JNiciR047734; Wed, 19 Oct 2011 23:44:38 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9JNicuo047731; Wed, 19 Oct 2011 23:44:38 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201110192344.p9JNicuo047731@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Wed, 19 Oct 2011 23:44:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226553 - in head/sys: boot/zfs cddl/boot/zfs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Oct 2011 23:44:38 -0000 Author: pjd Date: Wed Oct 19 23:44:38 2011 New Revision: 226553 URL: http://svn.freebsd.org/changeset/base/226553 Log: Always pass data size for checksum verification function, as using physical block size declared in bp may not always be what we want. For example in case of gang block header physical block size declared in bp is much larger than SPA_GANGBLOCKSIZE (512 bytes) and checksum calculation failed. This bug could lead to accessing unallocated memory and resets/failures during boot. MFC after: 3 days Modified: head/sys/boot/zfs/zfsimpl.c head/sys/cddl/boot/zfs/zfssubr.c Modified: head/sys/boot/zfs/zfsimpl.c ============================================================================== --- head/sys/boot/zfs/zfsimpl.c Wed Oct 19 23:40:37 2011 (r226552) +++ head/sys/boot/zfs/zfsimpl.c Wed Oct 19 23:44:38 2011 (r226553) @@ -347,7 +347,7 @@ vdev_read_phys(vdev_t *vdev, const blkpt rc = vdev->v_phys_read(vdev, vdev->v_read_priv, offset, buf, psize); if (rc) return (rc); - if (bp && zio_checksum_error(bp, buf, offset)) + if (bp && zio_checksum_verify(bp, buf, offset, psize)) return (EIO); return (0); Modified: head/sys/cddl/boot/zfs/zfssubr.c ============================================================================== --- head/sys/cddl/boot/zfs/zfssubr.c Wed Oct 19 23:40:37 2011 (r226552) +++ head/sys/cddl/boot/zfs/zfssubr.c Wed Oct 19 23:44:38 2011 (r226553) @@ -181,10 +181,10 @@ zio_checksum_label_verifier(zio_cksum_t } static int -zio_checksum_error(const blkptr_t *bp, void *data, uint64_t offset) +zio_checksum_verify(const blkptr_t *bp, void *data, uint64_t offset, + uint64_t size) { unsigned int checksum = BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER : BP_GET_CHECKSUM(bp); - uint64_t size = BP_GET_PSIZE(bp); zio_checksum_info_t *ci; zio_cksum_t actual_cksum, expected_cksum, verifier; int byteswap; @@ -1240,10 +1240,10 @@ vdev_child(vdev_t *pvd, uint64_t devidx) * any ereports we generate can note it. */ static int -raidz_checksum_verify(const blkptr_t *bp, void *data) +raidz_checksum_verify(const blkptr_t *bp, void *data, uint64_t size) { - return (zio_checksum_error(bp, data, 0)); + return (zio_checksum_verify(bp, data, 0, size)); } /* @@ -1293,7 +1293,7 @@ raidz_parity_verify(raidz_map_t *rm) */ static int vdev_raidz_combrec(raidz_map_t *rm, const blkptr_t *bp, void *data, - off_t offset, int total_errors, int data_errors) + off_t offset, uint64_t bytes, int total_errors, int data_errors) { raidz_col_t *rc; void *orig[VDEV_RAIDZ_MAXPARITY]; @@ -1372,7 +1372,7 @@ vdev_raidz_combrec(raidz_map_t *rm, cons * success. */ code = vdev_raidz_reconstruct(rm, tgts, n); - if (raidz_checksum_verify(bp, data) == 0) { + if (raidz_checksum_verify(bp, data, bytes) == 0) { for (i = 0; i < n; i++) { c = tgts[i]; rc = &rm->rm_col[c]; @@ -1543,7 +1543,7 @@ reconstruct: */ if (total_errors <= rm->rm_firstdatacol - parity_untried) { if (data_errors == 0) { - if (raidz_checksum_verify(bp, data) == 0) { + if (raidz_checksum_verify(bp, data, bytes) == 0) { /* * If we read parity information (unnecessarily * as it happens since no reconstruction was @@ -1588,7 +1588,7 @@ reconstruct: code = vdev_raidz_reconstruct(rm, tgts, n); - if (raidz_checksum_verify(bp, data) == 0) { + if (raidz_checksum_verify(bp, data, bytes) == 0) { /* * If we read more parity disks than were used * for reconstruction, confirm that the other @@ -1662,8 +1662,8 @@ reconstruct: if (total_errors > rm->rm_firstdatacol) { error = EIO; } else if (total_errors < rm->rm_firstdatacol && - (code = vdev_raidz_combrec(rm, bp, data, offset, total_errors, - data_errors)) != 0) { + (code = vdev_raidz_combrec(rm, bp, data, offset, bytes, + total_errors, data_errors)) != 0) { /* * If we didn't use all the available parity for the * combinatorial reconstruction, verify that the remaining