|
|
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 |
|