1 # This is a BitKeeper generated patch for the following project:
2 # Project Name: Linux kernel tree
3 # This patch format is intended for GNU patch command version 2.5 or higher.
4 # This patch includes the following deltas:
5 # ChangeSet 1.1142 -> 1.1143
6 # net/ipv4/netfilter/ip_conntrack_core.c 1.17 -> 1.18
7 # include/linux/sysctl.h 1.22 -> 1.23
8 # net/ipv6/tcp_ipv6.c 1.21 -> 1.22
9 # include/net/tcp.h 1.21 -> 1.22
10 # net/ipv4/tcp.c 1.25 -> 1.26
11 # net/ipv4/tcp_ipv4.c 1.20 -> 1.21
12 # net/ipv4/route.c 1.21 -> 1.22
13 # (new) -> 1.1 include/linux/jhash.h
15 # The following is the BitKeeper ChangeSet Log
16 # --------------------------------------------
17 # 03/05/03 davem@nuts.ninka.net 1.1143
18 # [NET]: Fix hashing exploits in ipv4 routing, IP conntrack, and TCP synq.
20 # Several hash table implementations in the networking were
21 # remotely exploitable. Remote attackers could launch attacks
22 # whereby, using carefully choosen forged source addresses, make
23 # every routing cache entry get hashed into the same hash chain.
25 # Netfilter's IP conntrack module and the TCP syn-queue implementation
26 # had identical vulnerabilities and have been fixed too.
28 # The choosen solution to the problem involved using Bob's Jenkins
29 # hash along with a randomly choosen input. For the ipv4 routing
30 # cache we take things one step further and periodically choose a
31 # new random secret. By default this happens every 10 minutes, but
32 # this is configurable by the user via sysctl knobs.
33 # --------------------------------------------
35 diff -Nru a/include/net/tcp.h b/include/net/tcp.h
36 --- a/include/net/tcp.h Tue May 6 02:39:57 2003
37 +++ b/include/net/tcp.h Tue May 6 02:39:57 2003
43 struct open_request *syn_table[TCP_SYNQ_HSIZE];
46 diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
47 --- a/net/ipv4/route.c Tue May 6 02:39:57 2003
48 +++ b/net/ipv4/route.c Tue May 6 02:39:57 2003
50 #include <linux/mroute.h>
51 #include <linux/netfilter_ipv4.h>
52 #include <linux/random.h>
53 +#include <linux/jhash.h>
54 #include <net/protocol.h>
56 #include <net/route.h>
58 int ip_rt_mtu_expires = 10 * 60 * HZ;
59 int ip_rt_min_pmtu = 512 + 20 + 20;
60 int ip_rt_min_advmss = 256;
62 +int ip_rt_secret_interval = 10 * 60 * HZ;
63 static unsigned long rt_deadline;
65 #define RTprint(a...) printk(KERN_DEBUG a)
67 static struct timer_list rt_flush_timer;
68 static struct timer_list rt_periodic_timer;
69 +static struct timer_list rt_secret_timer;
72 * Interface to generic destination cache.
74 static struct rt_hash_bucket *rt_hash_table;
75 static unsigned rt_hash_mask;
76 static int rt_hash_log;
77 +static unsigned int rt_hash_rnd;
79 struct rt_cache_stat rt_cache_stat[NR_CPUS];
81 static int rt_intern_hash(unsigned hash, struct rtable *rth,
84 -static __inline__ unsigned rt_hash_code(u32 daddr, u32 saddr, u8 tos)
85 +static unsigned int rt_hash_code(u32 daddr, u32 saddr, u8 tos)
87 - unsigned hash = ((daddr & 0xF0F0F0F0) >> 4) |
88 - ((daddr & 0x0F0F0F0F) << 4);
89 - hash ^= saddr ^ tos;
90 - hash ^= (hash >> 16);
91 - return (hash ^ (hash >> 8)) & rt_hash_mask;
92 + return (jenkins_hash_3words(daddr, saddr, (u32) tos, rt_hash_rnd)
96 static int rt_cache_get_info(char *buffer, char **start, off_t offset,
98 spin_unlock_bh(&rt_flush_lock);
101 +static void rt_secret_rebuild(unsigned long dummy)
103 + unsigned long now = jiffies;
105 + get_random_bytes(&rt_hash_rnd, 4);
107 + mod_timer(&rt_secret_timer, now + ip_rt_secret_interval);
111 Short description of GC goals.
113 @@ -2414,6 +2423,15 @@
115 proc_handler: &proc_dointvec,
118 + ctl_name: NET_IPV4_ROUTE_SECRET_INTERVAL,
119 + procname: "secret_interval",
120 + data: &ip_rt_secret_interval,
121 + maxlen: sizeof(int),
123 + proc_handler: &proc_dointvec_jiffies,
124 + strategy: &sysctl_jiffies,
129 @@ -2444,15 +2462,25 @@
133 - /* Copy first cpu. */
135 - memcpy(buffer, IP_RT_ACCT_CPU(0), length);
137 - /* Add the other cpus in, one int at a time */
138 - for (i = 1; i < smp_num_cpus; i++) {
140 - for (j = 0; j < length/4; j++)
141 - ((u32*)buffer)[j] += ((u32*)IP_RT_ACCT_CPU(i))[j];
142 + offset /= sizeof(u32);
145 + u32 *src = ((u32 *) IP_RT_ACCT_CPU(0)) + offset;
146 + u32 *dst = (u32 *) buffer;
148 + /* Copy first cpu. */
150 + memcpy(dst, src, length);
152 + /* Add the other cpus in, one int at a time */
153 + for (i = 1; i < smp_num_cpus; i++) {
156 + src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset;
158 + for (j = 0; j < length/4; j++)
164 @@ -2462,6 +2490,9 @@
168 + rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^
169 + (jiffies ^ (jiffies >> 7)));
171 #ifdef CONFIG_NET_CLS_ROUTE
173 (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++)
174 @@ -2518,6 +2549,7 @@
176 rt_flush_timer.function = rt_run_flush;
177 rt_periodic_timer.function = rt_check_expire;
178 + rt_secret_timer.function = rt_secret_rebuild;
180 /* All the timers, started at system startup tend
181 to synchronize. Perturb it a bit.
182 @@ -2525,6 +2557,10 @@
183 rt_periodic_timer.expires = jiffies + net_random() % ip_rt_gc_interval +
185 add_timer(&rt_periodic_timer);
187 + rt_secret_timer.expires = jiffies + net_random() % ip_rt_secret_interval +
188 + ip_rt_secret_interval;
189 + add_timer(&rt_secret_timer);
191 proc_net_create ("rt_cache", 0, rt_cache_get_info);
192 proc_net_create ("rt_cache_stat", 0, rt_cache_stat_get_info);
193 diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
194 --- a/net/ipv4/tcp.c Tue May 6 02:39:57 2003
195 +++ b/net/ipv4/tcp.c Tue May 6 02:39:57 2003
197 #include <linux/init.h>
198 #include <linux/smp_lock.h>
199 #include <linux/fs.h>
200 +#include <linux/random.h>
202 #include <net/icmp.h>
205 for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++)
206 if ((1<<lopt->max_qlen_log) >= sysctl_max_syn_backlog)
208 + get_random_bytes(&lopt->hash_rnd, 4);
210 write_lock_bh(&tp->syn_wait_lock);
211 tp->listen_opt = lopt;
212 diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
213 --- a/net/ipv4/tcp_ipv4.c Tue May 6 02:39:57 2003
214 +++ b/net/ipv4/tcp_ipv4.c Tue May 6 02:39:57 2003
216 #include <linux/fcntl.h>
217 #include <linux/random.h>
218 #include <linux/cache.h>
219 +#include <linux/jhash.h>
220 #include <linux/init.h>
222 #include <net/icmp.h>
223 @@ -868,12 +869,10 @@
224 return ((struct rtable*)skb->dst)->rt_iif;
227 -static __inline__ unsigned tcp_v4_synq_hash(u32 raddr, u16 rport)
228 +static __inline__ u32 tcp_v4_synq_hash(u32 raddr, u16 rport, u32 rnd)
230 - unsigned h = raddr ^ rport;
233 - return h&(TCP_SYNQ_HSIZE-1);
234 + return (jenkins_hash_2words(raddr, (u32) rport, rnd)
235 + & (TCP_SYNQ_HSIZE - 1));
238 static struct open_request *tcp_v4_search_req(struct tcp_opt *tp,
240 struct tcp_listen_opt *lopt = tp->listen_opt;
241 struct open_request *req, **prev;
243 - for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport)];
244 + for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport, lopt->hash_rnd)];
245 (req = *prev) != NULL;
246 prev = &req->dl_next) {
247 if (req->rmt_port == rport &&
250 struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
251 struct tcp_listen_opt *lopt = tp->listen_opt;
252 - unsigned h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port);
253 + u32 h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port, lopt->hash_rnd);
255 req->expires = jiffies + TCP_TIMEOUT_INIT;
257 diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
258 --- a/net/ipv6/tcp_ipv6.c Tue May 6 02:39:57 2003
259 +++ b/net/ipv6/tcp_ipv6.c Tue May 6 02:39:57 2003
261 #include <linux/in6.h>
262 #include <linux/netdevice.h>
263 #include <linux/init.h>
264 +#include <linux/jhash.h>
265 #include <linux/ipsec.h>
267 #include <linux/ipv6.h>
268 @@ -368,12 +369,12 @@
269 * Open request hash tables.
272 -static __inline__ unsigned tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport)
273 +static u32 tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport, u32 rnd)
275 - unsigned h = raddr->s6_addr32[3] ^ rport;
278 - return h&(TCP_SYNQ_HSIZE-1);
279 + return (jenkins_hash_3words(raddr->s6_addr32[0] ^ raddr->s6_addr32[1],
280 + raddr->s6_addr32[2] ^ raddr->s6_addr32[3],
282 + & (TCP_SYNQ_HSIZE - 1));
285 static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
287 struct tcp_listen_opt *lopt = tp->listen_opt;
288 struct open_request *req, **prev;
290 - for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport)];
291 + for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
292 (req = *prev) != NULL;
293 prev = &req->dl_next) {
294 if (req->rmt_port == rport &&
295 @@ -1135,7 +1136,7 @@
297 struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
298 struct tcp_listen_opt *lopt = tp->listen_opt;
299 - unsigned h = tcp_v6_synq_hash(&req->af.v6_req.rmt_addr, req->rmt_port);
300 + u32 h = tcp_v6_synq_hash(&req->af.v6_req.rmt_addr, req->rmt_port, lopt->hash_rnd);
303 req->expires = jiffies + TCP_TIMEOUT_INIT;
304 # This is a BitKeeper generated patch for the following project:
305 # Project Name: Linux kernel tree
306 # This patch format is intended for GNU patch command version 2.5 or higher.
307 # This patch includes the following deltas:
308 # ChangeSet 1.1144 -> 1.1145
309 # net/ipv4/netfilter/ip_conntrack_core.c 1.18 -> 1.19
310 # net/ipv6/tcp_ipv6.c 1.22 -> 1.23
311 # net/ipv4/tcp_ipv4.c 1.21 -> 1.22
312 # include/linux/jhash.h 1.1 -> 1.2
313 # net/ipv4/route.c 1.22 -> 1.23
315 # The following is the BitKeeper ChangeSet Log
316 # --------------------------------------------
317 # 03/05/03 jmorris@intercode.com.au 1.1145
318 # [NET]: Cosmetic cleanups of jhash code.
319 # - Consistent naming (i.e. jhash_xxx)
320 # - Reduces the 2&1 word variants to call jhash_3words()
321 # - Replaces __inline__ with inline.
322 # --------------------------------------------
324 diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
325 --- a/net/ipv4/route.c Tue May 6 02:40:04 2003
326 +++ b/net/ipv4/route.c Tue May 6 02:40:04 2003
329 static unsigned int rt_hash_code(u32 daddr, u32 saddr, u8 tos)
331 - return (jenkins_hash_3words(daddr, saddr, (u32) tos, rt_hash_rnd)
332 + return (jhash_3words(daddr, saddr, (u32) tos, rt_hash_rnd)
336 diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
337 --- a/net/ipv4/tcp_ipv4.c Tue May 6 02:40:04 2003
338 +++ b/net/ipv4/tcp_ipv4.c Tue May 6 02:40:04 2003
341 static __inline__ u32 tcp_v4_synq_hash(u32 raddr, u16 rport, u32 rnd)
343 - return (jenkins_hash_2words(raddr, (u32) rport, rnd)
344 - & (TCP_SYNQ_HSIZE - 1));
345 + return (jhash_2words(raddr, (u32) rport, rnd) & (TCP_SYNQ_HSIZE - 1));
348 static struct open_request *tcp_v4_search_req(struct tcp_opt *tp,
349 diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
350 --- a/net/ipv6/tcp_ipv6.c Tue May 6 02:40:04 2003
351 +++ b/net/ipv6/tcp_ipv6.c Tue May 6 02:40:04 2003
354 static u32 tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport, u32 rnd)
356 - return (jenkins_hash_3words(raddr->s6_addr32[0] ^ raddr->s6_addr32[1],
357 - raddr->s6_addr32[2] ^ raddr->s6_addr32[3],
359 - & (TCP_SYNQ_HSIZE - 1));
360 + return (jhash_3words(raddr->s6_addr32[0] ^ raddr->s6_addr32[1],
361 + raddr->s6_addr32[2] ^ raddr->s6_addr32[3],
362 + (u32) rport, rnd) & (TCP_SYNQ_HSIZE - 1));
365 static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
366 # This is a BitKeeper generated patch for the following project:
367 # Project Name: Linux kernel tree
368 # This patch format is intended for GNU patch command version 2.5 or higher.
369 # This patch includes the following deltas:
370 # ChangeSet 1.1145 -> 1.1146
371 # net/ipv4/route.c 1.23 -> 1.24
373 # The following is the BitKeeper ChangeSet Log
374 # --------------------------------------------
375 # 03/05/04 jmorris@intercode.com.au 1.1146
376 # [IPV4]: Choose new rt_hash_rnd every rt_run_flush.
377 # --------------------------------------------
379 diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
380 --- a/net/ipv4/route.c Tue May 6 02:40:09 2003
381 +++ b/net/ipv4/route.c Tue May 6 02:40:09 2003
386 + get_random_bytes(&rt_hash_rnd, 4);
388 for (i = rt_hash_mask; i >= 0; i--) {
389 write_lock_bh(&rt_hash_table[i].lock);
390 rth = rt_hash_table[i].chain;
393 unsigned long now = jiffies;
395 - get_random_bytes(&rt_hash_rnd, 4);
397 mod_timer(&rt_secret_timer, now + ip_rt_secret_interval);
399 # This is a BitKeeper generated patch for the following project:
400 # Project Name: Linux kernel tree
401 # This patch format is intended for GNU patch command version 2.5 or higher.
402 # This patch includes the following deltas:
403 # ChangeSet 1.1094 -> 1.1095
404 # net/ipv4/tcp_minisocks.c 1.27 -> 1.28
406 # The following is the BitKeeper ChangeSet Log
407 # --------------------------------------------
408 # 03/05/07 olof@austin.ibm.com 1.1095
409 # [TCP]: tcp_twkill leaves death row list in inconsistent state over tcp_timewait_kill.
410 # --------------------------------------------
412 diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
413 --- a/net/ipv4/tcp_minisocks.c Wed May 7 02:29:49 2003
414 +++ b/net/ipv4/tcp_minisocks.c Wed May 7 02:29:49 2003
417 while((tw = tcp_tw_death_row[tcp_tw_death_row_slot]) != NULL) {
418 tcp_tw_death_row[tcp_tw_death_row_slot] = tw->next_death;
419 + if (tw->next_death)
420 + tw->next_death->pprev_death = tw->pprev_death;
421 tw->pprev_death = NULL;
422 spin_unlock(&tw_death_lock);