DragonFlyBSD Kernel Audit
DF-2087 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/acpica/Osd/OsdMemory.c b/sys/dev/acpica/Osd/OsdMemory.c
@@ -35,12 +35,25 @@
 #include "acpi.h"
 
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/malloc.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
 MALLOC_DEFINE(M_ACPICA, "acpica", "ACPICA memory pool");
 
+/*
+ * Serializes access to the acpi_mapbase list (DF-2087).
+ */
+static struct lock acpi_map_lock;
+
+static void
+acpi_memtrack_lockinit(void *dummy)
+{
+	lockinit(&acpi_map_lock, "acpimap", 0, 0);
+}
+SYSINIT(acpi_memtrack, SI_BOOT1_LOCK, SI_ORDER_ANY, acpi_memtrack_lockinit, NULL);
+
 struct acpi_memtrack {
     struct acpi_memtrack *next;
     void *base;
@@ -92,11 +105,22 @@
     if (map == NULL)
 	return(NULL);
     else {
+	lockmgr(&acpi_map_lock, LK_EXCLUSIVE);
 #ifdef ACPI_DEBUG_MEMMAP
 	for (track = acpi_mapbase; track != NULL; track = track->next) {
 	    if (track->base == map)
 		break;
 	}
+	if (track != NULL) {
+	    /* Unlink found track before re-adding at head (DF-2088) */
+	    acpi_memtrack_t *pp;
+	    for (pp = &acpi_mapbase; *pp != NULL; pp = &(*pp)->next) {
+		if (*pp == track) {
+		    *pp = track->next;
+		    break;
+		}
+	    }
+	}
 #else
 	track = NULL;
 #endif
@@ -114,6 +138,7 @@
 	track->unmapper.line = 0;
 #endif
 	acpi_mapbase = track;
+	lockmgr(&acpi_map_lock, LK_RELEASE);
     }
     return(map);
 }
@@ -130,6 +155,7 @@
     struct acpi_memtrack **ptrack;
     acpi_memtrack_t track;
 
+    lockmgr(&acpi_map_lock, LK_EXCLUSIVE);
 again:
     for (ptrack = &acpi_mapbase; (track = *ptrack); ptrack = &track->next) {
 #ifdef ACPI_DEBUG_MEMMAP
@@ -149,6 +175,7 @@
 #else
 	    kfree(track, M_ACPICA);
 #endif
+	    lockmgr(&acpi_map_lock, LK_RELEASE);
 	    return;
 	}
 	/*
@@ -199,6 +226,7 @@
 	}
     }
 #endif
+    lockmgr(&acpi_map_lock, LK_RELEASE);
 }
 
 ACPI_STATUS