]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.20-nethashfix.patch
- added description of djurban's branch
[packages/kernel.git] / linux-2.4.20-nethashfix.patch
CommitLineData
e6ffc12d
JB
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
14#
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.
19#
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.
24#
25# Netfilter's IP conntrack module and the TCP syn-queue implementation
26# had identical vulnerabilities and have been fixed too.
27#
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# --------------------------------------------
34#
e6ffc12d
JB
35diff -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
38@@ -1604,6 +1604,7 @@
39 int qlen;
40 int qlen_young;
41 int clock_hand;
42+ u32 hash_rnd;
43 struct open_request *syn_table[TCP_SYNQ_HSIZE];
44 };
45
e6ffc12d
JB
46diff -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
49@@ -85,6 +85,7 @@
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>
55 #include <net/ip.h>
56 #include <net/route.h>
57@@ -117,13 +118,14 @@
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;
61-
62+int ip_rt_secret_interval = 10 * 60 * HZ;
63 static unsigned long rt_deadline;
64
65 #define RTprint(a...) printk(KERN_DEBUG a)
66
67 static struct timer_list rt_flush_timer;
68 static struct timer_list rt_periodic_timer;
69+static struct timer_list rt_secret_timer;
70
71 /*
72 * Interface to generic destination cache.
73@@ -194,19 +196,17 @@
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;
78
79 struct rt_cache_stat rt_cache_stat[NR_CPUS];
80
81 static int rt_intern_hash(unsigned hash, struct rtable *rth,
82 struct rtable **res);
83
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)
86 {
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)
93+ & rt_hash_mask);
94 }
95
96 static int rt_cache_get_info(char *buffer, char **start, off_t offset,
97@@ -479,6 +479,15 @@
98 spin_unlock_bh(&rt_flush_lock);
99 }
100
101+static void rt_secret_rebuild(unsigned long dummy)
102+{
103+ unsigned long now = jiffies;
104+
105+ get_random_bytes(&rt_hash_rnd, 4);
106+ rt_cache_flush(0);
107+ mod_timer(&rt_secret_timer, now + ip_rt_secret_interval);
108+}
109+
110 /*
111 Short description of GC goals.
112
113@@ -2414,6 +2423,15 @@
114 mode: 0644,
115 proc_handler: &proc_dointvec,
116 },
117+ {
118+ ctl_name: NET_IPV4_ROUTE_SECRET_INTERVAL,
119+ procname: "secret_interval",
120+ data: &ip_rt_secret_interval,
121+ maxlen: sizeof(int),
122+ mode: 0644,
123+ proc_handler: &proc_dointvec_jiffies,
124+ strategy: &sysctl_jiffies,
125+ },
126 { 0 }
127 };
128 #endif
129@@ -2444,15 +2462,25 @@
130 *eof = 1;
131 }
132
133- /* Copy first cpu. */
134- *start = buffer;
135- memcpy(buffer, IP_RT_ACCT_CPU(0), length);
136-
137- /* Add the other cpus in, one int at a time */
138- for (i = 1; i < smp_num_cpus; i++) {
139- unsigned int j;
140- for (j = 0; j < length/4; j++)
141- ((u32*)buffer)[j] += ((u32*)IP_RT_ACCT_CPU(i))[j];
142+ offset /= sizeof(u32);
143+
144+ if (length > 0) {
145+ u32 *src = ((u32 *) IP_RT_ACCT_CPU(0)) + offset;
146+ u32 *dst = (u32 *) buffer;
147+
148+ /* Copy first cpu. */
149+ *start = buffer;
150+ memcpy(dst, src, length);
151+
152+ /* Add the other cpus in, one int at a time */
153+ for (i = 1; i < smp_num_cpus; i++) {
154+ unsigned int j;
155+
156+ src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset;
157+
158+ for (j = 0; j < length/4; j++)
159+ dst[j] += src[j];
160+ }
161 }
162 return length;
163 }
164@@ -2462,6 +2490,9 @@
165 {
166 int i, order, goal;
167
168+ rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^
169+ (jiffies ^ (jiffies >> 7)));
170+
171 #ifdef CONFIG_NET_CLS_ROUTE
172 for (order = 0;
173 (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++)
174@@ -2518,6 +2549,7 @@
175
176 rt_flush_timer.function = rt_run_flush;
177 rt_periodic_timer.function = rt_check_expire;
178+ rt_secret_timer.function = rt_secret_rebuild;
179
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 +
184 ip_rt_gc_interval;
185 add_timer(&rt_periodic_timer);
186+
187+ rt_secret_timer.expires = jiffies + net_random() % ip_rt_secret_interval +
188+ ip_rt_secret_interval;
189+ add_timer(&rt_secret_timer);
190
191 proc_net_create ("rt_cache", 0, rt_cache_get_info);
192 proc_net_create ("rt_cache_stat", 0, rt_cache_stat_get_info);
193diff -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
196@@ -252,6 +252,7 @@
197 #include <linux/init.h>
198 #include <linux/smp_lock.h>
199 #include <linux/fs.h>
200+#include <linux/random.h>
201
202 #include <net/icmp.h>
203 #include <net/tcp.h>
204@@ -542,6 +543,7 @@
205 for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++)
206 if ((1<<lopt->max_qlen_log) >= sysctl_max_syn_backlog)
207 break;
208+ get_random_bytes(&lopt->hash_rnd, 4);
209
210 write_lock_bh(&tp->syn_wait_lock);
211 tp->listen_opt = lopt;
212diff -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
215@@ -56,6 +56,7 @@
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>
221
222 #include <net/icmp.h>
223@@ -868,12 +869,10 @@
224 return ((struct rtable*)skb->dst)->rt_iif;
225 }
226
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)
229 {
230- unsigned h = raddr ^ rport;
231- h ^= h>>16;
232- h ^= h>>8;
233- return h&(TCP_SYNQ_HSIZE-1);
234+ return (jenkins_hash_2words(raddr, (u32) rport, rnd)
235+ & (TCP_SYNQ_HSIZE - 1));
236 }
237
238 static struct open_request *tcp_v4_search_req(struct tcp_opt *tp,
239@@ -884,7 +883,7 @@
240 struct tcp_listen_opt *lopt = tp->listen_opt;
241 struct open_request *req, **prev;
242
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 &&
248@@ -904,7 +903,7 @@
249 {
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);
254
255 req->expires = jiffies + TCP_TIMEOUT_INIT;
256 req->retrans = 0;
257diff -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
260@@ -36,6 +36,7 @@
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>
266
267 #include <linux/ipv6.h>
268@@ -368,12 +369,12 @@
269 * Open request hash tables.
270 */
271
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)
274 {
275- unsigned h = raddr->s6_addr32[3] ^ rport;
276- h ^= h>>16;
277- h ^= h>>8;
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],
281+ (u32) rport, rnd)
282+ & (TCP_SYNQ_HSIZE - 1));
283 }
284
285 static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
286@@ -386,7 +387,7 @@
287 struct tcp_listen_opt *lopt = tp->listen_opt;
288 struct open_request *req, **prev;
289
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 @@
296 {
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);
301
302 req->sk = NULL;
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
314#
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# --------------------------------------------
323#
e6ffc12d
JB
324diff -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
327@@ -205,7 +205,7 @@
328
329 static unsigned int rt_hash_code(u32 daddr, u32 saddr, u8 tos)
330 {
331- return (jenkins_hash_3words(daddr, saddr, (u32) tos, rt_hash_rnd)
332+ return (jhash_3words(daddr, saddr, (u32) tos, rt_hash_rnd)
333 & rt_hash_mask);
334 }
335
336diff -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
339@@ -871,8 +871,7 @@
340
341 static __inline__ u32 tcp_v4_synq_hash(u32 raddr, u16 rport, u32 rnd)
342 {
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));
346 }
347
348 static struct open_request *tcp_v4_search_req(struct tcp_opt *tp,
349diff -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
352@@ -371,10 +371,9 @@
353
354 static u32 tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport, u32 rnd)
355 {
356- return (jenkins_hash_3words(raddr->s6_addr32[0] ^ raddr->s6_addr32[1],
357- raddr->s6_addr32[2] ^ raddr->s6_addr32[3],
358- (u32) rport, rnd)
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));
363 }
364
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
372#
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# --------------------------------------------
378#
379diff -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
382@@ -421,6 +421,8 @@
383
384 rt_deadline = 0;
385
386+ get_random_bytes(&rt_hash_rnd, 4);
387+
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;
391@@ -483,7 +485,6 @@
392 {
393 unsigned long now = jiffies;
394
395- get_random_bytes(&rt_hash_rnd, 4);
396 rt_cache_flush(0);
397 mod_timer(&rt_secret_timer, now + ip_rt_secret_interval);
398 }
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
405#
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# --------------------------------------------
411#
412diff -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
415@@ -444,6 +444,8 @@
416
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);
423
This page took 0.426127 seconds and 4 git commands to generate.