diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2006-03-22 16:54:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-22 16:54:15 -0500 |
commit | 1cde64365b0c4f576f8f45b834e6a6de081b5914 (patch) | |
tree | 86f35fc9f292365c87b7ff90e0933e9d38db2863 /net/ipv4 | |
parent | 50b521aa54f415a626bfd63d1a9b72120e9fbe88 (diff) |
[NETFILTER]: ctnetlink: Fix expectaction mask dumping
The expectation mask has some particularities that requires a different
handling. The protocol number fields can be set to non-valid protocols,
ie. l3num is set to 0xFFFF. Since that protocol does not exist, the mask
tuple will not be dumped. Moreover, this results in a kernel panic when
nf_conntrack accesses the array of protocol handlers, that is PF_MAX (0x1F)
long.
This patch introduces the function ctnetlink_exp_dump_mask, that correctly
dumps the expectation mask. Such function uses the l3num value from the
expectation tuple that is a valid layer 3 protocol number. The value of the
l3num mask isn't dumped since it is meaningless from the userspace side.
Thanks to Yasuyuki Kozakai and Patrick McHardy for the feedback.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_netlink.c | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 5ce2e3fc2c7f..9b6e19bae90f 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * (C) 2001 by Jay Schulist <jschlst@samba.org> | 4 | * (C) 2001 by Jay Schulist <jschlst@samba.org> |
5 | * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org> | 5 | * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org> |
6 | * (C) 2003 by Patrick Mchardy <kaber@trash.net> | 6 | * (C) 2003 by Patrick Mchardy <kaber@trash.net> |
7 | * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net> | 7 | * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net> |
8 | * | 8 | * |
9 | * I've reworked this stuff to use attributes instead of conntrack | 9 | * I've reworked this stuff to use attributes instead of conntrack |
10 | * structures. 5.44 am. I need more tea. --pablo 05/07/11. | 10 | * structures. 5.44 am. I need more tea. --pablo 05/07/11. |
@@ -53,20 +53,18 @@ static char __initdata version[] = "0.90"; | |||
53 | 53 | ||
54 | static inline int | 54 | static inline int |
55 | ctnetlink_dump_tuples_proto(struct sk_buff *skb, | 55 | ctnetlink_dump_tuples_proto(struct sk_buff *skb, |
56 | const struct ip_conntrack_tuple *tuple) | 56 | const struct ip_conntrack_tuple *tuple, |
57 | struct ip_conntrack_protocol *proto) | ||
57 | { | 58 | { |
58 | struct ip_conntrack_protocol *proto; | ||
59 | int ret = 0; | 59 | int ret = 0; |
60 | struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); | ||
60 | 61 | ||
61 | NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); | 62 | NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); |
62 | 63 | ||
63 | /* If no protocol helper is found, this function will return the | ||
64 | * generic protocol helper, so proto won't *ever* be NULL */ | ||
65 | proto = ip_conntrack_proto_find_get(tuple->dst.protonum); | ||
66 | if (likely(proto->tuple_to_nfattr)) | 64 | if (likely(proto->tuple_to_nfattr)) |
67 | ret = proto->tuple_to_nfattr(skb, tuple); | 65 | ret = proto->tuple_to_nfattr(skb, tuple); |
68 | 66 | ||
69 | ip_conntrack_proto_put(proto); | 67 | NFA_NEST_END(skb, nest_parms); |
70 | 68 | ||
71 | return ret; | 69 | return ret; |
72 | 70 | ||
@@ -75,28 +73,41 @@ nfattr_failure: | |||
75 | } | 73 | } |
76 | 74 | ||
77 | static inline int | 75 | static inline int |
78 | ctnetlink_dump_tuples(struct sk_buff *skb, | 76 | ctnetlink_dump_tuples_ip(struct sk_buff *skb, |
79 | const struct ip_conntrack_tuple *tuple) | 77 | const struct ip_conntrack_tuple *tuple) |
80 | { | 78 | { |
81 | struct nfattr *nest_parms; | 79 | struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); |
82 | int ret; | ||
83 | 80 | ||
84 | nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); | ||
85 | NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); | 81 | NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); |
86 | NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip); | 82 | NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip); |
87 | NFA_NEST_END(skb, nest_parms); | ||
88 | 83 | ||
89 | nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); | ||
90 | ret = ctnetlink_dump_tuples_proto(skb, tuple); | ||
91 | NFA_NEST_END(skb, nest_parms); | 84 | NFA_NEST_END(skb, nest_parms); |
92 | 85 | ||
93 | return ret; | 86 | return 0; |
94 | 87 | ||
95 | nfattr_failure: | 88 | nfattr_failure: |
96 | return -1; | 89 | return -1; |
97 | } | 90 | } |
98 | 91 | ||
99 | static inline int | 92 | static inline int |
93 | ctnetlink_dump_tuples(struct sk_buff *skb, | ||
94 | const struct ip_conntrack_tuple *tuple) | ||
95 | { | ||
96 | int ret; | ||
97 | struct ip_conntrack_protocol *proto; | ||
98 | |||
99 | ret = ctnetlink_dump_tuples_ip(skb, tuple); | ||
100 | if (unlikely(ret < 0)) | ||
101 | return ret; | ||
102 | |||
103 | proto = ip_conntrack_proto_find_get(tuple->dst.protonum); | ||
104 | ret = ctnetlink_dump_tuples_proto(skb, tuple, proto); | ||
105 | ip_conntrack_proto_put(proto); | ||
106 | |||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | static inline int | ||
100 | ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct) | 111 | ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct) |
101 | { | 112 | { |
102 | u_int32_t status = htonl((u_int32_t) ct->status); | 113 | u_int32_t status = htonl((u_int32_t) ct->status); |
@@ -1135,6 +1146,33 @@ nfattr_failure: | |||
1135 | } | 1146 | } |
1136 | 1147 | ||
1137 | static inline int | 1148 | static inline int |
1149 | ctnetlink_exp_dump_mask(struct sk_buff *skb, | ||
1150 | const struct ip_conntrack_tuple *tuple, | ||
1151 | const struct ip_conntrack_tuple *mask) | ||
1152 | { | ||
1153 | int ret; | ||
1154 | struct ip_conntrack_protocol *proto; | ||
1155 | struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); | ||
1156 | |||
1157 | ret = ctnetlink_dump_tuples_ip(skb, mask); | ||
1158 | if (unlikely(ret < 0)) | ||
1159 | goto nfattr_failure; | ||
1160 | |||
1161 | proto = ip_conntrack_proto_find_get(tuple->dst.protonum); | ||
1162 | ret = ctnetlink_dump_tuples_proto(skb, mask, proto); | ||
1163 | ip_conntrack_proto_put(proto); | ||
1164 | if (unlikely(ret < 0)) | ||
1165 | goto nfattr_failure; | ||
1166 | |||
1167 | NFA_NEST_END(skb, nest_parms); | ||
1168 | |||
1169 | return 0; | ||
1170 | |||
1171 | nfattr_failure: | ||
1172 | return -1; | ||
1173 | } | ||
1174 | |||
1175 | static inline int | ||
1138 | ctnetlink_exp_dump_expect(struct sk_buff *skb, | 1176 | ctnetlink_exp_dump_expect(struct sk_buff *skb, |
1139 | const struct ip_conntrack_expect *exp) | 1177 | const struct ip_conntrack_expect *exp) |
1140 | { | 1178 | { |
@@ -1144,7 +1182,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, | |||
1144 | 1182 | ||
1145 | if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) | 1183 | if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) |
1146 | goto nfattr_failure; | 1184 | goto nfattr_failure; |
1147 | if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) | 1185 | if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0) |
1148 | goto nfattr_failure; | 1186 | goto nfattr_failure; |
1149 | if (ctnetlink_exp_dump_tuple(skb, | 1187 | if (ctnetlink_exp_dump_tuple(skb, |
1150 | &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, | 1188 | &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, |