Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 16 May 2012 20:14:52 +0000 (13:14 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 16 May 2012 20:14:52 +0000 (13:14 -0700)
Pull networking tree from David Miller:

1) ptp_pch driver build broke during this merge window due to missing
   slab.h header, fix from Geery Uytterhoeven.

2) If ipset passes in a bogus hash table size we crash because the size
   is not validated properly.  Compounding this, gcc-4.7 can miscompile
   ipset such that even when the user specifies legitimate parameters
   the tool passes in an out-of-range size to the kernel.

   Fix from Jozsef Kadlecsik.

3) Users have reported that the netdev watchdog can trigger with pch_gbe
   devices, and it turns out this is happening because of races in the
   TX path of the driver leading to the transmitter hanging.  Fix from
   Eric Dumazet, reported and tested by Andy Cress.

4) Novatel USB551L devices match the generic class entries for the cdc
   ethernet USB driver, but they don't work because they have generic
   descriptors and thus need FLAG_WWAN to function properly.

   Add the necessary ID table entry to fix this, from Dan Williams.

5) A recursive locking fix in the USBNET driver added a new problem, in
   that packet list traversal is now racy and we can thus access
   unlinked SKBs and crash.

   Avoid this situation by adding some extra state tracking, from Ming
   Lei.

6) The rtlwifi conversion to asynchronous firmware loading is racy, fix
   by reordering the probe procedure.  From Larry Finger.

   Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=43187

7) Fix regressions with bluetooth keyboards by notifying userland
   properly when the security level changes, from Gustavo Padovan.

8) Bluetooth needs to make sure device connected events are emitted
   before other kinds of events, otherwise userspace will think there is
   no baseband link yet and therefore abort the sockets associated with
   that connection.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  netfilter: ipset: fix hash size checking in kernel
  ptp_pch: Add missing #include <linux/slab.h>
  pch_gbe: fix transmit races
  cdc_ether: add Novatel USB551L device IDs for FLAG_WWAN
  usbnet: fix skb traversing races during unlink(v2)
  Bluetooth: mgmt: Fix device_connected sending order
  Bluetooth: notify userspace of security level change
  rtlwifi: fix for race condition when firmware is cached

22 files changed:
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/usbnet.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/usb.c
drivers/ptp/ptp_pch.c
include/linux/netfilter/ipset/ip_set_ahash.h
include/linux/usb/usbnet.h
include/net/bluetooth/bluetooth.h
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/netfilter/ipset/ip_set_hash_ip.c
net/netfilter/ipset/ip_set_hash_ipport.c
net/netfilter/ipset/ip_set_hash_ipportip.c
net/netfilter/ipset/ip_set_hash_ipportnet.c
net/netfilter/ipset/ip_set_hash_net.c
net/netfilter/ipset/ip_set_hash_netiface.c
net/netfilter/ipset/ip_set_hash_netport.c

index dd14915..ba78174 100644 (file)
@@ -584,7 +584,6 @@ struct pch_gbe_hw_stats {
 /**
  * struct pch_gbe_adapter - board specific private data structure
  * @stats_lock:        Spinlock structure for status
- * @tx_queue_lock:     Spinlock structure for transmit
  * @ethtool_lock:      Spinlock structure for ethtool
  * @irq_sem:           Semaphore for interrupt
  * @netdev:            Pointer of network device structure
@@ -609,7 +608,6 @@ struct pch_gbe_hw_stats {
 
 struct pch_gbe_adapter {
        spinlock_t stats_lock;
-       spinlock_t tx_queue_lock;
        spinlock_t ethtool_lock;
        atomic_t irq_sem;
        struct net_device *netdev;
index 8035e5f..1e38d50 100644 (file)
@@ -640,14 +640,11 @@ static void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw)
  */
 static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter)
 {
-       int size;
-
-       size = (int)sizeof(struct pch_gbe_tx_ring);
-       adapter->tx_ring = kzalloc(size, GFP_KERNEL);
+       adapter->tx_ring = kzalloc(sizeof(*adapter->tx_ring), GFP_KERNEL);
        if (!adapter->tx_ring)
                return -ENOMEM;
-       size = (int)sizeof(struct pch_gbe_rx_ring);
-       adapter->rx_ring = kzalloc(size, GFP_KERNEL);
+
+       adapter->rx_ring = kzalloc(sizeof(*adapter->rx_ring), GFP_KERNEL);
        if (!adapter->rx_ring) {
                kfree(adapter->tx_ring);
                return -ENOMEM;
@@ -1162,7 +1159,6 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
        struct sk_buff *tmp_skb;
        unsigned int frame_ctrl;
        unsigned int ring_num;
-       unsigned long flags;
 
        /*-- Set frame control --*/
        frame_ctrl = 0;
@@ -1211,14 +1207,14 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
                        }
                }
        }
