tipc: fix an infoleak in tipc_nl_compat_link_dump
[pandora-kernel.git] / net / tipc / node.c
index 2d106ef..915bc6b 100644 (file)
@@ -112,6 +112,7 @@ struct tipc_node *tipc_node_create(u32 addr)
                        break;
        }
        list_add_tail(&n_ptr->list, &temp_node->list);
+       n_ptr->block_setup = WAIT_PEER_DOWN;
 
        tipc_num_nodes++;
 
@@ -312,7 +313,7 @@ static void node_established_contact(struct tipc_node *n_ptr)
        }
 }
 
-static void node_cleanup_finished(unsigned long node_addr)
+static void node_name_purge_complete(unsigned long node_addr)
 {
        struct tipc_node *n_ptr;
 
@@ -320,7 +321,7 @@ static void node_cleanup_finished(unsigned long node_addr)
        n_ptr = tipc_node_find(node_addr);
        if (n_ptr) {
                tipc_node_lock(n_ptr);
-               n_ptr->cleanup_required = 0;
+               n_ptr->block_setup &= ~WAIT_NAMES_GONE;
                tipc_node_unlock(n_ptr);
        }
        read_unlock_bh(&tipc_net_lock);
@@ -331,28 +332,32 @@ static void node_lost_contact(struct tipc_node *n_ptr)
        char addr_string[16];
        u32 i;
 
-       /* Clean up broadcast reception remains */
-       n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
-       while (n_ptr->bclink.deferred_head) {
-               struct sk_buff *buf = n_ptr->bclink.deferred_head;
-               n_ptr->bclink.deferred_head = buf->next;
-               buf_discard(buf);
-       }
-       if (n_ptr->bclink.defragm) {
-               buf_discard(n_ptr->bclink.defragm);
-               n_ptr->bclink.defragm = NULL;
-       }
+       info("Lost contact with %s\n",
+            tipc_addr_string_fill(addr_string, n_ptr->addr));
+
+       /* Flush broadcast link info associated with lost node */
 
        if (n_ptr->bclink.supported) {
+               n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
+               while (n_ptr->bclink.deferred_head) {
+                       struct sk_buff *buf = n_ptr->bclink.deferred_head;
+                       n_ptr->bclink.deferred_head = buf->next;
+                       buf_discard(buf);
+               }
+
+               if (n_ptr->bclink.defragm) {
+                       buf_discard(n_ptr->bclink.defragm);
+                       n_ptr->bclink.defragm = NULL;
+               }
+
+               tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
                tipc_bclink_acknowledge(n_ptr,
                                        mod(n_ptr->bclink.acked + 10000));
-               tipc_nmap_remove(&tipc_bcast_nmap, n_ptr->addr);
                if (n_ptr->addr < tipc_own_addr)
                        tipc_own_tag--;
-       }
 
-       info("Lost contact with %s\n",
-            tipc_addr_string_fill(addr_string, n_ptr->addr));
+               n_ptr->bclink.supported = 0;
+       }
 
        /* Abort link changeover */
        for (i = 0; i < MAX_BEARERS; i++) {
@@ -367,10 +372,10 @@ static void node_lost_contact(struct tipc_node *n_ptr)
        /* Notify subscribers */
        tipc_nodesub_notify(n_ptr);
 
-       /* Prevent re-contact with node until all cleanup is done */
+       /* Prevent re-contact with node until cleanup is done */
 
-       n_ptr->cleanup_required = 1;
-       tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
+       n_ptr->block_setup = WAIT_PEER_DOWN | WAIT_NAMES_GONE;
+       tipc_k_signal((Handler)node_name_purge_complete, n_ptr->addr);
 }
 
 struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
@@ -480,7 +485,8 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
                                continue;
                        link_info.dest = htonl(n_ptr->addr);
                        link_info.up = htonl(tipc_link_is_up(n_ptr->links[i]));
-                       strcpy(link_info.str, n_ptr->links[i]->name);
+                       strncpy(link_info.str, n_ptr->links[i]->name,
+                               sizeof(link_info.str));
                        tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO,
                                            &link_info, sizeof(link_info));
                }