summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-07-31 11:49:09 -0400
committerDavid S. Miller <davem@davemloft.net>2019-07-31 11:49:09 -0400
commitfa9586aff919a93761a76feb69718b54d49fdd8e (patch)
tree1bcc1afd7642464740c1f7486eaf22f0c09977a6
parent246902bdf562d45ea3475fac64c93048a7a39f01 (diff)
parent7cdc4412284777c76c919e2ab33b3b8dbed18559 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== netfilter fixes for net The following patchset contains Netfilter fixes for your net tree: 1) memleak in ebtables from the error path for the 32/64 compat layer, from Florian Westphal. 2) Fix inverted meta ifname/ifidx matching when no interface is set on either from the input/output path, from Phil Sutter. 3) Remove goto label in nft_meta_bridge, also from Phil. 4) Missing include guard in xt_connlabel, from Masahiro Yamada. 5) Two patch to fix ipset destination MAC matching coming from Stephano Brivio, via Jozsef Kadlecsik. 6) Fix set rename and listing concurrency problem, from Shijie Luo. Patch also coming via Jozsef Kadlecsik. 7) ebtables 32/64 compat missing base chain policy in rule count, from Florian Westphal. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/netfilter/xt_connlabel.h6
-rw-r--r--net/bridge/netfilter/ebtables.c32
-rw-r--r--net/bridge/netfilter/nft_meta_bridge.c10
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ipmac.c2
-rw-r--r--net/netfilter/ipset/ip_set_core.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipmac.c6
-rw-r--r--net/netfilter/nft_meta.c16
7 files changed, 35 insertions, 39 deletions
diff --git a/include/uapi/linux/netfilter/xt_connlabel.h b/include/uapi/linux/netfilter/xt_connlabel.h
index 2312f0ec07b2..323f0dfc2a4e 100644
--- a/include/uapi/linux/netfilter/xt_connlabel.h
+++ b/include/uapi/linux/netfilter/xt_connlabel.h
@@ -1,4 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2
3#ifndef _UAPI_XT_CONNLABEL_H
4#define _UAPI_XT_CONNLABEL_H
5
2#include <linux/types.h> 6#include <linux/types.h>
3 7
4#define XT_CONNLABEL_MAXBIT 127 8#define XT_CONNLABEL_MAXBIT 127
@@ -11,3 +15,5 @@ struct xt_connlabel_mtinfo {
11 __u16 bit; 15 __u16 bit;
12 __u16 options; 16 __u16 options;
13}; 17};
18
19#endif /* _UAPI_XT_CONNLABEL_H */
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 963dfdc14827..c8177a89f52c 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1770,20 +1770,28 @@ static int compat_calc_entry(const struct ebt_entry *e,
1770 return 0; 1770 return 0;
1771} 1771}
1772 1772
1773static int ebt_compat_init_offsets(unsigned int number)
1774{
1775 if (number > INT_MAX)
1776 return -EINVAL;
1777
1778 /* also count the base chain policies */
1779 number += NF_BR_NUMHOOKS;
1780
1781 return xt_compat_init_offsets(NFPROTO_BRIDGE, number);
1782}
1773 1783
1774static int compat_table_info(const struct ebt_table_info *info, 1784static int compat_table_info(const struct ebt_table_info *info,
1775 struct compat_ebt_replace *newinfo) 1785 struct compat_ebt_replace *newinfo)
1776{ 1786{
1777 unsigned int size = info->entries_size; 1787 unsigned int size = info->entries_size;
1778 const void *entries = info->entries; 1788 const void *entries = info->entries;
1789 int ret;
1779 1790
1780 newinfo->entries_size = size; 1791 newinfo->entries_size = size;
1781 if (info->nentries) { 1792 ret = ebt_compat_init_offsets(info->nentries);
1782 int ret = xt_compat_init_offsets(NFPROTO_BRIDGE, 1793 if (ret)
1783 info->nentries); 1794 return ret;
1784 if (ret)
1785 return ret;
1786 }
1787 1795
1788 return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info, 1796 return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info,
1789 entries, newinfo); 1797 entries, newinfo);
@@ -2234,11 +2242,9 @@ static int compat_do_replace(struct net *net, void __user *user,
2234 2242
2235 xt_compat_lock(NFPROTO_BRIDGE); 2243 xt_compat_lock(NFPROTO_BRIDGE);
2236 2244
2237 if (tmp.nentries) { 2245 ret = ebt_compat_init_offsets(tmp.nentries);
2238 ret = xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries); 2246 if (ret < 0)
2239 if (ret < 0) 2247 goto out_unlock;
2240 goto out_unlock;
2241 }
2242 2248
2243 ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state); 2249 ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state);
2244 if (ret < 0) 2250 if (ret < 0)
@@ -2261,8 +2267,10 @@ static int compat_do_replace(struct net *net, void __user *user,
2261 state.buf_kern_len = size64; 2267 state.buf_kern_len = size64;
2262 2268
2263 ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state); 2269 ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state);
2264 if (WARN_ON(ret < 0)) 2270 if (WARN_ON(ret < 0)) {
2271 vfree(entries_tmp);
2265 goto out_unlock; 2272 goto out_unlock;
2273 }
2266 2274
2267 vfree(entries_tmp); 2275 vfree(entries_tmp);
2268 tmp.entries_size = size64; 2276 tmp.entries_size = size64;
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index bed66f536b34..1804e867f715 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -30,13 +30,9 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
30 switch (priv->key) { 30 switch (priv->key) {
31 case NFT_META_BRI_IIFNAME: 31 case NFT_META_BRI_IIFNAME:
32 br_dev = nft_meta_get_bridge(in); 32 br_dev = nft_meta_get_bridge(in);
33 if (!br_dev)
34 goto err;
35 break; 33 break;
36 case NFT_META_BRI_OIFNAME: 34 case NFT_META_BRI_OIFNAME:
37 br_dev = nft_meta_get_bridge(out); 35 br_dev = nft_meta_get_bridge(out);
38 if (!br_dev)
39 goto err;
40 break; 36 break;
41 case NFT_META_BRI_IIFPVID: { 37 case NFT_META_BRI_IIFPVID: {
42 u16 p_pvid; 38 u16 p_pvid;
@@ -61,13 +57,11 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
61 return; 57 return;
62 } 58 }
63 default: 59 default:
64 goto out; 60 return nft_meta_get_eval(expr, regs, pkt);
65 } 61 }
66 62
67 strncpy((char *)dest, br_dev->name, IFNAMSIZ); 63 strncpy((char *)dest, br_dev ? br_dev->name : "", IFNAMSIZ);
68 return; 64 return;
69out:
70 return nft_meta_get_eval(expr, regs, pkt);
71err: 65err:
72 regs->verdict.code = NFT_BREAK; 66 regs->verdict.code = NFT_BREAK;
73} 67}
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index ca7ac4a25ada..1d4e63326e68 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -226,7 +226,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
226 226
227 e.id = ip_to_id(map, ip); 227 e.id = ip_to_id(map, ip);
228 228
229 if (opt->flags & IPSET_DIM_ONE_SRC) 229 if (opt->flags & IPSET_DIM_TWO_SRC)
230 ether_addr_copy(e.ether, eth_hdr(skb)->h_source); 230 ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
231 else 231 else
232 ether_addr_copy(e.ether, eth_hdr(skb)->h_dest); 232 ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 2e151856ad99..e64d5f9a89dd 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1161,7 +1161,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl,
1161 return -ENOENT; 1161 return -ENOENT;
1162 1162
1163 write_lock_bh(&ip_set_ref_lock); 1163 write_lock_bh(&ip_set_ref_lock);
1164 if (set->ref != 0) { 1164 if (set->ref != 0 || set->ref_netlink != 0) {
1165 ret = -IPSET_ERR_REFERENCED; 1165 ret = -IPSET_ERR_REFERENCED;
1166 goto out; 1166 goto out;
1167 } 1167 }
diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
index faf59b6a998f..24d8f4df4230 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
@@ -89,15 +89,11 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
89 struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } }; 89 struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
90 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); 90 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
91 91
92 /* MAC can be src only */
93 if (!(opt->flags & IPSET_DIM_TWO_SRC))
94 return 0;
95
96 if (skb_mac_header(skb) < skb->head || 92 if (skb_mac_header(skb) < skb->head ||
97 (skb_mac_header(skb) + ETH_HLEN) > skb->data) 93 (skb_mac_header(skb) + ETH_HLEN) > skb->data)
98 return -EINVAL; 94 return -EINVAL;
99 95
100 if (opt->flags & IPSET_DIM_ONE_SRC) 96 if (opt->flags & IPSET_DIM_TWO_SRC)
101 ether_addr_copy(e.ether, eth_hdr(skb)->h_source); 97 ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
102 else 98 else
103 ether_addr_copy(e.ether, eth_hdr(skb)->h_dest); 99 ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index f1b1d948c07b..f69afb9ff3cb 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -60,24 +60,16 @@ void nft_meta_get_eval(const struct nft_expr *expr,
60 *dest = skb->mark; 60 *dest = skb->mark;
61 break; 61 break;
62 case NFT_META_IIF: 62 case NFT_META_IIF:
63 if (in == NULL) 63 *dest = in ? in->ifindex : 0;
64 goto err;
65 *dest = in->ifindex;
66 break; 64 break;
67 case NFT_META_OIF: 65 case NFT_META_OIF:
68 if (out == NULL) 66 *dest = out ? out->ifindex : 0;
69 goto err;
70 *dest = out->ifindex;
71 break; 67 break;
72 case NFT_META_IIFNAME: 68 case NFT_META_IIFNAME:
73 if (in == NULL) 69 strncpy((char *)dest, in ? in->name : "", IFNAMSIZ);
74 goto err;
75 strncpy((char *)dest, in->name, IFNAMSIZ);
76 break; 70 break;
77 case NFT_META_OIFNAME: 71 case NFT_META_OIFNAME:
78 if (out == NULL) 72 strncpy((char *)dest, out ? out->name : "", IFNAMSIZ);
79 goto err;
80 strncpy((char *)dest, out->name, IFNAMSIZ);
81 break; 73 break;
82 case NFT_META_IIFTYPE: 74 case NFT_META_IIFTYPE:
83 if (in == NULL) 75 if (in == NULL)