cdown / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone

Blame SOURCES/0194-liblkid-Add-length-check-in-probe_nilfs2-before-crc3.patch

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