Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a46ff87 authored by David S. Miller's avatar David S. Miller
Browse files


Pablo Neira Ayuso says:

====================
The following patchset contains three Netfilter fixes for your net tree,
they are:

* fix incorrect comparison in the new netnet hash ipset type, from
  Dave Jones.

* fix splat in hashlimit due to missing removal of the content of its
  proc entry in netnamespaces, from Sergey Popovich.

* fix missing rule flushing operation by table in nf_tables. Table
  flushing was already discussed back in October but this got lost and
  no patch has hit the tree to address this issue so far, from me.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 66e56cd4 cf9dc09d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ hash_netnet4_data_equal(const struct hash_netnet4_elem *ip1,
		     u32 *multi)
{
	return ip1->ipcmp == ip2->ipcmp &&
	       ip2->ccmp == ip2->ccmp;
	       ip1->ccmp == ip2->ccmp;
}

static inline int
+33 −13
Original line number Diff line number Diff line
@@ -1717,6 +1717,19 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
	return -ENOENT;
}

static int nf_table_delrule_by_chain(struct nft_ctx *ctx)
{
	struct nft_rule *rule;
	int err;

	list_for_each_entry(rule, &ctx->chain->rules, list) {
		err = nf_tables_delrule_one(ctx, rule);
		if (err < 0)
			return err;
	}
	return 0;
}

static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
			     const struct nlmsghdr *nlh,
			     const struct nlattr * const nla[])
@@ -1725,8 +1738,8 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
	const struct nft_af_info *afi;
	struct net *net = sock_net(skb->sk);
	const struct nft_table *table;
	struct nft_chain *chain;
	struct nft_rule *rule, *tmp;
	struct nft_chain *chain = NULL;
	struct nft_rule *rule;
	int family = nfmsg->nfgen_family, err = 0;
	struct nft_ctx ctx;

@@ -1738,22 +1751,29 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
	if (IS_ERR(table))
		return PTR_ERR(table);

	if (nla[NFTA_RULE_CHAIN]) {
		chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
		if (IS_ERR(chain))
			return PTR_ERR(chain);
	}

	nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);

	if (chain) {
		if (nla[NFTA_RULE_HANDLE]) {
		rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
			rule = nf_tables_rule_lookup(chain,
						     nla[NFTA_RULE_HANDLE]);
			if (IS_ERR(rule))
				return PTR_ERR(rule);

			err = nf_tables_delrule_one(&ctx, rule);
		} else {
		/* Remove all rules in this chain */
		list_for_each_entry_safe(rule, tmp, &chain->rules, list) {
			err = nf_tables_delrule_one(&ctx, rule);
			err = nf_table_delrule_by_chain(&ctx);
		}
	} else {
		list_for_each_entry(chain, &table->chains, list) {
			ctx.chain = chain;
			err = nf_table_delrule_by_chain(&ctx);
			if (err < 0)
				break;
		}
+11 −14
Original line number Diff line number Diff line
@@ -325,13 +325,11 @@ static void htable_gc(unsigned long htlong)
	add_timer(&ht->timer);
}

static void htable_destroy(struct xt_hashlimit_htable *hinfo)
static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo)
{
	struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net);
	struct proc_dir_entry *parent;

	del_timer_sync(&hinfo->timer);

	if (hinfo->family == NFPROTO_IPV4)
		parent = hashlimit_net->ipt_hashlimit;
	else
@@ -339,7 +337,12 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)

	if (parent != NULL)
		remove_proc_entry(hinfo->name, parent);
}

static void htable_destroy(struct xt_hashlimit_htable *hinfo)
{
	del_timer_sync(&hinfo->timer);
	htable_remove_proc_entry(hinfo);
	htable_selective_cleanup(hinfo, select_all);
	kfree(hinfo->name);
	vfree(hinfo);
@@ -883,21 +886,15 @@ static int __net_init hashlimit_proc_net_init(struct net *net)
static void __net_exit hashlimit_proc_net_exit(struct net *net)
{
	struct xt_hashlimit_htable *hinfo;
	struct proc_dir_entry *pde;
	struct hashlimit_net *hashlimit_net = hashlimit_pernet(net);

	/* recent_net_exit() is called before recent_mt_destroy(). Make sure
	 * that the parent xt_recent proc entry is is empty before trying to
	 * remove it.
	/* hashlimit_net_exit() is called before hashlimit_mt_destroy().
	 * Make sure that the parent ipt_hashlimit and ip6t_hashlimit proc
	 * entries is empty before trying to remove it.
	 */
	mutex_lock(&hashlimit_mutex);
	pde = hashlimit_net->ipt_hashlimit;
	if (pde == NULL)
		pde = hashlimit_net->ip6t_hashlimit;

	hlist_for_each_entry(hinfo, &hashlimit_net->htables, node)
		remove_proc_entry(hinfo->name, pde);

		htable_remove_proc_entry(hinfo);
	hashlimit_net->ipt_hashlimit = NULL;
	hashlimit_net->ip6t_hashlimit = NULL;
	mutex_unlock(&hashlimit_mutex);