aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2006-03-22 16:54:15 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-22 16:54:15 -0500
commit1cde64365b0c4f576f8f45b834e6a6de081b5914 (patch)
tree86f35fc9f292365c87b7ff90e0933e9d38db2863 /net
parent50b521aa54f415a626bfd63d1a9b72120e9fbe88 (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')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c72
-rw-r--r--net/netfilter/nf_conntrack_netlink.c84
2 files changed, 117 insertions, 39 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
54static inline int 54static inline int
55ctnetlink_dump_tuples_proto(struct sk_buff *skb, 55ctnetlink_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
77static inline int 75static inline int
78ctnetlink_dump_tuples(struct sk_buff *skb, 76ctnetlink_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
95nfattr_failure: 88nfattr_failure:
96 return -1; 89 return -1;
97} 90}
98 91
99static inline int 92static inline int
93ctnetlink_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
110static inline int
100ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct) 111ctnetlink_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
1137static inline int 1148static inline int
1149ctnetlink_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
1171nfattr_failure:
1172 return -1;
1173}
1174
1175static inline int
1138ctnetlink_exp_dump_expect(struct sk_buff *skb, 1176ctnetlink_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,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 5eadf009bb15..0e0e9d7b34c8 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_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-2006 by Harald Welte <laforge@gnumonks.org> 5 * (C) 2002-2006 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.
@@ -55,20 +55,18 @@ static char __initdata version[] = "0.93";
55 55
56static inline int 56static inline int
57ctnetlink_dump_tuples_proto(struct sk_buff *skb, 57ctnetlink_dump_tuples_proto(struct sk_buff *skb,
58 const struct nf_conntrack_tuple *tuple) 58 const struct nf_conntrack_tuple *tuple,
59 struct nf_conntrack_protocol *proto)
59{ 60{
60 struct nf_conntrack_protocol *proto;
61 int ret = 0; 61 int ret = 0;
62 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
62 63
63 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 64 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
64 65
65 /* If no protocol helper is found, this function will return the
66 * generic protocol helper, so proto won't *ever* be NULL */
67 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
68 if (likely(proto->tuple_to_nfattr)) 66 if (likely(proto->tuple_to_nfattr))
69 ret = proto->tuple_to_nfattr(skb, tuple); 67 ret = proto->tuple_to_nfattr(skb, tuple);
70 68
71 nf_ct_proto_put(proto); 69 NFA_NEST_END(skb, nest_parms);
72 70
73 return ret; 71 return ret;
74 72
@@ -77,33 +75,44 @@ nfattr_failure:
77} 75}
78 76
79static inline int 77static inline int
80ctnetlink_dump_tuples(struct sk_buff *skb, 78ctnetlink_dump_tuples_ip(struct sk_buff *skb,
81 const struct nf_conntrack_tuple *tuple) 79 const struct nf_conntrack_tuple *tuple,
80 struct nf_conntrack_l3proto *l3proto)
82{ 81{
83 struct nfattr *nest_parms;
84 struct nf_conntrack_l3proto *l3proto;
85 int ret = 0; 82 int ret = 0;
86 83 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
87 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 84
88
89 nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
90 if (likely(l3proto->tuple_to_nfattr)) 85 if (likely(l3proto->tuple_to_nfattr))
91 ret = l3proto->tuple_to_nfattr(skb, tuple); 86 ret = l3proto->tuple_to_nfattr(skb, tuple);
87
92 NFA_NEST_END(skb, nest_parms); 88 NFA_NEST_END(skb, nest_parms);
93 89
90 return ret;
91
92nfattr_failure:
93 return -1;
94}
95
96static inline int
97ctnetlink_dump_tuples(struct sk_buff *skb,
98 const struct nf_conntrack_tuple *tuple)
99{
100 int ret;
101 struct nf_conntrack_l3proto *l3proto;
102 struct nf_conntrack_protocol *proto;
103
104 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
105 ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto);
94 nf_ct_l3proto_put(l3proto); 106 nf_ct_l3proto_put(l3proto);
95 107
96 if (unlikely(ret < 0)) 108 if (unlikely(ret < 0))
97 return ret; 109 return ret;
98 110
99 nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); 111 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
100 ret = ctnetlink_dump_tuples_proto(skb, tuple); 112 ret = ctnetlink_dump_tuples_proto(skb, tuple, proto);
101 NFA_NEST_END(skb, nest_parms); 113 nf_ct_proto_put(proto);
102 114
103 return ret; 115 return ret;
104
105nfattr_failure:
106 return -1;
107} 116}
108 117
109static inline int 118static inline int
@@ -1153,6 +1162,37 @@ nfattr_failure:
1153} 1162}
1154 1163
1155static inline int 1164static inline int
1165ctnetlink_exp_dump_mask(struct sk_buff *skb,
1166 const struct nf_conntrack_tuple *tuple,
1167 const struct nf_conntrack_tuple *mask)
1168{
1169 int ret;
1170 struct nf_conntrack_l3proto *l3proto;
1171 struct nf_conntrack_protocol *proto;
1172 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
1173
1174 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
1175 ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
1176 nf_ct_l3proto_put(l3proto);
1177
1178 if (unlikely(ret < 0))
1179 goto nfattr_failure;
1180
1181 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
1182 ret = ctnetlink_dump_tuples_proto(skb, mask, proto);
1183 nf_ct_proto_put(proto);
1184 if (unlikely(ret < 0))
1185 goto nfattr_failure;
1186
1187 NFA_NEST_END(skb, nest_parms);
1188
1189 return 0;
1190
1191nfattr_failure:
1192 return -1;
1193}
1194
1195static inline int
1156ctnetlink_exp_dump_expect(struct sk_buff *skb, 1196ctnetlink_exp_dump_expect(struct sk_buff *skb,
1157 const struct nf_conntrack_expect *exp) 1197 const struct nf_conntrack_expect *exp)
1158{ 1198{
@@ -1162,7 +1202,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
1162 1202
1163 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) 1203 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
1164 goto nfattr_failure; 1204 goto nfattr_failure;
1165 if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) 1205 if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
1166 goto nfattr_failure; 1206 goto nfattr_failure;
1167 if (ctnetlink_exp_dump_tuple(skb, 1207 if (ctnetlink_exp_dump_tuple(skb,
1168 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 1208 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,