diff options
| author | Jan Engelhardt <jengelh@medozas.de> | 2009-06-29 08:31:46 -0400 |
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2009-06-29 08:31:46 -0400 |
| commit | d6d3f08b0fd998b647a05540cedd11a067b72867 (patch) | |
| tree | 9f5152df21771607d13440fe5ae2db9c08051a6b /net | |
| parent | 8a3af79361e85db6fec4173ef1916322471c19e3 (diff) | |
netfilter: xtables: conntrack match revision 2
As reported by Philip, the UNTRACKED state bit does not fit within
the 8-bit state_mask member. Enlarge state_mask and give status_mask
a few more bits too.
Reported-by: Philip Craig <philipc@snapgear.com>
References: http://markmail.org/thread/b7eg6aovfh4agyz7
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/netfilter/xt_conntrack.c | 66 |
1 files changed, 60 insertions, 6 deletions
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 0b7139f3dd78..fc581800698e 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
| @@ -129,7 +129,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr, | |||
| 129 | 129 | ||
| 130 | static inline bool | 130 | static inline bool |
| 131 | conntrack_mt_origsrc(const struct nf_conn *ct, | 131 | conntrack_mt_origsrc(const struct nf_conn *ct, |
| 132 | const struct xt_conntrack_mtinfo1 *info, | 132 | const struct xt_conntrack_mtinfo2 *info, |
| 133 | u_int8_t family) | 133 | u_int8_t family) |
| 134 | { | 134 | { |
| 135 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, | 135 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, |
| @@ -138,7 +138,7 @@ conntrack_mt_origsrc(const struct nf_conn *ct, | |||
| 138 | 138 | ||
| 139 | static inline bool | 139 | static inline bool |
| 140 | conntrack_mt_origdst(const struct nf_conn *ct, | 140 | conntrack_mt_origdst(const struct nf_conn *ct, |
| 141 | const struct xt_conntrack_mtinfo1 *info, | 141 | const struct xt_conntrack_mtinfo2 *info, |
| 142 | u_int8_t family) | 142 | u_int8_t family) |
| 143 | { | 143 | { |
| 144 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3, | 144 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3, |
| @@ -147,7 +147,7 @@ conntrack_mt_origdst(const struct nf_conn *ct, | |||
| 147 | 147 | ||
| 148 | static inline bool | 148 | static inline bool |
| 149 | conntrack_mt_replsrc(const struct nf_conn *ct, | 149 | conntrack_mt_replsrc(const struct nf_conn *ct, |
| 150 | const struct xt_conntrack_mtinfo1 *info, | 150 | const struct xt_conntrack_mtinfo2 *info, |
| 151 | u_int8_t family) | 151 | u_int8_t family) |
| 152 | { | 152 | { |
| 153 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3, | 153 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3, |
| @@ -156,7 +156,7 @@ conntrack_mt_replsrc(const struct nf_conn *ct, | |||
| 156 | 156 | ||
| 157 | static inline bool | 157 | static inline bool |
| 158 | conntrack_mt_repldst(const struct nf_conn *ct, | 158 | conntrack_mt_repldst(const struct nf_conn *ct, |
| 159 | const struct xt_conntrack_mtinfo1 *info, | 159 | const struct xt_conntrack_mtinfo2 *info, |
| 160 | u_int8_t family) | 160 | u_int8_t family) |
| 161 | { | 161 | { |
| 162 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3, | 162 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3, |
| @@ -164,7 +164,7 @@ conntrack_mt_repldst(const struct nf_conn *ct, | |||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static inline bool | 166 | static inline bool |
| 167 | ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info, | 167 | ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info, |
| 168 | const struct nf_conn *ct) | 168 | const struct nf_conn *ct) |
| 169 | { | 169 | { |
| 170 | const struct nf_conntrack_tuple *tuple; | 170 | const struct nf_conntrack_tuple *tuple; |
| @@ -204,7 +204,7 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info, | |||
| 204 | static bool | 204 | static bool |
| 205 | conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | 205 | conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
| 206 | { | 206 | { |
| 207 | const struct xt_conntrack_mtinfo1 *info = par->matchinfo; | 207 | const struct xt_conntrack_mtinfo2 *info = par->matchinfo; |
| 208 | enum ip_conntrack_info ctinfo; | 208 | enum ip_conntrack_info ctinfo; |
| 209 | const struct nf_conn *ct; | 209 | const struct nf_conn *ct; |
| 210 | unsigned int statebit; | 210 | unsigned int statebit; |
| @@ -278,6 +278,16 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
| 278 | return true; | 278 | return true; |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | static bool | ||
| 282 | conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) | ||
| 283 | { | ||
| 284 | const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo; | ||
| 285 | struct xt_match_param newpar = *par; | ||
| 286 | |||
| 287 | newpar.matchinfo = *info; | ||
| 288 | return conntrack_mt(skb, &newpar); | ||
| 289 | } | ||
| 290 | |||
| 281 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) | 291 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) |
| 282 | { | 292 | { |
| 283 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 293 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { |
| @@ -288,11 +298,45 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par) | |||
| 288 | return true; | 298 | return true; |
| 289 | } | 299 | } |
| 290 | 300 | ||
| 301 | static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par) | ||
| 302 | { | ||
| 303 | struct xt_conntrack_mtinfo1 *info = par->matchinfo; | ||
| 304 | struct xt_conntrack_mtinfo2 *up; | ||
| 305 | int ret = conntrack_mt_check(par); | ||
| 306 | |||
| 307 | if (ret < 0) | ||
| 308 | return ret; | ||
| 309 | |||
| 310 | up = kmalloc(sizeof(*up), GFP_KERNEL); | ||
| 311 | if (up == NULL) { | ||
| 312 | nf_ct_l3proto_module_put(par->family); | ||
| 313 | return -ENOMEM; | ||
| 314 | } | ||
| 315 | |||
| 316 | /* | ||
| 317 | * The strategy here is to minimize the overhead of v1 matching, | ||
| 318 | * by prebuilding a v2 struct and putting the pointer into the | ||
| 319 | * v1 dataspace. | ||
| 320 | */ | ||
| 321 | memcpy(up, info, offsetof(typeof(*info), state_mask)); | ||
| 322 | up->state_mask = info->state_mask; | ||
| 323 | up->status_mask = info->status_mask; | ||
| 324 | *(void **)info = up; | ||
| 325 | return true; | ||
| 326 | } | ||
| 327 | |||
| 291 | static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) | 328 | static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) |
| 292 | { | 329 | { |
| 293 | nf_ct_l3proto_module_put(par->family); | 330 | nf_ct_l3proto_module_put(par->family); |
| 294 | } | 331 | } |
| 295 | 332 | ||
| 333 | static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par) | ||
| 334 | { | ||
| 335 | struct xt_conntrack_mtinfo2 **info = par->matchinfo; | ||
| 336 | kfree(*info); | ||
| 337 | conntrack_mt_destroy(par); | ||
| 338 | } | ||
| 339 | |||
| 296 | #ifdef CONFIG_COMPAT | 340 | #ifdef CONFIG_COMPAT |
| 297 | struct compat_xt_conntrack_info | 341 | struct compat_xt_conntrack_info |
| 298 | { | 342 | { |
| @@ -363,6 +407,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = { | |||
| 363 | .revision = 1, | 407 | .revision = 1, |
| 364 | .family = NFPROTO_UNSPEC, | 408 | .family = NFPROTO_UNSPEC, |
| 365 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), | 409 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), |
| 410 | .match = conntrack_mt_v1, | ||
| 411 | .checkentry = conntrack_mt_check_v1, | ||
| 412 | .destroy = conntrack_mt_destroy_v1, | ||
| 413 | .me = THIS_MODULE, | ||
| 414 | }, | ||
| 415 | { | ||
| 416 | .name = "conntrack", | ||
| 417 | .revision = 2, | ||
| 418 | .family = NFPROTO_UNSPEC, | ||
| 419 | .matchsize = sizeof(struct xt_conntrack_mtinfo2), | ||
| 366 | .match = conntrack_mt, | 420 | .match = conntrack_mt, |
| 367 | .checkentry = conntrack_mt_check, | 421 | .checkentry = conntrack_mt_check, |
| 368 | .destroy = conntrack_mt_destroy, | 422 | .destroy = conntrack_mt_destroy, |
