svn commit: r304753 - head/sys/cddl/boot/zfs

Toomas Soome tsoome at FreeBSD.org
Wed Aug 24 16:30:17 UTC 2016


Author: tsoome
Date: Wed Aug 24 16:30:15 2016
New Revision: 304753
URL: https://svnweb.freebsd.org/changeset/base/304753

Log:
  Bug 212114 - loader: zio_checksum_verify() must test spa for NULL pointer
  
  The issue was introduced with adding support for salted checksums, and
  was revealed by bhyve userboot.so.
  
  During pool discovery the loader is reading pool label from disks, and
  at that time the spa structure is not yet set up, so the NULL pointer
  is passed for spa. This condition must be checked to avoid the corruption
  of the memory and NULL pointer dereference.
  
  PR:		212114
  Reported by:	tsoome at freebsd.com
  Reviewed by:	allanjude
  Approved by:	allanjude (mentor)
  Differential Revision:	https://reviews.freebsd.org/D7634

Modified:
  head/sys/cddl/boot/zfs/zfssubr.c

Modified: head/sys/cddl/boot/zfs/zfssubr.c
==============================================================================
--- head/sys/cddl/boot/zfs/zfssubr.c	Wed Aug 24 15:36:48 2016	(r304752)
+++ head/sys/cddl/boot/zfs/zfssubr.c	Wed Aug 24 16:30:15 2016	(r304753)
@@ -270,6 +270,7 @@ zio_checksum_verify(const spa_t *spa, co
 	uint64_t size;
 	unsigned int checksum;
 	zio_checksum_info_t *ci;
+	void *ctx = NULL;
 	zio_cksum_t actual_cksum, expected_cksum, verifier;
 	int byteswap;
 
@@ -282,7 +283,11 @@ zio_checksum_verify(const spa_t *spa, co
 	if (ci->ci_func[0] == NULL || ci->ci_func[1] == NULL)
 		return (EINVAL);
 
-	zio_checksum_template_init(checksum, (spa_t *) spa);
+	if (spa != NULL) {
+		zio_checksum_template_init(checksum, (spa_t *) spa);
+		ctx = spa->spa_cksum_tmpls[checksum];
+	}
+
 	if (ci->ci_flags & ZCHECKSUM_FLAG_EMBEDDED) {
 		zio_eck_t *eck;
 
@@ -306,8 +311,7 @@ zio_checksum_verify(const spa_t *spa, co
 
 		expected_cksum = eck->zec_cksum;
 		eck->zec_cksum = verifier;
-		ci->ci_func[byteswap](data, size,
-		    spa->spa_cksum_tmpls[checksum], &actual_cksum);
+		ci->ci_func[byteswap](data, size, ctx, &actual_cksum);
 		eck->zec_cksum = expected_cksum;
 
 		if (byteswap)
@@ -315,8 +319,7 @@ zio_checksum_verify(const spa_t *spa, co
 			    sizeof (zio_cksum_t));
 	} else {
 		expected_cksum = bp->blk_cksum;
-		ci->ci_func[0](data, size, spa->spa_cksum_tmpls[checksum],
-		    &actual_cksum);
+		ci->ci_func[0](data, size, ctx, &actual_cksum);
 	}
 
 	if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) {


More information about the svn-src-all mailing list