netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Phil Sutter <phil@nwl.cc>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [iptables PATCH] xshared: Fix response to unprivileged users
Date: Thu, 27 Jan 2022 17:28:39 +0100	[thread overview]
Message-ID: <YfLINxzIDlCwej1X@salvia> (raw)
In-Reply-To: <20220120101653.28280-1-phil@nwl.cc>

[-- Attachment #1: Type: text/plain, Size: 1068 bytes --]

Hi Phil,

On Thu, Jan 20, 2022 at 11:16:53AM +0100, Phil Sutter wrote:
> Expected behaviour in both variants is:
> 
> * Print help without error, append extension help if -m and/or -j
>   options are present
> * Indicate lack of permissions in an error message for anything else
> 
> With iptables-nft, this was broken basically from day 1. Shared use of
> do_parse() then somewhat broke legacy: it started complaining about
> inability to create a lock file.
> 
> Fix this by making iptables-nft assume extension revision 0 is present
> if permissions don't allow to verify. This is consistent with legacy.
> 
> Second part is to exit directly after printing help - this avoids having
> to make the following code "nop-aware" to prevent privileged actions.

On top of this patch, it should be possible to allow for some
nfnetlink command to be used from unpriviledged process.

I'm attaching a sketch patch, it skips module autoload which is should
not be triggered by an unpriviledged process.

This should allow for better help with -m/-j if the module is present.

[-- Attachment #2: x.patch --]
[-- Type: text/x-diff, Size: 3313 bytes --]

diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 241e005f290a..1e10bf19af93 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -28,6 +28,7 @@ struct nfnl_callback {
 	const struct nla_policy	*policy;
 	enum nfnl_callback_type	type;
 	__u16			attr_count;
+	bool			unpriviledged;
 };
 
 enum nfnl_abort_action {
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 7e2c8dd01408..0f450c8a43ac 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -211,21 +211,24 @@ EXPORT_SYMBOL_GPL(nfnetlink_broadcast);
 static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 			     struct netlink_ext_ack *extack)
 {
+	const struct nfnetlink_subsystem *ss;
 	struct net *net = sock_net(skb->sk);
 	const struct nfnl_callback *nc;
-	const struct nfnetlink_subsystem *ss;
+	bool cap_net_admin;
 	int type, err;
 
 	/* All the messages must at least contain nfgenmsg */
 	if (nlmsg_len(nlh) < sizeof(struct nfgenmsg))
 		return 0;
 
+	cap_net_admin = netlink_net_capable(skb, CAP_NET_ADMIN);
+
 	type = nlh->nlmsg_type;
 replay:
 	rcu_read_lock();
 
 	ss = nfnetlink_get_subsys(type);
-	if (!ss) {
+	if (!ss && cap_net_admin) {
 #ifdef CONFIG_MODULES
 		rcu_read_unlock();
 		request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
@@ -245,6 +248,11 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return -EINVAL;
 	}
 
+	if (cap_net_admin && !nc->unpriviledged) {
+		rcu_read_unlock();
+		return -EPERM;
+	}
+
 	{
 		int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
 		struct nfnl_net *nfnlnet = nfnl_pernet(net);
@@ -607,6 +615,11 @@ static void nfnetlink_rcv_skb_batch(struct sk_buff *skb, struct nlmsghdr *nlh)
 	u32 gen_id = 0;
 	u16 res_id;
 
+	if (!netlink_net_capable(skb, CAP_NET_ADMIN)) {
+		netlink_ack(skb, nlh, -EPERM, NULL);
+		return;
+	}
+
 	msglen = NLMSG_ALIGN(nlh->nlmsg_len);
 	if (msglen > skb->len)
 		msglen = skb->len;
@@ -643,11 +656,6 @@ static void nfnetlink_rcv(struct sk_buff *skb)
 	    skb->len < nlh->nlmsg_len)
 		return;
 
-	if (!netlink_net_capable(skb, CAP_NET_ADMIN)) {
-		netlink_ack(skb, nlh, -EPERM, NULL);
-		return;
-	}
-
 	if (nlh->nlmsg_type == NFNL_MSG_BATCH_BEGIN)
 		nfnetlink_rcv_skb_batch(skb, nlh);
 	else
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index f69cc73c5813..a3a23707fcb3 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -677,10 +677,13 @@ static int nfnl_compat_get_rcu(struct sk_buff *skb,
 		return -EINVAL;
 
 	rcu_read_unlock();
-	try_then_request_module(xt_find_revision(family, name, rev, target, &ret),
-				fmt, name);
-	if (ret < 0)
-		goto out_put;
+	if (netlink_net_capable(skb, CAP_NET_ADMIN)) {
+		try_then_request_module(xt_find_revision(family, name, rev,
+							 target, &ret),
+					fmt, name);
+		if (ret < 0)
+			goto out_put;
+	}
 
 	skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (skb2 == NULL) {
@@ -718,7 +721,8 @@ static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = {
 		.call		= nfnl_compat_get_rcu,
 		.type		= NFNL_CB_RCU,
 		.attr_count	= NFTA_COMPAT_MAX,
-		.policy		= nfnl_compat_policy_get
+		.policy		= nfnl_compat_policy_get,
+		.unpriviledged	= true,
 	},
 };
 

  parent reply	other threads:[~2022-01-27 16:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-20 10:16 [iptables PATCH] xshared: Fix response to unprivileged users Phil Sutter
2022-01-20 10:33 ` Florian Westphal
2022-01-27 16:28 ` Pablo Neira Ayuso [this message]
2022-01-27 17:08   ` Phil Sutter
2022-01-27 17:21     ` Pablo Neira Ayuso
2022-01-27 17:29       ` Phil Sutter
2022-01-27 17:31         ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YfLINxzIDlCwej1X@salvia \
    --to=pablo@netfilter.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=phil@nwl.cc \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).