afs_conn: make release_conns_vector() actually work
authorGarrett Wollman <wollman@csail.mit.edu>
Mon, 23 Jul 2012 03:20:01 +0000 (23:20 -0400)
committerDerrick Brashear <shadow@dementix.org>
Thu, 26 Jul 2012 17:53:48 +0000 (10:53 -0700)
release_conns_vector must never have been called before with
a non-null parameter, because it could not possibly work.
The first line of the loop is a null pointer dereference, and
if that were fixed, there's also a modify-after-free bug as well.
It's not clear how what the old version was trying to do; this
version makes a stab at doing something sensible but might be
less than required.  (Note that this would be much simpler if
converted to queue(3) macros or a similar standard linked-list
data structure.)

Change-Id: I4c0fb7ed1ee977dcc0b4dfb32557882679069731
Reviewed-on: http://gerrit.openafs.org/7838
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Alistair Ferguson <alistair.ferguson@mac.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>

src/afs/afs_conn.c

index 8b2dd73..bdde19b 100644 (file)
@@ -180,14 +180,15 @@ release_conns_user_server(struct unixuser *xu, struct server *xs)
 
 
 static void
-release_conns_vector(struct sa_conn_vector *xcv)
+release_conns_vector(struct sa_conn_vector *tcv)
 {
     int cix, glocked;
     struct afs_conn *tc;
-    struct sa_conn_vector *tcv = NULL;
-    struct sa_conn_vector **lcv = NULL;
-    for (tcv = xcv; tcv; lcv = &tcv->next, tcv = *lcv) {
-        *lcv = tcv->next;
+    struct sa_conn_vector *next;
+
+    while (tcv != NULL) {
+       next = tcv->next;
+
         /* you know it, you love it, the GLOCK */
         glocked = ISAFS_GLOCK();
         if (glocked)
@@ -204,6 +205,7 @@ release_conns_vector(struct sa_conn_vector *xcv)
         if (glocked)
             AFS_GLOCK();
         afs_osi_Free(tcv, sizeof(struct sa_conn_vector));
+       tcv = next;
     }
 
 }        /* release_conns_vector */