#define IS_ACTIVE(partdef) ((partdef).flags & 1)
-#define IS_PARTDEF_VALID(partdef, hdsize) \
- ( \
- (partdef).flags & 1 && \
- isalnum((partdef).id[0]) && \
- isalnum((partdef).id[1]) && \
- isalnum((partdef).id[2]) && \
- be32_to_cpu((partdef).start) <= (hdsize) && \
- be32_to_cpu((partdef).start) + \
- be32_to_cpu((partdef).size) <= (hdsize) \
- )
+static int is_valid_dimension(uint32_t start, uint32_t size, uint32_t maxoff)
+{
+ uint64_t end = start + size;
+
+ return end >= start
+ && 0 < start && start <= maxoff
+ && 0 < size && size <= maxoff
+ && 0 < end && end <= maxoff;
+}
+
+static int is_valid_partition(struct atari_part_def *part, uint32_t maxoff)
+{
+ uint32_t start = be32_to_cpu(part->start),
+ size = be32_to_cpu(part->size);
+
+ return (part->flags & 1)
+ && isalnum(part->id[0])
+ && isalnum(part->id[1])
+ && isalnum(part->id[2])
+ && is_valid_dimension(start, size, maxoff);
+}
static int is_id_common(char *id)
{
unsigned i;
int has_xgm = 0;
int rc = 0;
- off_t hdsize;
+ uint32_t rssize; /* size in sectors from root sector */
+ uint64_t size; /* size in sectors from system */
/* Atari partition is not defined for other sector sizes */
if (blkid_probe_get_sectorsize(pr) != 512)
goto nothing;
+ size = blkid_probe_get_size(pr) / 512;
+
+ /* Atari is not well defined to support large disks */
+ if (size > INT32_MAX)
+ goto nothing;
+
+ /* read root sector */
rs = (struct atari_rootsector *) blkid_probe_get_sector(pr, 0);
if (!rs) {
if (errno)
goto nothing;
}
- hdsize = blkid_probe_get_size(pr) / 512;
+ rssize = be32_to_cpu(rs->hd_size);
+
+ /* check number of sectors stored in the root sector */
+ if (rssize < 2 || rssize > size)
+ goto nothing;
+
+ /* check list of bad blocks */
+ if ((rs->bsl_start || rs->bsl_len)
+ && !is_valid_dimension(be32_to_cpu(rs->bsl_start),
+ be32_to_cpu(rs->bsl_len),
+ rssize))
+ goto nothing;
/*
* At least one valid partition required
*/
for (i = 0; i < 4; i++) {
- if (IS_PARTDEF_VALID(rs->part[i], hdsize)) {
+ if (is_valid_partition(&rs->part[i], rssize)) {
if (blkid_probe_set_magic(pr,
offsetof(struct atari_rootsector, part[i]),
sizeof(rs->part[i].flags) + sizeof(rs->part[i].id),
blkid_partlist_increment_partno(ls);
continue;
}
-
if (!memcmp(p->id, "XGM", 3)) {
has_xgm = 1;
rc = parse_extended(pr, ls, tab, p);