libafs: Add afs_conn refCount imbalance safeguard
authorAndrew Deason <adeason@sinenomine.net>
Mon, 25 Jul 2011 16:12:37 +0000 (11:12 -0500)
committerDerrick Brashear <shadow@dementia.org>
Fri, 29 Jul 2011 21:15:59 +0000 (14:15 -0700)
If someone is putting back too many refs, we can detect so very
easily. If we see that such a thing is happening, give a warning and
bail out, instead of risking a panic or memory corruption.

Change-Id: I36c968f9cd7cab3f569d3f6860f41678f026fba8
Reviewed-on: http://gerrit.openafs.org/5094
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/afs/afs_conn.c

index f842a91..f63ac63 100644 (file)
@@ -596,6 +596,24 @@ afs_PutConn(struct afs_conn *ac, struct rx_connection *rxconn,
 {
     AFS_STATCNT(afs_PutConn);
     ac->refCount--;
+    if (ac->refCount < 0) {
+       static int warned = 0;
+       /* So, someone is 'put'ing more refs than they got. From now on, we
+        * have no idea if the structure is actually still in use, so just
+        * set the refcount to a really negative number to make it unlikely
+        * that the count will ever reach 0 and the conn gets freed. This
+        * leaks memory, but the alternative is panicing, or risking memory
+        * corruption. */
+       ac->refCount = -10000;
+       if (!warned) {
+           warned = 1;
+           afs_warn("afs_PutConn: negative refCount with 0x%lx; this should "
+                    "not ever happen! Trying to carry on anyway, but please "
+                    "report this issue\n",
+                    (unsigned long)(uintptrsz)ac);
+       }
+       return;
+    }
     ac->parent->refCount--;
     rx_PutConnection(rxconn);
 }                              /*afs_PutConn */