6b9308
From 71ac1ab735eeaa71af0198253c06f783c8582362 Mon Sep 17 00:00:00 2001
6b9308
From: Torsten Hilbrich <torsten.hilbrich@secunet.com>
6b9308
Date: Mon, 20 Jun 2016 07:09:10 +0200
6b9308
Subject: [PATCH 194/197] liblkid: Add length check in probe_nilfs2 before
6b9308
 crc32
6b9308
6b9308
The bytes variable is read from the file system to probe and must be
6b9308
checked before used as length parameter in the crc32 call.
6b9308
6b9308
The following problems may occur here:
6b9308
6b9308
- bytes smaller than sumoff + 4: underflow in length calculation
6b9308
- bytes larger than remaining space in sb: overflow of buffer
6b9308
6b9308
This fixes a problem where an encrypted volume had the correct magic
6b9308
values 0x3434 at offset 0x406 and the following uint16_t (which is
6b9308
read into the nilfs_super_block.s_bytes struct) was parsed as 1.
6b9308
6b9308
Then crc32 was called with the length value 18446744073709551597
6b9308
causing a segmentation fault.
6b9308
6b9308
[kzak@redhat.com: - fix probe_nilfs2() return code
6b9308
		  - RHEL-7: return 1 if superblock bytes are out if
6b9308
		    range; we use the same for invalid superblock in
6b9308
                    current upstream tree]
6b9308
6b9308
Upstream: http://github.com/karelzak/util-linux/commit/ac681a310c32319423297544833932f4d689a7a2
6b9308
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1802240
6b9308
Signed-off-by: Karel Zak <kzak@redhat.com>
6b9308
---
6b9308
 libblkid/src/superblocks/nilfs.c | 9 ++++++++-
6b9308
 1 file changed, 8 insertions(+), 1 deletion(-)
6b9308
6b9308
diff --git a/libblkid/src/superblocks/nilfs.c b/libblkid/src/superblocks/nilfs.c
6b9308
index a7e4939a2..a4b3c22b6 100644
6b9308
--- a/libblkid/src/superblocks/nilfs.c
6b9308
+++ b/libblkid/src/superblocks/nilfs.c
6b9308
@@ -78,6 +78,7 @@ static int probe_nilfs2(blkid_probe pr, const struct blkid_idmag *mag)
6b9308
 	static unsigned char sum[4];
6b9308
 	const int sumoff = offsetof(struct nilfs_super_block, s_sum);
6b9308
 	size_t bytes;
6b9308
+	const size_t crc_start = sumoff + 4;
6b9308
 	uint32_t crc;
6b9308
 
6b9308
 	sb = blkid_probe_get_sb(pr, mag, struct nilfs_super_block);
6b9308
@@ -85,9 +86,15 @@ static int probe_nilfs2(blkid_probe pr, const struct blkid_idmag *mag)
6b9308
 		return errno ? -errno : 1;
6b9308
 
6b9308
 	bytes = le16_to_cpu(sb->s_bytes);
6b9308
+	/* ensure that no underrun can happen in the length parameter
6b9308
+	 * of the crc32 call or more data are processed than read into
6b9308
+	 * sb */
6b9308
+	if (bytes < crc_start || bytes > sizeof(struct nilfs_super_block))
6b9308
+		return 1;
6b9308
+
6b9308
 	crc = crc32(le32_to_cpu(sb->s_crc_seed), (unsigned char *)sb, sumoff);
6b9308
 	crc = crc32(crc, sum, 4);
6b9308
-	crc = crc32(crc, (unsigned char *)sb + sumoff + 4, bytes - sumoff - 4);
6b9308
+	crc = crc32(crc, (unsigned char *)sb + crc_start, bytes - crc_start);
6b9308
 
6b9308
 	if (crc != le32_to_cpu(sb->s_sum))
6b9308
 		return 1;
6b9308
-- 
6b9308
2.25.2
6b9308