⬢ DragonFlyBSD Kernel Audit
DF-5433 / fix.diff
← back to finding ↓ download raw
--- a/sys/platform/pc64/acpica/acpi_madt.c
+++ b/sys/platform/pc64/acpica/acpi_madt.c
@@ -275,7 +275,19 @@
 	int	cpu;
 	int	bsp_found;
 	int	bsp_apic_id;
+	uint8_t	seen[NAPICID / 8];	/* apic ids already given a slot */
 };
+
+static boolean_t
+madt_lapic_id_seen(struct madt_lapic_pass2_cbarg *arg, u_int id)
+{
+	boolean_t was;
+
+	if (id >= NAPICID)
+		return FALSE;	/* handled elsewhere (DF-1042) */
+	was = (arg->seen[id >> 3] & (1 << (id & 7))) != 0;
+	arg->seen[id >> 3] |= 1 << (id & 7);
+	return was;
 
 static int
 madt_lapic_pass2_callback(void *xarg, const ACPI_SUBTABLE_HEADER *ent)
@@ -290,6 +302,12 @@
 	if (lapic_ent->LapicFlags & ACPI_MADT_ENABLED) {
 		int cpu;
 
+		if (madt_lapic_id_seen(arg, lapic_ent->Id)) {
+			kprintf("ACPI MADT: duplicate CPU apic id %d "
+			    "(cpu id %d), ignoring entry\n",
+			    lapic_ent->Id, arg->cpu);
+			return 0;
+		}
 		if (lapic_ent->Id == arg->bsp_apic_id) {
 			cpu = 0;
 			if (arg->bsp_found) {
@@ -330,6 +348,12 @@
 	if (x2apic_ent->LapicFlags & ACPI_MADT_ENABLED) {
 		int cpu;
 
+		if (madt_lapic_id_seen(arg, x2apic_ent->LocalApicId)) {
+			kprintf("ACPI MADT: duplicate CPU apic id %u "
+			    "(cpu id %d), ignoring entry\n",
+			    x2apic_ent->LocalApicId, arg->cpu);
+			return 0;
+		}
 		if (x2apic_ent->LocalApicId == arg->bsp_apic_id) {
 			cpu = 0;
 			arg->bsp_found = 1;