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