-       spin_lock_irqsave(&tx_ring->tx_lock, flags);
+
        ring_num = tx_ring->next_to_use;
        if (unlikely((ring_num + 1) == tx_ring->count))
                tx_ring->next_to_use = 0;
        else
                tx_ring->next_to_use = ring_num + 1;
 
-       spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+
        buffer_info = &tx_ring->buffer_info[ring_num];
        tmp_skb = buffer_info->skb;
 
@@ -1518,7 +1514,7 @@ pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter,
                                                &rx_ring->rx_buff_pool_logic,
                                                GFP_KERNEL);
        if (!rx_ring->rx_buff_pool) {
-               pr_err("Unable to allocate memory for the receive poll buffer\n");
+               pr_err("Unable to allocate memory for the receive pool buffer\n");
                return -ENOMEM;
        }
        memset(rx_ring->rx_buff_pool, 0, size);
@@ -1637,15 +1633,17 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
        pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
                 cleaned_count);
        /* Recover from running out of Tx resources in xmit_frame */
+       spin_lock(&tx_ring->tx_lock);
        if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) {
                netif_wake_queue(adapter->netdev);
                adapter->stats.tx_restart_count++;
                pr_debug("Tx wake queue\n");
        }
-       spin_lock(&adapter->tx_queue_lock);
+
        tx_ring->next_to_clean = i;
-       spin_unlock(&adapter->tx_queue_lock);
+
        pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
+       spin_unlock(&tx_ring->tx_lock);
        return cleaned;
 }
 
@@ -2037,7 +2035,6 @@ static int pch_gbe_sw_init(struct pch_gbe_adapter *adapter)
                return -ENOMEM;
        }
        spin_lock_init(&adapter->hw.miim_lock);
-       spin_lock_init(&adapter->tx_queue_lock);
        spin_lock_init(&adapter->stats_lock);
        spin_lock_init(&adapter->ethtool_lock);
        atomic_set(&adapter->irq_sem, 0);
@@ -2142,10 +2139,10 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                         tx_ring->next_to_use, tx_ring->next_to_clean);
                return NETDEV_TX_BUSY;
        }
-       spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 
        /* CRC,ITAG no support */
        pch_gbe_tx_queue(adapter, tx_ring, skb);
+       spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
        return NETDEV_TX_OK;
 }
 
