Commit 3a3ec1b2 authored by David S. Miller's avatar David S. Miller
Browse files


Pablo Neira Ayuso says:

====================
netfilter fixes for net

The following patchset contains netfilter updates for your net tree,
they are:

1) Fix refcount leak when dumping the dying/unconfirmed conntrack lists,
   from Florian Westphal.

2) Fix crash in NAT when removing a netnamespace, also from Florian.

3) Fix a crash in IPVS when trying to remove an estimator out of the
   sysctl scope, from Julian Anastasov.

4) Add zone attribute to the routing to calculate the message size in
   ctnetlink events, from Ken-ichirou MATSUZAWA.

5) Another fix for the dying/unconfirmed list which was preventing to
   dump more than one memory page of entries (~17 entries in x86_64).

6) Fix missing RCU-safe list insertion in the rule replacement code
   in nf_tables.

7) Since the new transaction infrastructure is in place, we have to
   upgrade the chain use counter from u16 to u32 to avoid overflow
   after more than 2^16 rules are added.

8) Fix refcount leak when replacing rule in nf_tables. This problem
   was also introduced in new transaction.

9) Call the ->destroy() callback when releasing nft-xt rules to fix
   module refcount leaks.

10) Set the family in the netlink messages that contain set elements
    in nf_tables to make it consistent with other object types.

11) Don't dump NAT port information if it is unset in nft_nat.

12) Update the MAINTAINERS file, I have merged the ebtables entry
    into netfilter. While at it, also removed the netfilter users
    mailing list, the development list should be enough.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 62a02c98 db9cf3a3
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -3189,14 +3189,6 @@ L: linux-scsi@vger.kernel.org
S:	Maintained
F:	drivers/scsi/eata_pio.*

EBTABLES
L:	netfilter-devel@vger.kernel.org
W:	http://ebtables.sourceforge.net/
S:	Orphan
F:	include/linux/netfilter_bridge/ebt_*.h
F:	include/uapi/linux/netfilter_bridge/ebt_*.h
F:	net/bridge/netfilter/ebt*.c

EC100 MEDIA DRIVER
M:	Antti Palosaari <crope@iki.fi>
L:	linux-media@vger.kernel.org
@@ -6105,12 +6097,11 @@ F: Documentation/networking/s2io.txt
F:	Documentation/networking/vxge.txt
F:	drivers/net/ethernet/neterion/

NETFILTER/IPTABLES
NETFILTER ({IP,IP6,ARP,EB,NF}TABLES)
M:	Pablo Neira Ayuso <pablo@netfilter.org>
M:	Patrick McHardy <kaber@trash.net>
M:	Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
L:	netfilter-devel@vger.kernel.org
L:	netfilter@vger.kernel.org
L:	coreteam@netfilter.org
W:	http://www.netfilter.org/
W:	http://www.iptables.org/
+3 −3
Original line number Diff line number Diff line
@@ -503,9 +503,9 @@ enum nft_chain_flags {
 *	@net: net namespace that this chain belongs to
 *	@table: table that this chain belongs to
 *	@handle: chain handle
 *	@flags: bitmask of enum nft_chain_flags
 *	@use: number of jump references to this chain
 *	@level: length of longest path to this chain
 *	@flags: bitmask of enum nft_chain_flags
 *	@name: name of the chain
 */
struct nft_chain {
@@ -514,9 +514,9 @@ struct nft_chain {
	struct net			*net;
	struct nft_table		*table;
	u64				handle;
	u8				flags;
	u16				use;
	u32				use;
	u16				level;
	u8				flags;
	char				name[NFT_CHAIN_MAXNAMELEN];
};

+1 −1
Original line number Diff line number Diff line
@@ -3778,6 +3778,7 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
	cancel_delayed_work_sync(&ipvs->defense_work);
	cancel_work_sync(&ipvs->defense_work.work);
	unregister_net_sysctl_table(ipvs->sysctl_hdr);
	ip_vs_stop_estimator(net, &ipvs->tot_stats);
}

#else
@@ -3840,7 +3841,6 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
	struct netns_ipvs *ipvs = net_ipvs(net);

	ip_vs_trash_cleanup(net);
	ip_vs_stop_estimator(net, &ipvs->tot_stats);
	ip_vs_control_net_cleanup_sysctl(net);
	remove_proc_entry("ip_vs_stats_percpu", net->proc_net);
	remove_proc_entry("ip_vs_stats", net->proc_net);
+13 −7
Original line number Diff line number Diff line
@@ -596,6 +596,9 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct)
#endif
#ifdef CONFIG_NF_CONNTRACK_MARK
	       + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
