DragonFly bugs List (threaded) for 2007-03
DragonFly BSD
DragonFly bugs List (threaded) for 2007-03
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: [issue568] ACPI(?) double-free on shutdown (More K9AGM fun)


From: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>
Date: Thu, 8 Mar 2007 08:32:43 -0800 (PST)

:Joe "Floid" Kanowitz <jkanowitz@snet.net> added the comment:
:
:Looks like the patch was a winner; what you've won, I'm not experienced (or
:awake) enough to figure out.
:
:http://bugs.dragonflybsd.org/file213/Patch_Panic_1.png and
:http://bugs.dragonflybsd.org/file214/Patch_Panic_2.png ,
:
:hopefully the PNGs are less eye-searingly blurry than the JPGs were, and
:hopefully I'll have a working serial header within a week or two.
:
:-Floid

    Yah.  It looks like a reference count problem in the ACPI contrib code,
    and it doesn't look like it will be easy to find.

    The ACPI code is clearly reusing freed memory so it may panic in 
    other ways, but we can try just letting this error slide and see if
    that stops your panics.  Here's a patch to try.

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>

Index: Osd/OsdCache.c
===================================================================
RCS file: /cvs/src/sys/dev/acpica5/Osd/OsdCache.c,v
retrieving revision 1.2
diff -u -r1.2 OsdCache.c
--- Osd/OsdCache.c	19 Jan 2007 23:58:53 -0000	1.2
+++ Osd/OsdCache.c	8 Mar 2007 16:29:37 -0000
@@ -39,6 +39,20 @@
 	struct objcache_malloc_args args;
 };
 
+/*
+ * Add some magic numbers to catch double-frees earlier rather
+ * then later.
+ */
+struct acpiobjhead {
+	int state;
+	int unused;
+};
+
+#define TRACK_ALLOCATED	0x7AF45533
+#define TRACK_FREED	0x7B056644
+
+#define OBJHEADSIZE	sizeof(struct acpiobjhead)
+
 #include "acpi.h"
 
 #ifndef ACPI_USE_LOCAL_CACHE
@@ -50,7 +64,7 @@
 	ACPI_CACHE_T *cache;
 
 	cache = kmalloc(sizeof(*cache), M_TEMP, M_WAITOK);
-	cache->args.objsize = ObjectSize;
+	cache->args.objsize = OBJHEADSIZE + ObjectSize;
 	cache->args.mtype = M_CACHE;
 	cache->cache = objcache_create(CacheName, 0, 0, NULL, NULL,
 	    NULL, objcache_malloc_alloc, objcache_malloc_free, &cache->args);
@@ -79,17 +93,30 @@
 void *
 AcpiOsAcquireObject(ACPI_CACHE_T *Cache)
 {
+	struct acpiobjhead *head;
 	void *Object;
 
-	Object = objcache_get(Cache->cache, M_WAITOK);
-	bzero(Object, Cache->args.objsize);
-	return Object;
+	head = objcache_get(Cache->cache, M_WAITOK);
+	bzero(head, Cache->args.objsize);
+	head->state = TRACK_ALLOCATED;
+	return (head + 1);
 }
 
 ACPI_STATUS
 AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object)
 {
-	objcache_put(Cache->cache, Object);
+	struct acpiobjhead *head = (void *)((char *)Object - OBJHEADSIZE);
+
+	if (head->state != TRACK_ALLOCATED) {
+		if (head->state == TRACK_FREED)
+			printf("AcpiOsReleaseObject: Double Free %p (%08x)\n", Object, head->state);
+		else
+			printf("AcpiOsReleaseObject: Bad object %p (%08x)\n", Object, head->state);
+		return AE_OK;
+	}
+	head->state = TRACK_FREED;
+
+	objcache_put(Cache->cache, head);
 	return AE_OK;
 }
 



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]