dcavalca / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone
8ecbbe
From e7f0f5d3a80324e1430e979b0a170ded77b380e2 Mon Sep 17 00:00:00 2001
8ecbbe
From: Karel Zak <kzak@redhat.com>
8ecbbe
Date: Tue, 13 Oct 2020 16:19:20 +0200
8ecbbe
Subject: libblkid: make Atari more robust
8ecbbe
8ecbbe
* ignore large disks
8ecbbe
* check in-table stored device size
8ecbbe
* check bad sectors list
8ecbbe
* check partition dimensions against in-table device size
8ecbbe
8ecbbe
Addresses: https://github.com/karelzak/util-linux/issues/1159
8ecbbe
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2060030
8ecbbe
Upstream: http://github.com/util-linux/util-linux/commit/282ceadc3a72fc07dd0388b8880fd751490bb87f
8ecbbe
Signed-off-by: Karel Zak <kzak@redhat.com>
8ecbbe
---
8ecbbe
 libblkid/src/partitions/atari.c | 66 ++++++++++++++++++++++++---------
8ecbbe
 1 file changed, 48 insertions(+), 18 deletions(-)
8ecbbe
8ecbbe
diff --git a/libblkid/src/partitions/atari.c b/libblkid/src/partitions/atari.c
8ecbbe
index b469ef5a1..c3f77117a 100644
8ecbbe
--- a/libblkid/src/partitions/atari.c
8ecbbe
+++ b/libblkid/src/partitions/atari.c
8ecbbe
@@ -74,16 +74,27 @@ static int linux_isalnum(unsigned char c) {
8ecbbe
 
8ecbbe
 #define IS_ACTIVE(partdef) ((partdef).flags & 1)
8ecbbe
 
8ecbbe
-#define IS_PARTDEF_VALID(partdef, hdsize) \
8ecbbe
-	( \
8ecbbe
-		(partdef).flags & 1 && \
8ecbbe
-		isalnum((partdef).id[0]) && \
8ecbbe
-		isalnum((partdef).id[1]) && \
8ecbbe
-		isalnum((partdef).id[2]) && \
8ecbbe
-		be32_to_cpu((partdef).start) <= (hdsize) && \
8ecbbe
-		be32_to_cpu((partdef).start) + \
8ecbbe
-			be32_to_cpu((partdef).size) <= (hdsize) \
8ecbbe
-	)
8ecbbe
+static int is_valid_dimension(uint32_t start, uint32_t size, uint32_t maxoff)
8ecbbe
+{
8ecbbe
+	uint64_t end = start + size;
8ecbbe
+
8ecbbe
+	return  end >= start
8ecbbe
+		&& 0 < start && start <= maxoff
8ecbbe
+		&& 0 < size && size <= maxoff
8ecbbe
+		&& 0 < end && end <= maxoff;
8ecbbe
+}
8ecbbe
+
8ecbbe
+static int is_valid_partition(struct atari_part_def *part, uint32_t maxoff)
8ecbbe
+{
8ecbbe
+	uint32_t start = be32_to_cpu(part->start),
8ecbbe
+		 size = be32_to_cpu(part->size);
8ecbbe
+
8ecbbe
+	return (part->flags & 1)
8ecbbe
+		&& isalnum(part->id[0])
8ecbbe
+		&& isalnum(part->id[1])
8ecbbe
+		&& isalnum(part->id[2])
8ecbbe
+		&& is_valid_dimension(start, size, maxoff);
8ecbbe
+}
8ecbbe
 
8ecbbe
 static int is_id_common(char *id)
8ecbbe
 {
8ecbbe
@@ -184,12 +195,20 @@ static int probe_atari_pt(blkid_probe pr,
8ecbbe
 	unsigned i;
8ecbbe
 	int has_xgm = 0;
8ecbbe
 	int rc = 0;
8ecbbe
-	off_t hdsize;
8ecbbe
+	uint32_t rssize;	/* size in sectors from root sector */
8ecbbe
+	uint64_t size;		/* size in sectors from system */
8ecbbe
 
8ecbbe
 	/* Atari partition is not defined for other sector sizes */
8ecbbe
 	if (blkid_probe_get_sectorsize(pr) != 512)
8ecbbe
 		goto nothing;
8ecbbe
 
8ecbbe
+	size = blkid_probe_get_size(pr) / 512;
8ecbbe
+
8ecbbe
+	/* Atari is not well defined to support large disks */
8ecbbe
+	if (size > INT32_MAX)
8ecbbe
+		goto nothing;
8ecbbe
+
8ecbbe
+	/* read root sector */
8ecbbe
 	rs = (struct atari_rootsector *) blkid_probe_get_sector(pr, 0);
8ecbbe
 	if (!rs) {
8ecbbe
 		if (errno)
8ecbbe
@@ -197,17 +216,29 @@ static int probe_atari_pt(blkid_probe pr,
8ecbbe
 		goto nothing;
8ecbbe
 	}
8ecbbe
 
8ecbbe
-	hdsize = blkid_probe_get_size(pr) / 512;
8ecbbe
+	rssize = be32_to_cpu(rs->hd_size);
8ecbbe
+
8ecbbe
+	/* check number of sectors stored in the root sector */
8ecbbe
+	if (rssize < 2 || rssize > size)
8ecbbe
+		goto nothing;
8ecbbe
+
8ecbbe
+	/* check list of bad blocks */
8ecbbe
+	if ((rs->bsl_start || rs->bsl_len)
8ecbbe
+	    && !is_valid_dimension(be32_to_cpu(rs->bsl_start),
8ecbbe
+				   be32_to_cpu(rs->bsl_len),
8ecbbe
+				   rssize))
8ecbbe
+		goto nothing;
8ecbbe
 
8ecbbe
 	/*
8ecbbe
 	 * At least one valid partition required
8ecbbe
 	 */
8ecbbe
 	for (i = 0; i < 4; i++) {
8ecbbe
-		if (IS_PARTDEF_VALID(rs->part[i], hdsize)) {
8ecbbe
-			blkid_probe_set_magic(pr,
8ecbbe
-				offsetof(struct atari_rootsector, part[i]),
8ecbbe
-				sizeof(rs->part[i].flags) + sizeof(rs->part[i].id),
8ecbbe
-				(unsigned char *) &rs->part[i]);
8ecbbe
+		if (is_valid_partition(&rs->part[i], rssize)) {
8ecbbe
+			if (blkid_probe_set_magic(pr,
8ecbbe
+					offsetof(struct atari_rootsector, part[i]),
8ecbbe
+					sizeof(rs->part[i].flags) + sizeof(rs->part[i].id),
8ecbbe
+					(unsigned char *) &rs->part[i]))
8ecbbe
+				goto err;
8ecbbe
 			break;
8ecbbe
 		}
8ecbbe
 	}
8ecbbe
@@ -234,7 +265,6 @@ static int probe_atari_pt(blkid_probe pr,
8ecbbe
 			blkid_partlist_increment_partno(ls);
8ecbbe
 			continue;
8ecbbe
 		}
8ecbbe
-
8ecbbe
 		if (!memcmp(p->id, "XGM", 3)) {
8ecbbe
 			has_xgm = 1;
8ecbbe
 			rc = parse_extended(pr, ls, tab, p);
8ecbbe
-- 
8ecbbe
2.36.1
8ecbbe