index 00880ed..425e201 100644 (file)
@@ -485,6 +485,7 @@ static const struct driver_info wwan_info = {
 /*-------------------------------------------------------------------------*/
 
 #define HUAWEI_VENDOR_ID       0x12D1
+#define NOVATEL_VENDOR_ID      0x1410
 
 static const struct usb_device_id      products [] = {
 /*
@@ -602,6 +603,21 @@ static const struct usb_device_id  products [] = {
  * because of bugs/quirks in a given product (like Zaurus, above).
  */
 {
+       /* Novatel USB551L */
+       /* This match must come *before* the generic CDC-ETHER match so that
+        * we get FLAG_WWAN set on the device, since it's descriptors are
+        * generic CDC-ETHER.
+        */
+       .match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
+                | USB_DEVICE_ID_MATCH_PRODUCT
+                | USB_DEVICE_ID_MATCH_INT_INFO,
+       .idVendor               = NOVATEL_VENDOR_ID,
+       .idProduct              = 0xB001,
+       .bInterfaceClass        = USB_CLASS_COMM,
+       .bInterfaceSubClass     = USB_CDC_SUBCLASS_ETHERNET,
+       .bInterfaceProtocol     = USB_CDC_PROTO_NONE,
+       .driver_info = (unsigned long)&wwan_info,
+}, {
        USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
                        USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &cdc_info,
index 2d927fb..b38db48 100644 (file)
@@ -282,17 +282,32 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(usbnet_change_mtu);
 
+/* The caller must hold list->lock */
+static void __usbnet_queue_skb(struct sk_buff_head *list,
+                       struct sk_buff *newsk, enum skb_state state)
+{
+       struct skb_data *entry = (struct skb_data *) newsk->cb;
+
+       __skb_queue_tail(list, newsk);
+       entry->state = state;
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from
  * completion callbacks.  2.5 should have fixed those bugs...
  */
 
-static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list)
+static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
+               struct sk_buff_head *list, enum skb_state state)
 {
        unsigned long           flags;
+       enum skb_state          old_state;
+       struct skb_data *entry = (struct skb_data *) skb->cb;
 
        spin_lock_irqsave(&list->lock, flags);
+       old_state = entry->state;
+       entry->state = state;
        __skb_unlink(skb, list);
        spin_unlock(&list->lock);
        spin_lock(&dev->done.lock);
@@ -300,6 +315,7 @@ static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_hea
        if (dev->done.qlen == 1)
                tasklet_schedule(&dev->bh);
        spin_unlock_irqrestore(&dev->done.lock, flags);
+       return old_state;
 }
 
 /* some work can't be done in tasklets, so we use keventd
@@ -340,7 +356,6 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
        entry = (struct skb_data *) skb->cb;
        entry->urb = urb;
        entry->dev = dev;
-       entry->state = rx_start;
        entry->length = 0;
 
        usb_fill_bulk_urb (urb, dev->udev, dev->in,
@@ -372,7 +387,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
                        tasklet_schedule (&dev->bh);
                        break;
                case 0:
-                       __skb_queue_tail (&dev->rxq, skb);
+                       __usbnet_queue_skb(&dev->rxq, skb, rx_start);
                }
        } else {
                netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
@@ -423,16 +438,17 @@ static void rx_complete (struct urb *urb)
        struct skb_data         *entry = (struct skb_data *) skb->cb;
        struct usbnet           *dev = entry->dev;
        int                     urb_status = urb->status;
+       enum skb_state          state;
 
        skb_put (skb, urb->actual_length);
-       entry->state = rx_done;
+       state = rx_done;
        entry->urb = NULL;
 
        switch (urb_status) {
        /* success */
        case 0:
                if (skb->len < dev->net->hard_header_len) {
-                       entry->state = rx_cleanup;
+                       state = rx_cleanup;
                        dev->net->stats.rx_errors++;
                        dev->net->stats.rx_length_errors++;
                        netif_dbg(dev, rx_err, dev->net,
@@ -471,7 +487,7 @@ static void rx_complete (struct urb *urb)
                                  "rx throttle %d\n", urb_status);
                }
 block:
-               entry->state = rx_cleanup;
+               state = rx_cleanup;
                entry->urb = urb;
                urb = NULL;
                break;
@@ -482,17 +498,18 @@ block:
                // FALLTHROUGH
 
        default:
-               entry->state = rx_cleanup;
+               state = rx_cleanup;
                dev->net->stats.rx_errors++;
                netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status);
                break;
        }
 
