[svn-commits] russell: linux/trunk r4673 - /linux/trunk/drivers/dahdi/dahdi-base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sat Aug 2 15:42:54 CDT 2008


Author: russell
Date: Sat Aug  2 15:42:54 2008
New Revision: 4673

URL: http://svn.digium.com/view/dahdi?view=rev&rev=4673
Log:
Rework free_tone_zone a bit to avoid a potential memory leak in a weird scenario.
It was theoretically possible that a zone was registered after we removed a zone,
but before we tried to put it back after determining that it was busy.  If this
occurred, then when putting the zone back, we would overwrite the reference to
the newly created zone, leaking the associated memory.

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=4673&r1=4672&r2=4673
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Sat Aug  2 15:42:54 2008
@@ -1183,30 +1183,27 @@
 
 static int free_tone_zone(int num)
 {
-	struct dahdi_zone *z;
+	struct dahdi_zone *z = NULL;
+	int res = 0;
 
 	if ((num >= DAHDI_TONE_ZONE_MAX) || (num < 0))
 		return -EINVAL;
 
 	write_lock(&zone_lock);
-	z = tone_zones[num];
-	tone_zones[num] = NULL;
+	if (tone_zones[num]) {
+		if (!atomic_read(&tone_zones[num]->refcount)) {
+			z = tone_zones[num];
+			tone_zones[num] = NULL;
+		} else {
+			res = -EBUSY;
+		}
+	}
 	write_unlock(&zone_lock);
-	if (!z)
-		return 0;
-
-	if (atomic_read(&z->refcount)) {
-		/* channels are still using this zone so put it back */
-		write_lock(&zone_lock);
-		tone_zones[num] = z;
-		write_unlock(&zone_lock);
-
-		return -EBUSY;
-	} else {
+
+	if (z)
 		kfree(z);
 
-		return 0;
-	}
+	return res;
 }
 
 static int dahdi_register_tone_zone(int num, struct dahdi_zone *zone)




More information about the svn-commits mailing list