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