-       defer_bh(dev, skb, &dev->rxq);
+       state = defer_bh(dev, skb, &dev->rxq, state);
 
        if (urb) {
                if (netif_running (dev->net) &&
-                   !test_bit (EVENT_RX_HALT, &dev->flags)) {
+                   !test_bit (EVENT_RX_HALT, &dev->flags) &&
+                   state != unlink_start) {
                        rx_submit (dev, urb, GFP_ATOMIC);
                        usb_mark_last_busy(dev->udev);
                        return;
@@ -579,16 +596,23 @@ EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq);
 static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
 {
        unsigned long           flags;
-       struct sk_buff          *skb, *skbnext;
+       struct sk_buff          *skb;
        int                     count = 0;
 
        spin_lock_irqsave (&q->lock, flags);
-       skb_queue_walk_safe(q, skb, skbnext) {
+       while (!skb_queue_empty(q)) {
                struct skb_data         *entry;
                struct urb              *urb;
                int                     retval;
 
-               entry = (struct skb_data *) skb->cb;
+               skb_queue_walk(q, skb) {
+                       entry = (struct skb_data *) skb->cb;
+                       if (entry->state != unlink_start)
+                               goto found;
+               }
+               break;
+found:
+               entry->state = unlink_start;
                urb = entry->urb;
 
                /*
@@ -1039,8 +1063,7 @@ static void tx_complete (struct urb *urb)
        }
 
        usb_autopm_put_interface_async(dev->intf);
-       entry->state = tx_done;
-       defer_bh(dev, skb, &dev->txq);
+       (void) defer_bh(dev, skb, &dev->txq, tx_done);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1096,7 +1119,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
        entry = (struct skb_data *) skb->cb;
        entry->urb = urb;
        entry->dev = dev;
-       entry->state = tx_start;
        entry->length = length;
 
        usb_fill_bulk_urb (urb, dev->udev, dev->out,
@@ -1155,7 +1177,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
                break;
        case 0:
                net->trans_start = jiffies;
-               __skb_queue_tail (&dev->txq, skb);
+               __usbnet_queue_skb(&dev->txq, skb, tx_start);
                if (dev->txq.qlen >= TX_QLEN (dev))
                        netif_stop_queue (net);
        }
index cc15fdb..67f9430 100644 (file)
@@ -1851,14 +1851,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        /*like read eeprom and so on */
        rtlpriv->cfg->ops->read_eeprom_info(hw);
 
-       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
-               err = -ENODEV;
-               goto fail3;
-       }
-
-       rtlpriv->cfg->ops->init_sw_leds(hw);
-
        /*aspm */
        rtl_pci_init_aspm(hw);
 
@@ -1877,6 +1869,14 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
                goto fail3;
        }
 
+       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
+               err = -ENODEV;
+               goto fail3;
+       }
+
+       rtlpriv->cfg->ops->init_sw_leds(hw);
+
        err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
index d04dbda..a6049d7 100644 (file)
@@ -971,11 +971,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
        rtlpriv->cfg->ops->read_chip_version(hw);
        /*like read eeprom and so on */
        rtlpriv->cfg->ops->read_eeprom_info(hw);
-       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
-               goto error_out;
-       }
-       rtlpriv->cfg->ops->init_sw_leds(hw);
        err = _rtl_usb_init(hw);
        if (err)
                goto error_out;
@@ -987,6 +982,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
                         "Can't allocate sw for mac80211\n");
                goto error_out;
        }
+       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
+               goto error_out;
+       }
+       rtlpriv->cfg->ops->init_sw_leds(hw);
 
        return 0;
 error_out:
index 375eb04..6fff680 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/ptp_clock_kernel.h>
+#include <linux/slab.h>
 
 #define STATION_ADDR_LEN       20
 #define PCI_DEVICE_ID_PCH_1588 0x8819
index 05a5d72..230a290 100644 (file)
@@ -99,6 +99,22 @@ struct ip_set_hash {
 #endif
 };
 
+static size_t
+htable_size(u8 hbits)
+{
+       size_t hsize;
+
+       /* We must fit both into u32 in jhash and size_t */
+       if (hbits > 31)
+               return 0;
+       hsize = jhash_size(hbits);
+       if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket)
+           < hsize)
+               return 0;
+
+       return hsize * sizeof(struct hbucket) + sizeof(struct htable);
+}
+
 /* Compute htable_bits from the user input parameter hashsize */
 static u8
 htable_bits(u32 hashsize)
