diff options
Diffstat (limited to 'net')
35 files changed, 229 insertions, 139 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index f0e82682e071..fb61b6c79235 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -578,7 +578,7 @@ static int br_process_vlan_info(struct net_bridge *br, | |||
578 | } | 578 | } |
579 | *vinfo_last = NULL; | 579 | *vinfo_last = NULL; |
580 | 580 | ||
581 | return 0; | 581 | return err; |
582 | } | 582 | } |
583 | 583 | ||
584 | return br_vlan_info(br, p, cmd, vinfo_curr); | 584 | return br_vlan_info(br, p, cmd, vinfo_curr); |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 1f75e11ac35a..003b2d6d655f 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -78,7 +78,7 @@ MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)"); | |||
78 | static struct kmem_cache *rcv_cache __read_mostly; | 78 | static struct kmem_cache *rcv_cache __read_mostly; |
79 | 79 | ||
80 | /* table of registered CAN protocols */ | 80 | /* table of registered CAN protocols */ |
81 | static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly; | 81 | static const struct can_proto __rcu *proto_tab[CAN_NPROTO] __read_mostly; |
82 | static DEFINE_MUTEX(proto_tab_lock); | 82 | static DEFINE_MUTEX(proto_tab_lock); |
83 | 83 | ||
84 | static atomic_t skbcounter = ATOMIC_INIT(0); | 84 | static atomic_t skbcounter = ATOMIC_INIT(0); |
@@ -788,7 +788,7 @@ int can_proto_register(const struct can_proto *cp) | |||
788 | 788 | ||
789 | mutex_lock(&proto_tab_lock); | 789 | mutex_lock(&proto_tab_lock); |
790 | 790 | ||
791 | if (proto_tab[proto]) { | 791 | if (rcu_access_pointer(proto_tab[proto])) { |
792 | pr_err("can: protocol %d already registered\n", proto); | 792 | pr_err("can: protocol %d already registered\n", proto); |
793 | err = -EBUSY; | 793 | err = -EBUSY; |
794 | } else | 794 | } else |
@@ -812,7 +812,7 @@ void can_proto_unregister(const struct can_proto *cp) | |||
812 | int proto = cp->protocol; | 812 | int proto = cp->protocol; |
813 | 813 | ||
814 | mutex_lock(&proto_tab_lock); | 814 | mutex_lock(&proto_tab_lock); |
815 | BUG_ON(proto_tab[proto] != cp); | 815 | BUG_ON(rcu_access_pointer(proto_tab[proto]) != cp); |
816 | RCU_INIT_POINTER(proto_tab[proto], NULL); | 816 | RCU_INIT_POINTER(proto_tab[proto], NULL); |
817 | mutex_unlock(&proto_tab_lock); | 817 | mutex_unlock(&proto_tab_lock); |
818 | 818 | ||
@@ -875,9 +875,14 @@ static int can_pernet_init(struct net *net) | |||
875 | spin_lock_init(&net->can.can_rcvlists_lock); | 875 | spin_lock_init(&net->can.can_rcvlists_lock); |
876 | net->can.can_rx_alldev_list = | 876 | net->can.can_rx_alldev_list = |
877 | kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL); | 877 | kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL); |
878 | 878 | if (!net->can.can_rx_alldev_list) | |
879 | goto out; | ||
879 | net->can.can_stats = kzalloc(sizeof(struct s_stats), GFP_KERNEL); | 880 | net->can.can_stats = kzalloc(sizeof(struct s_stats), GFP_KERNEL); |
881 | if (!net->can.can_stats) | ||
882 | goto out_free_alldev_list; | ||
880 | net->can.can_pstats = kzalloc(sizeof(struct s_pstats), GFP_KERNEL); | 883 | net->can.can_pstats = kzalloc(sizeof(struct s_pstats), GFP_KERNEL); |
884 | if (!net->can.can_pstats) | ||
885 | goto out_free_can_stats; | ||
881 | 886 | ||
882 | if (IS_ENABLED(CONFIG_PROC_FS)) { | 887 | if (IS_ENABLED(CONFIG_PROC_FS)) { |
883 | /* the statistics are updated every second (timer triggered) */ | 888 | /* the statistics are updated every second (timer triggered) */ |
@@ -892,6 +897,13 @@ static int can_pernet_init(struct net *net) | |||
892 | } | 897 | } |
893 | 898 | ||
894 | return 0; | 899 | return 0; |
900 | |||
901 | out_free_can_stats: | ||
902 | kfree(net->can.can_stats); | ||
903 | out_free_alldev_list: | ||
904 | kfree(net->can.can_rx_alldev_list); | ||
905 | out: | ||
906 | return -ENOMEM; | ||
895 | } | 907 | } |
896 | 908 | ||
897 | static void can_pernet_exit(struct net *net) | 909 | static void can_pernet_exit(struct net *net) |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 47a8748d953a..13690334efa3 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -1493,13 +1493,14 @@ static int bcm_init(struct sock *sk) | |||
1493 | static int bcm_release(struct socket *sock) | 1493 | static int bcm_release(struct socket *sock) |
1494 | { | 1494 | { |
1495 | struct sock *sk = sock->sk; | 1495 | struct sock *sk = sock->sk; |
1496 | struct net *net = sock_net(sk); | 1496 | struct net *net; |
1497 | struct bcm_sock *bo; | 1497 | struct bcm_sock *bo; |
1498 | struct bcm_op *op, *next; | 1498 | struct bcm_op *op, *next; |
1499 | 1499 | ||
1500 | if (sk == NULL) | 1500 | if (!sk) |
1501 | return 0; | 1501 | return 0; |
1502 | 1502 | ||
1503 | net = sock_net(sk); | ||
1503 | bo = bcm_sk(sk); | 1504 | bo = bcm_sk(sk); |
1504 | 1505 | ||
1505 | /* remove bcm_ops, timer, rx_unregister(), etc. */ | 1506 | /* remove bcm_ops, timer, rx_unregister(), etc. */ |
diff --git a/net/core/dev.c b/net/core/dev.c index cf5894f0e6eb..24ac9083bc13 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1149,9 +1149,8 @@ static int dev_alloc_name_ns(struct net *net, | |||
1149 | return ret; | 1149 | return ret; |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | static int dev_get_valid_name(struct net *net, | 1152 | int dev_get_valid_name(struct net *net, struct net_device *dev, |
1153 | struct net_device *dev, | 1153 | const char *name) |
1154 | const char *name) | ||
1155 | { | 1154 | { |
1156 | BUG_ON(!net); | 1155 | BUG_ON(!net); |
1157 | 1156 | ||
@@ -1167,6 +1166,7 @@ static int dev_get_valid_name(struct net *net, | |||
1167 | 1166 | ||
1168 | return 0; | 1167 | return 0; |
1169 | } | 1168 | } |
1169 | EXPORT_SYMBOL(dev_get_valid_name); | ||
1170 | 1170 | ||
1171 | /** | 1171 | /** |
1172 | * dev_change_name - change name of a device | 1172 | * dev_change_name - change name of a device |
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 709a4e6fb447..f9c7a88cd981 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c | |||
@@ -303,7 +303,18 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
303 | case SIOCSIFTXQLEN: | 303 | case SIOCSIFTXQLEN: |
304 | if (ifr->ifr_qlen < 0) | 304 | if (ifr->ifr_qlen < 0) |
305 | return -EINVAL; | 305 | return -EINVAL; |
306 | dev->tx_queue_len = ifr->ifr_qlen; | 306 | if (dev->tx_queue_len ^ ifr->ifr_qlen) { |
307 | unsigned int orig_len = dev->tx_queue_len; | ||
308 | |||
309 | dev->tx_queue_len = ifr->ifr_qlen; | ||
310 | err = call_netdevice_notifiers( | ||
311 | NETDEV_CHANGE_TX_QUEUE_LEN, dev); | ||
312 | err = notifier_to_errno(err); | ||
313 | if (err) { | ||
314 | dev->tx_queue_len = orig_len; | ||
315 | return err; | ||
316 | } | ||
317 | } | ||
307 | return 0; | 318 | return 0; |
308 | 319 | ||
309 | case SIOCSIFNAME: | 320 | case SIOCSIFNAME: |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 0c406306792a..f8fcf450a36e 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -452,7 +452,7 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, | |||
452 | EXPORT_SYMBOL(ethtool_convert_link_mode_to_legacy_u32); | 452 | EXPORT_SYMBOL(ethtool_convert_link_mode_to_legacy_u32); |
453 | 453 | ||
454 | /* return false if legacy contained non-0 deprecated fields | 454 | /* return false if legacy contained non-0 deprecated fields |
455 | * transceiver/maxtxpkt/maxrxpkt. rest of ksettings always updated | 455 | * maxtxpkt/maxrxpkt. rest of ksettings always updated |
456 | */ | 456 | */ |
457 | static bool | 457 | static bool |
458 | convert_legacy_settings_to_link_ksettings( | 458 | convert_legacy_settings_to_link_ksettings( |
@@ -467,8 +467,7 @@ convert_legacy_settings_to_link_ksettings( | |||
467 | * deprecated legacy fields, and they should not use | 467 | * deprecated legacy fields, and they should not use |
468 | * %ETHTOOL_GLINKSETTINGS/%ETHTOOL_SLINKSETTINGS | 468 | * %ETHTOOL_GLINKSETTINGS/%ETHTOOL_SLINKSETTINGS |
469 | */ | 469 | */ |
470 | if (legacy_settings->transceiver || | 470 | if (legacy_settings->maxtxpkt || |
471 | legacy_settings->maxtxpkt || | ||
472 | legacy_settings->maxrxpkt) | 471 | legacy_settings->maxrxpkt) |
473 | retval = false; | 472 | retval = false; |
474 | 473 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index ccf62f44140a..b79c44cc8145 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -1840,31 +1840,31 @@ static const struct bpf_func_proto bpf_redirect_proto = { | |||
1840 | .arg2_type = ARG_ANYTHING, | 1840 | .arg2_type = ARG_ANYTHING, |
1841 | }; | 1841 | }; |
1842 | 1842 | ||
1843 | BPF_CALL_3(bpf_sk_redirect_map, struct bpf_map *, map, u32, key, u64, flags) | 1843 | BPF_CALL_4(bpf_sk_redirect_map, struct sk_buff *, skb, |
1844 | struct bpf_map *, map, u32, key, u64, flags) | ||
1844 | { | 1845 | { |
1845 | struct redirect_info *ri = this_cpu_ptr(&redirect_info); | 1846 | struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); |
1846 | 1847 | ||
1847 | if (unlikely(flags)) | 1848 | if (unlikely(flags)) |
1848 | return SK_ABORTED; | 1849 | return SK_ABORTED; |
1849 | 1850 | ||
1850 | ri->ifindex = key; | 1851 | tcb->bpf.key = key; |
1851 | ri->flags = flags; | 1852 | tcb->bpf.flags = flags; |
1852 | ri->map = map; | 1853 | tcb->bpf.map = map; |
1853 | 1854 | ||
1854 | return SK_REDIRECT; | 1855 | return SK_REDIRECT; |
1855 | } | 1856 | } |
1856 | 1857 | ||
1857 | struct sock *do_sk_redirect_map(void) | 1858 | struct sock *do_sk_redirect_map(struct sk_buff *skb) |
1858 | { | 1859 | { |
1859 | struct redirect_info *ri = this_cpu_ptr(&redirect_info); | 1860 | struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); |
1860 | struct sock *sk = NULL; | 1861 | struct sock *sk = NULL; |
1861 | 1862 | ||
1862 | if (ri->map) { | 1863 | if (tcb->bpf.map) { |
1863 | sk = __sock_map_lookup_elem(ri->map, ri->ifindex); | 1864 | sk = __sock_map_lookup_elem(tcb->bpf.map, tcb->bpf.key); |
1864 | 1865 | ||
1865 | ri->ifindex = 0; | 1866 | tcb->bpf.key = 0; |
1866 | ri->map = NULL; | 1867 | tcb->bpf.map = NULL; |
1867 | /* we do not clear flags for future lookup */ | ||
1868 | } | 1868 | } |
1869 | 1869 | ||
1870 | return sk; | 1870 | return sk; |
@@ -1874,9 +1874,10 @@ static const struct bpf_func_proto bpf_sk_redirect_map_proto = { | |||
1874 | .func = bpf_sk_redirect_map, | 1874 | .func = bpf_sk_redirect_map, |
1875 | .gpl_only = false, | 1875 | .gpl_only = false, |
1876 | .ret_type = RET_INTEGER, | 1876 | .ret_type = RET_INTEGER, |
1877 | .arg1_type = ARG_CONST_MAP_PTR, | 1877 | .arg1_type = ARG_PTR_TO_CTX, |
1878 | .arg2_type = ARG_ANYTHING, | 1878 | .arg2_type = ARG_CONST_MAP_PTR, |
1879 | .arg3_type = ARG_ANYTHING, | 1879 | .arg3_type = ARG_ANYTHING, |
1880 | .arg4_type = ARG_ANYTHING, | ||
1880 | }; | 1881 | }; |
1881 | 1882 | ||
1882 | BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb) | 1883 | BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb) |
@@ -3902,7 +3903,6 @@ static bool sk_skb_is_valid_access(int off, int size, | |||
3902 | 3903 | ||
3903 | if (type == BPF_WRITE) { | 3904 | if (type == BPF_WRITE) { |
3904 | switch (off) { | 3905 | switch (off) { |
3905 | case bpf_ctx_range(struct __sk_buff, mark): | ||
3906 | case bpf_ctx_range(struct __sk_buff, tc_index): | 3906 | case bpf_ctx_range(struct __sk_buff, tc_index): |
3907 | case bpf_ctx_range(struct __sk_buff, priority): | 3907 | case bpf_ctx_range(struct __sk_buff, priority): |
3908 | break; | 3908 | break; |
@@ -3912,6 +3912,8 @@ static bool sk_skb_is_valid_access(int off, int size, | |||
3912 | } | 3912 | } |
3913 | 3913 | ||
3914 | switch (off) { | 3914 | switch (off) { |
3915 | case bpf_ctx_range(struct __sk_buff, mark): | ||
3916 | return false; | ||
3915 | case bpf_ctx_range(struct __sk_buff, data): | 3917 | case bpf_ctx_range(struct __sk_buff, data): |
3916 | info->reg_type = PTR_TO_PACKET; | 3918 | info->reg_type = PTR_TO_PACKET; |
3917 | break; | 3919 | break; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 20b550d07fe3..04680a53c8dd 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1551,7 +1551,10 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
1551 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, | 1551 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, |
1552 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, | 1552 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, |
1553 | [IFLA_NET_NS_FD] = { .type = NLA_U32 }, | 1553 | [IFLA_NET_NS_FD] = { .type = NLA_U32 }, |
1554 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, | 1554 | /* IFLA_IFALIAS is a string, but policy is set to NLA_BINARY to |
1555 | * allow 0-length string (needed to remove an alias). | ||
1556 | */ | ||
1557 | [IFLA_IFALIAS] = { .type = NLA_BINARY, .len = IFALIASZ - 1 }, | ||
1555 | [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, | 1558 | [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, |
1556 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, | 1559 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, |
1557 | [IFLA_PORT_SELF] = { .type = NLA_NESTED }, | 1560 | [IFLA_PORT_SELF] = { .type = NLA_NESTED }, |
@@ -2172,7 +2175,7 @@ static int do_setlink(const struct sk_buff *skb, | |||
2172 | dev->tx_queue_len = orig_len; | 2175 | dev->tx_queue_len = orig_len; |
2173 | goto errout; | 2176 | goto errout; |
2174 | } | 2177 | } |
2175 | status |= DO_SETLINK_NOTIFY; | 2178 | status |= DO_SETLINK_MODIFIED; |
2176 | } | 2179 | } |
2177 | } | 2180 | } |
2178 | 2181 | ||
@@ -2332,7 +2335,7 @@ static int do_setlink(const struct sk_buff *skb, | |||
2332 | 2335 | ||
2333 | errout: | 2336 | errout: |
2334 | if (status & DO_SETLINK_MODIFIED) { | 2337 | if (status & DO_SETLINK_MODIFIED) { |
2335 | if (status & DO_SETLINK_NOTIFY) | 2338 | if ((status & DO_SETLINK_NOTIFY) == DO_SETLINK_NOTIFY) |
2336 | netdev_state_change(dev); | 2339 | netdev_state_change(dev); |
2337 | 2340 | ||
2338 | if (err < 0) | 2341 | if (err < 0) |
@@ -4373,13 +4376,17 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi | |||
4373 | 4376 | ||
4374 | switch (event) { | 4377 | switch (event) { |
4375 | case NETDEV_REBOOT: | 4378 | case NETDEV_REBOOT: |
4379 | case NETDEV_CHANGEMTU: | ||
4376 | case NETDEV_CHANGEADDR: | 4380 | case NETDEV_CHANGEADDR: |
4377 | case NETDEV_CHANGENAME: | 4381 | case NETDEV_CHANGENAME: |
4378 | case NETDEV_FEAT_CHANGE: | 4382 | case NETDEV_FEAT_CHANGE: |
4379 | case NETDEV_BONDING_FAILOVER: | 4383 | case NETDEV_BONDING_FAILOVER: |
4384 | case NETDEV_POST_TYPE_CHANGE: | ||
4380 | case NETDEV_NOTIFY_PEERS: | 4385 | case NETDEV_NOTIFY_PEERS: |
4386 | case NETDEV_CHANGEUPPER: | ||
4381 | case NETDEV_RESEND_IGMP: | 4387 | case NETDEV_RESEND_IGMP: |
4382 | case NETDEV_CHANGEINFODATA: | 4388 | case NETDEV_CHANGEINFODATA: |
4389 | case NETDEV_CHANGE_TX_QUEUE_LEN: | ||
4383 | rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event), | 4390 | rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event), |
4384 | GFP_KERNEL, NULL); | 4391 | GFP_KERNEL, NULL); |
4385 | break; | 4392 | break; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 40717501cbdd..97e604d55d55 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1124,9 +1124,13 @@ int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb, | |||
1124 | 1124 | ||
1125 | err = __zerocopy_sg_from_iter(sk, skb, &msg->msg_iter, len); | 1125 | err = __zerocopy_sg_from_iter(sk, skb, &msg->msg_iter, len); |
1126 | if (err == -EFAULT || (err == -EMSGSIZE && skb->len == orig_len)) { | 1126 | if (err == -EFAULT || (err == -EMSGSIZE && skb->len == orig_len)) { |
1127 | struct sock *save_sk = skb->sk; | ||
1128 | |||
1127 | /* Streams do not free skb on error. Reset to prev state. */ | 1129 | /* Streams do not free skb on error. Reset to prev state. */ |
1128 | msg->msg_iter = orig_iter; | 1130 | msg->msg_iter = orig_iter; |
1131 | skb->sk = sk; | ||
1129 | ___pskb_trim(skb, orig_len); | 1132 | ___pskb_trim(skb, orig_len); |
1133 | skb->sk = save_sk; | ||
1130 | return err; | 1134 | return err; |
1131 | } | 1135 | } |
1132 | 1136 | ||
@@ -1895,7 +1899,7 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta) | |||
1895 | } | 1899 | } |
1896 | 1900 | ||
1897 | /* If we need update frag list, we are in troubles. | 1901 | /* If we need update frag list, we are in troubles. |
1898 | * Certainly, it possible to add an offset to skb data, | 1902 | * Certainly, it is possible to add an offset to skb data, |
1899 | * but taking into account that pulling is expected to | 1903 | * but taking into account that pulling is expected to |
1900 | * be very rare operation, it is worth to fight against | 1904 | * be very rare operation, it is worth to fight against |
1901 | * further bloating skb head and crucify ourselves here instead. | 1905 | * further bloating skb head and crucify ourselves here instead. |
diff --git a/net/core/sock.c b/net/core/sock.c index 35656a9e4e44..759400053110 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1677,12 +1677,17 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) | |||
1677 | newsk->sk_dst_pending_confirm = 0; | 1677 | newsk->sk_dst_pending_confirm = 0; |
1678 | newsk->sk_wmem_queued = 0; | 1678 | newsk->sk_wmem_queued = 0; |
1679 | newsk->sk_forward_alloc = 0; | 1679 | newsk->sk_forward_alloc = 0; |
1680 | |||
1681 | /* sk->sk_memcg will be populated at accept() time */ | ||
1682 | newsk->sk_memcg = NULL; | ||
1683 | |||
1680 | atomic_set(&newsk->sk_drops, 0); | 1684 | atomic_set(&newsk->sk_drops, 0); |
1681 | newsk->sk_send_head = NULL; | 1685 | newsk->sk_send_head = NULL; |
1682 | newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; | 1686 | newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; |
1683 | atomic_set(&newsk->sk_zckey, 0); | 1687 | atomic_set(&newsk->sk_zckey, 0); |
1684 | 1688 | ||
1685 | sock_reset_flag(newsk, SOCK_DONE); | 1689 | sock_reset_flag(newsk, SOCK_DONE); |
1690 | cgroup_sk_alloc(&newsk->sk_cgrp_data); | ||
1686 | 1691 | ||
1687 | rcu_read_lock(); | 1692 | rcu_read_lock(); |
1688 | filter = rcu_dereference(sk->sk_filter); | 1693 | filter = rcu_dereference(sk->sk_filter); |
@@ -1714,9 +1719,6 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) | |||
1714 | newsk->sk_incoming_cpu = raw_smp_processor_id(); | 1719 | newsk->sk_incoming_cpu = raw_smp_processor_id(); |
1715 | atomic64_set(&newsk->sk_cookie, 0); | 1720 | atomic64_set(&newsk->sk_cookie, 0); |
1716 | 1721 | ||
1717 | mem_cgroup_sk_alloc(newsk); | ||
1718 | cgroup_sk_alloc(&newsk->sk_cgrp_data); | ||
1719 | |||
1720 | /* | 1722 | /* |
1721 | * Before updating sk_refcnt, we must commit prior changes to memory | 1723 | * Before updating sk_refcnt, we must commit prior changes to memory |
1722 | * (Documentation/RCU/rculist_nulls.txt for details) | 1724 | * (Documentation/RCU/rculist_nulls.txt for details) |
diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c index eed1ebf7f29d..b1e0dbea1e8c 100644 --- a/net/core/sock_reuseport.c +++ b/net/core/sock_reuseport.c | |||
@@ -36,9 +36,14 @@ int reuseport_alloc(struct sock *sk) | |||
36 | * soft irq of receive path or setsockopt from process context | 36 | * soft irq of receive path or setsockopt from process context |
37 | */ | 37 | */ |
38 | spin_lock_bh(&reuseport_lock); | 38 | spin_lock_bh(&reuseport_lock); |
39 | WARN_ONCE(rcu_dereference_protected(sk->sk_reuseport_cb, | 39 | |
40 | lockdep_is_held(&reuseport_lock)), | 40 | /* Allocation attempts can occur concurrently via the setsockopt path |
41 | "multiple allocations for the same socket"); | 41 | * and the bind/hash path. Nothing to do when we lose the race. |
42 | */ | ||
43 | if (rcu_dereference_protected(sk->sk_reuseport_cb, | ||
44 | lockdep_is_held(&reuseport_lock))) | ||
45 | goto out; | ||
46 | |||
42 | reuse = __reuseport_alloc(INIT_SOCKS); | 47 | reuse = __reuseport_alloc(INIT_SOCKS); |
43 | if (!reuse) { | 48 | if (!reuse) { |
44 | spin_unlock_bh(&reuseport_lock); | 49 | spin_unlock_bh(&reuseport_lock); |
@@ -49,6 +54,7 @@ int reuseport_alloc(struct sock *sk) | |||
49 | reuse->num_socks = 1; | 54 | reuse->num_socks = 1; |
50 | rcu_assign_pointer(sk->sk_reuseport_cb, reuse); | 55 | rcu_assign_pointer(sk->sk_reuseport_cb, reuse); |
51 | 56 | ||
57 | out: | ||
52 | spin_unlock_bh(&reuseport_lock); | 58 | spin_unlock_bh(&reuseport_lock); |
53 | 59 | ||
54 | return 0; | 60 | return 0; |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 001c08696334..0490916864f9 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -414,8 +414,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, | |||
414 | sk_daddr_set(newsk, ireq->ir_rmt_addr); | 414 | sk_daddr_set(newsk, ireq->ir_rmt_addr); |
415 | sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); | 415 | sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); |
416 | newinet->inet_saddr = ireq->ir_loc_addr; | 416 | newinet->inet_saddr = ireq->ir_loc_addr; |
417 | newinet->inet_opt = ireq->opt; | 417 | RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt)); |
418 | ireq->opt = NULL; | ||
419 | newinet->mc_index = inet_iif(skb); | 418 | newinet->mc_index = inet_iif(skb); |
420 | newinet->mc_ttl = ip_hdr(skb)->ttl; | 419 | newinet->mc_ttl = ip_hdr(skb)->ttl; |
421 | newinet->inet_id = jiffies; | 420 | newinet->inet_id = jiffies; |
@@ -430,7 +429,10 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, | |||
430 | if (__inet_inherit_port(sk, newsk) < 0) | 429 | if (__inet_inherit_port(sk, newsk) < 0) |
431 | goto put_and_exit; | 430 | goto put_and_exit; |
432 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); | 431 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); |
433 | 432 | if (*own_req) | |
433 | ireq->ireq_opt = NULL; | ||
434 | else | ||
435 | newinet->inet_opt = NULL; | ||
434 | return newsk; | 436 | return newsk; |
435 | 437 | ||
436 | exit_overflow: | 438 | exit_overflow: |
@@ -441,6 +443,7 @@ exit: | |||
441 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); | 443 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); |
442 | return NULL; | 444 | return NULL; |
443 | put_and_exit: | 445 | put_and_exit: |
446 | newinet->inet_opt = NULL; | ||
444 | inet_csk_prepare_forced_close(newsk); | 447 | inet_csk_prepare_forced_close(newsk); |
445 | dccp_done(newsk); | 448 | dccp_done(newsk); |
446 | goto exit; | 449 | goto exit; |
@@ -492,7 +495,7 @@ static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req | |||
492 | ireq->ir_rmt_addr); | 495 | ireq->ir_rmt_addr); |
493 | err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, | 496 | err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, |
494 | ireq->ir_rmt_addr, | 497 | ireq->ir_rmt_addr, |
495 | ireq->opt); | 498 | rcu_dereference(ireq->ireq_opt)); |
496 | err = net_xmit_eval(err); | 499 | err = net_xmit_eval(err); |
497 | } | 500 | } |
498 | 501 | ||
@@ -548,7 +551,7 @@ out: | |||
548 | static void dccp_v4_reqsk_destructor(struct request_sock *req) | 551 | static void dccp_v4_reqsk_destructor(struct request_sock *req) |
549 | { | 552 | { |
550 | dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg); | 553 | dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg); |
551 | kfree(inet_rsk(req)->opt); | 554 | kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); |
552 | } | 555 | } |
553 | 556 | ||
554 | void dccp_syn_ack_timeout(const struct request_sock *req) | 557 | void dccp_syn_ack_timeout(const struct request_sock *req) |
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index 8737412c7b27..e1d4d898a007 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c | |||
@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data) | |||
224 | static void dns_resolver_describe(const struct key *key, struct seq_file *m) | 224 | static void dns_resolver_describe(const struct key *key, struct seq_file *m) |
225 | { | 225 | { |
226 | seq_puts(m, key->description); | 226 | seq_puts(m, key->description); |
227 | if (key_is_instantiated(key)) { | 227 | if (key_is_positive(key)) { |
228 | int err = PTR_ERR(key->payload.data[dns_key_error]); | 228 | int err = PTR_ERR(key->payload.data[dns_key_error]); |
229 | 229 | ||
230 | if (err) | 230 | if (err) |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 91a2557942fa..f48fe6fc7e8c 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -70,11 +70,9 @@ config IP_MULTIPLE_TABLES | |||
70 | address into account. Furthermore, the TOS (Type-Of-Service) field | 70 | address into account. Furthermore, the TOS (Type-Of-Service) field |
71 | of the packet can be used for routing decisions as well. | 71 | of the packet can be used for routing decisions as well. |
72 | 72 | ||
73 | If you are interested in this, please see the preliminary | 73 | If you need more information, see the Linux Advanced |
74 | documentation at <http://www.compendium.com.ar/policy-routing.txt> | 74 | Routing and Traffic Control documentation at |
75 | and <ftp://post.tepkom.ru/pub/vol2/Linux/docs/advanced-routing.tex>. | 75 | <http://lartc.org/howto/lartc.rpdb.html> |
76 | You will need supporting software from | ||
77 | <ftp://ftp.tux.org/pub/net/ip-routing/>. | ||
78 | 76 | ||
79 | If unsure, say N. | 77 | If unsure, say N. |
80 | 78 | ||
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 2ae8f54cb321..82178cc69c96 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -1951,7 +1951,7 @@ int cipso_v4_req_setattr(struct request_sock *req, | |||
1951 | buf = NULL; | 1951 | buf = NULL; |
1952 | 1952 | ||
1953 | req_inet = inet_rsk(req); | 1953 | req_inet = inet_rsk(req); |
1954 | opt = xchg(&req_inet->opt, opt); | 1954 | opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt); |
1955 | if (opt) | 1955 | if (opt) |
1956 | kfree_rcu(opt, rcu); | 1956 | kfree_rcu(opt, rcu); |
1957 | 1957 | ||
@@ -1973,11 +1973,13 @@ req_setattr_failure: | |||
1973 | * values on failure. | 1973 | * values on failure. |
1974 | * | 1974 | * |
1975 | */ | 1975 | */ |
1976 | static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr) | 1976 | static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) |
1977 | { | 1977 | { |
1978 | struct ip_options_rcu *opt = rcu_dereference_protected(*opt_ptr, 1); | ||
1978 | int hdr_delta = 0; | 1979 | int hdr_delta = 0; |
1979 | struct ip_options_rcu *opt = *opt_ptr; | ||
1980 | 1980 | ||
1981 | if (!opt || opt->opt.cipso == 0) | ||
1982 | return 0; | ||
1981 | if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) { | 1983 | if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) { |
1982 | u8 cipso_len; | 1984 | u8 cipso_len; |
1983 | u8 cipso_off; | 1985 | u8 cipso_off; |
@@ -2039,14 +2041,10 @@ static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr) | |||
2039 | */ | 2041 | */ |
2040 | void cipso_v4_sock_delattr(struct sock *sk) | 2042 | void cipso_v4_sock_delattr(struct sock *sk) |
2041 | { | 2043 | { |
2042 | int hdr_delta; | ||
2043 | struct ip_options_rcu *opt; | ||
2044 | struct inet_sock *sk_inet; | 2044 | struct inet_sock *sk_inet; |
2045 | int hdr_delta; | ||
2045 | 2046 | ||
2046 | sk_inet = inet_sk(sk); | 2047 | sk_inet = inet_sk(sk); |
2047 | opt = rcu_dereference_protected(sk_inet->inet_opt, 1); | ||
2048 | if (!opt || opt->opt.cipso == 0) | ||
2049 | return; | ||
2050 | 2048 | ||
2051 | hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt); | 2049 | hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt); |
2052 | if (sk_inet->is_icsk && hdr_delta > 0) { | 2050 | if (sk_inet->is_icsk && hdr_delta > 0) { |
@@ -2066,15 +2064,7 @@ void cipso_v4_sock_delattr(struct sock *sk) | |||
2066 | */ | 2064 | */ |
2067 | void cipso_v4_req_delattr(struct request_sock *req) | 2065 | void cipso_v4_req_delattr(struct request_sock *req) |
2068 | { | 2066 | { |
2069 | struct ip_options_rcu *opt; | 2067 | cipso_v4_delopt(&inet_rsk(req)->ireq_opt); |
2070 | struct inet_request_sock *req_inet; | ||
2071 | |||
2072 | req_inet = inet_rsk(req); | ||
2073 | opt = req_inet->opt; | ||
2074 | if (!opt || opt->opt.cipso == 0) | ||
2075 | return; | ||
2076 | |||
2077 | cipso_v4_delopt(&req_inet->opt); | ||
2078 | } | 2068 | } |
2079 | 2069 | ||
2080 | /** | 2070 | /** |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 5c965ecc96a0..ca03a1dcbc8f 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -475,6 +475,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern) | |||
475 | } | 475 | } |
476 | spin_unlock_bh(&queue->fastopenq.lock); | 476 | spin_unlock_bh(&queue->fastopenq.lock); |
477 | } | 477 | } |
478 | mem_cgroup_sk_alloc(newsk); | ||
478 | out: | 479 | out: |
479 | release_sock(sk); | 480 | release_sock(sk); |
480 | if (req) | 481 | if (req) |
@@ -537,9 +538,10 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk, | |||
537 | { | 538 | { |
538 | const struct inet_request_sock *ireq = inet_rsk(req); | 539 | const struct inet_request_sock *ireq = inet_rsk(req); |
539 | struct net *net = read_pnet(&ireq->ireq_net); | 540 | struct net *net = read_pnet(&ireq->ireq_net); |
540 | struct ip_options_rcu *opt = ireq->opt; | 541 | struct ip_options_rcu *opt; |
541 | struct rtable *rt; | 542 | struct rtable *rt; |
542 | 543 | ||
544 | opt = rcu_dereference(ireq->ireq_opt); | ||
543 | flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, | 545 | flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, |
544 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, | 546 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, |
545 | sk->sk_protocol, inet_sk_flowi_flags(sk), | 547 | sk->sk_protocol, inet_sk_flowi_flags(sk), |
@@ -573,10 +575,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, | |||
573 | struct flowi4 *fl4; | 575 | struct flowi4 *fl4; |
574 | struct rtable *rt; | 576 | struct rtable *rt; |
575 | 577 | ||
578 | opt = rcu_dereference(ireq->ireq_opt); | ||
576 | fl4 = &newinet->cork.fl.u.ip4; | 579 | fl4 = &newinet->cork.fl.u.ip4; |
577 | 580 | ||
578 | rcu_read_lock(); | ||
579 | opt = rcu_dereference(newinet->inet_opt); | ||
580 | flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, | 581 | flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, |
581 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, | 582 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, |
582 | sk->sk_protocol, inet_sk_flowi_flags(sk), | 583 | sk->sk_protocol, inet_sk_flowi_flags(sk), |
@@ -589,13 +590,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, | |||
589 | goto no_route; | 590 | goto no_route; |
590 | if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) | 591 | if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) |
591 | goto route_err; | 592 | goto route_err; |
592 | rcu_read_unlock(); | ||
593 | return &rt->dst; | 593 | return &rt->dst; |
594 | 594 | ||
595 | route_err: | 595 | route_err: |
596 | ip_rt_put(rt); | 596 | ip_rt_put(rt); |
597 | no_route: | 597 | no_route: |
598 | rcu_read_unlock(); | ||
599 | __IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); | 598 | __IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); |
600 | return NULL; | 599 | return NULL; |
601 | } | 600 | } |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 597bb4cfe805..e7d15fb0d94d 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -456,10 +456,7 @@ static int inet_reuseport_add_sock(struct sock *sk, | |||
456 | return reuseport_add_sock(sk, sk2); | 456 | return reuseport_add_sock(sk, sk2); |
457 | } | 457 | } |
458 | 458 | ||
459 | /* Initial allocation may have already happened via setsockopt */ | 459 | return reuseport_alloc(sk); |
460 | if (!rcu_access_pointer(sk->sk_reuseport_cb)) | ||
461 | return reuseport_alloc(sk); | ||
462 | return 0; | ||
463 | } | 460 | } |
464 | 461 | ||
465 | int __inet_hash(struct sock *sk, struct sock *osk) | 462 | int __inet_hash(struct sock *sk, struct sock *osk) |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b1bb1b3a1082..77cf32a80952 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) | |||
355 | /* We throwed the options of the initial SYN away, so we hope | 355 | /* We throwed the options of the initial SYN away, so we hope |
356 | * the ACK carries the same options again (see RFC1122 4.2.3.8) | 356 | * the ACK carries the same options again (see RFC1122 4.2.3.8) |
357 | */ | 357 | */ |
358 | ireq->opt = tcp_v4_save_options(sock_net(sk), skb); | 358 | RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb)); |
359 | 359 | ||
360 | if (security_inet_conn_request(sk, skb, req)) { | 360 | if (security_inet_conn_request(sk, skb, req)) { |
361 | reqsk_free(req); | 361 | reqsk_free(req); |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b2390bfdc68f..ab3f12898245 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -6167,7 +6167,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops, | |||
6167 | struct inet_request_sock *ireq = inet_rsk(req); | 6167 | struct inet_request_sock *ireq = inet_rsk(req); |
6168 | 6168 | ||
6169 | kmemcheck_annotate_bitfield(ireq, flags); | 6169 | kmemcheck_annotate_bitfield(ireq, flags); |
6170 | ireq->opt = NULL; | 6170 | ireq->ireq_opt = NULL; |
6171 | #if IS_ENABLED(CONFIG_IPV6) | 6171 | #if IS_ENABLED(CONFIG_IPV6) |
6172 | ireq->pktopts = NULL; | 6172 | ireq->pktopts = NULL; |
6173 | #endif | 6173 | #endif |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 28ca4e177047..e22439f05e46 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -877,7 +877,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, | |||
877 | 877 | ||
878 | err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, | 878 | err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, |
879 | ireq->ir_rmt_addr, | 879 | ireq->ir_rmt_addr, |
880 | ireq->opt); | 880 | rcu_dereference(ireq->ireq_opt)); |
881 | err = net_xmit_eval(err); | 881 | err = net_xmit_eval(err); |
882 | } | 882 | } |
883 | 883 | ||
@@ -889,7 +889,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, | |||
889 | */ | 889 | */ |
890 | static void tcp_v4_reqsk_destructor(struct request_sock *req) | 890 | static void tcp_v4_reqsk_destructor(struct request_sock *req) |
891 | { | 891 | { |
892 | kfree(inet_rsk(req)->opt); | 892 | kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); |
893 | } | 893 | } |
894 | 894 | ||
895 | #ifdef CONFIG_TCP_MD5SIG | 895 | #ifdef CONFIG_TCP_MD5SIG |
@@ -1265,10 +1265,11 @@ static void tcp_v4_init_req(struct request_sock *req, | |||
1265 | struct sk_buff *skb) | 1265 | struct sk_buff *skb) |
1266 | { | 1266 | { |
1267 | struct inet_request_sock *ireq = inet_rsk(req); | 1267 | struct inet_request_sock *ireq = inet_rsk(req); |
1268 | struct net *net = sock_net(sk_listener); | ||
1268 | 1269 | ||
1269 | sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); | 1270 | sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); |
1270 | sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); | 1271 | sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); |
1271 | ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb); | 1272 | RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); |
1272 | } | 1273 | } |
1273 | 1274 | ||
1274 | static struct dst_entry *tcp_v4_route_req(const struct sock *sk, | 1275 | static struct dst_entry *tcp_v4_route_req(const struct sock *sk, |
@@ -1355,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, | |||
1355 | sk_daddr_set(newsk, ireq->ir_rmt_addr); | 1356 | sk_daddr_set(newsk, ireq->ir_rmt_addr); |
1356 | sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); | 1357 | sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); |
1357 | newsk->sk_bound_dev_if = ireq->ir_iif; | 1358 | newsk->sk_bound_dev_if = ireq->ir_iif; |
1358 | newinet->inet_saddr = ireq->ir_loc_addr; | 1359 | newinet->inet_saddr = ireq->ir_loc_addr; |
1359 | inet_opt = ireq->opt; | 1360 | inet_opt = rcu_dereference(ireq->ireq_opt); |
1360 | rcu_assign_pointer(newinet->inet_opt, inet_opt); | 1361 | RCU_INIT_POINTER(newinet->inet_opt, inet_opt); |
1361 | ireq->opt = NULL; | ||
1362 | newinet->mc_index = inet_iif(skb); | 1362 | newinet->mc_index = inet_iif(skb); |
1363 | newinet->mc_ttl = ip_hdr(skb)->ttl; | 1363 | newinet->mc_ttl = ip_hdr(skb)->ttl; |
1364 | newinet->rcv_tos = ip_hdr(skb)->tos; | 1364 | newinet->rcv_tos = ip_hdr(skb)->tos; |
@@ -1403,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, | |||
1403 | if (__inet_inherit_port(sk, newsk) < 0) | 1403 | if (__inet_inherit_port(sk, newsk) < 0) |
1404 | goto put_and_exit; | 1404 | goto put_and_exit; |
1405 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); | 1405 | *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); |
1406 | if (*own_req) | 1406 | if (likely(*own_req)) { |
1407 | tcp_move_syn(newtp, req); | 1407 | tcp_move_syn(newtp, req); |
1408 | 1408 | ireq->ireq_opt = NULL; | |
1409 | } else { | ||
1410 | newinet->inet_opt = NULL; | ||
1411 | } | ||
1409 | return newsk; | 1412 | return newsk; |
1410 | 1413 | ||
1411 | exit_overflow: | 1414 | exit_overflow: |
@@ -1416,6 +1419,7 @@ exit: | |||
1416 | tcp_listendrop(sk); | 1419 | tcp_listendrop(sk); |
1417 | return NULL; | 1420 | return NULL; |
1418 | put_and_exit: | 1421 | put_and_exit: |
1422 | newinet->inet_opt = NULL; | ||
1419 | inet_csk_prepare_forced_close(newsk); | 1423 | inet_csk_prepare_forced_close(newsk); |
1420 | tcp_done(newsk); | 1424 | tcp_done(newsk); |
1421 | goto exit; | 1425 | goto exit; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 7c9a6e4a7253..a6699af05539 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -231,10 +231,7 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot) | |||
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | /* Initial allocation may have already happened via setsockopt */ | 234 | return reuseport_alloc(sk); |
235 | if (!rcu_access_pointer(sk->sk_reuseport_cb)) | ||
236 | return reuseport_alloc(sk); | ||
237 | return 0; | ||
238 | } | 235 | } |
239 | 236 | ||
240 | /** | 237 | /** |
@@ -1061,7 +1058,7 @@ back_from_confirm: | |||
1061 | /* ... which is an evident application bug. --ANK */ | 1058 | /* ... which is an evident application bug. --ANK */ |
1062 | release_sock(sk); | 1059 | release_sock(sk); |
1063 | 1060 | ||
1064 | net_dbg_ratelimited("cork app bug 2\n"); | 1061 | net_dbg_ratelimited("socket already corked\n"); |
1065 | err = -EINVAL; | 1062 | err = -EINVAL; |
1066 | goto out; | 1063 | goto out; |
1067 | } | 1064 | } |
@@ -1144,7 +1141,7 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, | |||
1144 | if (unlikely(!up->pending)) { | 1141 | if (unlikely(!up->pending)) { |
1145 | release_sock(sk); | 1142 | release_sock(sk); |
1146 | 1143 | ||
1147 | net_dbg_ratelimited("udp cork app bug 3\n"); | 1144 | net_dbg_ratelimited("cork failed\n"); |
1148 | return -EINVAL; | 1145 | return -EINVAL; |
1149 | } | 1146 | } |
1150 | 1147 | ||
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 8081bafe441b..15535ee327c5 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -315,6 +315,7 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space, | |||
315 | } | 315 | } |
316 | opt_space->dst1opt = fopt->dst1opt; | 316 | opt_space->dst1opt = fopt->dst1opt; |
317 | opt_space->opt_flen = fopt->opt_flen; | 317 | opt_space->opt_flen = fopt->opt_flen; |
318 | opt_space->tot_len = fopt->tot_len; | ||
318 | return opt_space; | 319 | return opt_space; |
319 | } | 320 | } |
320 | EXPORT_SYMBOL_GPL(fl6_merge_options); | 321 | EXPORT_SYMBOL_GPL(fl6_merge_options); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 43ca864327c7..5110a418cc4d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1161,11 +1161,11 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, | |||
1161 | if (WARN_ON(v6_cork->opt)) | 1161 | if (WARN_ON(v6_cork->opt)) |
1162 | return -EINVAL; | 1162 | return -EINVAL; |
1163 | 1163 | ||
1164 | v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation); | 1164 | v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation); |
1165 | if (unlikely(!v6_cork->opt)) | 1165 | if (unlikely(!v6_cork->opt)) |
1166 | return -ENOBUFS; | 1166 | return -ENOBUFS; |
1167 | 1167 | ||
1168 | v6_cork->opt->tot_len = opt->tot_len; | 1168 | v6_cork->opt->tot_len = sizeof(*opt); |
1169 | v6_cork->opt->opt_flen = opt->opt_flen; | 1169 | v6_cork->opt->opt_flen = opt->opt_flen; |
1170 | v6_cork->opt->opt_nflen = opt->opt_nflen; | 1170 | v6_cork->opt->opt_nflen = opt->opt_nflen; |
1171 | 1171 | ||
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index bc6e8bfc5be4..f50452b919d5 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -988,6 +988,9 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, | |||
988 | session->name, cmd, arg); | 988 | session->name, cmd, arg); |
989 | 989 | ||
990 | sk = ps->sock; | 990 | sk = ps->sock; |
991 | if (!sk) | ||
992 | return -EBADR; | ||
993 | |||
991 | sock_hold(sk); | 994 | sock_hold(sk); |
992 | 995 | ||
993 | switch (cmd) { | 996 | switch (cmd) { |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index a98fc2b5e0dc..ae995c8480db 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | 6 | * Copyright 2013-2014 Intel Mobile Communications GmbH |
7 | * Copyright 2015 Intel Deutschland GmbH | 7 | * Copyright 2015-2017 Intel Deutschland GmbH |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -620,9 +620,6 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
620 | 620 | ||
621 | pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; | 621 | pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; |
622 | idx = key->conf.keyidx; | 622 | idx = key->conf.keyidx; |
623 | key->local = sdata->local; | ||
624 | key->sdata = sdata; | ||
625 | key->sta = sta; | ||
626 | 623 | ||
627 | mutex_lock(&sdata->local->key_mtx); | 624 | mutex_lock(&sdata->local->key_mtx); |
628 | 625 | ||
@@ -633,6 +630,21 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
633 | else | 630 | else |
634 | old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]); | 631 | old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]); |
635 | 632 | ||
633 | /* | ||
634 | * Silently accept key re-installation without really installing the | ||
635 | * new version of the key to avoid nonce reuse or replay issues. | ||
636 | */ | ||
637 | if (old_key && key->conf.keylen == old_key->conf.keylen && | ||
638 | !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) { | ||
639 | ieee80211_key_free_unused(key); | ||
640 | ret = 0; | ||
641 | goto out; | ||
642 | } | ||
643 | |||
644 | key->local = sdata->local; | ||
645 | key->sdata = sdata; | ||
646 | key->sta = sta; | ||
647 | |||
636 | increment_tailroom_need_count(sdata); | 648 | increment_tailroom_need_count(sdata); |
637 | 649 | ||
638 | ieee80211_key_replace(sdata, sta, pairwise, old_key, key); | 650 | ieee80211_key_replace(sdata, sta, pairwise, old_key, key); |
@@ -648,6 +660,7 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
648 | ret = 0; | 660 | ret = 0; |
649 | } | 661 | } |
650 | 662 | ||
663 | out: | ||
651 | mutex_unlock(&sdata->local->key_mtx); | 664 | mutex_unlock(&sdata->local->key_mtx); |
652 | 665 | ||
653 | return ret; | 666 | return ret; |
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index af3d636534ef..d30f7bd741d0 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h | |||
@@ -286,6 +286,7 @@ struct ncsi_dev_priv { | |||
286 | struct work_struct work; /* For channel management */ | 286 | struct work_struct work; /* For channel management */ |
287 | struct packet_type ptype; /* NCSI packet Rx handler */ | 287 | struct packet_type ptype; /* NCSI packet Rx handler */ |
288 | struct list_head node; /* Form NCSI device list */ | 288 | struct list_head node; /* Form NCSI device list */ |
289 | #define NCSI_MAX_VLAN_VIDS 15 | ||
289 | struct list_head vlan_vids; /* List of active VLAN IDs */ | 290 | struct list_head vlan_vids; /* List of active VLAN IDs */ |
290 | }; | 291 | }; |
291 | 292 | ||
diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c index 6898e7229285..f135938bf781 100644 --- a/net/ncsi/ncsi-aen.c +++ b/net/ncsi/ncsi-aen.c | |||
@@ -187,7 +187,7 @@ static struct ncsi_aen_handler { | |||
187 | } ncsi_aen_handlers[] = { | 187 | } ncsi_aen_handlers[] = { |
188 | { NCSI_PKT_AEN_LSC, 12, ncsi_aen_handler_lsc }, | 188 | { NCSI_PKT_AEN_LSC, 12, ncsi_aen_handler_lsc }, |
189 | { NCSI_PKT_AEN_CR, 4, ncsi_aen_handler_cr }, | 189 | { NCSI_PKT_AEN_CR, 4, ncsi_aen_handler_cr }, |
190 | { NCSI_PKT_AEN_HNCDSC, 4, ncsi_aen_handler_hncdsc } | 190 | { NCSI_PKT_AEN_HNCDSC, 8, ncsi_aen_handler_hncdsc } |
191 | }; | 191 | }; |
192 | 192 | ||
193 | int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb) | 193 | int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb) |
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index 3fd3c39e6278..28c42b22b748 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c | |||
@@ -189,6 +189,7 @@ static void ncsi_channel_monitor(unsigned long data) | |||
189 | struct ncsi_channel *nc = (struct ncsi_channel *)data; | 189 | struct ncsi_channel *nc = (struct ncsi_channel *)data; |
190 | struct ncsi_package *np = nc->package; | 190 | struct ncsi_package *np = nc->package; |
191 | struct ncsi_dev_priv *ndp = np->ndp; | 191 | struct ncsi_dev_priv *ndp = np->ndp; |
192 | struct ncsi_channel_mode *ncm; | ||
192 | struct ncsi_cmd_arg nca; | 193 | struct ncsi_cmd_arg nca; |
193 | bool enabled, chained; | 194 | bool enabled, chained; |
194 | unsigned int monitor_state; | 195 | unsigned int monitor_state; |
@@ -202,11 +203,15 @@ static void ncsi_channel_monitor(unsigned long data) | |||
202 | monitor_state = nc->monitor.state; | 203 | monitor_state = nc->monitor.state; |
203 | spin_unlock_irqrestore(&nc->lock, flags); | 204 | spin_unlock_irqrestore(&nc->lock, flags); |
204 | 205 | ||
205 | if (!enabled || chained) | 206 | if (!enabled || chained) { |
207 | ncsi_stop_channel_monitor(nc); | ||
206 | return; | 208 | return; |
209 | } | ||
207 | if (state != NCSI_CHANNEL_INACTIVE && | 210 | if (state != NCSI_CHANNEL_INACTIVE && |
208 | state != NCSI_CHANNEL_ACTIVE) | 211 | state != NCSI_CHANNEL_ACTIVE) { |
212 | ncsi_stop_channel_monitor(nc); | ||
209 | return; | 213 | return; |
214 | } | ||
210 | 215 | ||
211 | switch (monitor_state) { | 216 | switch (monitor_state) { |
212 | case NCSI_CHANNEL_MONITOR_START: | 217 | case NCSI_CHANNEL_MONITOR_START: |
@@ -217,28 +222,28 @@ static void ncsi_channel_monitor(unsigned long data) | |||
217 | nca.type = NCSI_PKT_CMD_GLS; | 222 | nca.type = NCSI_PKT_CMD_GLS; |
218 | nca.req_flags = 0; | 223 | nca.req_flags = 0; |
219 | ret = ncsi_xmit_cmd(&nca); | 224 | ret = ncsi_xmit_cmd(&nca); |
220 | if (ret) { | 225 | if (ret) |
221 | netdev_err(ndp->ndev.dev, "Error %d sending GLS\n", | 226 | netdev_err(ndp->ndev.dev, "Error %d sending GLS\n", |
222 | ret); | 227 | ret); |
223 | return; | ||
224 | } | ||
225 | |||
226 | break; | 228 | break; |
227 | case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX: | 229 | case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX: |
228 | break; | 230 | break; |
229 | default: | 231 | default: |
230 | if (!(ndp->flags & NCSI_DEV_HWA) && | 232 | if (!(ndp->flags & NCSI_DEV_HWA)) { |
231 | state == NCSI_CHANNEL_ACTIVE) { | ||
232 | ncsi_report_link(ndp, true); | 233 | ncsi_report_link(ndp, true); |
233 | ndp->flags |= NCSI_DEV_RESHUFFLE; | 234 | ndp->flags |= NCSI_DEV_RESHUFFLE; |
234 | } | 235 | } |
235 | 236 | ||
237 | ncsi_stop_channel_monitor(nc); | ||
238 | |||
239 | ncm = &nc->modes[NCSI_MODE_LINK]; | ||
236 | spin_lock_irqsave(&nc->lock, flags); | 240 | spin_lock_irqsave(&nc->lock, flags); |
237 | nc->state = NCSI_CHANNEL_INVISIBLE; | 241 | nc->state = NCSI_CHANNEL_INVISIBLE; |
242 | ncm->data[2] &= ~0x1; | ||
238 | spin_unlock_irqrestore(&nc->lock, flags); | 243 | spin_unlock_irqrestore(&nc->lock, flags); |
239 | 244 | ||
240 | spin_lock_irqsave(&ndp->lock, flags); | 245 | spin_lock_irqsave(&ndp->lock, flags); |
241 | nc->state = NCSI_CHANNEL_INACTIVE; | 246 | nc->state = NCSI_CHANNEL_ACTIVE; |
242 | list_add_tail_rcu(&nc->link, &ndp->channel_queue); | 247 | list_add_tail_rcu(&nc->link, &ndp->channel_queue); |
243 | spin_unlock_irqrestore(&ndp->lock, flags); | 248 | spin_unlock_irqrestore(&ndp->lock, flags); |
244 | ncsi_process_next_channel(ndp); | 249 | ncsi_process_next_channel(ndp); |
@@ -732,6 +737,10 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc, | |||
732 | if (index < 0) { | 737 | if (index < 0) { |
733 | netdev_err(ndp->ndev.dev, | 738 | netdev_err(ndp->ndev.dev, |
734 | "Failed to add new VLAN tag, error %d\n", index); | 739 | "Failed to add new VLAN tag, error %d\n", index); |
740 | if (index == -ENOSPC) | ||
741 | netdev_err(ndp->ndev.dev, | ||
742 | "Channel %u already has all VLAN filters set\n", | ||
743 | nc->id); | ||
735 | return -1; | 744 | return -1; |
736 | } | 745 | } |
737 | 746 | ||
@@ -998,12 +1007,15 @@ static bool ncsi_check_hwa(struct ncsi_dev_priv *ndp) | |||
998 | struct ncsi_package *np; | 1007 | struct ncsi_package *np; |
999 | struct ncsi_channel *nc; | 1008 | struct ncsi_channel *nc; |
1000 | unsigned int cap; | 1009 | unsigned int cap; |
1010 | bool has_channel = false; | ||
1001 | 1011 | ||
1002 | /* The hardware arbitration is disabled if any one channel | 1012 | /* The hardware arbitration is disabled if any one channel |
1003 | * doesn't support explicitly. | 1013 | * doesn't support explicitly. |
1004 | */ | 1014 | */ |
1005 | NCSI_FOR_EACH_PACKAGE(ndp, np) { | 1015 | NCSI_FOR_EACH_PACKAGE(ndp, np) { |
1006 | NCSI_FOR_EACH_CHANNEL(np, nc) { | 1016 | NCSI_FOR_EACH_CHANNEL(np, nc) { |
1017 | has_channel = true; | ||
1018 | |||
1007 | cap = nc->caps[NCSI_CAP_GENERIC].cap; | 1019 | cap = nc->caps[NCSI_CAP_GENERIC].cap; |
1008 | if (!(cap & NCSI_CAP_GENERIC_HWA) || | 1020 | if (!(cap & NCSI_CAP_GENERIC_HWA) || |
1009 | (cap & NCSI_CAP_GENERIC_HWA_MASK) != | 1021 | (cap & NCSI_CAP_GENERIC_HWA_MASK) != |
@@ -1014,8 +1026,13 @@ static bool ncsi_check_hwa(struct ncsi_dev_priv *ndp) | |||
1014 | } | 1026 | } |
1015 | } | 1027 | } |
1016 | 1028 | ||
1017 | ndp->flags |= NCSI_DEV_HWA; | 1029 | if (has_channel) { |
1018 | return true; | 1030 | ndp->flags |= NCSI_DEV_HWA; |
1031 | return true; | ||
1032 | } | ||
1033 | |||
1034 | ndp->flags &= ~NCSI_DEV_HWA; | ||
1035 | return false; | ||
1019 | } | 1036 | } |
1020 | 1037 | ||
1021 | static int ncsi_enable_hwa(struct ncsi_dev_priv *ndp) | 1038 | static int ncsi_enable_hwa(struct ncsi_dev_priv *ndp) |
@@ -1403,7 +1420,6 @@ static int ncsi_kick_channels(struct ncsi_dev_priv *ndp) | |||
1403 | 1420 | ||
1404 | int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) | 1421 | int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) |
1405 | { | 1422 | { |
1406 | struct ncsi_channel_filter *ncf; | ||
1407 | struct ncsi_dev_priv *ndp; | 1423 | struct ncsi_dev_priv *ndp; |
1408 | unsigned int n_vids = 0; | 1424 | unsigned int n_vids = 0; |
1409 | struct vlan_vid *vlan; | 1425 | struct vlan_vid *vlan; |
@@ -1420,7 +1436,6 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) | |||
1420 | } | 1436 | } |
1421 | 1437 | ||
1422 | ndp = TO_NCSI_DEV_PRIV(nd); | 1438 | ndp = TO_NCSI_DEV_PRIV(nd); |
1423 | ncf = ndp->hot_channel->filters[NCSI_FILTER_VLAN]; | ||
1424 | 1439 | ||
1425 | /* Add the VLAN id to our internal list */ | 1440 | /* Add the VLAN id to our internal list */ |
1426 | list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) { | 1441 | list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) { |
@@ -1431,12 +1446,11 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) | |||
1431 | return 0; | 1446 | return 0; |
1432 | } | 1447 | } |
1433 | } | 1448 | } |
1434 | 1449 | if (n_vids >= NCSI_MAX_VLAN_VIDS) { | |
1435 | if (n_vids >= ncf->total) { | 1450 | netdev_warn(dev, |
1436 | netdev_info(dev, | 1451 | "tried to add vlan id %u but NCSI max already registered (%u)\n", |
1437 | "NCSI Channel supports up to %u VLAN tags but %u are already set\n", | 1452 | vid, NCSI_MAX_VLAN_VIDS); |
1438 | ncf->total, n_vids); | 1453 | return -ENOSPC; |
1439 | return -EINVAL; | ||
1440 | } | 1454 | } |
1441 | 1455 | ||
1442 | vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); | 1456 | vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); |
diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index 265b9a892d41..927dad4759d1 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c | |||
@@ -959,7 +959,7 @@ static struct ncsi_rsp_handler { | |||
959 | { NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf }, | 959 | { NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf }, |
960 | { NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf }, | 960 | { NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf }, |
961 | { NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc }, | 961 | { NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc }, |
962 | { NCSI_PKT_RSP_GVI, 36, ncsi_rsp_handler_gvi }, | 962 | { NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi }, |
963 | { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc }, | 963 | { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc }, |
964 | { NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp }, | 964 | { NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp }, |
965 | { NCSI_PKT_RSP_GCPS, 172, ncsi_rsp_handler_gcps }, | 965 | { NCSI_PKT_RSP_GCPS, 172, ncsi_rsp_handler_gcps }, |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 336d9c6dcad9..767c84e10e20 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -2307,6 +2307,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, | |||
2307 | size_t tlvlen = 0; | 2307 | size_t tlvlen = 0; |
2308 | struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk); | 2308 | struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk); |
2309 | unsigned int flags = 0; | 2309 | unsigned int flags = 0; |
2310 | bool nlk_has_extack = nlk->flags & NETLINK_F_EXT_ACK; | ||
2310 | 2311 | ||
2311 | /* Error messages get the original request appened, unless the user | 2312 | /* Error messages get the original request appened, unless the user |
2312 | * requests to cap the error message, and get extra error data if | 2313 | * requests to cap the error message, and get extra error data if |
@@ -2317,7 +2318,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, | |||
2317 | payload += nlmsg_len(nlh); | 2318 | payload += nlmsg_len(nlh); |
2318 | else | 2319 | else |
2319 | flags |= NLM_F_CAPPED; | 2320 | flags |= NLM_F_CAPPED; |
2320 | if (nlk->flags & NETLINK_F_EXT_ACK && extack) { | 2321 | if (nlk_has_extack && extack) { |
2321 | if (extack->_msg) | 2322 | if (extack->_msg) |
2322 | tlvlen += nla_total_size(strlen(extack->_msg) + 1); | 2323 | tlvlen += nla_total_size(strlen(extack->_msg) + 1); |
2323 | if (extack->bad_attr) | 2324 | if (extack->bad_attr) |
@@ -2326,8 +2327,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, | |||
2326 | } else { | 2327 | } else { |
2327 | flags |= NLM_F_CAPPED; | 2328 | flags |= NLM_F_CAPPED; |
2328 | 2329 | ||
2329 | if (nlk->flags & NETLINK_F_EXT_ACK && | 2330 | if (nlk_has_extack && extack && extack->cookie_len) |
2330 | extack && extack->cookie_len) | ||
2331 | tlvlen += nla_total_size(extack->cookie_len); | 2331 | tlvlen += nla_total_size(extack->cookie_len); |
2332 | } | 2332 | } |
2333 | 2333 | ||
@@ -2347,7 +2347,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, | |||
2347 | errmsg->error = err; | 2347 | errmsg->error = err; |
2348 | memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh)); | 2348 | memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh)); |
2349 | 2349 | ||
2350 | if (nlk->flags & NETLINK_F_EXT_ACK && extack) { | 2350 | if (nlk_has_extack && extack) { |
2351 | if (err) { | 2351 | if (err) { |
2352 | if (extack->_msg) | 2352 | if (extack->_msg) |
2353 | WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, | 2353 | WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 3f5caa3fbd06..4f4fa323171d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1767,7 +1767,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | |||
1767 | 1767 | ||
1768 | out: | 1768 | out: |
1769 | if (err && rollover) { | 1769 | if (err && rollover) { |
1770 | kfree(rollover); | 1770 | kfree_rcu(rollover, rcu); |
1771 | po->rollover = NULL; | 1771 | po->rollover = NULL; |
1772 | } | 1772 | } |
1773 | mutex_unlock(&fanout_mutex); | 1773 | mutex_unlock(&fanout_mutex); |
@@ -1794,8 +1794,10 @@ static struct packet_fanout *fanout_release(struct sock *sk) | |||
1794 | else | 1794 | else |
1795 | f = NULL; | 1795 | f = NULL; |
1796 | 1796 | ||
1797 | if (po->rollover) | 1797 | if (po->rollover) { |
1798 | kfree_rcu(po->rollover, rcu); | 1798 | kfree_rcu(po->rollover, rcu); |
1799 | po->rollover = NULL; | ||
1800 | } | ||
1799 | } | 1801 | } |
1800 | mutex_unlock(&fanout_mutex); | 1802 | mutex_unlock(&fanout_mutex); |
1801 | 1803 | ||
@@ -3849,6 +3851,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, | |||
3849 | void *data = &val; | 3851 | void *data = &val; |
3850 | union tpacket_stats_u st; | 3852 | union tpacket_stats_u st; |
3851 | struct tpacket_rollover_stats rstats; | 3853 | struct tpacket_rollover_stats rstats; |
3854 | struct packet_rollover *rollover; | ||
3852 | 3855 | ||
3853 | if (level != SOL_PACKET) | 3856 | if (level != SOL_PACKET) |
3854 | return -ENOPROTOOPT; | 3857 | return -ENOPROTOOPT; |
@@ -3927,13 +3930,18 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, | |||
3927 | 0); | 3930 | 0); |
3928 | break; | 3931 | break; |
3929 | case PACKET_ROLLOVER_STATS: | 3932 | case PACKET_ROLLOVER_STATS: |
3930 | if (!po->rollover) | 3933 | rcu_read_lock(); |
3934 | rollover = rcu_dereference(po->rollover); | ||
3935 | if (rollover) { | ||
3936 | rstats.tp_all = atomic_long_read(&rollover->num); | ||
3937 | rstats.tp_huge = atomic_long_read(&rollover->num_huge); | ||
3938 | rstats.tp_failed = atomic_long_read(&rollover->num_failed); | ||
3939 | data = &rstats; | ||
3940 | lv = sizeof(rstats); | ||
3941 | } | ||
3942 | rcu_read_unlock(); | ||
3943 | if (!rollover) | ||
3931 | return -EINVAL; | 3944 | return -EINVAL; |
3932 | rstats.tp_all = atomic_long_read(&po->rollover->num); | ||
3933 | rstats.tp_huge = atomic_long_read(&po->rollover->num_huge); | ||
3934 | rstats.tp_failed = atomic_long_read(&po->rollover->num_failed); | ||
3935 | data = &rstats; | ||
3936 | lv = sizeof(rstats); | ||
3937 | break; | 3945 | break; |
3938 | case PACKET_TX_HAS_OFF: | 3946 | case PACKET_TX_HAS_OFF: |
3939 | val = po->tp_tx_has_off; | 3947 | val = po->tp_tx_has_off; |
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 73c980e26581..054e32872808 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -311,10 +311,11 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, | |||
311 | call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, tx_total_len, | 311 | call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, tx_total_len, |
312 | gfp); | 312 | gfp); |
313 | /* The socket has been unlocked. */ | 313 | /* The socket has been unlocked. */ |
314 | if (!IS_ERR(call)) | 314 | if (!IS_ERR(call)) { |
315 | call->notify_rx = notify_rx; | 315 | call->notify_rx = notify_rx; |
316 | mutex_unlock(&call->user_mutex); | ||
317 | } | ||
316 | 318 | ||
317 | mutex_unlock(&call->user_mutex); | ||
318 | _leave(" = %p", call); | 319 | _leave(" = %p", call); |
319 | return call; | 320 | return call; |
320 | } | 321 | } |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 92a07141fd07..34f10e75f3b9 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -421,7 +421,7 @@ void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t, | |||
421 | { | 421 | { |
422 | struct dst_entry *dst; | 422 | struct dst_entry *dst; |
423 | 423 | ||
424 | if (!t) | 424 | if (sock_owned_by_user(sk) || !t) |
425 | return; | 425 | return; |
426 | dst = sctp_transport_dst_check(t); | 426 | dst = sctp_transport_dst_check(t); |
427 | if (dst) | 427 | if (dst) |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 88c28421ec15..c75acdf71a6f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4978,6 +4978,10 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) | |||
4978 | struct socket *sock; | 4978 | struct socket *sock; |
4979 | int err = 0; | 4979 | int err = 0; |
4980 | 4980 | ||
4981 | /* Do not peel off from one netns to another one. */ | ||
4982 | if (!net_eq(current->nsproxy->net_ns, sock_net(sk))) | ||
4983 | return -EINVAL; | ||
4984 | |||
4981 | if (!asoc) | 4985 | if (!asoc) |
4982 | return -EINVAL; | 4986 | return -EINVAL; |
4983 | 4987 | ||
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index bbac023e70d1..5583df708b8c 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c | |||
@@ -310,11 +310,15 @@ static void hvs_close_connection(struct vmbus_channel *chan) | |||
310 | struct sock *sk = get_per_channel_state(chan); | 310 | struct sock *sk = get_per_channel_state(chan); |
311 | struct vsock_sock *vsk = vsock_sk(sk); | 311 | struct vsock_sock *vsk = vsock_sk(sk); |
312 | 312 | ||
313 | lock_sock(sk); | ||
314 | |||
313 | sk->sk_state = TCP_CLOSE; | 315 | sk->sk_state = TCP_CLOSE; |
314 | sock_set_flag(sk, SOCK_DONE); | 316 | sock_set_flag(sk, SOCK_DONE); |
315 | vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN; | 317 | vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN; |
316 | 318 | ||
317 | sk->sk_state_change(sk); | 319 | sk->sk_state_change(sk); |
320 | |||
321 | release_sock(sk); | ||
318 | } | 322 | } |
319 | 323 | ||
320 | static void hvs_open_connection(struct vmbus_channel *chan) | 324 | static void hvs_open_connection(struct vmbus_channel *chan) |
@@ -344,6 +348,7 @@ static void hvs_open_connection(struct vmbus_channel *chan) | |||
344 | if (!sk) | 348 | if (!sk) |
345 | return; | 349 | return; |
346 | 350 | ||
351 | lock_sock(sk); | ||
347 | if ((conn_from_host && sk->sk_state != TCP_LISTEN) || | 352 | if ((conn_from_host && sk->sk_state != TCP_LISTEN) || |
348 | (!conn_from_host && sk->sk_state != TCP_SYN_SENT)) | 353 | (!conn_from_host && sk->sk_state != TCP_SYN_SENT)) |
349 | goto out; | 354 | goto out; |
@@ -395,9 +400,7 @@ static void hvs_open_connection(struct vmbus_channel *chan) | |||
395 | 400 | ||
396 | vsock_insert_connected(vnew); | 401 | vsock_insert_connected(vnew); |
397 | 402 | ||
398 | lock_sock(sk); | ||
399 | vsock_enqueue_accept(sk, new); | 403 | vsock_enqueue_accept(sk, new); |
400 | release_sock(sk); | ||
401 | } else { | 404 | } else { |
402 | sk->sk_state = TCP_ESTABLISHED; | 405 | sk->sk_state = TCP_ESTABLISHED; |
403 | sk->sk_socket->state = SS_CONNECTED; | 406 | sk->sk_socket->state = SS_CONNECTED; |
@@ -410,6 +413,8 @@ static void hvs_open_connection(struct vmbus_channel *chan) | |||
410 | out: | 413 | out: |
411 | /* Release refcnt obtained when we called vsock_find_bound_socket() */ | 414 | /* Release refcnt obtained when we called vsock_find_bound_socket() */ |
412 | sock_put(sk); | 415 | sock_put(sk); |
416 | |||
417 | release_sock(sk); | ||
413 | } | 418 | } |
414 | 419 | ||
415 | static u32 hvs_get_local_cid(void) | 420 | static u32 hvs_get_local_cid(void) |
@@ -476,13 +481,21 @@ out: | |||
476 | 481 | ||
477 | static void hvs_release(struct vsock_sock *vsk) | 482 | static void hvs_release(struct vsock_sock *vsk) |
478 | { | 483 | { |
484 | struct sock *sk = sk_vsock(vsk); | ||
479 | struct hvsock *hvs = vsk->trans; | 485 | struct hvsock *hvs = vsk->trans; |
480 | struct vmbus_channel *chan = hvs->chan; | 486 | struct vmbus_channel *chan; |
487 | |||
488 | lock_sock(sk); | ||
489 | |||
490 | sk->sk_state = SS_DISCONNECTING; | ||
491 | vsock_remove_sock(vsk); | ||
492 | |||
493 | release_sock(sk); | ||
481 | 494 | ||
495 | chan = hvs->chan; | ||
482 | if (chan) | 496 | if (chan) |
483 | hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN); | 497 | hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN); |
484 | 498 | ||
485 | vsock_remove_sock(vsk); | ||
486 | } | 499 | } |
487 | 500 | ||
488 | static void hvs_destruct(struct vsock_sock *vsk) | 501 | static void hvs_destruct(struct vsock_sock *vsk) |