Commit 1275361c407d17d56717cd706785a31c2353d696

Authored by Linus Torvalds

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
... ... @@ -153,6 +153,7 @@
153 153 return ret;
154 154  
155 155 nfattr_failure:
  156 + ip_conntrack_proto_put(proto);
156 157 return -1;
157 158 }
158 159  
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