In SMP, if a bridge fdb is being created when another CPU at the same time
delete the bridge, this newly created fdb may incur a leakage:

CPU0:

static void del_nbp(struct net_bridge_port *p)
{
        /*
         * CPU1 enter br_fdb_update(), bridge port is still valid.
         */
        ......
        spin_lock_bh(&br->lock);
        br_stp_disable_port(p);
        spin_unlock_bh(&br->lock);

        br_ifinfo_notify(RTM_DELLINK, p);

        br_fdb_delete_by_port(br, p, 1);

        /*
         * CPU1 call fdb_create() for the being deleted bridge,
         * a fdb would be add to bridge's fdb hash table, and will never
         * be freed. because when deleting a bridge, linux flush fdb for
each
         * bridge port, but this newly created fdb belong to no bridge port
         */
        ......
}

To fix this, fdb_create() should be changed to:
{
        struct net_bridge_fdb_entry *fdb;

        /*
         * if the bridge port is deleted, then return.
         */
        if (!(source->state == BR_STATE_LEARNING ||
              source->state == BR_STATE_FORWARDING))
                return;

        fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
        if (fdb) {
                memcpy(fdb->addr.addr, addr, ETH_ALEN);
                atomic_set(&fdb->use_count, 1);
                hlist_add_head_rcu(&fdb->hlist, head);

                fdb->dst = source;
                fdb->is_local = is_local;
                fdb->is_static = is_local;
                fdb->ageing_timer = jiffies;
        }
        return fdb;
}



-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to