Commit b1185090 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: remove nf_conntrack_helper sysctl and modparam toggles



__nf_ct_try_assign_helper() remains in place but it now requires a
template to configure the helper.

A toggle to disable automatic helper assignment was added by:

  a9006892 ("netfilter: nf_ct_helper: allow to disable automatic helper assignment")

in 2012 to address the issues described in "Secure use of iptables and
connection tracking helpers". Automatic conntrack helper assignment was
disabled by:

  3bb398d9 ("netfilter: nf_ct_helper: disable automatic helper assignment")

back in 2016.

This patch removes the sysctl and modparam toggles, users now have to
rely on explicit conntrack helper configuration via ruleset.

Update tools/testing/selftests/netfilter/nft_conntrack_helper.sh to
check that auto-assignment does not happen anymore.

Acked-by: default avatarAaron Conole <aconole@redhat.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 13a9d08c
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -53,8 +53,6 @@ struct nf_conntrack_net {
	/* only used when new connection is allocated: */
	atomic_t count;
	unsigned int expect_count;
	u8 sysctl_auto_assign_helper;
	bool auto_assign_helper_warned;

	/* only used from work queues, configuration plane, and so on: */
	unsigned int users4;
+0 −1
Original line number Diff line number Diff line
@@ -101,7 +101,6 @@ struct netns_ct {
	u8			sysctl_log_invalid; /* Log invalid packets */
	u8			sysctl_events;
	u8			sysctl_acct;
	u8			sysctl_auto_assign_helper;
	u8			sysctl_tstamp;
	u8			sysctl_checksum;

+1 −6
Original line number Diff line number Diff line
@@ -1782,7 +1782,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
		}
		spin_unlock_bh(&nf_conntrack_expect_lock);
	}
	if (!exp)
	if (!exp && tmpl)
		__nf_ct_try_assign_helper(ct, tmpl, GFP_ATOMIC);

	/* Other CPU might have obtained a pointer to this object before it was
@@ -2068,10 +2068,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
	ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
	if (ct->master || (help && !hlist_empty(&help->expectations)))
		return;

	rcu_read_lock();
	__nf_ct_try_assign_helper(ct, NULL, GFP_ATOMIC);
	rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);

@@ -2797,7 +2793,6 @@ int nf_conntrack_init_net(struct net *net)
	nf_conntrack_acct_pernet_init(net);
	nf_conntrack_tstamp_pernet_init(net);
	nf_conntrack_ecache_pernet_init(net);
	nf_conntrack_helper_pernet_init(net);
	nf_conntrack_proto_pernet_init(net);

	return 0;
+10 −70
Original line number Diff line number Diff line
@@ -35,11 +35,6 @@ unsigned int nf_ct_helper_hsize __read_mostly;
EXPORT_SYMBOL_GPL(nf_ct_helper_hsize);
static unsigned int nf_ct_helper_count __read_mostly;

static bool nf_ct_auto_assign_helper __read_mostly = false;
module_param_named(nf_conntrack_helper, nf_ct_auto_assign_helper, bool, 0644);
MODULE_PARM_DESC(nf_conntrack_helper,
		 "Enable automatic conntrack helper assignment (default 0)");

static DEFINE_MUTEX(nf_ct_nat_helpers_mutex);
static struct list_head nf_ct_nat_helpers __read_mostly;

@@ -51,24 +46,6 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
		(__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
}

static struct nf_conntrack_helper *
__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
{
	struct nf_conntrack_helper *helper;
	struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
	unsigned int h;

	if (!nf_ct_helper_count)
		return NULL;

	h = helper_hash(tuple);
	hlist_for_each_entry_rcu(helper, &nf_ct_helper_hash[h], hnode) {
		if (nf_ct_tuple_src_mask_cmp(tuple, &helper->tuple, &mask))
			return helper;
	}
	return NULL;
}

struct nf_conntrack_helper *
__nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum)
{
@@ -209,33 +186,11 @@ nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
}
EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);

static struct nf_conntrack_helper *
nf_ct_lookup_helper(struct nf_conn *ct, struct net *net)
{
	struct nf_conntrack_net *cnet = nf_ct_pernet(net);

	if (!cnet->sysctl_auto_assign_helper) {
		if (cnet->auto_assign_helper_warned)
			return NULL;
		if (!__nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple))
			return NULL;
		pr_info("nf_conntrack: default automatic helper assignment "
			"has been turned off for security reasons and CT-based "
			"firewall rule not found. Use the iptables CT target "
			"to attach helpers instead.\n");
		cnet->auto_assign_helper_warned = true;
		return NULL;
	}

	return __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
}

int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
			      gfp_t flags)
{
	struct nf_conntrack_helper *helper = NULL;
	struct nf_conn_help *help;
	struct net *net = nf_ct_net(ct);

	/* We already got a helper explicitly attached. The function
	 * nf_conntrack_alter_reply - in case NAT is in use - asks for looking
@@ -246,24 +201,22 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
	if (test_bit(IPS_HELPER_BIT, &ct->status))
		return 0;

	if (tmpl != NULL) {
	if (WARN_ON_ONCE(!tmpl))
		return 0;

	help = nfct_help(tmpl);
	if (help != NULL) {
		helper = rcu_dereference(help->helper);
		set_bit(IPS_HELPER_BIT, &ct->status);
	}
	}

	help = nfct_help(ct);

	if (helper == NULL) {
		helper = nf_ct_lookup_helper(ct, net);
	if (helper == NULL) {
		if (help)
			RCU_INIT_POINTER(help->helper, NULL);
		return 0;
	}
	}

	if (help == NULL) {
		help = nf_ct_helper_ext_add(ct, flags);
@@ -545,19 +498,6 @@ void nf_nat_helper_unregister(struct nf_conntrack_nat_helper *nat)
}
EXPORT_SYMBOL_GPL(nf_nat_helper_unregister);

void nf_ct_set_auto_assign_helper_warned(struct net *net)
{
	nf_ct_pernet(net)->auto_assign_helper_warned = true;
}
EXPORT_SYMBOL_GPL(nf_ct_set_auto_assign_helper_warned);

void nf_conntrack_helper_pernet_init(struct net *net)
{
	struct nf_conntrack_net *cnet = nf_ct_pernet(net);

	cnet->sysctl_auto_assign_helper = nf_ct_auto_assign_helper;
}

int nf_conntrack_helper_init(void)
{
	nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
+0 −5
Original line number Diff line number Diff line
@@ -2298,11 +2298,6 @@ ctnetlink_create_conntrack(struct net *net,
			ct->status |= IPS_HELPER;
			RCU_INIT_POINTER(help->helper, helper);
		}
	} else {
		/* try an implicit helper assignation */
		err = __nf_ct_try_assign_helper(ct, NULL, GFP_ATOMIC);
		if (err < 0)
			goto err2;
	}

	err = ctnetlink_setup_nat(ct, cda);
Loading