#endif
#ifdef CONFIG_NF_CONNTRACK_ZONES
	       + nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
#endif
	       + ctnetlink_proto_size(ct)
	       + ctnetlink_label_size(ct)
@@ -1150,7 +1153,7 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
static int
ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
{
	struct nf_conn *ct, *last = NULL;
	struct nf_conn *ct, *last;
	struct nf_conntrack_tuple_hash *h;
	struct hlist_nulls_node *n;
	struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
@@ -1163,8 +1166,7 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
	if (cb->args[2])
		return 0;

	if (cb->args[0] == nr_cpu_ids)
		return 0;
	last = (struct nf_conn *)cb->args[1];

	for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
		struct ct_pcpu *pcpu;
@@ -1174,7 +1176,6 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying

		pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
		spin_lock_bh(&pcpu->lock);
		last = (struct nf_conn *)cb->args[1];
		list = dying ? &pcpu->dying : &pcpu->unconfirmed;
restart:
		hlist_nulls_for_each_entry(h, n, list, hnnode) {
@@ -1193,7 +1194,9 @@ restart:
						  ct);
			rcu_read_unlock();
			if (res < 0) {
				nf_conntrack_get(&ct->ct_general);
				if (!atomic_inc_not_zero(&ct->ct_general.use))
					continue;
				cb->args[0] = cpu;
				cb->args[1] = (unsigned long)ct;
				spin_unlock_bh(&pcpu->lock);
				goto out;
@@ -1202,10 +1205,10 @@ restart:
		if (cb->args[1]) {
			cb->args[1] = 0;
			goto restart;
		} else
			cb->args[2] = 1;
		}
		spin_unlock_bh(&pcpu->lock);
	}
	cb->args[2] = 1;
out:
	if (last)
		nf_ct_put(last);
@@ -2039,6 +2042,9 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
#endif
#ifdef CONFIG_NF_CONNTRACK_MARK
	       + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
#endif
#ifdef CONFIG_NF_CONNTRACK_ZONES
	       + nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
#endif
	       + ctnetlink_proto_size(ct)
	       ;
+34 −1
Original line number Diff line number Diff line
@@ -525,6 +525,39 @@ static int nf_nat_proto_remove(struct nf_conn *i, void *data)
	return i->status & IPS_NAT_MASK ? 1 : 0;
}

static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
{
	struct nf_conn_nat *nat = nfct_nat(ct);

	if (nf_nat_proto_remove(ct, data))
		return 1;

	if (!nat || !nat->ct)
		return 0;

	/* This netns is being destroyed, and conntrack has nat null binding.
	 * Remove it from bysource hash, as the table will be freed soon.
	 *
	 * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack()
	 * will delete entry from already-freed table.
	 */
	if (!del_timer(&ct->timeout))
		return 1;

	spin_lock_bh(&nf_nat_lock);
	hlist_del_rcu(&nat->bysource);
	ct->status &= ~IPS_NAT_DONE_MASK;
	nat->ct = NULL;
	spin_unlock_bh(&nf_nat_lock);

	add_timer(&ct->timeout);

	/* don't delete conntrack.  Although that would make things a lot
	 * simpler, we'd end up flushing all conntracks on nat rmmod.
	 */
	return 0;
}

static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
{
	struct nf_nat_proto_clean clean = {
@@ -795,7 +828,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
{
	struct nf_nat_proto_clean clean = {};

	nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean, 0, 0);
	nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean, 0, 0);
	synchronize_rcu();
	nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
}
Loading