DragonFlyBSD Kernel Audit
DF-2963 / fix.diff
← back to finding ↓ download raw
--- 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;