index 605b0aa..76f4396 100644 (file)
@@ -191,7 +191,8 @@ extern void usbnet_cdc_status(struct usbnet *, struct urb *);
 enum skb_state {
        illegal = 0,
        tx_start, tx_done,
-       rx_start, rx_done, rx_cleanup
+       rx_start, rx_done, rx_cleanup,
+       unlink_start
 };
 
 struct skb_data {      /* skb->cb is one of these */
index 262ebd1..a65910b 100644 (file)
@@ -191,6 +191,7 @@ struct bt_sock {
        struct list_head accept_q;
        struct sock *parent;
        u32 defer_setup;
+       bool suspended;
 };
 
 struct bt_sock_list {
index 72eb187..6fb68a9 100644 (file)
@@ -450,7 +450,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, poll_table *wa
                        sk->sk_state == BT_CONFIG)
                return mask;
 
-       if (sock_writeable(sk))
+       if (!bt_sk(sk)->suspended && sock_writeable(sk))
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
                set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
index edfd61a..d6dc44c 100644 (file)
@@ -2784,6 +2784,14 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
        if (conn) {
                hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
 
+               hci_dev_lock(hdev);
+               if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
+                   !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
+                       mgmt_device_connected(hdev, &conn->dst, conn->type,
+                                             conn->dst_type, 0, NULL, 0,
+                                             conn->dev_class);
+               hci_dev_unlock(hdev);
+
                /* Send to upper protocol */
                l2cap_recv_acldata(conn, skb, flags);
                return;
index 6c06525..1266f78 100644 (file)
@@ -2039,6 +2039,12 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
 
                clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
 
+               if (ev->status && conn->state == BT_CONNECTED) {
+                       hci_acl_disconn(conn, 0x13);
+                       hci_conn_put(conn);
+                       goto unlock;
+               }
+
                if (conn->state == BT_CONFIG) {
                        if (!ev->status)
                                conn->state = BT_CONNECTED;
@@ -2049,6 +2055,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
                        hci_encrypt_cfm(conn, ev->status, ev->encrypt);
        }
 
+unlock:
        hci_dev_unlock(hdev);
 }
 
@@ -2102,7 +2109,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
                goto unlock;
        }
 
