Fix segfault when sweeping realms and communities
authorJennifer Richards <jennifer@painless-security.com>
Thu, 22 Feb 2018 18:48:09 +0000 (13:48 -0500)
committerJennifer Richards <jennifer@painless-security.com>
Thu, 22 Feb 2018 18:48:09 +0000 (13:48 -0500)
Mutation of linked lists led to dereferencing a "next" pointer when the
last item in the list was removed. Fixed in three places.

common/tr_comm.c
common/tr_idp.c
common/tr_rp.c

index 6212b5d..dd3c304 100644 (file)
@@ -372,10 +372,10 @@ static TR_COMM *tr_comm_sweep_func(TR_COMM *head)
     return NULL;
 
   /* will not remove the head here, that has already been done */
-  for (comm=head; comm->next!=NULL; comm=comm->next) {
+  for (comm=head; (comm!=NULL) && (comm->next!=NULL); comm=comm->next) {
     if (comm->next->refcount==0) {
       old_next=comm->next;
-      tr_comm_remove(head, comm->next); /* changes comm->next */
+      tr_comm_remove(head, comm->next); /* changes comm->next, may make it null */
       tr_comm_free(old_next);
     }
   }
index 984e6b5..747397b 100644 (file)
@@ -389,11 +389,11 @@ TR_IDP_REALM *tr_idp_realm_sweep_func(TR_IDP_REALM *head)
   if (head==NULL)
     return NULL;
 
-  /* will not remove the head here, that has already been done */
-  for (idp=head; idp->next!=NULL; idp=idp->next) {
+  /* Will not remove the head here, that has already been done.*/
+  for (idp=head; (idp!=NULL) && (idp->next!=NULL); idp=idp->next) {
     if (idp->next->refcount==0) {
       old_next=idp->next;
-      tr_idp_realm_remove(head, idp->next); /* changes idp->next */
+      tr_idp_realm_remove(head, idp->next); /* changes idp->next, may make it NULL */
       tr_idp_realm_free(old_next);
     }
   }
index 495c77e..4acdc4b 100644 (file)
@@ -290,10 +290,10 @@ TR_RP_REALM *tr_rp_realm_sweep_func(TR_RP_REALM *head)
     return NULL;
 
   /* will not remove the head here, that has already been done */
-  for (rp=head; rp->next!=NULL; rp=rp->next) {
+  for (rp=head; (rp!=NULL) && (rp->next!=NULL); rp=rp->next) {
     if (rp->next->refcount==0) {
       old_next=rp->next;
-      tr_rp_realm_remove(head, rp->next); /* changes rp->next */
+      tr_rp_realm_remove(head, rp->next); /* changes rp->next, may make it null */
       tr_rp_realm_free(old_next);
     }
   }