[SCTP]: Fix local_addr deletions during list traversals.
[linux-3.10.git] / net / sctp / bind_addr.c
index a27511ebc4cb6ae80749a41c6b85239021749fee..ceefda025e2d3d31fbeb64e0b31d7866222c407f 100644 (file)
@@ -209,6 +209,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
 int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
 {
        struct sctp_sockaddr_entry *addr, *temp;
+       int found = 0;
 
        /* We hold the socket lock when calling this function,
         * and that acts as a writer synchronizing lock.
@@ -216,13 +217,14 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
        list_for_each_entry_safe(addr, temp, &bp->address_list, list) {
                if (sctp_cmp_addr_exact(&addr->a, del_addr)) {
                        /* Found the exact match. */
+                       found = 1;
                        addr->valid = 0;
                        list_del_rcu(&addr->list);
                        break;
                }
        }
 
-       if (addr && !addr->valid) {
+       if (found) {
                call_rcu(&addr->rcu, sctp_local_addr_free);
                SCTP_DBG_OBJCNT_DEC(addr);
                return 0;