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

Commit 37d2e7a2 authored by Harald Welte's avatar Harald Welte Committed by David S. Miller
Browse files

[NETFILTER] nfnetlink: unconditionally require CAP_NET_ADMIN



This patch unconditionally requires CAP_NET_ADMIN for all nfnetlink
messages.  It also removes the per-message cap_required field, since all
existing subsystems use CAP_NET_ADMIN for all their messages anyway.

Patrick McHardy owes me a beer if we ever need to re-introduce this.

Signed-off-by: default avatarHarald Welte <laforge@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3746a2b1
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -112,7 +112,6 @@ struct nfnl_callback
{
	int (*call)(struct sock *nl, struct sk_buff *skb, 
		struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
	kernel_cap_t cap_required; /* capabilities required for this msg */
	u_int16_t attr_count;	/* number of nfattr's */
};

+7 −14
Original line number Diff line number Diff line
@@ -1543,29 +1543,22 @@ static struct notifier_block ctnl_notifier_exp = {

static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
	[IPCTNL_MSG_CT_NEW]		= { .call = ctnetlink_new_conntrack,
					    .attr_count = CTA_MAX,
					    .cap_required = CAP_NET_ADMIN },
					    .attr_count = CTA_MAX, },
	[IPCTNL_MSG_CT_GET] 		= { .call = ctnetlink_get_conntrack,
					    .attr_count = CTA_MAX,
					    .cap_required = CAP_NET_ADMIN },
					    .attr_count = CTA_MAX, },
	[IPCTNL_MSG_CT_DELETE]  	= { .call = ctnetlink_del_conntrack,
					    .attr_count = CTA_MAX,
					    .cap_required = CAP_NET_ADMIN },
					    .attr_count = CTA_MAX, },
	[IPCTNL_MSG_CT_GET_CTRZERO] 	= { .call = ctnetlink_get_conntrack,
					    .attr_count = CTA_MAX,
					    .cap_required = CAP_NET_ADMIN },
					    .attr_count = CTA_MAX, },
};

static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
	[IPCTNL_MSG_EXP_GET]		= { .call = ctnetlink_get_expect,
					    .attr_count = CTA_EXPECT_MAX,
					    .cap_required = CAP_NET_ADMIN },
					    .attr_count = CTA_EXPECT_MAX, },
	[IPCTNL_MSG_EXP_NEW]		= { .call = ctnetlink_new_expect,
					    .attr_count = CTA_EXPECT_MAX,
					    .cap_required = CAP_NET_ADMIN },
					    .attr_count = CTA_EXPECT_MAX, },
	[IPCTNL_MSG_EXP_DELETE]		= { .call = ctnetlink_del_expect,
					    .attr_count = CTA_EXPECT_MAX,
					    .cap_required = CAP_NET_ADMIN },
					    .attr_count = CTA_EXPECT_MAX, },
};

static struct nfnetlink_subsystem ctnl_subsys = {
+12 −16
Original line number Diff line number Diff line
@@ -223,6 +223,12 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
		 NFNL_SUBSYS_ID(nlh->nlmsg_type),
		 NFNL_MSG_TYPE(nlh->nlmsg_type));

	if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
		DEBUGP("missing CAP_NET_ADMIN\n");
		*errp = -EPERM;
		return -1;
	}

	/* Only requests are handled by kernel now. */
	if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
		DEBUGP("received non-request message\n");
@@ -240,15 +246,12 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
	ss = nfnetlink_get_subsys(type);
	if (!ss) {
#ifdef CONFIG_KMOD
		if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
		/* don't call nfnl_shunlock, since it would reenter
		 * with further packet processing */
		up(&nfnl_sem);
			request_module("nfnetlink-subsys-%d",
					NFNL_SUBSYS_ID(type));
		request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
		nfnl_shlock();
		ss = nfnetlink_get_subsys(type);
		}
		if (!ss)
#endif
			goto err_inval;
@@ -260,13 +263,6 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
		goto err_inval;
	}

	if (nc->cap_required && 
	    !cap_raised(NETLINK_CB(skb).eff_cap, nc->cap_required)) {
		DEBUGP("permission denied for type %d\n", type);
		*errp = -EPERM;
		return -1;
	}

	{
		u_int16_t attr_count = 
			ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
+2 −4
Original line number Diff line number Diff line
@@ -862,11 +862,9 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,

static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
	[NFULNL_MSG_PACKET]	= { .call = nfulnl_recv_unsupp,
				    .attr_count = NFULA_MAX,
				    .cap_required = CAP_NET_ADMIN, },
				    .attr_count = NFULA_MAX, },
	[NFULNL_MSG_CONFIG]	= { .call = nfulnl_recv_config,
				    .attr_count = NFULA_CFG_MAX,
				    .cap_required = CAP_NET_ADMIN },
				    .attr_count = NFULA_CFG_MAX, },
};

static struct nfnetlink_subsystem nfulnl_subsys = {
+3 −6
Original line number Diff line number Diff line
@@ -931,14 +931,11 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,

static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
	[NFQNL_MSG_PACKET]	= { .call = nfqnl_recv_unsupp,
				    .attr_count = NFQA_MAX,
				    .cap_required = CAP_NET_ADMIN },
				    .attr_count = NFQA_MAX, },
	[NFQNL_MSG_VERDICT]	= { .call = nfqnl_recv_verdict,
				    .attr_count = NFQA_MAX,
				    .cap_required = CAP_NET_ADMIN },
				    .attr_count = NFQA_MAX, },
	[NFQNL_MSG_CONFIG]	= { .call = nfqnl_recv_config,
				    .attr_count = NFQA_CFG_MAX,
				    .cap_required = CAP_NET_ADMIN },
				    .attr_count = NFQA_CFG_MAX, },
};

static struct nfnetlink_subsystem nfqnl_subsys = {