diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-02 20:35:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-02 20:35:53 -0400 |
commit | 918fe1b3157978ada4267468008c5f89ef101e7d (patch) | |
tree | 7f3f8a1561f6683c89010cc6db6afb3089273cf8 /net | |
parent | e0255aec66a156b4062a486878d8bb0355a4abc5 (diff) | |
parent | cd075ce4679ca7797734c4f6c5aa23878c8e2208 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) Infinite loop in _decode_session6(), from Eric Dumazet.
2) Pass correct argument to nla_strlcpy() in netfilter, also from Eric
Dumazet.
3) Out of bounds memory access in ipv6 srh code, from Mathieu Xhonneux.
4) NULL deref in XDP_REDIRECT handling of tun driver, from Toshiaki
Makita.
5) Incorrect idr release in cls_flower, from Paul Blakey.
6) Probe error handling fix in davinci_emac, from Dan Carpenter.
7) Memory leak in XPS configuration, from Alexander Duyck.
8) Use after free with cloned sockets in kcm, from Kirill Tkhai.
9) MTU handling fixes fo ip_tunnel and ip6_tunnel, from Nicolas
Dichtel.
10) Fix UAPI hole in bpf data structure for 32-bit compat applications,
from Daniel Borkmann.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (33 commits)
bpf: fix uapi hole for 32 bit compat applications
net: usb: cdc_mbim: add flag FLAG_SEND_ZLP
ip6_tunnel: remove magic mtu value 0xFFF8
ip_tunnel: restore binding to ifaces with a large mtu
net: dsa: b53: Add BCM5389 support
kcm: Fix use-after-free caused by clonned sockets
net-sysfs: Fix memory leak in XPS configuration
ixgbe: fix parsing of TC actions for HW offload
net: ethernet: davinci_emac: fix error handling in probe()
net/ncsi: Fix array size in dumpit handler
cls_flower: Fix incorrect idr release when failing to modify rule
net/sonic: Use dma_mapping_error()
xfrm Fix potential error pointer dereference in xfrm_bundle_create.
vhost_net: flush batched heads before trying to busy polling
tun: Fix NULL pointer dereference in XDP redirect
be2net: Fix error detection logic for BE3
net: qmi_wwan: Add Netgear Aircard 779S
mlxsw: spectrum: Forbid creation of VLAN 1 over port/LAG
atm: zatm: fix memcmp casting
iwlwifi: pcie: compare with number of IRQs requested for, not number of CPUs
...
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 3 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 6 | ||||
-rw-r--r-- | net/ipv4/ip_tunnel.c | 8 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 11 | ||||
-rw-r--r-- | net/ipv6/seg6_iptunnel.c | 4 | ||||
-rw-r--r-- | net/ipv6/sit.c | 5 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 2 | ||||
-rw-r--r-- | net/kcm/kcmsock.c | 2 | ||||
-rw-r--r-- | net/ncsi/ncsi-netlink.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 21 | ||||
-rw-r--r-- | net/netfilter/nf_tables_api.c | 8 | ||||
-rw-r--r-- | net/netfilter/nf_tables_core.c | 4 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_acct.c | 2 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_cthelper.c | 4 | ||||
-rw-r--r-- | net/netfilter/nft_ct.c | 20 | ||||
-rw-r--r-- | net/netfilter/nft_limit.c | 38 | ||||
-rw-r--r-- | net/netfilter/nft_meta.c | 14 | ||||
-rw-r--r-- | net/sched/cls_flower.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 5 |
19 files changed, 97 insertions, 64 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 28a4c3490359..6ba639f6c51d 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1954,7 +1954,8 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt, | |||
1954 | int off, pad = 0; | 1954 | int off, pad = 0; |
1955 | unsigned int size_kern, match_size = mwt->match_size; | 1955 | unsigned int size_kern, match_size = mwt->match_size; |
1956 | 1956 | ||
1957 | strlcpy(name, mwt->u.name, sizeof(name)); | 1957 | if (strscpy(name, mwt->u.name, sizeof(name)) < 0) |
1958 | return -EINVAL; | ||
1958 | 1959 | ||
1959 | if (state->buf_kern_start) | 1960 | if (state->buf_kern_start) |
1960 | dst = state->buf_kern_start + state->buf_kern_offset; | 1961 | dst = state->buf_kern_start + state->buf_kern_offset; |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index c476f0794132..bb7e80f4ced3 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -1214,9 +1214,6 @@ static ssize_t xps_cpus_show(struct netdev_queue *queue, | |||
1214 | cpumask_var_t mask; | 1214 | cpumask_var_t mask; |
1215 | unsigned long index; | 1215 | unsigned long index; |
1216 | 1216 | ||
1217 | if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) | ||
1218 | return -ENOMEM; | ||
1219 | |||
1220 | index = get_netdev_queue_index(queue); | 1217 | index = get_netdev_queue_index(queue); |
1221 | 1218 | ||
1222 | if (dev->num_tc) { | 1219 | if (dev->num_tc) { |
@@ -1226,6 +1223,9 @@ static ssize_t xps_cpus_show(struct netdev_queue *queue, | |||
1226 | return -EINVAL; | 1223 | return -EINVAL; |
1227 | } | 1224 | } |
1228 | 1225 | ||
1226 | if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) | ||
1227 | return -ENOMEM; | ||
1228 | |||
1229 | rcu_read_lock(); | 1229 | rcu_read_lock(); |
1230 | dev_maps = rcu_dereference(dev->xps_maps); | 1230 | dev_maps = rcu_dereference(dev->xps_maps); |
1231 | if (dev_maps) { | 1231 | if (dev_maps) { |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 6b0e362cc99b..38d906baf1df 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -328,7 +328,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev) | |||
328 | 328 | ||
329 | if (tdev) { | 329 | if (tdev) { |
330 | hlen = tdev->hard_header_len + tdev->needed_headroom; | 330 | hlen = tdev->hard_header_len + tdev->needed_headroom; |
331 | mtu = tdev->mtu; | 331 | mtu = min(tdev->mtu, IP_MAX_MTU); |
332 | } | 332 | } |
333 | 333 | ||
334 | dev->needed_headroom = t_hlen + hlen; | 334 | dev->needed_headroom = t_hlen + hlen; |
@@ -362,7 +362,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net, | |||
362 | nt = netdev_priv(dev); | 362 | nt = netdev_priv(dev); |
363 | t_hlen = nt->hlen + sizeof(struct iphdr); | 363 | t_hlen = nt->hlen + sizeof(struct iphdr); |
364 | dev->min_mtu = ETH_MIN_MTU; | 364 | dev->min_mtu = ETH_MIN_MTU; |
365 | dev->max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen; | 365 | dev->max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen; |
366 | ip_tunnel_add(itn, nt); | 366 | ip_tunnel_add(itn, nt); |
367 | return nt; | 367 | return nt; |
368 | 368 | ||
@@ -930,7 +930,7 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict) | |||
930 | { | 930 | { |
931 | struct ip_tunnel *tunnel = netdev_priv(dev); | 931 | struct ip_tunnel *tunnel = netdev_priv(dev); |
932 | int t_hlen = tunnel->hlen + sizeof(struct iphdr); | 932 | int t_hlen = tunnel->hlen + sizeof(struct iphdr); |
933 | int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen; | 933 | int max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen; |
934 | 934 | ||
935 | if (new_mtu < ETH_MIN_MTU) | 935 | if (new_mtu < ETH_MIN_MTU) |
936 | return -EINVAL; | 936 | return -EINVAL; |
@@ -1107,7 +1107,7 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[], | |||
1107 | 1107 | ||
1108 | mtu = ip_tunnel_bind_dev(dev); | 1108 | mtu = ip_tunnel_bind_dev(dev); |
1109 | if (tb[IFLA_MTU]) { | 1109 | if (tb[IFLA_MTU]) { |
1110 | unsigned int max = 0xfff8 - dev->hard_header_len - nt->hlen; | 1110 | unsigned int max = IP_MAX_MTU - dev->hard_header_len - nt->hlen; |
1111 | 1111 | ||
1112 | mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU, | 1112 | mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU, |
1113 | (unsigned int)(max - sizeof(struct iphdr))); | 1113 | (unsigned int)(max - sizeof(struct iphdr))); |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index da66aaac51ce..00e138a44cbb 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1692,8 +1692,13 @@ int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) | |||
1692 | if (new_mtu < ETH_MIN_MTU) | 1692 | if (new_mtu < ETH_MIN_MTU) |
1693 | return -EINVAL; | 1693 | return -EINVAL; |
1694 | } | 1694 | } |
1695 | if (new_mtu > 0xFFF8 - dev->hard_header_len) | 1695 | if (tnl->parms.proto == IPPROTO_IPV6 || tnl->parms.proto == 0) { |
1696 | return -EINVAL; | 1696 | if (new_mtu > IP6_MAX_MTU - dev->hard_header_len) |
1697 | return -EINVAL; | ||
1698 | } else { | ||
1699 | if (new_mtu > IP_MAX_MTU - dev->hard_header_len) | ||
1700 | return -EINVAL; | ||
1701 | } | ||
1697 | dev->mtu = new_mtu; | 1702 | dev->mtu = new_mtu; |
1698 | return 0; | 1703 | return 0; |
1699 | } | 1704 | } |
@@ -1841,7 +1846,7 @@ ip6_tnl_dev_init_gen(struct net_device *dev) | |||
1841 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | 1846 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) |
1842 | dev->mtu -= 8; | 1847 | dev->mtu -= 8; |
1843 | dev->min_mtu = ETH_MIN_MTU; | 1848 | dev->min_mtu = ETH_MIN_MTU; |
1844 | dev->max_mtu = 0xFFF8 - dev->hard_header_len; | 1849 | dev->max_mtu = IP6_MAX_MTU - dev->hard_header_len; |
1845 | 1850 | ||
1846 | return 0; | 1851 | return 0; |
1847 | 1852 | ||
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c index 5fe139484919..bf4763fd68c2 100644 --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c | |||
@@ -103,7 +103,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) | |||
103 | hdrlen = (osrh->hdrlen + 1) << 3; | 103 | hdrlen = (osrh->hdrlen + 1) << 3; |
104 | tot_len = hdrlen + sizeof(*hdr); | 104 | tot_len = hdrlen + sizeof(*hdr); |
105 | 105 | ||
106 | err = skb_cow_head(skb, tot_len); | 106 | err = skb_cow_head(skb, tot_len + skb->mac_len); |
107 | if (unlikely(err)) | 107 | if (unlikely(err)) |
108 | return err; | 108 | return err; |
109 | 109 | ||
@@ -161,7 +161,7 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) | |||
161 | 161 | ||
162 | hdrlen = (osrh->hdrlen + 1) << 3; | 162 | hdrlen = (osrh->hdrlen + 1) << 3; |
163 | 163 | ||
164 | err = skb_cow_head(skb, hdrlen); | 164 | err = skb_cow_head(skb, hdrlen + skb->mac_len); |
165 | if (unlikely(err)) | 165 | if (unlikely(err)) |
166 | return err; | 166 | return err; |
167 | 167 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 2afce37a7177..e9400ffa7875 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -1371,7 +1371,7 @@ static void ipip6_tunnel_setup(struct net_device *dev) | |||
1371 | dev->hard_header_len = LL_MAX_HEADER + t_hlen; | 1371 | dev->hard_header_len = LL_MAX_HEADER + t_hlen; |
1372 | dev->mtu = ETH_DATA_LEN - t_hlen; | 1372 | dev->mtu = ETH_DATA_LEN - t_hlen; |
1373 | dev->min_mtu = IPV6_MIN_MTU; | 1373 | dev->min_mtu = IPV6_MIN_MTU; |
1374 | dev->max_mtu = 0xFFF8 - t_hlen; | 1374 | dev->max_mtu = IP6_MAX_MTU - t_hlen; |
1375 | dev->flags = IFF_NOARP; | 1375 | dev->flags = IFF_NOARP; |
1376 | netif_keep_dst(dev); | 1376 | netif_keep_dst(dev); |
1377 | dev->addr_len = 4; | 1377 | dev->addr_len = 4; |
@@ -1583,7 +1583,8 @@ static int ipip6_newlink(struct net *src_net, struct net_device *dev, | |||
1583 | if (tb[IFLA_MTU]) { | 1583 | if (tb[IFLA_MTU]) { |
1584 | u32 mtu = nla_get_u32(tb[IFLA_MTU]); | 1584 | u32 mtu = nla_get_u32(tb[IFLA_MTU]); |
1585 | 1585 | ||
1586 | if (mtu >= IPV6_MIN_MTU && mtu <= 0xFFF8 - dev->hard_header_len) | 1586 | if (mtu >= IPV6_MIN_MTU && |
1587 | mtu <= IP6_MAX_MTU - dev->hard_header_len) | ||
1587 | dev->mtu = mtu; | 1588 | dev->mtu = mtu; |
1588 | } | 1589 | } |
1589 | 1590 | ||
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 416fe67271a9..86dba282a147 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -126,7 +126,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
126 | struct flowi6 *fl6 = &fl->u.ip6; | 126 | struct flowi6 *fl6 = &fl->u.ip6; |
127 | int onlyproto = 0; | 127 | int onlyproto = 0; |
128 | const struct ipv6hdr *hdr = ipv6_hdr(skb); | 128 | const struct ipv6hdr *hdr = ipv6_hdr(skb); |
129 | u16 offset = sizeof(*hdr); | 129 | u32 offset = sizeof(*hdr); |
130 | struct ipv6_opt_hdr *exthdr; | 130 | struct ipv6_opt_hdr *exthdr; |
131 | const unsigned char *nh = skb_network_header(skb); | 131 | const unsigned char *nh = skb_network_header(skb); |
132 | u16 nhoff = IP6CB(skb)->nhoff; | 132 | u16 nhoff = IP6CB(skb)->nhoff; |
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index dc76bc346829..d3601d421571 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c | |||
@@ -1671,7 +1671,7 @@ static struct file *kcm_clone(struct socket *osock) | |||
1671 | __module_get(newsock->ops->owner); | 1671 | __module_get(newsock->ops->owner); |
1672 | 1672 | ||
1673 | newsk = sk_alloc(sock_net(osock->sk), PF_KCM, GFP_KERNEL, | 1673 | newsk = sk_alloc(sock_net(osock->sk), PF_KCM, GFP_KERNEL, |
1674 | &kcm_proto, true); | 1674 | &kcm_proto, false); |
1675 | if (!newsk) { | 1675 | if (!newsk) { |
1676 | sock_release(newsock); | 1676 | sock_release(newsock); |
1677 | return ERR_PTR(-ENOMEM); | 1677 | return ERR_PTR(-ENOMEM); |
diff --git a/net/ncsi/ncsi-netlink.c b/net/ncsi/ncsi-netlink.c index 8d7e849d4825..41cede4041d3 100644 --- a/net/ncsi/ncsi-netlink.c +++ b/net/ncsi/ncsi-netlink.c | |||
@@ -215,7 +215,7 @@ err: | |||
215 | static int ncsi_pkg_info_all_nl(struct sk_buff *skb, | 215 | static int ncsi_pkg_info_all_nl(struct sk_buff *skb, |
216 | struct netlink_callback *cb) | 216 | struct netlink_callback *cb) |
217 | { | 217 | { |
218 | struct nlattr *attrs[NCSI_ATTR_MAX]; | 218 | struct nlattr *attrs[NCSI_ATTR_MAX + 1]; |
219 | struct ncsi_package *np, *package; | 219 | struct ncsi_package *np, *package; |
220 | struct ncsi_dev_priv *ndp; | 220 | struct ncsi_dev_priv *ndp; |
221 | unsigned int package_id; | 221 | unsigned int package_id; |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index f36098887ad0..3ecca0616d8c 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -2381,8 +2381,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
2381 | struct ipvs_sync_daemon_cfg cfg; | 2381 | struct ipvs_sync_daemon_cfg cfg; |
2382 | 2382 | ||
2383 | memset(&cfg, 0, sizeof(cfg)); | 2383 | memset(&cfg, 0, sizeof(cfg)); |
2384 | strlcpy(cfg.mcast_ifn, dm->mcast_ifn, | 2384 | ret = -EINVAL; |
2385 | sizeof(cfg.mcast_ifn)); | 2385 | if (strscpy(cfg.mcast_ifn, dm->mcast_ifn, |
2386 | sizeof(cfg.mcast_ifn)) <= 0) | ||
2387 | goto out_dec; | ||
2386 | cfg.syncid = dm->syncid; | 2388 | cfg.syncid = dm->syncid; |
2387 | ret = start_sync_thread(ipvs, &cfg, dm->state); | 2389 | ret = start_sync_thread(ipvs, &cfg, dm->state); |
2388 | } else { | 2390 | } else { |
@@ -2420,12 +2422,19 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
2420 | } | 2422 | } |
2421 | } | 2423 | } |
2422 | 2424 | ||
2425 | if ((cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_EDIT) && | ||
2426 | strnlen(usvc.sched_name, IP_VS_SCHEDNAME_MAXLEN) == | ||
2427 | IP_VS_SCHEDNAME_MAXLEN) { | ||
2428 | ret = -EINVAL; | ||
2429 | goto out_unlock; | ||
2430 | } | ||
2431 | |||
2423 | /* Check for valid protocol: TCP or UDP or SCTP, even for fwmark!=0 */ | 2432 | /* Check for valid protocol: TCP or UDP or SCTP, even for fwmark!=0 */ |
2424 | if (usvc.protocol != IPPROTO_TCP && usvc.protocol != IPPROTO_UDP && | 2433 | if (usvc.protocol != IPPROTO_TCP && usvc.protocol != IPPROTO_UDP && |
2425 | usvc.protocol != IPPROTO_SCTP) { | 2434 | usvc.protocol != IPPROTO_SCTP) { |
2426 | pr_err("set_ctl: invalid protocol: %d %pI4:%d %s\n", | 2435 | pr_err("set_ctl: invalid protocol: %d %pI4:%d\n", |
2427 | usvc.protocol, &usvc.addr.ip, | 2436 | usvc.protocol, &usvc.addr.ip, |
2428 | ntohs(usvc.port), usvc.sched_name); | 2437 | ntohs(usvc.port)); |
2429 | ret = -EFAULT; | 2438 | ret = -EFAULT; |
2430 | goto out_unlock; | 2439 | goto out_unlock; |
2431 | } | 2440 | } |
@@ -2847,7 +2856,7 @@ static const struct nla_policy ip_vs_cmd_policy[IPVS_CMD_ATTR_MAX + 1] = { | |||
2847 | static const struct nla_policy ip_vs_daemon_policy[IPVS_DAEMON_ATTR_MAX + 1] = { | 2856 | static const struct nla_policy ip_vs_daemon_policy[IPVS_DAEMON_ATTR_MAX + 1] = { |
2848 | [IPVS_DAEMON_ATTR_STATE] = { .type = NLA_U32 }, | 2857 | [IPVS_DAEMON_ATTR_STATE] = { .type = NLA_U32 }, |
2849 | [IPVS_DAEMON_ATTR_MCAST_IFN] = { .type = NLA_NUL_STRING, | 2858 | [IPVS_DAEMON_ATTR_MCAST_IFN] = { .type = NLA_NUL_STRING, |
2850 | .len = IP_VS_IFNAME_MAXLEN }, | 2859 | .len = IP_VS_IFNAME_MAXLEN - 1 }, |
2851 | [IPVS_DAEMON_ATTR_SYNC_ID] = { .type = NLA_U32 }, | 2860 | [IPVS_DAEMON_ATTR_SYNC_ID] = { .type = NLA_U32 }, |
2852 | [IPVS_DAEMON_ATTR_SYNC_MAXLEN] = { .type = NLA_U16 }, | 2861 | [IPVS_DAEMON_ATTR_SYNC_MAXLEN] = { .type = NLA_U16 }, |
2853 | [IPVS_DAEMON_ATTR_MCAST_GROUP] = { .type = NLA_U32 }, | 2862 | [IPVS_DAEMON_ATTR_MCAST_GROUP] = { .type = NLA_U32 }, |
@@ -2865,7 +2874,7 @@ static const struct nla_policy ip_vs_svc_policy[IPVS_SVC_ATTR_MAX + 1] = { | |||
2865 | [IPVS_SVC_ATTR_PORT] = { .type = NLA_U16 }, | 2874 | [IPVS_SVC_ATTR_PORT] = { .type = NLA_U16 }, |
2866 | [IPVS_SVC_ATTR_FWMARK] = { .type = NLA_U32 }, | 2875 | [IPVS_SVC_ATTR_FWMARK] = { .type = NLA_U32 }, |
2867 | [IPVS_SVC_ATTR_SCHED_NAME] = { .type = NLA_NUL_STRING, | 2876 | [IPVS_SVC_ATTR_SCHED_NAME] = { .type = NLA_NUL_STRING, |
2868 | .len = IP_VS_SCHEDNAME_MAXLEN }, | 2877 | .len = IP_VS_SCHEDNAME_MAXLEN - 1 }, |
2869 | [IPVS_SVC_ATTR_PE_NAME] = { .type = NLA_NUL_STRING, | 2878 | [IPVS_SVC_ATTR_PE_NAME] = { .type = NLA_NUL_STRING, |
2870 | .len = IP_VS_PENAME_MAXLEN }, | 2879 | .len = IP_VS_PENAME_MAXLEN }, |
2871 | [IPVS_SVC_ATTR_FLAGS] = { .type = NLA_BINARY, | 2880 | [IPVS_SVC_ATTR_FLAGS] = { .type = NLA_BINARY, |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 91e80aa852d6..501e48a7965b 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -1298,8 +1298,10 @@ static void nft_chain_stats_replace(struct nft_base_chain *chain, | |||
1298 | rcu_assign_pointer(chain->stats, newstats); | 1298 | rcu_assign_pointer(chain->stats, newstats); |
1299 | synchronize_rcu(); | 1299 | synchronize_rcu(); |
1300 | free_percpu(oldstats); | 1300 | free_percpu(oldstats); |
1301 | } else | 1301 | } else { |
1302 | rcu_assign_pointer(chain->stats, newstats); | 1302 | rcu_assign_pointer(chain->stats, newstats); |
1303 | static_branch_inc(&nft_counters_enabled); | ||
1304 | } | ||
1303 | } | 1305 | } |
1304 | 1306 | ||
1305 | static void nf_tables_chain_destroy(struct nft_ctx *ctx) | 1307 | static void nf_tables_chain_destroy(struct nft_ctx *ctx) |
@@ -4706,7 +4708,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) | |||
4706 | if (idx > s_idx) | 4708 | if (idx > s_idx) |
4707 | memset(&cb->args[1], 0, | 4709 | memset(&cb->args[1], 0, |
4708 | sizeof(cb->args) - sizeof(cb->args[0])); | 4710 | sizeof(cb->args) - sizeof(cb->args[0])); |
4709 | if (filter && filter->table[0] && | 4711 | if (filter && filter->table && |
4710 | strcmp(filter->table, table->name)) | 4712 | strcmp(filter->table, table->name)) |
4711 | goto cont; | 4713 | goto cont; |
4712 | if (filter && | 4714 | if (filter && |
@@ -5380,7 +5382,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb, | |||
5380 | if (idx > s_idx) | 5382 | if (idx > s_idx) |
5381 | memset(&cb->args[1], 0, | 5383 | memset(&cb->args[1], 0, |
5382 | sizeof(cb->args) - sizeof(cb->args[0])); | 5384 | sizeof(cb->args) - sizeof(cb->args[0])); |
5383 | if (filter && filter->table[0] && | 5385 | if (filter && filter->table && |
5384 | strcmp(filter->table, table->name)) | 5386 | strcmp(filter->table, table->name)) |
5385 | goto cont; | 5387 | goto cont; |
5386 | 5388 | ||
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 942702a2776f..40e744572283 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c | |||
@@ -126,15 +126,15 @@ static noinline void nft_update_chain_stats(const struct nft_chain *chain, | |||
126 | if (!base_chain->stats) | 126 | if (!base_chain->stats) |
127 | return; | 127 | return; |
128 | 128 | ||
129 | local_bh_disable(); | ||
129 | stats = this_cpu_ptr(rcu_dereference(base_chain->stats)); | 130 | stats = this_cpu_ptr(rcu_dereference(base_chain->stats)); |
130 | if (stats) { | 131 | if (stats) { |
131 | local_bh_disable(); | ||
132 | u64_stats_update_begin(&stats->syncp); | 132 | u64_stats_update_begin(&stats->syncp); |
133 | stats->pkts++; | 133 | stats->pkts++; |
134 | stats->bytes += pkt->skb->len; | 134 | stats->bytes += pkt->skb->len; |
135 | u64_stats_update_end(&stats->syncp); | 135 | u64_stats_update_end(&stats->syncp); |
136 | local_bh_enable(); | ||
137 | } | 136 | } |
137 | local_bh_enable(); | ||
138 | } | 138 | } |
139 | 139 | ||
140 | struct nft_jumpstack { | 140 | struct nft_jumpstack { |
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 6ddf89183e7b..a0e5adf0b3b6 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c | |||
@@ -115,7 +115,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl, | |||
115 | nfacct->flags = flags; | 115 | nfacct->flags = flags; |
116 | } | 116 | } |
117 | 117 | ||
118 | nla_strlcpy(nfacct->name, nla_data(tb[NFACCT_NAME]), NFACCT_NAME_MAX); | 118 | nla_strlcpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX); |
119 | 119 | ||
120 | if (tb[NFACCT_BYTES]) { | 120 | if (tb[NFACCT_BYTES]) { |
121 | atomic64_set(&nfacct->bytes, | 121 | atomic64_set(&nfacct->bytes, |
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index fa026b269b36..cb5b5f207777 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c | |||
@@ -150,7 +150,7 @@ nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy, | |||
150 | return -EINVAL; | 150 | return -EINVAL; |
151 | 151 | ||
152 | nla_strlcpy(expect_policy->name, | 152 | nla_strlcpy(expect_policy->name, |
153 | nla_data(tb[NFCTH_POLICY_NAME]), NF_CT_HELPER_NAME_LEN); | 153 | tb[NFCTH_POLICY_NAME], NF_CT_HELPER_NAME_LEN); |
154 | expect_policy->max_expected = | 154 | expect_policy->max_expected = |
155 | ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX])); | 155 | ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX])); |
156 | if (expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) | 156 | if (expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) |
@@ -235,7 +235,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[], | |||
235 | goto err1; | 235 | goto err1; |
236 | 236 | ||
237 | nla_strlcpy(helper->name, | 237 | nla_strlcpy(helper->name, |
238 | nla_data(tb[NFCTH_NAME]), NF_CT_HELPER_NAME_LEN); | 238 | tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN); |
239 | size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); | 239 | size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); |
240 | if (size > FIELD_SIZEOF(struct nf_conn_help, data)) { | 240 | if (size > FIELD_SIZEOF(struct nf_conn_help, data)) { |
241 | ret = -ENOMEM; | 241 | ret = -ENOMEM; |
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index ea737fd789e8..5c0de704bad5 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c | |||
@@ -880,22 +880,26 @@ static int nft_ct_helper_obj_dump(struct sk_buff *skb, | |||
880 | struct nft_object *obj, bool reset) | 880 | struct nft_object *obj, bool reset) |
881 | { | 881 | { |
882 | const struct nft_ct_helper_obj *priv = nft_obj_data(obj); | 882 | const struct nft_ct_helper_obj *priv = nft_obj_data(obj); |
883 | const struct nf_conntrack_helper *helper = priv->helper4; | 883 | const struct nf_conntrack_helper *helper; |
884 | u16 family; | 884 | u16 family; |
885 | 885 | ||
886 | if (priv->helper4 && priv->helper6) { | ||
887 | family = NFPROTO_INET; | ||
888 | helper = priv->helper4; | ||
889 | } else if (priv->helper6) { | ||
890 | family = NFPROTO_IPV6; | ||
891 | helper = priv->helper6; | ||
892 | } else { | ||
893 | family = NFPROTO_IPV4; | ||
894 | helper = priv->helper4; | ||
895 | } | ||
896 | |||
886 | if (nla_put_string(skb, NFTA_CT_HELPER_NAME, helper->name)) | 897 | if (nla_put_string(skb, NFTA_CT_HELPER_NAME, helper->name)) |
887 | return -1; | 898 | return -1; |
888 | 899 | ||
889 | if (nla_put_u8(skb, NFTA_CT_HELPER_L4PROTO, priv->l4proto)) | 900 | if (nla_put_u8(skb, NFTA_CT_HELPER_L4PROTO, priv->l4proto)) |
890 | return -1; | 901 | return -1; |
891 | 902 | ||
892 | if (priv->helper4 && priv->helper6) | ||
893 | family = NFPROTO_INET; | ||
894 | else if (priv->helper6) | ||
895 | family = NFPROTO_IPV6; | ||
896 | else | ||
897 | family = NFPROTO_IPV4; | ||
898 | |||
899 | if (nla_put_be16(skb, NFTA_CT_HELPER_L3PROTO, htons(family))) | 903 | if (nla_put_be16(skb, NFTA_CT_HELPER_L3PROTO, htons(family))) |
900 | return -1; | 904 | return -1; |
901 | 905 | ||
diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c index a9fc298ef4c3..72f13a1144dd 100644 --- a/net/netfilter/nft_limit.c +++ b/net/netfilter/nft_limit.c | |||
@@ -51,10 +51,13 @@ static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost) | |||
51 | return !limit->invert; | 51 | return !limit->invert; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* Use same default as in iptables. */ | ||
55 | #define NFT_LIMIT_PKT_BURST_DEFAULT 5 | ||
56 | |||
54 | static int nft_limit_init(struct nft_limit *limit, | 57 | static int nft_limit_init(struct nft_limit *limit, |
55 | const struct nlattr * const tb[]) | 58 | const struct nlattr * const tb[], bool pkts) |
56 | { | 59 | { |
57 | u64 unit; | 60 | u64 unit, tokens; |
58 | 61 | ||
59 | if (tb[NFTA_LIMIT_RATE] == NULL || | 62 | if (tb[NFTA_LIMIT_RATE] == NULL || |
60 | tb[NFTA_LIMIT_UNIT] == NULL) | 63 | tb[NFTA_LIMIT_UNIT] == NULL) |
@@ -68,18 +71,25 @@ static int nft_limit_init(struct nft_limit *limit, | |||
68 | 71 | ||
69 | if (tb[NFTA_LIMIT_BURST]) | 72 | if (tb[NFTA_LIMIT_BURST]) |
70 | limit->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST])); | 73 | limit->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST])); |
71 | else | 74 | |
72 | limit->burst = 0; | 75 | if (pkts && limit->burst == 0) |
76 | limit->burst = NFT_LIMIT_PKT_BURST_DEFAULT; | ||
73 | 77 | ||
74 | if (limit->rate + limit->burst < limit->rate) | 78 | if (limit->rate + limit->burst < limit->rate) |
75 | return -EOVERFLOW; | 79 | return -EOVERFLOW; |
76 | 80 | ||
77 | /* The token bucket size limits the number of tokens can be | 81 | if (pkts) { |
78 | * accumulated. tokens_max specifies the bucket size. | 82 | tokens = div_u64(limit->nsecs, limit->rate) * limit->burst; |
79 | * tokens_max = unit * (rate + burst) / rate. | 83 | } else { |
80 | */ | 84 | /* The token bucket size limits the number of tokens can be |
81 | limit->tokens = div_u64(limit->nsecs * (limit->rate + limit->burst), | 85 | * accumulated. tokens_max specifies the bucket size. |
82 | limit->rate); | 86 | * tokens_max = unit * (rate + burst) / rate. |
87 | */ | ||
88 | tokens = div_u64(limit->nsecs * (limit->rate + limit->burst), | ||
89 | limit->rate); | ||
90 | } | ||
91 | |||
92 | limit->tokens = tokens; | ||
83 | limit->tokens_max = limit->tokens; | 93 | limit->tokens_max = limit->tokens; |
84 | 94 | ||
85 | if (tb[NFTA_LIMIT_FLAGS]) { | 95 | if (tb[NFTA_LIMIT_FLAGS]) { |
@@ -144,7 +154,7 @@ static int nft_limit_pkts_init(const struct nft_ctx *ctx, | |||
144 | struct nft_limit_pkts *priv = nft_expr_priv(expr); | 154 | struct nft_limit_pkts *priv = nft_expr_priv(expr); |
145 | int err; | 155 | int err; |
146 | 156 | ||
147 | err = nft_limit_init(&priv->limit, tb); | 157 | err = nft_limit_init(&priv->limit, tb, true); |
148 | if (err < 0) | 158 | if (err < 0) |
149 | return err; | 159 | return err; |
150 | 160 | ||
@@ -185,7 +195,7 @@ static int nft_limit_bytes_init(const struct nft_ctx *ctx, | |||
185 | { | 195 | { |
186 | struct nft_limit *priv = nft_expr_priv(expr); | 196 | struct nft_limit *priv = nft_expr_priv(expr); |
187 | 197 | ||
188 | return nft_limit_init(priv, tb); | 198 | return nft_limit_init(priv, tb, false); |
189 | } | 199 | } |
190 | 200 | ||
191 | static int nft_limit_bytes_dump(struct sk_buff *skb, | 201 | static int nft_limit_bytes_dump(struct sk_buff *skb, |
@@ -246,7 +256,7 @@ static int nft_limit_obj_pkts_init(const struct nft_ctx *ctx, | |||
246 | struct nft_limit_pkts *priv = nft_obj_data(obj); | 256 | struct nft_limit_pkts *priv = nft_obj_data(obj); |
247 | int err; | 257 | int err; |
248 | 258 | ||
249 | err = nft_limit_init(&priv->limit, tb); | 259 | err = nft_limit_init(&priv->limit, tb, true); |
250 | if (err < 0) | 260 | if (err < 0) |
251 | return err; | 261 | return err; |
252 | 262 | ||
@@ -289,7 +299,7 @@ static int nft_limit_obj_bytes_init(const struct nft_ctx *ctx, | |||
289 | { | 299 | { |
290 | struct nft_limit *priv = nft_obj_data(obj); | 300 | struct nft_limit *priv = nft_obj_data(obj); |
291 | 301 | ||
292 | return nft_limit_init(priv, tb); | 302 | return nft_limit_init(priv, tb, false); |
293 | } | 303 | } |
294 | 304 | ||
295 | static int nft_limit_obj_bytes_dump(struct sk_buff *skb, | 305 | static int nft_limit_obj_bytes_dump(struct sk_buff *skb, |
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 8fb91940e2e7..204af9899482 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c | |||
@@ -234,7 +234,7 @@ void nft_meta_set_eval(const struct nft_expr *expr, | |||
234 | struct sk_buff *skb = pkt->skb; | 234 | struct sk_buff *skb = pkt->skb; |
235 | u32 *sreg = ®s->data[meta->sreg]; | 235 | u32 *sreg = ®s->data[meta->sreg]; |
236 | u32 value = *sreg; | 236 | u32 value = *sreg; |
237 | u8 pkt_type; | 237 | u8 value8; |
238 | 238 | ||
239 | switch (meta->key) { | 239 | switch (meta->key) { |
240 | case NFT_META_MARK: | 240 | case NFT_META_MARK: |
@@ -244,15 +244,17 @@ void nft_meta_set_eval(const struct nft_expr *expr, | |||
244 | skb->priority = value; | 244 | skb->priority = value; |
245 | break; | 245 | break; |
246 | case NFT_META_PKTTYPE: | 246 | case NFT_META_PKTTYPE: |
247 | pkt_type = nft_reg_load8(sreg); | 247 | value8 = nft_reg_load8(sreg); |
248 | 248 | ||
249 | if (skb->pkt_type != pkt_type && | 249 | if (skb->pkt_type != value8 && |
250 | skb_pkt_type_ok(pkt_type) && | 250 | skb_pkt_type_ok(value8) && |
251 | skb_pkt_type_ok(skb->pkt_type)) | 251 | skb_pkt_type_ok(skb->pkt_type)) |
252 | skb->pkt_type = pkt_type; | 252 | skb->pkt_type = value8; |
253 | break; | 253 | break; |
254 | case NFT_META_NFTRACE: | 254 | case NFT_META_NFTRACE: |
255 | skb->nf_trace = !!value; | 255 | value8 = nft_reg_load8(sreg); |
256 | |||
257 | skb->nf_trace = !!value8; | ||
256 | break; | 258 | break; |
257 | default: | 259 | default: |
258 | WARN_ON(1); | 260 | WARN_ON(1); |
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index d964e60c730e..c79f6e71512e 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c | |||
@@ -977,7 +977,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, | |||
977 | return 0; | 977 | return 0; |
978 | 978 | ||
979 | errout_idr: | 979 | errout_idr: |
980 | if (fnew->handle) | 980 | if (!fold) |
981 | idr_remove(&head->handle_idr, fnew->handle); | 981 | idr_remove(&head->handle_idr, fnew->handle); |
982 | errout: | 982 | errout: |
983 | tcf_exts_destroy(&fnew->exts); | 983 | tcf_exts_destroy(&fnew->exts); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 40b54cc64243..5f48251c1319 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1658,7 +1658,6 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
1658 | trailer_len -= xdst_prev->u.dst.xfrm->props.trailer_len; | 1658 | trailer_len -= xdst_prev->u.dst.xfrm->props.trailer_len; |
1659 | } | 1659 | } |
1660 | 1660 | ||
1661 | out: | ||
1662 | return &xdst0->u.dst; | 1661 | return &xdst0->u.dst; |
1663 | 1662 | ||
1664 | put_states: | 1663 | put_states: |
@@ -1667,8 +1666,8 @@ put_states: | |||
1667 | free_dst: | 1666 | free_dst: |
1668 | if (xdst0) | 1667 | if (xdst0) |
1669 | dst_release_immediate(&xdst0->u.dst); | 1668 | dst_release_immediate(&xdst0->u.dst); |
1670 | xdst0 = ERR_PTR(err); | 1669 | |
1671 | goto out; | 1670 | return ERR_PTR(err); |
1672 | } | 1671 | } |
1673 | 1672 | ||
1674 | static int xfrm_expand_policies(const struct flowi *fl, u16 family, | 1673 | static int xfrm_expand_policies(const struct flowi *fl, u16 family, |