Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull more networking fixes from David Miller:

1) Eric Dumazet discovered and fixed what turned out to be a family of
bugs. These functions were using pskb_may_pull() which might need
to reallocate the linear SKB data buffer, but the callers were not
expecting this possibility. The callers have cached pointers to the
packet header areas, and would need to reload them if we were to
continue using pskb_may_pull().

So they could end up reading garbage.

It's easier to just change these RAW4/RAW6/MIP6 routines to use
skb_header_pointer() instead of pskb_may_pull(), which won't modify
the linear SKB data area.

2) Dave Jone's syscall spammer caught a case where a non-TCP socket can
call down into the TCP keepalive code. The case basically involves
creating a raw socket with sk_protocol == IPPROTO_TCP, then calling
setsockopt(sock_fd, SO_KEEPALIVE, ...)

Fixed by Eric Dumazet.

3) Bluetooth devices do not get configured properly while being powered
on, resulting in always using legacy pairing instead of SSP. Fix
from Andrzej Kaczmarek.

4) Bluetooth cancels delayed work erroneously, put stricter checks in
place. From Andrei Emeltchenko.

5) Fix deadlock between cfg80211_mutex and reg_regdb_search_mutex in
cfg80211, from Luis R. Rodriguez.

6) Fix interrupt double release in iwlwifi, from Emmanuel Grumbach.

7) Missing module license in bcm87xx driver, from Peter Huewe.

8) Team driver can lose port changed events when adding devices to a
team, fix from Jiri Pirko.

9) Fix endless loop when trying ot unregister PPPOE device in zombie
state, from Xiaodong Xu.

10) batman-adv layer needs to set MAC address of software device
earlier, otherwise we call tt_local_add with it uninitialized.

11) Fix handling of KSZ8021 PHYs, it's matched currently by KS8051 but
that doesn't program the device properly. From Marek Vasut.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
ipv6: mip6: fix mip6_mh_filter()
ipv6: raw: fix icmpv6_filter()
net: guard tcp_set_keepalive() to tcp sockets
phy/micrel: Add missing header to micrel_phy.h
phy/micrel: Rename KS80xx to KSZ80xx
phy/micrel: Implement support for KSZ8021
batman-adv: Fix symmetry check / route flapping in multi interface setups
batman-adv: Fix change mac address of soft iface.
pppoe: drop PPPOX_ZOMBIEs in pppoe_release
team: send port changed when added
ipv4: raw: fix icmp_filter()
net/phy/bcm87xx: Add MODULE_LICENSE("GPL") to GPL driver
iwlwifi: don't double free the interrupt in failure path
cfg80211: fix possible circular lock on reg_regdb_search()
Bluetooth: Fix not removing power_off delayed work
Bluetooth: Fix freeing uninitialized delayed works
Bluetooth: mgmt: Fix enabling LE while powered off
Bluetooth: mgmt: Fix enabling SSP while powered off

