DF-2963 / fix.diff
--- sys/kern/subr_diskgpt.c.orig +++ sys/kern/subr_diskgpt.c @@ -49,6 +49,17 @@ #define MAX_GPT_ENTRIES 128 /* max number of GPT entries */ +/* + * The devfs minor encoding (dkmakeminor(), sys/sys/diskslice.h) can only + * represent slice indices 0..DKMAXSLICES-1 (7 bits). GPT entry #0 maps to + * COMPATIBILITY_SLICE (0) and entry #N (N >= 1) maps to BASE_SLICE+N-1, + * so entry #127 would map to slice index 128 -- whose top bit is silently + * dropped by the encoder. The resulting "s127" device gets slice 0's + * minor: a duplicate major:minor in devfs whose I/O silently aliases the + * compatibility slice. Never map entries to unrepresentable indices. + */ +#define MAX_GPT_SLICES (DKMAXSLICES - BASE_SLICE + 1) + static void gpt_setslice(const char *sname, struct disk_info *info, struct diskslice *sp, const struct gpt_ent *sent); @@ -177,7 +188,12 @@ /* * Create a slice for each partition. */ - for (i = 0; i < (int)entries && i < MAX_GPT_ENTRIES; ++i) { + if (entries > MAX_GPT_SLICES) { + kprintf("%s: GPT has %d entries; only %d slice devices " + "representable, ignoring entry %d\n", + dname, entries, MAX_GPT_SLICES, MAX_GPT_SLICES); + } + for (i = 0; i < (int)entries && i < MAX_GPT_SLICES; ++i) { struct gpt_ent sent; char partname[2]; char *sname; |