[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: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3746a2b140
commit
37d2e7a20d
|
@ -112,7 +112,6 @@ struct nfnl_callback
|
||||||
{
|
{
|
||||||
int (*call)(struct sock *nl, struct sk_buff *skb,
|
int (*call)(struct sock *nl, struct sk_buff *skb,
|
||||||
struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
|
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 */
|
u_int16_t attr_count; /* number of nfattr's */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1543,29 +1543,22 @@ static struct notifier_block ctnl_notifier_exp = {
|
||||||
|
|
||||||
static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
|
static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
|
||||||
[IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
|
[IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
|
||||||
.attr_count = CTA_MAX,
|
.attr_count = CTA_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
[IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
|
[IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
|
||||||
.attr_count = CTA_MAX,
|
.attr_count = CTA_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
[IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
|
[IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
|
||||||
.attr_count = CTA_MAX,
|
.attr_count = CTA_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
[IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
|
[IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
|
||||||
.attr_count = CTA_MAX,
|
.attr_count = CTA_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
|
static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
|
||||||
[IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
|
[IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
|
||||||
.attr_count = CTA_EXPECT_MAX,
|
.attr_count = CTA_EXPECT_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
[IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
|
[IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
|
||||||
.attr_count = CTA_EXPECT_MAX,
|
.attr_count = CTA_EXPECT_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
[IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
|
[IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
|
||||||
.attr_count = CTA_EXPECT_MAX,
|
.attr_count = CTA_EXPECT_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct nfnetlink_subsystem ctnl_subsys = {
|
static struct nfnetlink_subsystem ctnl_subsys = {
|
||||||
|
|
|
@ -223,6 +223,12 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
|
||||||
NFNL_SUBSYS_ID(nlh->nlmsg_type),
|
NFNL_SUBSYS_ID(nlh->nlmsg_type),
|
||||||
NFNL_MSG_TYPE(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. */
|
/* Only requests are handled by kernel now. */
|
||||||
if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
|
if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
|
||||||
DEBUGP("received non-request message\n");
|
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);
|
ss = nfnetlink_get_subsys(type);
|
||||||
if (!ss) {
|
if (!ss) {
|
||||||
#ifdef CONFIG_KMOD
|
#ifdef CONFIG_KMOD
|
||||||
if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
|
/* don't call nfnl_shunlock, since it would reenter
|
||||||
/* don't call nfnl_shunlock, since it would reenter
|
* with further packet processing */
|
||||||
* with further packet processing */
|
up(&nfnl_sem);
|
||||||
up(&nfnl_sem);
|
request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
|
||||||
request_module("nfnetlink-subsys-%d",
|
nfnl_shlock();
|
||||||
NFNL_SUBSYS_ID(type));
|
ss = nfnetlink_get_subsys(type);
|
||||||
nfnl_shlock();
|
|
||||||
ss = nfnetlink_get_subsys(type);
|
|
||||||
}
|
|
||||||
if (!ss)
|
if (!ss)
|
||||||
#endif
|
#endif
|
||||||
goto err_inval;
|
goto err_inval;
|
||||||
|
@ -260,13 +263,6 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
|
||||||
goto err_inval;
|
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 =
|
u_int16_t attr_count =
|
||||||
ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
|
ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
|
||||||
|
|
|
@ -862,11 +862,9 @@ out_put:
|
||||||
|
|
||||||
static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
|
static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
|
||||||
[NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp,
|
[NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp,
|
||||||
.attr_count = NFULA_MAX,
|
.attr_count = NFULA_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN, },
|
|
||||||
[NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config,
|
[NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config,
|
||||||
.attr_count = NFULA_CFG_MAX,
|
.attr_count = NFULA_CFG_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct nfnetlink_subsystem nfulnl_subsys = {
|
static struct nfnetlink_subsystem nfulnl_subsys = {
|
||||||
|
|
|
@ -931,14 +931,11 @@ out_put:
|
||||||
|
|
||||||
static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
|
static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
|
||||||
[NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp,
|
[NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp,
|
||||||
.attr_count = NFQA_MAX,
|
.attr_count = NFQA_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
[NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict,
|
[NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict,
|
||||||
.attr_count = NFQA_MAX,
|
.attr_count = NFQA_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
[NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config,
|
[NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config,
|
||||||
.attr_count = NFQA_CFG_MAX,
|
.attr_count = NFQA_CFG_MAX, },
|
||||||
.cap_required = CAP_NET_ADMIN },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct nfnetlink_subsystem nfqnl_subsys = {
|
static struct nfnetlink_subsystem nfqnl_subsys = {
|
||||||
|
|
Loading…
Reference in New Issue