+152 -61
+1 -1
arch/arm/mach-mxs/mach-mxs.c
··· 261 261 enable_clk_enet_out(); 262 262 263 263 if (IS_BUILTIN(CONFIG_PHYLIB)) 264 - phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK, 264 + phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK, 265 265 apx4devkit_phy_fixup); 266 266 267 267 mxsfb_pdata.mode_list = apx4devkit_video_modes;
+2
drivers/net/phy/bcm87xx.c
··· 229 229 ARRAY_SIZE(bcm87xx_driver)); 230 230 } 231 231 module_exit(bcm87xx_exit); 232 + 233 + MODULE_LICENSE("GPL");
+36 -9
drivers/net/phy/micrel.c
··· 21 21 #include <linux/phy.h> 22 22 #include <linux/micrel_phy.h> 23 23 24 + /* Operation Mode Strap Override */ 25 + #define MII_KSZPHY_OMSO 0x16 26 + #define KSZPHY_OMSO_B_CAST_OFF (1 << 9) 27 + #define KSZPHY_OMSO_RMII_OVERRIDE (1 << 1) 28 + #define KSZPHY_OMSO_MII_OVERRIDE (1 << 0) 29 + 24 30 /* general Interrupt control/status reg in vendor specific block. */ 25 31 #define MII_KSZPHY_INTCS 0x1B 26 32 #define KSZPHY_INTCS_JABBER (1 << 15) ··· 107 101 return 0; 108 102 } 109 103 104 + static int ksz8021_config_init(struct phy_device *phydev) 105 + { 106 + const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE; 107 + phy_write(phydev, MII_KSZPHY_OMSO, val); 108 + return 0; 109 + } 110 + 110 111 static int ks8051_config_init(struct phy_device *phydev) 111 112 { 112 113 int regval; ··· 141 128 .config_intr = ks8737_config_intr, 142 129 .driver = { .owner = THIS_MODULE,}, 143 130 }, { 144 - .phy_id = PHY_ID_KS8041, 131 + .phy_id = PHY_ID_KSZ8021, 132 + .phy_id_mask = 0x00ffffff, 133 + .name = "Micrel KSZ8021", 134 + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | 135 + SUPPORTED_Asym_Pause), 136 + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 137 + .config_init = ksz8021_config_init, 138 + .config_aneg = genphy_config_aneg, 139 + .read_status = genphy_read_status, 140 + .ack_interrupt = kszphy_ack_interrupt, 141 + .config_intr = kszphy_config_intr, 142 + .driver = { .owner = THIS_MODULE,}, 143 + }, { 144 + .phy_id = PHY_ID_KSZ8041, 145 145 .phy_id_mask = 0x00fffff0, 146 - .name = "Micrel KS8041", 146 + .name = "Micrel KSZ8041", 147 147 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause 148 148 | SUPPORTED_Asym_Pause), 149 149 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, ··· 167 141 .config_intr = kszphy_config_intr, 168 142 .driver = { .owner = THIS_MODULE,}, 169 143 }, { 170 - .phy_id = PHY_ID_KS8051, 144 + .phy_id = PHY_ID_KSZ8051, 171 145 .phy_id_mask = 0x00fffff0, 172 - .name = "Micrel KS8051", 146 + .name = "Micrel KSZ8051", 173 147 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause 174 148 | SUPPORTED_Asym_Pause), 175 149 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, ··· 180 154 .config_intr = kszphy_config_intr, 181 155 .driver = { .owner = THIS_MODULE,}, 182 156 }, { 183 - .phy_id = PHY_ID_KS8001, 184 - .name = "Micrel KS8001 or KS8721", 157 + .phy_id = PHY_ID_KSZ8001, 158 + .name = "Micrel KSZ8001 or KS8721", 185 159 .phy_id_mask = 0x00ffffff, 186 160 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), 187 161 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, ··· 227 201 228 202 static struct mdio_device_id __maybe_unused micrel_tbl[] = { 229 203 { PHY_ID_KSZ9021, 0x000ffffe }, 230 - { PHY_ID_KS8001, 0x00ffffff }, 204 + { PHY_ID_KSZ8001, 0x00ffffff }, 231 205 { PHY_ID_KS8737, 0x00fffff0 }, 232 - { PHY_ID_KS8041, 0x00fffff0 }, 233 - { PHY_ID_KS8051, 0x00fffff0 }, 206 + { PHY_ID_KSZ8021, 0x00ffffff }, 207 + { PHY_ID_KSZ8041, 0x00fffff0 }, 208 + { PHY_ID_KSZ8051, 0x00fffff0 }, 234 209 { } 235 210 }; 236 211
+1 -1
drivers/net/ppp/pppoe.c
··· 570 570 571 571 po = pppox_sk(sk); 572 572 573 - if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { 573 + if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) { 574 574 dev_put(po->pppoe_dev); 575 575 po->pppoe_dev = NULL; 576 576 }
+24 -8
drivers/net/team/team.c
··· 848 848 } 849 849 #endif 850 850 851 - static void __team_port_change_check(struct team_port *port, bool linkup); 851 + static void __team_port_change_port_added(struct team_port *port, bool linkup); 852 852 853 853 static int team_port_add(struct team *team, struct net_device *port_dev) 854 854 { ··· 948 948 team_port_enable(team, port); 949 949 list_add_tail_rcu(&port->list, &team->port_list); 950 950 __team_compute_features(team); 951 - __team_port_change_check(port, !!netif_carrier_ok(port_dev)); 951 + __team_port_change_port_added(port, !!netif_carrier_ok(port_dev)); 952 952 __team_options_change_check(team); 953 953 954 954 netdev_info(dev, "Port device %s added\n", portname); ··· 983 983 return err; 984 984 } 985 985 986 + static void __team_port_change_port_removed(struct team_port *port); 987 + 986 988 static int team_port_del(struct team *team, struct net_device *port_dev) 987 989 { 988 990 struct net_device *dev = team->dev; ··· 1001 999 __team_option_inst_mark_removed_port(team, port); 1002 1000 __team_options_change_check(team); 1003 1001 __team_option_inst_del_port(team, port); 1004 - port->removed = true; 1005 - __team_port_change_check(port, false); 1002 + __team_port_change_port_removed(port); 1006 1003 team_port_disable(team, port); 1007 1004 list_del_rcu(&port->list); 1008 1005 netdev_rx_handler_unregister(port_dev); ··· 2252 2251 } 2253 2252 2254 2253 /* rtnl lock is held */ 2255 - static void __team_port_change_check(struct team_port *port, bool linkup) 2254 + 2255 + static void __team_port_change_send(struct team_port *port, bool linkup) 2256 2256 { 2257 2257 int err; 2258 - 2259 - if (!port->removed && port->state.linkup == linkup) 2260 - return; 2261 2258 2262 2259 port->changed = true; 2263 2260 port->state.linkup = linkup; ··· 2279 2280 netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink\n", 2280 2281 port->dev->name); 2281 2282 2283 + } 2284 + 2285 + static void __team_port_change_check(struct team_port *port, bool linkup) 2286 + { 2287 + if (port->state.linkup != linkup) 2288 + __team_port_change_send(port, linkup); 2289 + } 2290 + 2291 + static void __team_port_change_port_added(struct team_port *port, bool linkup) 2292 + { 2293 + __team_port_change_send(port, linkup); 2294 + } 2295 + 2296 + static void __team_port_change_port_removed(struct team_port *port) 2297 + { 2298 + port->removed = true; 2299 + __team_port_change_send(port, false); 2282 2300 } 2283 2301 2284 2302 static void team_port_change_check(struct team_port *port, bool linkup)
+1
drivers/net/wireless/iwlwifi/pcie/trans.c
··· 1442 1442 return err; 1443 1443 1444 1444 err_free_irq: 1445 + trans_pcie->irq_requested = false; 1445 1446 free_irq(trans_pcie->irq, trans); 1446 1447 error: 1447 1448 iwl_free_isr_ict(trans);
+16 -3
include/linux/micrel_phy.h
··· 1 + /* 2 + * include/linux/micrel_phy.h 3 + * 4 + * Micrel PHY IDs 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the 8 + * Free Software Foundation; either version 2 of the License, or (at your 9 + * option) any later version. 10 + * 11 + */ 12 + 1 13 #ifndef _MICREL_PHY_H 2 14 #define _MICREL_PHY_H 3 15 ··· 17 5 18 6 #define PHY_ID_KSZ9021 0x00221610 19 7 #define PHY_ID_KS8737 0x00221720 20 - #define PHY_ID_KS8041 0x00221510 21 - #define PHY_ID_KS8051 0x00221550 8 + #define PHY_ID_KSZ8021 0x00221555 9 + #define PHY_ID_KSZ8041 0x00221510 10 + #define PHY_ID_KSZ8051 0x00221550 22 11 /* both for ks8001 Rev. A/B, and for ks8721 Rev 3. */ 23 - #define PHY_ID_KS8001 0x0022161A 12 + #define PHY_ID_KSZ8001 0x0022161A 24 13 25 14 /* struct phy_device dev_flags definitions */ 26 15 #define MICREL_PHY_50MHZ_CLK 0x00000001
+7 -6
net/batman-adv/bat_iv_ogm.c
··· 642 642 struct batadv_neigh_node *router = NULL; 643 643 struct batadv_orig_node *orig_node_tmp; 644 644 struct hlist_node *node; 645 - uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; 645 + int if_num; 646 + uint8_t sum_orig, sum_neigh; 646 647 uint8_t *neigh_addr; 647 648 648 649 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, ··· 728 727 if (router && (neigh_node->tq_avg == router->tq_avg)) { 729 728 orig_node_tmp = router->orig_node; 730 729 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 731 - bcast_own_sum_orig = 732 - orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 730 + if_num = router->if_incoming->if_num; 731 + sum_orig = orig_node_tmp->bcast_own_sum[if_num]; 733 732 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 734 733 735 734 orig_node_tmp = neigh_node->orig_node; 736 735 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 737 - bcast_own_sum_neigh = 738 - orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 736 + if_num = neigh_node->if_incoming->if_num; 737 + sum_neigh = orig_node_tmp->bcast_own_sum[if_num]; 739 738 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 740 739 741 - if (bcast_own_sum_orig >= bcast_own_sum_neigh) 740 + if (sum_orig >= sum_neigh) 742 741 goto update_tt; 743 742 } 744 743
+5 -2
net/batman-adv/soft-interface.c
··· 100 100 { 101 101 struct batadv_priv *bat_priv = netdev_priv(dev); 102 102 struct sockaddr *addr = p; 103 + uint8_t old_addr[ETH_ALEN]; 103 104 104 105 if (!is_valid_ether_addr(addr->sa_data)) 105 106 return -EADDRNOTAVAIL; 106 107 108 + memcpy(old_addr, dev->dev_addr, ETH_ALEN); 109 + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 110 + 107 111 /* only modify transtable if it has been initialized before */ 108 112 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { 109 - batadv_tt_local_remove(bat_priv, dev->dev_addr, 113 + batadv_tt_local_remove(bat_priv, old_addr, 110 114 "mac address changed", false); 111 115 batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); 112 116 } 113 117 114 - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 115 118 dev->addr_assign_type &= ~NET_ADDR_RANDOM; 116 119 return 0; 117 120 }
+2
net/bluetooth/hci_core.c
··· 734 734 735 735 cancel_work_sync(&hdev->le_scan); 736 736 737 + cancel_delayed_work(&hdev->power_off); 738 + 737 739 hci_req_cancel(hdev, ENODEV); 738 740 hci_req_lock(hdev); 739 741
+1 -1
net/bluetooth/l2cap_core.c
··· 1008 1008 if (!conn) 1009 1009 return; 1010 1010 1011 - if (chan->mode == L2CAP_MODE_ERTM) { 1011 + if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) { 1012 1012 __clear_retrans_timer(chan); 1013 1013 __clear_monitor_timer(chan); 1014 1014 __clear_ack_timer(chan);
+16
net/bluetooth/mgmt.c
··· 2875 2875 if (scan) 2876 2876 hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 2877 2877 2878 + if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 2879 + u8 ssp = 1; 2880 + 2881 + hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp); 2882 + } 2883 + 2884 + if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 2885 + struct hci_cp_write_le_host_supported cp; 2886 + 2887 + cp.le = 1; 2888 + cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 2889 + 2890 + hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, 2891 + sizeof(cp), &cp); 2892 + } 2893 + 2878 2894 update_class(hdev); 2879 2895 update_name(hdev, hdev->dev_name); 2880 2896 update_eir(hdev);
+2 -1
net/core/sock.c
··· 691 691 692 692 case SO_KEEPALIVE: 693 693 #ifdef CONFIG_INET 694 - if (sk->sk_protocol == IPPROTO_TCP) 694 + if (sk->sk_protocol == IPPROTO_TCP && 695 + sk->sk_type == SOCK_STREAM) 695 696 tcp_set_keepalive(sk, valbool); 696 697 #endif 697 698 sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
+8 -6
net/ipv4/raw.c
··· 131 131 * 0 - deliver 132 132 * 1 - block 133 133 */ 134 - static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb) 134 + static int icmp_filter(const struct sock *sk, const struct sk_buff *skb) 135 135 { 136 - int type; 136 + struct icmphdr _hdr; 137 + const struct icmphdr *hdr; 137 138 138 - if (!pskb_may_pull(skb, sizeof(struct icmphdr))) 139 + hdr = skb_header_pointer(skb, skb_transport_offset(skb), 140 + sizeof(_hdr), &_hdr); 141 + if (!hdr) 139 142 return 1; 140 143 141 - type = icmp_hdr(skb)->type; 142 - if (type < 32) { 144 + if (hdr->type < 32) { 143 145 __u32 data = raw_sk(sk)->filter.data; 144 146 145 - return ((1 << type) & data) != 0; 147 + return ((1U << hdr->type) & data) != 0; 146 148 } 147 149 148 150 /* Do not block unknown ICMP types */
+11 -9
net/ipv6/mip6.c
··· 86 86 87 87 static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) 88 88 { 89 - struct ip6_mh *mh; 89 + struct ip6_mh _hdr; 90 + const struct ip6_mh *mh; 90 91 91 - if (!pskb_may_pull(skb, (skb_transport_offset(skb)) + 8) || 92 - !pskb_may_pull(skb, (skb_transport_offset(skb) + 93 - ((skb_transport_header(skb)[1] + 1) << 3)))) 92 + mh = skb_header_pointer(skb, skb_transport_offset(skb), 93 + sizeof(_hdr), &_hdr); 94 + if (!mh) 94 95 return -1; 95 96 96 - mh = (struct ip6_mh *)skb_transport_header(skb); 97 + if (((mh->ip6mh_hdrlen + 1) << 3) > skb->len) 98 + return -1; 97 99 98 100 if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) { 99 101 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n", 100 102 mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type)); 101 - mip6_param_prob(skb, 0, ((&mh->ip6mh_hdrlen) - 102 - skb_network_header(skb))); 103 + mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_hdrlen) + 104 + skb_network_header_len(skb)); 103 105 return -1; 104 106 } 105 107 106 108 if (mh->ip6mh_proto != IPPROTO_NONE) { 107 109 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n", 108 110 mh->ip6mh_proto); 109 - mip6_param_prob(skb, 0, ((&mh->ip6mh_proto) - 110 - skb_network_header(skb))); 111 + mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_proto) + 112 + skb_network_header_len(skb)); 111 113 return -1; 112 114 } 113 115
+10 -11
net/ipv6/raw.c
··· 107 107 * 0 - deliver 108 108 * 1 - block 109 109 */ 110 - static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb) 110 + static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb) 111 111 { 112 - struct icmp6hdr *icmph; 113 - struct raw6_sock *rp = raw6_sk(sk); 112 + struct icmp6hdr *_hdr; 113 + const struct icmp6hdr *hdr; 114 114 115 - if (pskb_may_pull(skb, sizeof(struct icmp6hdr))) { 116 - __u32 *data = &rp->filter.data[0]; 117 - int bit_nr; 115 + hdr = skb_header_pointer(skb, skb_transport_offset(skb), 116 + sizeof(_hdr), &_hdr); 117 + if (hdr) { 118 + const __u32 *data = &raw6_sk(sk)->filter.data[0]; 119 + unsigned int type = hdr->icmp6_type; 118 120 119 - icmph = (struct icmp6hdr *) skb->data; 120 - bit_nr = icmph->icmp6_type; 121 - 122 - return (data[bit_nr >> 5] & (1 << (bit_nr & 31))) != 0; 121 + return (data[type >> 5] & (1U << (type & 31))) != 0; 123 122 } 124 - return 0; 123 + return 1; 125 124 } 126 125 127 126 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+9 -3
net/wireless/reg.c
··· 350 350 struct reg_regdb_search_request *request; 351 351 const struct ieee80211_regdomain *curdom, *regdom; 352 352 int i, r; 353 + bool set_reg = false; 354 + 355 + mutex_lock(&cfg80211_mutex); 353 356 354 357 mutex_lock(&reg_regdb_search_mutex); 355 358 while (!list_empty(&reg_regdb_search_list)) { ··· 368 365 r = reg_copy_regd(&regdom, curdom); 369 366 if (r) 370 367 break; 371 - mutex_lock(&cfg80211_mutex); 372 - set_regdom(regdom); 373 - mutex_unlock(&cfg80211_mutex); 368 + set_reg = true; 374 369 break; 375 370 } 376 371 } ··· 376 375 kfree(request); 377 376 } 378 377 mutex_unlock(&reg_regdb_search_mutex); 378 + 379 + if (set_reg) 380 + set_regdom(regdom); 381 + 382 + mutex_unlock(&cfg80211_mutex); 379 383 } 380 384 381 385 static DECLARE_WORK(reg_regdb_work, reg_regdb_search);