You need to sign in or sign up before continuing.
提交 927ccbcc 编写于 作者: H Harald Welte 提交者: David S. Miller

[NETFILTER]: attribute count is an attribute of message type, not subsytem

Prior to this patch, every nfnetlink subsystem had to specify it's
attribute count.  However, in reality the attribute count depends on
the message type within the subsystem, not the subsystem itself.  This
patch moves 'attr_count' from 'struct nfnetlink_subsys' into
nfnl_callback to fix this.
Signed-off-by: NHarald Welte <laforge@netfilter.org>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 bd9a26b7
...@@ -85,9 +85,10 @@ struct nfgenmsg { ...@@ -85,9 +85,10 @@ struct nfgenmsg {
struct nfnl_callback struct nfnl_callback
{ {
kernel_cap_t cap_required; /* capabilities required for this msg */
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 */
}; };
struct nfnetlink_subsystem struct nfnetlink_subsystem
...@@ -95,7 +96,6 @@ struct nfnetlink_subsystem ...@@ -95,7 +96,6 @@ struct nfnetlink_subsystem
const char *name; const char *name;
__u8 subsys_id; /* nfnetlink subsystem ID */ __u8 subsys_id; /* nfnetlink subsystem ID */
__u8 cb_count; /* number of callbacks */ __u8 cb_count; /* number of callbacks */
u_int32_t attr_count; /* number of nfattr's */
struct nfnl_callback *cb; /* callback for individual types */ struct nfnl_callback *cb; /* callback for individual types */
}; };
......
...@@ -1484,21 +1484,28 @@ static struct notifier_block ctnl_notifier_exp = { ...@@ -1484,21 +1484,28 @@ 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,
.cap_required = CAP_NET_ADMIN }, .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,
.cap_required = CAP_NET_ADMIN }, .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,
.cap_required = CAP_NET_ADMIN }, .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,
.cap_required = CAP_NET_ADMIN }, .cap_required = CAP_NET_ADMIN },
}; };
static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_MAX] = { static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_MAX] = {
[IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect, [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
.attr_count = CTA_EXPECT_MAX,
.cap_required = CAP_NET_ADMIN }, .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,
.cap_required = CAP_NET_ADMIN }, .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,
.cap_required = CAP_NET_ADMIN }, .cap_required = CAP_NET_ADMIN },
}; };
...@@ -1506,7 +1513,6 @@ static struct nfnetlink_subsystem ctnl_subsys = { ...@@ -1506,7 +1513,6 @@ static struct nfnetlink_subsystem ctnl_subsys = {
.name = "conntrack", .name = "conntrack",
.subsys_id = NFNL_SUBSYS_CTNETLINK, .subsys_id = NFNL_SUBSYS_CTNETLINK,
.cb_count = IPCTNL_MSG_MAX, .cb_count = IPCTNL_MSG_MAX,
.attr_count = CTA_MAX,
.cb = ctnl_cb, .cb = ctnl_cb,
}; };
...@@ -1514,7 +1520,6 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = { ...@@ -1514,7 +1520,6 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
.name = "conntrack_expect", .name = "conntrack_expect",
.subsys_id = NFNL_SUBSYS_CTNETLINK_EXP, .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP,
.cb_count = IPCTNL_MSG_EXP_MAX, .cb_count = IPCTNL_MSG_EXP_MAX,
.attr_count = CTA_MAX,
.cb = ctnl_exp_cb, .cb = ctnl_exp_cb,
}; };
......
...@@ -155,8 +155,18 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys, ...@@ -155,8 +155,18 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
struct nlmsghdr *nlh, struct nfattr *cda[]) struct nlmsghdr *nlh, struct nfattr *cda[])
{ {
int min_len; int min_len;
u_int16_t attr_count;
u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
memset(cda, 0, sizeof(struct nfattr *) * subsys->attr_count); if (unlikely(cb_id >= subsys->cb_count)) {
DEBUGP("msgtype %u >= %u, returning\n",
cb_id, subsys->cb_count);
return -EINVAL;
}
attr_count = subsys->cb[cb_id].attr_count;
memset(cda, 0, sizeof(struct nfattr *) * attr_count);
/* check attribute lengths. */ /* check attribute lengths. */
min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg)); min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg));
...@@ -170,7 +180,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys, ...@@ -170,7 +180,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
while (NFA_OK(attr, attrlen)) { while (NFA_OK(attr, attrlen)) {
unsigned flavor = attr->nfa_type; unsigned flavor = attr->nfa_type;
if (flavor) { if (flavor) {
if (flavor > subsys->attr_count) if (flavor > attr_count)
return -EINVAL; return -EINVAL;
cda[flavor - 1] = attr; cda[flavor - 1] = attr;
} }
...@@ -256,9 +266,11 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb, ...@@ -256,9 +266,11 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
} }
{ {
struct nfattr *cda[ss->attr_count]; u_int16_t attr_count =
ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
struct nfattr *cda[attr_count];
memset(cda, 0, ss->attr_count*sizeof(struct nfattr *)); memset(cda, 0, sizeof(struct nfattr *) * attr_count);
err = nfnetlink_check_attributes(ss, nlh, cda); err = nfnetlink_check_attributes(ss, nlh, cda);
if (err < 0) if (err < 0)
......
...@@ -805,8 +805,10 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -805,8 +805,10 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
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,
.cap_required = CAP_NET_ADMIN }, .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,
.cap_required = CAP_NET_ADMIN }, .cap_required = CAP_NET_ADMIN },
}; };
...@@ -814,7 +816,6 @@ static struct nfnetlink_subsystem nfulnl_subsys = { ...@@ -814,7 +816,6 @@ static struct nfnetlink_subsystem nfulnl_subsys = {
.name = "log", .name = "log",
.subsys_id = NFNL_SUBSYS_ULOG, .subsys_id = NFNL_SUBSYS_ULOG,
.cb_count = NFULNL_MSG_MAX, .cb_count = NFULNL_MSG_MAX,
.attr_count = NFULA_MAX,
.cb = nfulnl_cb, .cb = nfulnl_cb,
}; };
......
...@@ -877,10 +877,13 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -877,10 +877,13 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
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,
.cap_required = CAP_NET_ADMIN }, .cap_required = CAP_NET_ADMIN },
[NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict, [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict,
.attr_count = NFQA_MAX,
.cap_required = CAP_NET_ADMIN }, .cap_required = CAP_NET_ADMIN },
[NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config, [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config,
.attr_count = NFQA_CFG_MAX,
.cap_required = CAP_NET_ADMIN }, .cap_required = CAP_NET_ADMIN },
}; };
...@@ -888,7 +891,6 @@ static struct nfnetlink_subsystem nfqnl_subsys = { ...@@ -888,7 +891,6 @@ static struct nfnetlink_subsystem nfqnl_subsys = {
.name = "nf_queue", .name = "nf_queue",
.subsys_id = NFNL_SUBSYS_QUEUE, .subsys_id = NFNL_SUBSYS_QUEUE,
.cb_count = NFQNL_MSG_MAX, .cb_count = NFQNL_MSG_MAX,
.attr_count = NFQA_MAX,
.cb = nfqnl_cb, .cb = nfqnl_cb,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册