diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2016-01-31 17:19:27 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2016-01-31 17:19:27 +0000 |
commit | 542776918893c7e0b6e8b3765c4c3018761a762b (patch) | |
tree | b0d60e072c661ca6710cd8706d628f1d31ff3d3f | |
parent | d142056ed9ba44eee97080c79405ab70c6ef5220 (diff) |
Don't use add_data_to_map() when reading from disk, since it resets some
of the dpme_ fields, overwriting data from disk.
Add some paranoia checks for map limits when reading from disk.
-rw-r--r-- | sbin/pdisk/partition_map.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/sbin/pdisk/partition_map.c b/sbin/pdisk/partition_map.c index f83366e29fa..c8a5caa0d51 100644 --- a/sbin/pdisk/partition_map.c +++ b/sbin/pdisk/partition_map.c @@ -1,4 +1,4 @@ -/* $OpenBSD: partition_map.c,v 1.93 2016/01/31 15:28:56 krw Exp $ */ +/* $OpenBSD: partition_map.c,v 1.94 2016/01/31 17:19:26 krw Exp $ */ /* * partition_map.c - partition map routines @@ -146,7 +146,7 @@ read_partition_map(struct partition_map *map) int ix; uint32_t limit, base, next, nextbase; - limit = 1; /* There has to be at least one, which has actual value. */ + limit = 1; /* There has to be at least one, which has the real limit. */ for (ix = 1; ix <= limit; ix++) { entry = malloc(sizeof(struct entry)); if (entry == NULL) @@ -163,8 +163,22 @@ read_partition_map(struct partition_map *map) free(entry); return 1; } - if (ix == 1) + if (ix == 1) { + if (entry->dpme_map_entries > entry->dpme_pblocks) { + warnx("Map entry count (%u) > # of physical " + "blocks (%u)", entry->dpme_map_entries, + entry->dpme_pblocks); + free(entry); + return 1; + } + if (entry->dpme_map_entries == 0) { + warnx("Map entry count == 0. Must be > 0"); + free(entry); + return 1; + } + map->maximum_in_map = entry->dpme_pblocks; limit = entry->dpme_map_entries; + } if (limit != entry->dpme_map_entries) { warnx("Invalid entry count on block %d. " "Expected %d, got %d", ix, limit, @@ -187,8 +201,11 @@ read_partition_map(struct partition_map *map) free(entry); return 1; } - - add_data_to_map(entry, ix, map); + entry->the_map = map; + entry->disk_address = ix; + insert_in_disk_order(entry); + insert_in_base_order(entry); + map->blocks_in_map++; } /* Traverse base_order looking for |