DragonFlyBSD Kernel Audit
DF-2397 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/agp/agp.c b/sys/dev/agp/agp.c
--- a/sys/dev/agp/agp.c
+++ b/sys/dev/agp/agp.c
@@ -471,15 +471,17 @@
 	}
 
 	mem = kmalloc(sizeof *mem, M_AGP, M_INTWAIT);
-	mem->am_id = sc->as_nextid++;
 	mem->am_size = size;
 	mem->am_type = 0;
 	mem->am_obj = vm_object_allocate(OBJT_DEFAULT, atop(round_page(size)));
 	mem->am_physical = 0;
 	mem->am_offset = 0;
 	mem->am_is_bound = 0;
+	lockmgr(&sc->as_lock, LK_EXCLUSIVE);
+	mem->am_id = sc->as_nextid++;
 	TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link);
 	sc->as_allocated += size;
+	lockmgr(&sc->as_lock, LK_RELEASE);
 
 	return mem;
 }
@@ -492,8 +494,10 @@
 	if (mem->am_is_bound)
 		return EBUSY;
 
+	lockmgr(&sc->as_lock, LK_EXCLUSIVE);
 	sc->as_allocated -= mem->am_size;
 	TAILQ_REMOVE(&sc->as_memory, mem, am_link);
+	lockmgr(&sc->as_lock, LK_RELEASE);
 	vm_object_deallocate(mem->am_obj);
 	kfree(mem, M_AGP);
 	return 0;
@@ -679,11 +683,15 @@
 	struct agp_memory *mem;
 
 	AGP_DPF("searching for memory block %d\n", id);
+	lockmgr(&sc->as_lock, LK_SHARED);
 	TAILQ_FOREACH(mem, &sc->as_memory, am_link) {
 		AGP_DPF("considering memory block %d\n", mem->am_id);
 		if (mem->am_id == id)
-			return mem;
+			break;
 	}
+	lockmgr(&sc->as_lock, LK_RELEASE);
+	if (mem)
+		return mem;
 	return 0;
 }