diff options
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/nfnetlink.c | 20 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 5 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_queue.c | 4 |
3 files changed, 22 insertions, 7 deletions
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 30b25f47f7cc..578e4fe40945 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -155,8 +155,18 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys, | |||
155 | struct nlmsghdr *nlh, struct nfattr *cda[]) | 155 | struct nlmsghdr *nlh, struct nfattr *cda[]) |
156 | { | 156 | { |
157 | int min_len; | 157 | int min_len; |
158 | u_int16_t attr_count; | ||
159 | u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type); | ||
158 | 160 | ||
159 | memset(cda, 0, sizeof(struct nfattr *) * subsys->attr_count); | 161 | if (unlikely(cb_id >= subsys->cb_count)) { |
162 | DEBUGP("msgtype %u >= %u, returning\n", | ||
163 | cb_id, subsys->cb_count); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | attr_count = subsys->cb[cb_id].attr_count; | ||
168 | |||
169 | memset(cda, 0, sizeof(struct nfattr *) * attr_count); | ||
160 | 170 | ||
161 | /* check attribute lengths. */ | 171 | /* check attribute lengths. */ |
162 | min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg)); | 172 | min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg)); |
@@ -170,7 +180,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys, | |||
170 | while (NFA_OK(attr, attrlen)) { | 180 | while (NFA_OK(attr, attrlen)) { |
171 | unsigned flavor = attr->nfa_type; | 181 | unsigned flavor = attr->nfa_type; |
172 | if (flavor) { | 182 | if (flavor) { |
173 | if (flavor > subsys->attr_count) | 183 | if (flavor > attr_count) |
174 | return -EINVAL; | 184 | return -EINVAL; |
175 | cda[flavor - 1] = attr; | 185 | cda[flavor - 1] = attr; |
176 | } | 186 | } |
@@ -256,9 +266,11 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb, | |||
256 | } | 266 | } |
257 | 267 | ||
258 | { | 268 | { |
259 | struct nfattr *cda[ss->attr_count]; | 269 | u_int16_t attr_count = |
270 | ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count; | ||
271 | struct nfattr *cda[attr_count]; | ||
260 | 272 | ||
261 | memset(cda, 0, ss->attr_count*sizeof(struct nfattr *)); | 273 | memset(cda, 0, sizeof(struct nfattr *) * attr_count); |
262 | 274 | ||
263 | err = nfnetlink_check_attributes(ss, nlh, cda); | 275 | err = nfnetlink_check_attributes(ss, nlh, cda); |
264 | if (err < 0) | 276 | if (err < 0) |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index f41045e385ae..1750f0d6e4de 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -805,8 +805,10 @@ out_put: | |||
805 | 805 | ||
806 | static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { | 806 | static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { |
807 | [NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp, | 807 | [NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp, |
808 | .cap_required = CAP_NET_ADMIN }, | 808 | .attr_count = NFULA_MAX, |
809 | .cap_required = CAP_NET_ADMIN, }, | ||
809 | [NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config, | 810 | [NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config, |
811 | .attr_count = NFULA_CFG_MAX, | ||
810 | .cap_required = CAP_NET_ADMIN }, | 812 | .cap_required = CAP_NET_ADMIN }, |
811 | }; | 813 | }; |
812 | 814 | ||
@@ -814,7 +816,6 @@ static struct nfnetlink_subsystem nfulnl_subsys = { | |||
814 | .name = "log", | 816 | .name = "log", |
815 | .subsys_id = NFNL_SUBSYS_ULOG, | 817 | .subsys_id = NFNL_SUBSYS_ULOG, |
816 | .cb_count = NFULNL_MSG_MAX, | 818 | .cb_count = NFULNL_MSG_MAX, |
817 | .attr_count = NFULA_MAX, | ||
818 | .cb = nfulnl_cb, | 819 | .cb = nfulnl_cb, |
819 | }; | 820 | }; |
820 | 821 | ||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index d7b0330d64b4..04323ee1eb8d 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -877,10 +877,13 @@ out_put: | |||
877 | 877 | ||
878 | static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { | 878 | static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { |
879 | [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp, | 879 | [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp, |
880 | .attr_count = NFQA_MAX, | ||
880 | .cap_required = CAP_NET_ADMIN }, | 881 | .cap_required = CAP_NET_ADMIN }, |
881 | [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict, | 882 | [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict, |
883 | .attr_count = NFQA_MAX, | ||
882 | .cap_required = CAP_NET_ADMIN }, | 884 | .cap_required = CAP_NET_ADMIN }, |
883 | [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config, | 885 | [NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config, |
886 | .attr_count = NFQA_CFG_MAX, | ||
884 | .cap_required = CAP_NET_ADMIN }, | 887 | .cap_required = CAP_NET_ADMIN }, |
885 | }; | 888 | }; |
886 | 889 | ||
@@ -888,7 +891,6 @@ static struct nfnetlink_subsystem nfqnl_subsys = { | |||
888 | .name = "nf_queue", | 891 | .name = "nf_queue", |
889 | .subsys_id = NFNL_SUBSYS_QUEUE, | 892 | .subsys_id = NFNL_SUBSYS_QUEUE, |
890 | .cb_count = NFQNL_MSG_MAX, | 893 | .cb_count = NFQNL_MSG_MAX, |
891 | .attr_count = NFQA_MAX, | ||
892 | .cb = nfqnl_cb, | 894 | .cb = nfqnl_cb, |
893 | }; | 895 | }; |
894 | 896 | ||