Commit 1275361c407d17d56717cd706785a31c2353d696
Exists in
master
and in
7 other branches
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [NET]: Fix MAX_HEADER setting. [NETFILTER]: ipt_REJECT: fix memory corruption [NETFILTER]: conntrack: fix refcount leak when finding expectation [NETFILTER]: ctnetlink: fix reference count leak [NETFILTER]: nf_conntrack: fix the race on assign helper to new conntrack [NETFILTER]: nfctnetlink: assign helper to newly created conntrack
Showing 6 changed files Side-by-side Diff
include/linux/netdevice.h
... | ... | @@ -93,8 +93,10 @@ |
93 | 93 | #endif |
94 | 94 | #endif |
95 | 95 | |
96 | -#if !defined(CONFIG_NET_IPIP) && \ | |
97 | - !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) | |
96 | +#if !defined(CONFIG_NET_IPIP) && !defined(CONFIG_NET_IPIP_MODULE) && \ | |
97 | + !defined(CONFIG_NET_IPGRE) && !defined(CONFIG_NET_IPGRE_MODULE) && \ | |
98 | + !defined(CONFIG_IPV6_SIT) && !defined(CONFIG_IPV6_SIT_MODULE) && \ | |
99 | + !defined(CONFIG_IPV6_TUNNEL) && !defined(CONFIG_IPV6_TUNNEL_MODULE) | |
98 | 100 | #define MAX_HEADER LL_MAX_HEADER |
99 | 101 | #else |
100 | 102 | #define MAX_HEADER (LL_MAX_HEADER + 48) |
net/ipv4/netfilter/ip_conntrack_core.c
... | ... | @@ -225,10 +225,8 @@ |
225 | 225 | struct ip_conntrack_expect *i; |
226 | 226 | |
227 | 227 | list_for_each_entry(i, &ip_conntrack_expect_list, list) { |
228 | - if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { | |
229 | - atomic_inc(&i->use); | |
228 | + if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) | |
230 | 229 | return i; |
231 | - } | |
232 | 230 | } |
233 | 231 | return NULL; |
234 | 232 | } |
... | ... | @@ -241,6 +239,8 @@ |
241 | 239 | |
242 | 240 | read_lock_bh(&ip_conntrack_lock); |
243 | 241 | i = __ip_conntrack_expect_find(tuple); |
242 | + if (i) | |
243 | + atomic_inc(&i->use); | |
244 | 244 | read_unlock_bh(&ip_conntrack_lock); |
245 | 245 | |
246 | 246 | return i; |
net/ipv4/netfilter/ip_conntrack_netlink.c
net/ipv4/netfilter/ipt_REJECT.c
... | ... | @@ -114,6 +114,14 @@ |
114 | 114 | tcph->window = 0; |
115 | 115 | tcph->urg_ptr = 0; |
116 | 116 | |
117 | + /* Adjust TCP checksum */ | |
118 | + tcph->check = 0; | |
119 | + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), | |
120 | + nskb->nh.iph->saddr, | |
121 | + nskb->nh.iph->daddr, | |
122 | + csum_partial((char *)tcph, | |
123 | + sizeof(struct tcphdr), 0)); | |
124 | + | |
117 | 125 | /* Set DF, id = 0 */ |
118 | 126 | nskb->nh.iph->frag_off = htons(IP_DF); |
119 | 127 | nskb->nh.iph->id = 0; |
120 | 128 | |
... | ... | @@ -129,14 +137,8 @@ |
129 | 137 | if (ip_route_me_harder(&nskb, addr_type)) |
130 | 138 | goto free_nskb; |
131 | 139 | |
132 | - /* Adjust TCP checksum */ | |
133 | 140 | nskb->ip_summed = CHECKSUM_NONE; |
134 | - tcph->check = 0; | |
135 | - tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), | |
136 | - nskb->nh.iph->saddr, | |
137 | - nskb->nh.iph->daddr, | |
138 | - csum_partial((char *)tcph, | |
139 | - sizeof(struct tcphdr), 0)); | |
141 | + | |
140 | 142 | /* Adjust IP TTL */ |
141 | 143 | nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); |
142 | 144 |
net/netfilter/nf_conntrack_core.c
... | ... | @@ -469,10 +469,8 @@ |
469 | 469 | struct nf_conntrack_expect *i; |
470 | 470 | |
471 | 471 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { |
472 | - if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { | |
473 | - atomic_inc(&i->use); | |
472 | + if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) | |
474 | 473 | return i; |
475 | - } | |
476 | 474 | } |
477 | 475 | return NULL; |
478 | 476 | } |
... | ... | @@ -485,6 +483,8 @@ |
485 | 483 | |
486 | 484 | read_lock_bh(&nf_conntrack_lock); |
487 | 485 | i = __nf_conntrack_expect_find(tuple); |
486 | + if (i) | |
487 | + atomic_inc(&i->use); | |
488 | 488 | read_unlock_bh(&nf_conntrack_lock); |
489 | 489 | |
490 | 490 | return i; |
... | ... | @@ -893,12 +893,6 @@ |
893 | 893 | |
894 | 894 | memset(conntrack, 0, nf_ct_cache[features].size); |
895 | 895 | conntrack->features = features; |
896 | - if (helper) { | |
897 | - struct nf_conn_help *help = nfct_help(conntrack); | |
898 | - NF_CT_ASSERT(help); | |
899 | - help->helper = helper; | |
900 | - } | |
901 | - | |
902 | 896 | atomic_set(&conntrack->ct_general.use, 1); |
903 | 897 | conntrack->ct_general.destroy = destroy_conntrack; |
904 | 898 | conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; |
905 | 899 | |
... | ... | @@ -982,8 +976,13 @@ |
982 | 976 | #endif |
983 | 977 | nf_conntrack_get(&conntrack->master->ct_general); |
984 | 978 | NF_CT_STAT_INC(expect_new); |
985 | - } else | |
979 | + } else { | |
980 | + struct nf_conn_help *help = nfct_help(conntrack); | |
981 | + | |
982 | + if (help) | |
983 | + help->helper = __nf_ct_helper_find(&repl_tuple); | |
986 | 984 | NF_CT_STAT_INC(new); |
985 | + } | |
987 | 986 | |
988 | 987 | /* Overload tuple linked list to put us in unconfirmed list. */ |
989 | 988 | list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed); |
net/netfilter/nf_conntrack_netlink.c
... | ... | @@ -161,6 +161,7 @@ |
161 | 161 | return ret; |
162 | 162 | |
163 | 163 | nfattr_failure: |
164 | + nf_ct_proto_put(proto); | |
164 | 165 | return -1; |
165 | 166 | } |
166 | 167 | |
... | ... | @@ -949,6 +950,7 @@ |
949 | 950 | { |
950 | 951 | struct nf_conn *ct; |
951 | 952 | int err = -EINVAL; |
953 | + struct nf_conn_help *help; | |
952 | 954 | |
953 | 955 | ct = nf_conntrack_alloc(otuple, rtuple); |
954 | 956 | if (ct == NULL || IS_ERR(ct)) |
955 | 957 | |
... | ... | @@ -976,8 +978,15 @@ |
976 | 978 | ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); |
977 | 979 | #endif |
978 | 980 | |
981 | + help = nfct_help(ct); | |
982 | + if (help) | |
983 | + help->helper = nf_ct_helper_find_get(rtuple); | |
984 | + | |
979 | 985 | add_timer(&ct->timeout); |
980 | 986 | nf_conntrack_hash_insert(ct); |
987 | + | |
988 | + if (help && help->helper) | |
989 | + nf_ct_helper_put(help->helper); | |
981 | 990 | |
982 | 991 | return 0; |
983 | 992 |