1 |
Author: dsd |
2 |
Date: 2008-02-26 14:29:50 +0000 (Tue, 26 Feb 2008) |
3 |
New Revision: 1259 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/2.6.23/1015_linux-2.6.23.16.patch |
7 |
genpatches-2.6/trunk/2.6.23/1016_linux-2.6.23.17.patch |
8 |
Removed: |
9 |
genpatches-2.6/trunk/2.6.23/1400_vmsplice-user-pointer.patch |
10 |
genpatches-2.6/trunk/2.6.23/1500_get-zero-user-pages.patch |
11 |
Modified: |
12 |
genpatches-2.6/trunk/2.6.23/0000_README |
13 |
Log: |
14 |
Linux 2.6.23.17 |
15 |
|
16 |
Modified: genpatches-2.6/trunk/2.6.23/0000_README |
17 |
=================================================================== |
18 |
--- genpatches-2.6/trunk/2.6.23/0000_README 2008-02-26 14:22:03 UTC (rev 1258) |
19 |
+++ genpatches-2.6/trunk/2.6.23/0000_README 2008-02-26 14:29:50 UTC (rev 1259) |
20 |
@@ -99,13 +99,13 @@ |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 2.6.23.15 |
23 |
|
24 |
-Patch: 1400_vmsplice-user-pointer.patch |
25 |
-From: http://bugs.gentoo.org/209460 |
26 |
-Desc: Fix another vmsplice() security issue |
27 |
+Patch: 1015_linux-2.6.23.16.patch |
28 |
+From: http://www.kernel.org |
29 |
+Desc: Linux 2.6.23.16 |
30 |
|
31 |
-Patch: 1500_get-zero-user-pages.patch |
32 |
-From: http://bugs.gentoo.org/209460 |
33 |
-Desc: Preventative measure against future vmsplice-like security issues |
34 |
+Patch: 1016_linux-2.6.23.17.patch |
35 |
+From: http://www.kernel.org |
36 |
+Desc: Linux 2.6.23.17 |
37 |
|
38 |
Patch: 1700_moduleparam.patch |
39 |
From: http://bugs.gentoo.org/187175 |
40 |
|
41 |
Added: genpatches-2.6/trunk/2.6.23/1015_linux-2.6.23.16.patch |
42 |
=================================================================== |
43 |
--- genpatches-2.6/trunk/2.6.23/1015_linux-2.6.23.16.patch (rev 0) |
44 |
+++ genpatches-2.6/trunk/2.6.23/1015_linux-2.6.23.16.patch 2008-02-26 14:29:50 UTC (rev 1259) |
45 |
@@ -0,0 +1,13 @@ |
46 |
+diff --git a/fs/splice.c b/fs/splice.c |
47 |
+index 2aa8f5a..1a9c0e6 100644 |
48 |
+--- a/fs/splice.c |
49 |
++++ b/fs/splice.c |
50 |
+@@ -1289,7 +1289,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, |
51 |
+ if (unlikely(!len)) |
52 |
+ break; |
53 |
+ error = -EFAULT; |
54 |
+- if (unlikely(!base)) |
55 |
++ if (!access_ok(VERIFY_READ, base, len)) |
56 |
+ break; |
57 |
+ |
58 |
+ /* |
59 |
|
60 |
Added: genpatches-2.6/trunk/2.6.23/1016_linux-2.6.23.17.patch |
61 |
=================================================================== |
62 |
--- genpatches-2.6/trunk/2.6.23/1016_linux-2.6.23.17.patch (rev 0) |
63 |
+++ genpatches-2.6/trunk/2.6.23/1016_linux-2.6.23.17.patch 2008-02-26 14:29:50 UTC (rev 1259) |
64 |
@@ -0,0 +1,485 @@ |
65 |
+diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c |
66 |
+index ba931be..5169ecc 100644 |
67 |
+--- a/arch/powerpc/platforms/powermac/feature.c |
68 |
++++ b/arch/powerpc/platforms/powermac/feature.c |
69 |
+@@ -2565,6 +2565,8 @@ static void __init probe_uninorth(void) |
70 |
+ |
71 |
+ /* Locate core99 Uni-N */ |
72 |
+ uninorth_node = of_find_node_by_name(NULL, "uni-n"); |
73 |
++ uninorth_maj = 1; |
74 |
++ |
75 |
+ /* Locate G5 u3 */ |
76 |
+ if (uninorth_node == NULL) { |
77 |
+ uninorth_node = of_find_node_by_name(NULL, "u3"); |
78 |
+@@ -2575,8 +2577,10 @@ static void __init probe_uninorth(void) |
79 |
+ uninorth_node = of_find_node_by_name(NULL, "u4"); |
80 |
+ uninorth_maj = 4; |
81 |
+ } |
82 |
+- if (uninorth_node == NULL) |
83 |
++ if (uninorth_node == NULL) { |
84 |
++ uninorth_maj = 0; |
85 |
+ return; |
86 |
++ } |
87 |
+ |
88 |
+ addrp = of_get_property(uninorth_node, "reg", NULL); |
89 |
+ if (addrp == NULL) |
90 |
+@@ -3029,3 +3033,8 @@ void pmac_resume_agp_for_card(struct pci_dev *dev) |
91 |
+ pmac_agp_resume(pmac_agp_bridge); |
92 |
+ } |
93 |
+ EXPORT_SYMBOL(pmac_resume_agp_for_card); |
94 |
++ |
95 |
++int pmac_get_uninorth_variant(void) |
96 |
++{ |
97 |
++ return uninorth_maj; |
98 |
++} |
99 |
+diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c |
100 |
+index eff3b22..7770e10 100644 |
101 |
+--- a/arch/x86_64/mm/pageattr.c |
102 |
++++ b/arch/x86_64/mm/pageattr.c |
103 |
+@@ -207,7 +207,7 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) |
104 |
+ if (__pa(address) < KERNEL_TEXT_SIZE) { |
105 |
+ unsigned long addr2; |
106 |
+ pgprot_t prot2; |
107 |
+- addr2 = __START_KERNEL_map + __pa(address); |
108 |
++ addr2 = __START_KERNEL_map + __pa(address) - phys_base; |
109 |
+ /* Make sure the kernel mappings stay executable */ |
110 |
+ prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); |
111 |
+ err = __change_page_attr(addr2, pfn, prot2, |
112 |
+diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c |
113 |
+index d409f67..1ebe7a3 100644 |
114 |
+--- a/drivers/macintosh/smu.c |
115 |
++++ b/drivers/macintosh/smu.c |
116 |
+@@ -85,6 +85,7 @@ struct smu_device { |
117 |
+ u32 cmd_buf_abs; /* command buffer absolute */ |
118 |
+ struct list_head cmd_list; |
119 |
+ struct smu_cmd *cmd_cur; /* pending command */ |
120 |
++ int broken_nap; |
121 |
+ struct list_head cmd_i2c_list; |
122 |
+ struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ |
123 |
+ struct timer_list i2c_timer; |
124 |
+@@ -135,6 +136,19 @@ static void smu_start_cmd(void) |
125 |
+ fend = faddr + smu->cmd_buf->length + 2; |
126 |
+ flush_inval_dcache_range(faddr, fend); |
127 |
+ |
128 |
++ |
129 |
++ /* We also disable NAP mode for the duration of the command |
130 |
++ * on U3 based machines. |
131 |
++ * This is slightly racy as it can be written back to 1 by a sysctl |
132 |
++ * but that never happens in practice. There seem to be an issue with |
133 |
++ * U3 based machines such as the iMac G5 where napping for the |
134 |
++ * whole duration of the command prevents the SMU from fetching it |
135 |
++ * from memory. This might be related to the strange i2c based |
136 |
++ * mechanism the SMU uses to access memory. |
137 |
++ */ |
138 |
++ if (smu->broken_nap) |
139 |
++ powersave_nap = 0; |
140 |
++ |
141 |
+ /* This isn't exactly a DMA mapping here, I suspect |
142 |
+ * the SMU is actually communicating with us via i2c to the |
143 |
+ * northbridge or the CPU to access RAM. |
144 |
+@@ -211,6 +225,10 @@ static irqreturn_t smu_db_intr(int irq, void *arg) |
145 |
+ misc = cmd->misc; |
146 |
+ mb(); |
147 |
+ cmd->status = rc; |
148 |
++ |
149 |
++ /* Re-enable NAP mode */ |
150 |
++ if (smu->broken_nap) |
151 |
++ powersave_nap = 1; |
152 |
+ bail: |
153 |
+ /* Start next command if any */ |
154 |
+ smu_start_cmd(); |
155 |
+@@ -461,7 +479,7 @@ int __init smu_init (void) |
156 |
+ if (np == NULL) |
157 |
+ return -ENODEV; |
158 |
+ |
159 |
+- printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); |
160 |
++ printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR); |
161 |
+ |
162 |
+ if (smu_cmdbuf_abs == 0) { |
163 |
+ printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
164 |
+@@ -533,6 +551,11 @@ int __init smu_init (void) |
165 |
+ goto fail; |
166 |
+ } |
167 |
+ |
168 |
++ /* U3 has an issue with NAP mode when issuing SMU commands */ |
169 |
++ smu->broken_nap = pmac_get_uninorth_variant() < 4; |
170 |
++ if (smu->broken_nap) |
171 |
++ printk(KERN_INFO "SMU: using NAP mode workaround\n"); |
172 |
++ |
173 |
+ sys_ctrler = SYS_CTRLER_SMU; |
174 |
+ return 0; |
175 |
+ |
176 |
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c |
177 |
+index 2c6116f..2b28a24 100644 |
178 |
+--- a/drivers/scsi/sd.c |
179 |
++++ b/drivers/scsi/sd.c |
180 |
+@@ -901,6 +901,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) |
181 |
+ unsigned int xfer_size = SCpnt->request_bufflen; |
182 |
+ unsigned int good_bytes = result ? 0 : xfer_size; |
183 |
+ u64 start_lba = SCpnt->request->sector; |
184 |
++ u64 end_lba = SCpnt->request->sector + (xfer_size / 512); |
185 |
+ u64 bad_lba; |
186 |
+ struct scsi_sense_hdr sshdr; |
187 |
+ int sense_valid = 0; |
188 |
+@@ -939,26 +940,23 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) |
189 |
+ goto out; |
190 |
+ if (xfer_size <= SCpnt->device->sector_size) |
191 |
+ goto out; |
192 |
+- switch (SCpnt->device->sector_size) { |
193 |
+- case 256: |
194 |
++ if (SCpnt->device->sector_size < 512) { |
195 |
++ /* only legitimate sector_size here is 256 */ |
196 |
+ start_lba <<= 1; |
197 |
+- break; |
198 |
+- case 512: |
199 |
+- break; |
200 |
+- case 1024: |
201 |
+- start_lba >>= 1; |
202 |
+- break; |
203 |
+- case 2048: |
204 |
+- start_lba >>= 2; |
205 |
+- break; |
206 |
+- case 4096: |
207 |
+- start_lba >>= 3; |
208 |
+- break; |
209 |
+- default: |
210 |
+- /* Print something here with limiting frequency. */ |
211 |
+- goto out; |
212 |
+- break; |
213 |
++ end_lba <<= 1; |
214 |
++ } else { |
215 |
++ /* be careful ... don't want any overflows */ |
216 |
++ u64 factor = SCpnt->device->sector_size / 512; |
217 |
++ do_div(start_lba, factor); |
218 |
++ do_div(end_lba, factor); |
219 |
+ } |
220 |
++ |
221 |
++ if (bad_lba < start_lba || bad_lba >= end_lba) |
222 |
++ /* the bad lba was reported incorrectly, we have |
223 |
++ * no idea where the error is |
224 |
++ */ |
225 |
++ goto out; |
226 |
++ |
227 |
+ /* This computation should always be done in terms of |
228 |
+ * the resolution of the device's medium. |
229 |
+ */ |
230 |
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c |
231 |
+index a2a4865..331a5bb 100644 |
232 |
+--- a/fs/nfs/write.c |
233 |
++++ b/fs/nfs/write.c |
234 |
+@@ -717,6 +717,17 @@ int nfs_flush_incompatible(struct file *file, struct page *page) |
235 |
+ } |
236 |
+ |
237 |
+ /* |
238 |
++ * If the page cache is marked as unsafe or invalid, then we can't rely on |
239 |
++ * the PageUptodate() flag. In this case, we will need to turn off |
240 |
++ * write optimisations that depend on the page contents being correct. |
241 |
++ */ |
242 |
++static int nfs_write_pageuptodate(struct page *page, struct inode *inode) |
243 |
++{ |
244 |
++ return PageUptodate(page) && |
245 |
++ !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA)); |
246 |
++} |
247 |
++ |
248 |
++/* |
249 |
+ * Update and possibly write a cached page of an NFS file. |
250 |
+ * |
251 |
+ * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad |
252 |
+@@ -737,10 +748,13 @@ int nfs_updatepage(struct file *file, struct page *page, |
253 |
+ (long long)(page_offset(page) +offset)); |
254 |
+ |
255 |
+ /* If we're not using byte range locks, and we know the page |
256 |
+- * is entirely in cache, it may be more efficient to avoid |
257 |
+- * fragmenting write requests. |
258 |
++ * is up to date, it may be more efficient to extend the write |
259 |
++ * to cover the entire page in order to avoid fragmentation |
260 |
++ * inefficiencies. |
261 |
+ */ |
262 |
+- if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { |
263 |
++ if (nfs_write_pageuptodate(page, inode) && |
264 |
++ inode->i_flock == NULL && |
265 |
++ !(file->f_mode & O_SYNC)) { |
266 |
+ count = max(count + offset, nfs_page_length(page)); |
267 |
+ offset = 0; |
268 |
+ } |
269 |
+diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h |
270 |
+index 26bcb0a..877c35a 100644 |
271 |
+--- a/include/asm-powerpc/pmac_feature.h |
272 |
++++ b/include/asm-powerpc/pmac_feature.h |
273 |
+@@ -392,6 +392,14 @@ extern u32 __iomem *uninorth_base; |
274 |
+ #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) |
275 |
+ #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) |
276 |
+ |
277 |
++/* Uninorth variant: |
278 |
++ * |
279 |
++ * 0 = not uninorth |
280 |
++ * 1 = U1.x or U2.x |
281 |
++ * 3 = U3 |
282 |
++ * 4 = U4 |
283 |
++ */ |
284 |
++extern int pmac_get_uninorth_variant(void); |
285 |
+ |
286 |
+ #endif /* __ASM_POWERPC_PMAC_FEATURE_H */ |
287 |
+ #endif /* __KERNEL__ */ |
288 |
+diff --git a/include/linux/ktime.h b/include/linux/ktime.h |
289 |
+index dae7143..15a0229 100644 |
290 |
+--- a/include/linux/ktime.h |
291 |
++++ b/include/linux/ktime.h |
292 |
+@@ -289,6 +289,8 @@ static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec) |
293 |
+ return ktime_add_ns(kt, usec * 1000); |
294 |
+ } |
295 |
+ |
296 |
++extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs); |
297 |
++ |
298 |
+ /* |
299 |
+ * The resolution of the clocks. The resolution value is returned in |
300 |
+ * the clock_getres() system call to give application programmers an |
301 |
+diff --git a/kernel/futex.c b/kernel/futex.c |
302 |
+index b658a9a..0c55a58 100644 |
303 |
+--- a/kernel/futex.c |
304 |
++++ b/kernel/futex.c |
305 |
+@@ -2063,7 +2063,7 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, |
306 |
+ |
307 |
+ t = timespec_to_ktime(ts); |
308 |
+ if (cmd == FUTEX_WAIT) |
309 |
+- t = ktime_add(ktime_get(), t); |
310 |
++ t = ktime_add_safe(ktime_get(), t); |
311 |
+ tp = &t; |
312 |
+ } |
313 |
+ /* |
314 |
+diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c |
315 |
+index f938c23..bba74b6 100644 |
316 |
+--- a/kernel/futex_compat.c |
317 |
++++ b/kernel/futex_compat.c |
318 |
+@@ -175,7 +175,7 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, |
319 |
+ |
320 |
+ t = timespec_to_ktime(ts); |
321 |
+ if (cmd == FUTEX_WAIT) |
322 |
+- t = ktime_add(ktime_get(), t); |
323 |
++ t = ktime_add_safe(ktime_get(), t); |
324 |
+ tp = &t; |
325 |
+ } |
326 |
+ if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) |
327 |
+diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c |
328 |
+index ee8d0ac..2ee0497 100644 |
329 |
+--- a/kernel/hrtimer.c |
330 |
++++ b/kernel/hrtimer.c |
331 |
+@@ -301,6 +301,24 @@ unsigned long ktime_divns(const ktime_t kt, s64 div) |
332 |
+ } |
333 |
+ #endif /* BITS_PER_LONG >= 64 */ |
334 |
+ |
335 |
++/* |
336 |
++ * Add two ktime values and do a safety check for overflow: |
337 |
++ */ |
338 |
++ |
339 |
++ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) |
340 |
++{ |
341 |
++ ktime_t res = ktime_add(lhs, rhs); |
342 |
++ |
343 |
++ /* |
344 |
++ * We use KTIME_SEC_MAX here, the maximum timeout which we can |
345 |
++ * return to user space in a timespec: |
346 |
++ */ |
347 |
++ if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) |
348 |
++ res = ktime_set(KTIME_SEC_MAX, 0); |
349 |
++ |
350 |
++ return res; |
351 |
++} |
352 |
++ |
353 |
+ /* High resolution timer related functions */ |
354 |
+ #ifdef CONFIG_HIGH_RES_TIMERS |
355 |
+ |
356 |
+@@ -658,13 +676,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) |
357 |
+ */ |
358 |
+ orun++; |
359 |
+ } |
360 |
+- timer->expires = ktime_add(timer->expires, interval); |
361 |
+- /* |
362 |
+- * Make sure, that the result did not wrap with a very large |
363 |
+- * interval. |
364 |
+- */ |
365 |
+- if (timer->expires.tv64 < 0) |
366 |
+- timer->expires = ktime_set(KTIME_SEC_MAX, 0); |
367 |
++ timer->expires = ktime_add_safe(timer->expires, interval); |
368 |
+ |
369 |
+ return orun; |
370 |
+ } |
371 |
+@@ -815,7 +827,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) |
372 |
+ new_base = switch_hrtimer_base(timer, base); |
373 |
+ |
374 |
+ if (mode == HRTIMER_MODE_REL) { |
375 |
+- tim = ktime_add(tim, new_base->get_time()); |
376 |
++ tim = ktime_add_safe(tim, new_base->get_time()); |
377 |
+ /* |
378 |
+ * CONFIG_TIME_LOW_RES is a temporary way for architectures |
379 |
+ * to signal that they simply return xtime in |
380 |
+@@ -824,16 +836,8 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) |
381 |
+ * timeouts. This will go away with the GTOD framework. |
382 |
+ */ |
383 |
+ #ifdef CONFIG_TIME_LOW_RES |
384 |
+- tim = ktime_add(tim, base->resolution); |
385 |
++ tim = ktime_add_safe(tim, base->resolution); |
386 |
+ #endif |
387 |
+- /* |
388 |
+- * Careful here: User space might have asked for a |
389 |
+- * very long sleep, so the add above might result in a |
390 |
+- * negative number, which enqueues the timer in front |
391 |
+- * of the queue. |
392 |
+- */ |
393 |
+- if (tim.tv64 < 0) |
394 |
+- tim.tv64 = KTIME_MAX; |
395 |
+ } |
396 |
+ timer->expires = tim; |
397 |
+ |
398 |
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c |
399 |
+index f1a73f0..7279484 100644 |
400 |
+--- a/kernel/irq/chip.c |
401 |
++++ b/kernel/irq/chip.c |
402 |
+@@ -246,6 +246,17 @@ static unsigned int default_startup(unsigned int irq) |
403 |
+ } |
404 |
+ |
405 |
+ /* |
406 |
++ * default shutdown function |
407 |
++ */ |
408 |
++static void default_shutdown(unsigned int irq) |
409 |
++{ |
410 |
++ struct irq_desc *desc = irq_desc + irq; |
411 |
++ |
412 |
++ desc->chip->mask(irq); |
413 |
++ desc->status |= IRQ_MASKED; |
414 |
++} |
415 |
++ |
416 |
++/* |
417 |
+ * Fixup enable/disable function pointers |
418 |
+ */ |
419 |
+ void irq_chip_set_defaults(struct irq_chip *chip) |
420 |
+@@ -256,8 +267,15 @@ void irq_chip_set_defaults(struct irq_chip *chip) |
421 |
+ chip->disable = default_disable; |
422 |
+ if (!chip->startup) |
423 |
+ chip->startup = default_startup; |
424 |
++ /* |
425 |
++ * We use chip->disable, when the user provided its own. When |
426 |
++ * we have default_disable set for chip->disable, then we need |
427 |
++ * to use default_shutdown, otherwise the irq line is not |
428 |
++ * disabled on free_irq(): |
429 |
++ */ |
430 |
+ if (!chip->shutdown) |
431 |
+- chip->shutdown = chip->disable; |
432 |
++ chip->shutdown = chip->disable != default_disable ? |
433 |
++ chip->disable : default_shutdown; |
434 |
+ if (!chip->name) |
435 |
+ chip->name = chip->typename; |
436 |
+ if (!chip->end) |
437 |
+diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c |
438 |
+index 7a15afb..00c9e25 100644 |
439 |
+--- a/kernel/posix-timers.c |
440 |
++++ b/kernel/posix-timers.c |
441 |
+@@ -765,9 +765,11 @@ common_timer_set(struct k_itimer *timr, int flags, |
442 |
+ /* SIGEV_NONE timers are not queued ! See common_timer_get */ |
443 |
+ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { |
444 |
+ /* Setup correct expiry time for relative timers */ |
445 |
+- if (mode == HRTIMER_MODE_REL) |
446 |
+- timer->expires = ktime_add(timer->expires, |
447 |
+- timer->base->get_time()); |
448 |
++ if (mode == HRTIMER_MODE_REL) { |
449 |
++ timer->expires = |
450 |
++ ktime_add_safe(timer->expires, |
451 |
++ timer->base->get_time()); |
452 |
++ } |
453 |
+ return 0; |
454 |
+ } |
455 |
+ |
456 |
+diff --git a/mm/memory.c b/mm/memory.c |
457 |
+index f82b359..51a8691 100644 |
458 |
+--- a/mm/memory.c |
459 |
++++ b/mm/memory.c |
460 |
+@@ -981,6 +981,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
461 |
+ int i; |
462 |
+ unsigned int vm_flags; |
463 |
+ |
464 |
++ if (len <= 0) |
465 |
++ return 0; |
466 |
+ /* |
467 |
+ * Require read or write permissions. |
468 |
+ * If 'force' is set, we only require the "MAY" flags. |
469 |
+diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c |
470 |
+index 70c5b7d..09b902d 100644 |
471 |
+--- a/net/netfilter/nf_conntrack_proto_tcp.c |
472 |
++++ b/net/netfilter/nf_conntrack_proto_tcp.c |
473 |
+@@ -135,7 +135,7 @@ enum tcp_bit_set { |
474 |
+ * CLOSE_WAIT: ACK seen (after FIN) |
475 |
+ * LAST_ACK: FIN seen (after FIN) |
476 |
+ * TIME_WAIT: last ACK seen |
477 |
+- * CLOSE: closed connection |
478 |
++ * CLOSE: closed connection (RST) |
479 |
+ * |
480 |
+ * LISTEN state is not used. |
481 |
+ * |
482 |
+@@ -834,8 +834,21 @@ static int tcp_packet(struct nf_conn *conntrack, |
483 |
+ case TCP_CONNTRACK_SYN_SENT: |
484 |
+ if (old_state < TCP_CONNTRACK_TIME_WAIT) |
485 |
+ break; |
486 |
+- if ((conntrack->proto.tcp.seen[!dir].flags & |
487 |
+- IP_CT_TCP_FLAG_CLOSE_INIT) |
488 |
++ /* RFC 1122: "When a connection is closed actively, |
489 |
++ * it MUST linger in TIME-WAIT state for a time 2xMSL |
490 |
++ * (Maximum Segment Lifetime). However, it MAY accept |
491 |
++ * a new SYN from the remote TCP to reopen the connection |
492 |
++ * directly from TIME-WAIT state, if..." |
493 |
++ * We ignore the conditions because we are in the |
494 |
++ * TIME-WAIT state anyway. |
495 |
++ * |
496 |
++ * Handle aborted connections: we and the server |
497 |
++ * think there is an existing connection but the client |
498 |
++ * aborts it and starts a new one. |
499 |
++ */ |
500 |
++ if (((conntrack->proto.tcp.seen[dir].flags |
501 |
++ | conntrack->proto.tcp.seen[!dir].flags) |
502 |
++ & IP_CT_TCP_FLAG_CLOSE_INIT) |
503 |
+ || (conntrack->proto.tcp.last_dir == dir |
504 |
+ && conntrack->proto.tcp.last_index == TCP_RST_SET)) { |
505 |
+ /* Attempt to reopen a closed/aborted connection. |
506 |
+@@ -850,16 +863,23 @@ static int tcp_packet(struct nf_conn *conntrack, |
507 |
+ case TCP_CONNTRACK_IGNORE: |
508 |
+ /* Ignored packets: |
509 |
+ * |
510 |
++ * Our connection entry may be out of sync, so ignore |
511 |
++ * packets which may signal the real connection between |
512 |
++ * the client and the server. |
513 |
++ * |
514 |
+ * a) SYN in ORIGINAL |
515 |
+ * b) SYN/ACK in REPLY |
516 |
+ * c) ACK in reply direction after initial SYN in original. |
517 |
++ * |
518 |
++ * If the ignored packet is invalid, the receiver will send |
519 |
++ * a RST we'll catch below. |
520 |
+ */ |
521 |
+ if (index == TCP_SYNACK_SET |
522 |
+ && conntrack->proto.tcp.last_index == TCP_SYN_SET |
523 |
+ && conntrack->proto.tcp.last_dir != dir |
524 |
+ && ntohl(th->ack_seq) == |
525 |
+ conntrack->proto.tcp.last_end) { |
526 |
+- /* This SYN/ACK acknowledges a SYN that we earlier |
527 |
++ /* b) This SYN/ACK acknowledges a SYN that we earlier |
528 |
+ * ignored as invalid. This means that the client and |
529 |
+ * the server are both in sync, while the firewall is |
530 |
+ * not. We kill this session and block the SYN/ACK so |
531 |
+@@ -884,7 +904,7 @@ static int tcp_packet(struct nf_conn *conntrack, |
532 |
+ write_unlock_bh(&tcp_lock); |
533 |
+ if (LOG_INVALID(IPPROTO_TCP)) |
534 |
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL, |
535 |
+- "nf_ct_tcp: invalid packed ignored "); |
536 |
++ "nf_ct_tcp: invalid packet ignored "); |
537 |
+ return NF_ACCEPT; |
538 |
+ case TCP_CONNTRACK_MAX: |
539 |
+ /* Invalid packet */ |
540 |
+@@ -938,8 +958,7 @@ static int tcp_packet(struct nf_conn *conntrack, |
541 |
+ |
542 |
+ conntrack->proto.tcp.state = new_state; |
543 |
+ if (old_state != new_state |
544 |
+- && (new_state == TCP_CONNTRACK_FIN_WAIT |
545 |
+- || new_state == TCP_CONNTRACK_CLOSE)) |
546 |
++ && new_state == TCP_CONNTRACK_FIN_WAIT) |
547 |
+ conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; |
548 |
+ timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans |
549 |
+ && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans |
550 |
|
551 |
Deleted: genpatches-2.6/trunk/2.6.23/1400_vmsplice-user-pointer.patch |
552 |
=================================================================== |
553 |
--- genpatches-2.6/trunk/2.6.23/1400_vmsplice-user-pointer.patch 2008-02-26 14:22:03 UTC (rev 1258) |
554 |
+++ genpatches-2.6/trunk/2.6.23/1400_vmsplice-user-pointer.patch 2008-02-26 14:29:50 UTC (rev 1259) |
555 |
@@ -1,36 +0,0 @@ |
556 |
-From: Bastian Blank <bastian@××××××××.org> |
557 |
-Date: Sun, 10 Feb 2008 14:47:57 +0000 (+0200) |
558 |
-Subject: splice: fix user pointer access in get_iovec_page_array() |
559 |
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=712a30e63c8066ed84385b12edbfb804f49cbc44 |
560 |
- |
561 |
-splice: fix user pointer access in get_iovec_page_array() |
562 |
- |
563 |
-Commit 8811930dc74a503415b35c4a79d14fb0b408a361 ("splice: missing user |
564 |
-pointer access verification") added the proper access_ok() calls to |
565 |
-copy_from_user_mmap_sem() which ensures we can copy the struct iovecs |
566 |
-from userspace to the kernel. |
567 |
- |
568 |
-But we also must check whether we can access the actual memory region |
569 |
-pointed to by the struct iovec to fix the access checks properly. |
570 |
- |
571 |
-Signed-off-by: Bastian Blank <waldi@××××××.org> |
572 |
-Acked-by: Oliver Pinter <oliver.pntr@×××××.com> |
573 |
-Cc: Jens Axboe <jens.axboe@××××××.com> |
574 |
-Cc: Andrew Morton <akpm@××××××××××××××××.org> |
575 |
-Signed-off-by: Pekka Enberg <penberg@×××××××××××.fi> |
576 |
-Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
577 |
---- |
578 |
- |
579 |
-diff --git a/fs/splice.c b/fs/splice.c |
580 |
-index 14e2262..9b559ee 100644 |
581 |
---- a/fs/splice.c |
582 |
-+++ b/fs/splice.c |
583 |
-@@ -1234,7 +1234,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, |
584 |
- if (unlikely(!len)) |
585 |
- break; |
586 |
- error = -EFAULT; |
587 |
-- if (unlikely(!base)) |
588 |
-+ if (!access_ok(VERIFY_READ, base, len)) |
589 |
- break; |
590 |
- |
591 |
- /* |
592 |
|
593 |
Deleted: genpatches-2.6/trunk/2.6.23/1500_get-zero-user-pages.patch |
594 |
=================================================================== |
595 |
--- genpatches-2.6/trunk/2.6.23/1500_get-zero-user-pages.patch 2008-02-26 14:22:03 UTC (rev 1258) |
596 |
+++ genpatches-2.6/trunk/2.6.23/1500_get-zero-user-pages.patch 2008-02-26 14:29:50 UTC (rev 1259) |
597 |
@@ -1,43 +0,0 @@ |
598 |
-From: Jonathan Corbet <corbet@×××.net> |
599 |
-Date: Mon, 11 Feb 2008 23:17:33 +0000 (-0700) |
600 |
-Subject: Be more robust about bad arguments in get_user_pages() |
601 |
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=900cf086fd2fbad07f72f4575449e0d0958f860f |
602 |
- |
603 |
-Be more robust about bad arguments in get_user_pages() |
604 |
- |
605 |
-So I spent a while pounding my head against my monitor trying to figure |
606 |
-out the vmsplice() vulnerability - how could a failure to check for |
607 |
-*read* access turn into a root exploit? It turns out that it's a buffer |
608 |
-overflow problem which is made easy by the way get_user_pages() is |
609 |
-coded. |
610 |
- |
611 |
-In particular, "len" is a signed int, and it is only checked at the |
612 |
-*end* of a do {} while() loop. So, if it is passed in as zero, the loop |
613 |
-will execute once and decrement len to -1. At that point, the loop will |
614 |
-proceed until the next invalid address is found; in the process, it will |
615 |
-likely overflow the pages array passed in to get_user_pages(). |
616 |
- |
617 |
-I think that, if get_user_pages() has been asked to grab zero pages, |
618 |
-that's what it should do. Thus this patch; it is, among other things, |
619 |
-enough to block the (already fixed) root exploit and any others which |
620 |
-might be lurking in similar code. I also think that the number of pages |
621 |
-should be unsigned, but changing the prototype of this function probably |
622 |
-requires some more careful review. |
623 |
- |
624 |
-Signed-off-by: Jonathan Corbet <corbet@×××.net> |
625 |
-Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
626 |
---- |
627 |
- |
628 |
-diff --git a/mm/memory.c b/mm/memory.c |
629 |
-index e5628a5..717aa0e 100644 |
630 |
---- a/mm/memory.c |
631 |
-+++ b/mm/memory.c |
632 |
-@@ -989,6 +989,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
633 |
- int i; |
634 |
- unsigned int vm_flags; |
635 |
- |
636 |
-+ if (len <= 0) |
637 |
-+ return 0; |
638 |
- /* |
639 |
- * Require read or write permissions. |
640 |
- * If 'force' is set, we only require the "MAY" flags. |
641 |
|
642 |
-- |
643 |
gentoo-commits@l.g.o mailing list |