-       if (!ev->status) {
+       if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
                struct hci_cp_remote_name_req cp;
                memset(&cp, 0, sizeof(cp));
                bacpy(&cp.bdaddr, &conn->dst);
@@ -2871,7 +2878,7 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
        if (conn->state != BT_CONFIG)
                goto unlock;
 
-       if (!ev->status) {
+       if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
                struct hci_cp_remote_name_req cp;
                memset(&cp, 0, sizeof(cp));
                bacpy(&cp.bdaddr, &conn->dst);
index 94552b3..6f9c25b 100644 (file)
@@ -4589,6 +4589,11 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
                if (!status && (chan->state == BT_CONNECTED ||
                                                chan->state == BT_CONFIG)) {
+                       struct sock *sk = chan->sk;
+
+                       bt_sk(sk)->suspended = false;
+                       sk->sk_state_change(sk);
+
                        l2cap_check_encryption(chan, encrypt);
                        l2cap_chan_unlock(chan);
                        continue;
index 29122ed..04e7c17 100644 (file)
@@ -592,10 +592,14 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
                        sk->sk_state = BT_CONFIG;
                        chan->state = BT_CONFIG;
 
-               /* or for ACL link, under defer_setup time */
-               } else if (sk->sk_state == BT_CONNECT2 &&
-                                       bt_sk(sk)->defer_setup) {
-                       err = l2cap_chan_check_security(chan);
+               /* or for ACL link */
+               } else if ((sk->sk_state == BT_CONNECT2 &&
+                          bt_sk(sk)->defer_setup) ||
+                          sk->sk_state == BT_CONNECTED) {
+                       if (!l2cap_chan_check_security(chan))
+                               bt_sk(sk)->suspended = true;
+                       else
+                               sk->sk_state_change(sk);
                } else {
                        err = -EINVAL;
                }
index 5139dea..828ce46 100644 (file)
@@ -364,6 +364,7 @@ hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 netmask, hbits;
+       size_t hsize;
        struct ip_set_hash *h;
 
        if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
@@ -405,9 +406,12 @@ hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        h->timeout = IPSET_NO_TIMEOUT;
 
        hbits = htable_bits(hashsize);
-       h->table = ip_set_alloc(
-                       sizeof(struct htable)
-                       + jhash_size(hbits) * sizeof(struct hbucket));
+       hsize = htable_size(hbits);
+       if (hsize == 0) {
+               kfree(h);
+               return -ENOMEM;
+       }
+       h->table = ip_set_alloc(hsize);
        if (!h->table) {
                kfree(h);
                return -ENOMEM;
index 9c27e24..e8dbb49 100644 (file)
@@ -449,6 +449,7 @@ hash_ipport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
+       size_t hsize;
 
        if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
                return -IPSET_ERR_INVALID_FAMILY;
@@ -476,9 +477,12 @@ hash_ipport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        h->timeout = IPSET_NO_TIMEOUT;
 
        hbits = htable_bits(hashsize);
-       h->table = ip_set_alloc(
-                       sizeof(struct htable)
-                       + jhash_size(hbits) * sizeof(struct hbucket));
+       hsize = htable_size(hbits);
+       if (hsize == 0) {
+               kfree(h);
+               return -ENOMEM;
+       }
+       h->table = ip_set_alloc(hsize);
        if (!h->table) {
                kfree(h);
                return -ENOMEM;
index 9134057..52f79d8 100644 (file)
@@ -467,6 +467,7 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
+       size_t hsize;
 
        if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
                return -IPSET_ERR_INVALID_FAMILY;
@@ -494,9 +495,12 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        h->timeout = IPSET_NO_TIMEOUT;
 
        hbits = htable_bits(hashsize);
-       h->table = ip_set_alloc(
-                       sizeof(struct htable)
-                       + jhash_size(hbits) * sizeof(struct hbucket));
+       hsize = htable_size(hbits);
+       if (hsize == 0) {
+               kfree(h);
+               return -ENOMEM;
+       }
+       h->table = ip_set_alloc(hsize);
        if (!h->table) {
                kfree(h);
                return -ENOMEM;
index 5d05e69..97583f5 100644 (file)
@@ -616,6 +616,7 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
+       size_t hsize;
 
        if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
                return -IPSET_ERR_INVALID_FAMILY;
@@ -645,9 +646,12 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        h->timeout = IPSET_NO_TIMEOUT;
 
        hbits = htable_bits(hashsize);
-       h->table = ip_set_alloc(
-                       sizeof(struct htable)
-                       + jhash_size(hbits) * sizeof(struct hbucket));
+       hsize = htable_size(hbits);
+       if (hsize == 0) {
+               kfree(h);
+               return -ENOMEM;
+       }
+       h->table = ip_set_alloc(hsize);
        if (!h->table) {
                kfree(h);
                return -ENOMEM;
index 7c3d945..1721cde 100644 (file)
@@ -460,6 +460,7 @@ hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        struct ip_set_hash *h;
        u8 hbits;
+       size_t hsize;
 
        if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
                return -IPSET_ERR_INVALID_FAMILY;
@@ -489,9 +490,12 @@ hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        h->timeout = IPSET_NO_TIMEOUT;
 
        hbits = htable_bits(hashsize);
-       h->table = ip_set_alloc(
-                       sizeof(struct htable)
-                       + jhash_size(hbits) * sizeof(struct hbucket));
+       hsize = htable_size(hbits);
+       if (hsize == 0) {
+               kfree(h);
+               return -ENOMEM;
+       }
+       h->table = ip_set_alloc(hsize);
        if (!h->table) {
                kfree(h);
                return -ENOMEM;
index f24037f..33bafc9 100644 (file)
@@ -722,6 +722,7 @@ hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
+       size_t hsize;
 
        if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
                return -IPSET_ERR_INVALID_FAMILY;
@@ -752,9 +753,12 @@ hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        h->ahash_max = AHASH_MAX_SIZE;
 
        hbits = htable_bits(hashsize);
-       h->table = ip_set_alloc(
-                       sizeof(struct htable)
-                       + jhash_size(hbits) * sizeof(struct hbucket));
+       hsize = htable_size(hbits);
+       if (hsize == 0) {
+               kfree(h);
+               return -ENOMEM;
+       }
+       h->table = ip_set_alloc(hsize);
        if (!h->table) {
                kfree(h);
                return -ENOMEM;
index ce2e771..3a5e198 100644 (file)
@@ -572,6 +572,7 @@ hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
+       size_t hsize;
 
        if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
                return -IPSET_ERR_INVALID_FAMILY;
@@ -601,9 +602,12 @@ hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        h->timeout = IPSET_NO_TIMEOUT;
 
        hbits = htable_bits(hashsize);
-       h->table = ip_set_alloc(
-                       sizeof(struct htable)
-                       + jhash_size(hbits) * sizeof(struct hbucket));
+       hsize = htable_size(hbits);
+       if (hsize == 0) {
+               kfree(h);
+               return -ENOMEM;
+       }
+       h->table = ip_set_alloc(hsize);
        if (!h->table) {
                kfree(h);
                return -ENOMEM;