Commit 56558208 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by David S. Miller

[NETFILTER] ctnetlink: More thorough size checking of attributes

Add missing size checks. Thanks Patrick McHardy for the hint.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarHarald Welte <laforge@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c0400c4f
...@@ -614,6 +614,11 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, ...@@ -614,6 +614,11 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
return 0; return 0;
} }
static const size_t cta_min_nat[CTA_NAT_MAX] = {
[CTA_NAT_MINIP-1] = sizeof(u_int32_t),
[CTA_NAT_MAXIP-1] = sizeof(u_int32_t),
};
static inline int static inline int
ctnetlink_parse_nat(struct nfattr *cda[], ctnetlink_parse_nat(struct nfattr *cda[],
const struct ip_conntrack *ct, struct ip_nat_range *range) const struct ip_conntrack *ct, struct ip_nat_range *range)
...@@ -627,6 +632,9 @@ ctnetlink_parse_nat(struct nfattr *cda[], ...@@ -627,6 +632,9 @@ ctnetlink_parse_nat(struct nfattr *cda[],
nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]); nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
return -EINVAL;
if (tb[CTA_NAT_MINIP-1]) if (tb[CTA_NAT_MINIP-1])
range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]); range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
...@@ -667,6 +675,14 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name) ...@@ -667,6 +675,14 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
return 0; return 0;
} }
static const size_t cta_min[CTA_MAX] = {
[CTA_STATUS-1] = sizeof(u_int32_t),
[CTA_TIMEOUT-1] = sizeof(u_int32_t),
[CTA_MARK-1] = sizeof(u_int32_t),
[CTA_USE-1] = sizeof(u_int32_t),
[CTA_ID-1] = sizeof(u_int32_t)
};
static int static int
ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
...@@ -678,6 +694,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, ...@@ -678,6 +694,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
DEBUGP("entered %s\n", __FUNCTION__); DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL;
if (cda[CTA_TUPLE_ORIG-1]) if (cda[CTA_TUPLE_ORIG-1])
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG); err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
else if (cda[CTA_TUPLE_REPLY-1]) else if (cda[CTA_TUPLE_REPLY-1])
...@@ -760,6 +779,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, ...@@ -760,6 +779,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
return 0; return 0;
} }
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL;
if (cda[CTA_TUPLE_ORIG-1]) if (cda[CTA_TUPLE_ORIG-1])
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG); err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
else if (cda[CTA_TUPLE_REPLY-1]) else if (cda[CTA_TUPLE_REPLY-1])
...@@ -1047,6 +1069,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, ...@@ -1047,6 +1069,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
DEBUGP("entered %s\n", __FUNCTION__); DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_MAX, cta_min))
return -EINVAL;
if (cda[CTA_TUPLE_ORIG-1]) { if (cda[CTA_TUPLE_ORIG-1]) {
err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG); err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG);
if (err < 0) if (err < 0)
...@@ -1252,6 +1277,11 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -1252,6 +1277,11 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len; return skb->len;
} }
static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
[CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t),
[CTA_EXPECT_ID-1] = sizeof(u_int32_t)
};
static int static int
ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
...@@ -1263,6 +1293,9 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, ...@@ -1263,6 +1293,9 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
DEBUGP("entered %s\n", __FUNCTION__); DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL;
if (nlh->nlmsg_flags & NLM_F_DUMP) { if (nlh->nlmsg_flags & NLM_F_DUMP) {
struct nfgenmsg *msg = NLMSG_DATA(nlh); struct nfgenmsg *msg = NLMSG_DATA(nlh);
u32 rlen; u32 rlen;
...@@ -1333,6 +1366,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, ...@@ -1333,6 +1366,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
struct ip_conntrack_helper *h; struct ip_conntrack_helper *h;
int err; int err;
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL;
if (cda[CTA_EXPECT_TUPLE-1]) { if (cda[CTA_EXPECT_TUPLE-1]) {
/* delete a single expect by tuple */ /* delete a single expect by tuple */
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
...@@ -1462,6 +1498,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, ...@@ -1462,6 +1498,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
DEBUGP("entered %s\n", __FUNCTION__); DEBUGP("entered %s\n", __FUNCTION__);
if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
return -EINVAL;
if (!cda[CTA_EXPECT_TUPLE-1] if (!cda[CTA_EXPECT_TUPLE-1]
|| !cda[CTA_EXPECT_MASK-1] || !cda[CTA_EXPECT_MASK-1]
|| !cda[CTA_EXPECT_MASTER-1]) || !cda[CTA_EXPECT_MASTER-1])
......
...@@ -357,6 +357,10 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa, ...@@ -357,6 +357,10 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
return -1; return -1;
} }
static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
[CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t),
};
static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct) static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
{ {
struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1]; struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
...@@ -369,6 +373,9 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct) ...@@ -369,6 +373,9 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr); nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
return -EINVAL;
if (!tb[CTA_PROTOINFO_TCP_STATE-1]) if (!tb[CTA_PROTOINFO_TCP_STATE-1])
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment