1 |
Author: gengor |
2 |
Date: 2008-12-03 00:31:33 +0000 (Wed, 03 Dec 2008) |
3 |
New Revision: 1413 |
4 |
|
5 |
Added: |
6 |
hardened/2.6/trunk/2.6.26/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch |
7 |
hardened/2.6/trunk/2.6.26/1402_cpqarry-fix-return-value-of-cpqarray_init.patch |
8 |
hardened/2.6/trunk/2.6.26/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch |
9 |
hardened/2.6/trunk/2.6.26/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch |
10 |
hardened/2.6/trunk/2.6.26/1405_i-oat-fix-async_tx.callback-checking.patch |
11 |
hardened/2.6/trunk/2.6.26/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch |
12 |
hardened/2.6/trunk/2.6.26/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch |
13 |
hardened/2.6/trunk/2.6.26/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch |
14 |
hardened/2.6/trunk/2.6.26/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch |
15 |
hardened/2.6/trunk/2.6.26/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch |
16 |
hardened/2.6/trunk/2.6.26/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch |
17 |
hardened/2.6/trunk/2.6.26/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch |
18 |
hardened/2.6/trunk/2.6.26/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch |
19 |
hardened/2.6/trunk/2.6.26/1414_acpi-avoid-empty-file-name-in-sysfs.patch |
20 |
hardened/2.6/trunk/2.6.26/1415_block-fix-nr_phys_segments-miscalculation-bug.patch |
21 |
hardened/2.6/trunk/2.6.26/1416_dm-raid1-flush-workqueue-before-destruction.patch |
22 |
hardened/2.6/trunk/2.6.26/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch |
23 |
hardened/2.6/trunk/2.6.26/1418_touch_mnt_namespace-when-the-mount-flags-change.patch |
24 |
hardened/2.6/trunk/2.6.26/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch |
25 |
hardened/2.6/trunk/2.6.26/1420_usb-ehci-fix-divide-by-zero-bug.patch |
26 |
hardened/2.6/trunk/2.6.26/1421_usb-ehci-fix-handling-of-dead-controllers.patch |
27 |
hardened/2.6/trunk/2.6.26/1422_usb-fix-ps3-usb-shutdown-problems.patch |
28 |
hardened/2.6/trunk/2.6.26/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch |
29 |
hardened/2.6/trunk/2.6.26/1503_inotify-fix-watch-removal-or-umount-races.patch |
30 |
hardened/2.6/trunk/2.6.26/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch |
31 |
hardened/2.6/trunk/2.6.26/4460_pax-fix-mmap-BUG_ON-task-size-check.patch |
32 |
hardened/2.6/trunk/2.6.26/4465_pax-fix-false-RLIMIT_STACK-warnings.patch |
33 |
Modified: |
34 |
hardened/2.6/trunk/2.6.26/0000_README |
35 |
Log: |
36 |
Update 2.6.26 trunk/ |
37 |
|
38 |
Modified: hardened/2.6/trunk/2.6.26/0000_README |
39 |
=================================================================== |
40 |
--- hardened/2.6/trunk/2.6.26/0000_README 2008-11-28 15:37:18 UTC (rev 1412) |
41 |
+++ hardened/2.6/trunk/2.6.26/0000_README 2008-12-03 00:31:33 UTC (rev 1413) |
42 |
@@ -3,22 +3,20 @@ |
43 |
|
44 |
Individual Patch Descriptions: |
45 |
----------------------------------------------------------------------------- |
46 |
-Patch: 1006_linux-2.6.26.7.patch |
47 |
-From: http://www.kernel.org |
48 |
-Desc: Linux 2.6.26.7 |
49 |
+Patch: 1401* -> 1413* |
50 |
+From http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git; |
51 |
+ a=commit;h=ff413e9814b3914ddf3d4634e9a6cc1c6b21e787 |
52 |
+Desc: Backported subset of 2.6.27.6 -stable release patches |
53 |
|
54 |
-Patch: 1007_linux-2.6.26.8.patch |
55 |
-From: http://www.kernel.org |
56 |
-Desc: Linux 2.6.26.8 |
57 |
+Patch: 1414* -> 1423* |
58 |
+From http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git; |
59 |
+ a=commit;h=526550b7f86d9d395ee1b27ed804e6ffc3feb17c |
60 |
+Desc: Backported subset of 2.6.27.7 -stable release patches |
61 |
|
62 |
-Patch: 1503_hfsplus-check-read_mapping_page-return-value.patch |
63 |
-From: Eric Sesterhenn <snakebyte@×××.de> |
64 |
-Desc: hfsplus: check return value of read_mapping_page() |
65 |
+Patch: 1503_inotify-fix-watch-removal-or-umount-races.patch |
66 |
+From: Al Viro <viro@×××××××××××××××.uk> |
67 |
+Desc: Fix inotify watch removal/umount races (bug #248754) |
68 |
|
69 |
-Patch: 1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch |
70 |
-From: Eric Sesterhenn <snakebyte@×××.de> |
71 |
-Desc: hfsplus: fix buffer overflow when mounting corrupted image |
72 |
- |
73 |
Patch: 4420_grsec-2.1.12-2.6.26.6-200810131006.patch |
74 |
From: http://www.grsecurity.net |
75 |
Desc: hardened-sources base patch from upstream grsecurity |
76 |
@@ -60,3 +58,15 @@ |
77 |
Patch: 4450_pax-2.6.26.7-test32-to-test33.patch |
78 |
From: Gordon Malm <gengor@g.o> |
79 |
Desc: Adds PaX changes from pax-2.6.26.7-test33 |
80 |
+ |
81 |
+Patch: 4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch |
82 |
+From: Gordon Malm <gengor@g.o> |
83 |
+Desc: Make selection of PAX_REFCOUNT depend on X86 (bug #246763) |
84 |
+ |
85 |
+Patch: 4460_pax-fix-mmap-BUG_ON-task-size-check.patch |
86 |
+From: Gordon Malm <gengor@g.o> |
87 |
+Desc: Fix incorrect vma task size check under SEGMEXEC |
88 |
+ |
89 |
+Patch: 4465_pax-fix-false-RLIMIT_STACK-warnings.patch |
90 |
+From: Gordon Malm <gengor@g.o> |
91 |
+Desc: Fix false-positive RLIMIT_STACK warnings |
92 |
|
93 |
Added: hardened/2.6/trunk/2.6.26/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch |
94 |
=================================================================== |
95 |
--- hardened/2.6/trunk/2.6.26/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch (rev 0) |
96 |
+++ hardened/2.6/trunk/2.6.26/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch 2008-12-03 00:31:33 UTC (rev 1413) |
97 |
@@ -0,0 +1,65 @@ |
98 |
+Added-By: Gordon Malm <gengor@g.o> |
99 |
+ |
100 |
+--- |
101 |
+ |
102 |
+From jejb@××××××.org Mon Nov 10 15:14:35 2008 |
103 |
+From: Li Zefan <lizf@××××××××××.com> |
104 |
+Date: Fri, 7 Nov 2008 00:05:48 GMT |
105 |
+Subject: cgroups: fix invalid cgrp->dentry before cgroup has been completely removed |
106 |
+To: stable@××××××.org |
107 |
+Message-ID: <200811070005.mA705mbU003066@×××××××××××.org> |
108 |
+ |
109 |
+From: Li Zefan <lizf@××××××××××.com> |
110 |
+ |
111 |
+commit 24eb089950ce44603b30a3145a2c8520e2b55bb1 upstream |
112 |
+ |
113 |
+This fixes an oops when reading /proc/sched_debug. |
114 |
+ |
115 |
+A cgroup won't be removed completely until finishing cgroup_diput(), so we |
116 |
+shouldn't invalidate cgrp->dentry in cgroup_rmdir(). Otherwise, when a |
117 |
+group is being removed while cgroup_path() gets called, we may trigger |
118 |
+NULL dereference BUG. |
119 |
+ |
120 |
+The bug can be reproduced: |
121 |
+ |
122 |
+ # cat test.sh |
123 |
+ #!/bin/sh |
124 |
+ mount -t cgroup -o cpu xxx /mnt |
125 |
+ for (( ; ; )) |
126 |
+ { |
127 |
+ mkdir /mnt/sub |
128 |
+ rmdir /mnt/sub |
129 |
+ } |
130 |
+ # ./test.sh & |
131 |
+ # cat /proc/sched_debug |
132 |
+ |
133 |
+BUG: unable to handle kernel NULL pointer dereference at 00000038 |
134 |
+IP: [<c045a47f>] cgroup_path+0x39/0x90 |
135 |
+.. |
136 |
+Call Trace: |
137 |
+ [<c0420344>] ? print_cfs_rq+0x6e/0x75d |
138 |
+ [<c0421160>] ? sched_debug_show+0x72d/0xc1e |
139 |
+.. |
140 |
+ |
141 |
+Signed-off-by: Li Zefan <lizf@××××××××××.com> |
142 |
+Acked-by: Paul Menage <menage@××××××.com> |
143 |
+Cc: Peter Zijlstra <a.p.zijlstra@××××××.nl> |
144 |
+Cc: Ingo Molnar <mingo@××××.hu> |
145 |
+Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org> |
146 |
+Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
147 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
148 |
+ |
149 |
+--- |
150 |
+ kernel/cgroup.c | 1 - |
151 |
+ 1 file changed, 1 deletion(-) |
152 |
+ |
153 |
+--- a/kernel/cgroup.c |
154 |
++++ b/kernel/cgroup.c |
155 |
+@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *un |
156 |
+ list_del(&cgrp->sibling); |
157 |
+ spin_lock(&cgrp->dentry->d_lock); |
158 |
+ d = dget(cgrp->dentry); |
159 |
+- cgrp->dentry = NULL; |
160 |
+ spin_unlock(&d->d_lock); |
161 |
+ |
162 |
+ cgroup_d_remove_dir(d); |
163 |
|
164 |
Added: hardened/2.6/trunk/2.6.26/1402_cpqarry-fix-return-value-of-cpqarray_init.patch |
165 |
=================================================================== |
166 |
--- hardened/2.6/trunk/2.6.26/1402_cpqarry-fix-return-value-of-cpqarray_init.patch (rev 0) |
167 |
+++ hardened/2.6/trunk/2.6.26/1402_cpqarry-fix-return-value-of-cpqarray_init.patch 2008-12-03 00:31:33 UTC (rev 1413) |
168 |
@@ -0,0 +1,55 @@ |
169 |
+Added-By: Gordon Malm <gengor@g.o> |
170 |
+ |
171 |
+--- |
172 |
+ |
173 |
+From 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 Mon Sep 17 00:00:00 2001 |
174 |
+From: Andrey Borzenkov <arvidjaar@××××.ru> |
175 |
+Date: Thu, 6 Nov 2008 12:53:15 -0800 |
176 |
+Subject: cpqarry: fix return value of cpqarray_init() |
177 |
+ |
178 |
+From: Andrey Borzenkov <arvidjaar@××××.ru> |
179 |
+ |
180 |
+commit 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 upstream. |
181 |
+ |
182 |
+As reported by Dick Gevers on Compaq ProLiant: |
183 |
+ |
184 |
+Oct 13 18:06:51 dvgcpl kernel: Compaq SMART2 Driver (v 2.6.0) |
185 |
+Oct 13 18:06:51 dvgcpl kernel: sys_init_module: 'cpqarray'->init |
186 |
+suspiciously returned 1, it should follow 0/-E convention |
187 |
+Oct 13 18:06:51 dvgcpl kernel: sys_init_module: loading module anyway... |
188 |
+Oct 13 18:06:51 dvgcpl kernel: Pid: 315, comm: modprobe Not tainted |
189 |
+2.6.27-desktop-0.rc8.2mnb #1 |
190 |
+Oct 13 18:06:51 dvgcpl kernel: [<c0380612>] ? printk+0x18/0x1e |
191 |
+Oct 13 18:06:51 dvgcpl kernel: [<c0158f85>] sys_init_module+0x155/0x1c0 |
192 |
+Oct 13 18:06:51 dvgcpl kernel: [<c0103f06>] syscall_call+0x7/0xb |
193 |
+Oct 13 18:06:51 dvgcpl kernel: ======================= |
194 |
+ |
195 |
+Make it return 0 on success and -ENODEV if no array was found. |
196 |
+ |
197 |
+Reported-by: Dick Gevers <dvgevers@××××××.nl> |
198 |
+Signed-off-by: Andrey Borzenkov <arvidjaar@××××.ru> |
199 |
+Cc: Jens Axboe <jens.axboe@××××××.com> |
200 |
+Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org> |
201 |
+Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
202 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
203 |
+ |
204 |
+--- |
205 |
+ drivers/block/cpqarray.c | 7 ++++++- |
206 |
+ 1 file changed, 6 insertions(+), 1 deletion(-) |
207 |
+ |
208 |
+--- a/drivers/block/cpqarray.c |
209 |
++++ b/drivers/block/cpqarray.c |
210 |
+@@ -567,7 +567,12 @@ static int __init cpqarray_init(void) |
211 |
+ num_cntlrs_reg++; |
212 |
+ } |
213 |
+ |
214 |
+- return(num_cntlrs_reg); |
215 |
++ if (num_cntlrs_reg) |
216 |
++ return 0; |
217 |
++ else { |
218 |
++ pci_unregister_driver(&cpqarray_pci_driver); |
219 |
++ return -ENODEV; |
220 |
++ } |
221 |
+ } |
222 |
+ |
223 |
+ /* Function to find the first free pointer into our hba[] array */ |
224 |
|
225 |
Added: hardened/2.6/trunk/2.6.26/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch |
226 |
=================================================================== |
227 |
--- hardened/2.6/trunk/2.6.26/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch (rev 0) |
228 |
+++ hardened/2.6/trunk/2.6.26/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch 2008-12-03 00:31:33 UTC (rev 1413) |
229 |
@@ -0,0 +1,82 @@ |
230 |
+Added-By: Gordon Malm <gengor@g.o> |
231 |
+ |
232 |
+--- |
233 |
+ |
234 |
+From jejb@××××××.org Mon Nov 10 15:08:55 2008 |
235 |
+From: Arthur Jones <ajones@××××××××.com> |
236 |
+Date: Fri, 7 Nov 2008 00:05:17 GMT |
237 |
+Subject: ext3: wait on all pending commits in ext3_sync_fs |
238 |
+To: stable@××××××.org |
239 |
+Message-ID: <200811070005.mA705Htq002320@×××××××××××.org> |
240 |
+ |
241 |
+From: Arthur Jones <ajones@××××××××.com> |
242 |
+ |
243 |
+commit c87591b719737b4e91eb1a9fa8fd55a4ff1886d6 upstream |
244 |
+ |
245 |
+In ext3_sync_fs, we only wait for a commit to finish if we started it, but |
246 |
+there may be one already in progress which will not be synced. |
247 |
+ |
248 |
+In the case of a data=ordered umount with pending long symlinks which are |
249 |
+delayed due to a long list of other I/O on the backing block device, this |
250 |
+causes the buffer associated with the long symlinks to not be moved to the |
251 |
+inode dirty list in the second phase of fsync_super. Then, before they |
252 |
+can be dirtied again, kjournald exits, seeing the UMOUNT flag and the |
253 |
+dirty pages are never written to the backing block device, causing long |
254 |
+symlink corruption and exposing new or previously freed block data to |
255 |
+userspace. |
256 |
+ |
257 |
+This can be reproduced with a script created |
258 |
+by Eric Sandeen <sandeen@××××××.com>: |
259 |
+ |
260 |
+ #!/bin/bash |
261 |
+ |
262 |
+ umount /mnt/test2 |
263 |
+ mount /dev/sdb4 /mnt/test2 |
264 |
+ rm -f /mnt/test2/* |
265 |
+ dd if=/dev/zero of=/mnt/test2/bigfile bs=1M count=512 |
266 |
+ touch |
267 |
+ /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename |
268 |
+ ln -s |
269 |
+ /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename |
270 |
+ /mnt/test2/link |
271 |
+ umount /mnt/test2 |
272 |
+ mount /dev/sdb4 /mnt/test2 |
273 |
+ ls /mnt/test2/ |
274 |
+ umount /mnt/test2 |
275 |
+ |
276 |
+To ensure all commits are synced, we flush all journal commits now when |
277 |
+sync_fs'ing ext3. |
278 |
+ |
279 |
+Signed-off-by: Arthur Jones <ajones@××××××××.com> |
280 |
+Cc: Eric Sandeen <sandeen@××××××.com> |
281 |
+Cc: Theodore Ts'o <tytso@×××.edu> |
282 |
+Cc: <linux-ext4@×××××××××××.org> |
283 |
+Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org> |
284 |
+Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
285 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
286 |
+ |
287 |
+--- |
288 |
+ fs/ext3/super.c | 11 +++++------ |
289 |
+ 1 file changed, 5 insertions(+), 6 deletions(-) |
290 |
+ |
291 |
+--- a/fs/ext3/super.c |
292 |
++++ b/fs/ext3/super.c |
293 |
+@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct sup |
294 |
+ |
295 |
+ static int ext3_sync_fs(struct super_block *sb, int wait) |
296 |
+ { |
297 |
+- tid_t target; |
298 |
+- |
299 |
+ sb->s_dirt = 0; |
300 |
+- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) { |
301 |
+- if (wait) |
302 |
+- log_wait_commit(EXT3_SB(sb)->s_journal, target); |
303 |
+- } |
304 |
++ if (wait) |
305 |
++ ext3_force_commit(sb); |
306 |
++ else |
307 |
++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL); |
308 |
++ |
309 |
+ return 0; |
310 |
+ } |
311 |
+ |
312 |
|
313 |
Added: hardened/2.6/trunk/2.6.26/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch |
314 |
=================================================================== |
315 |
--- hardened/2.6/trunk/2.6.26/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch (rev 0) |
316 |
+++ hardened/2.6/trunk/2.6.26/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch 2008-12-03 00:31:33 UTC (rev 1413) |
317 |
@@ -0,0 +1,48 @@ |
318 |
+Added-By: Gordon Malm <gengor@g.o> |
319 |
+ |
320 |
+--- |
321 |
+ |
322 |
+From jkosina@××××.cz Tue Nov 11 15:52:41 2008 |
323 |
+From: Jiri Kosina <jkosina@××××.cz> |
324 |
+Date: Tue, 11 Nov 2008 23:45:38 +0100 (CET) |
325 |
+Subject: HID: fix incorrent length condition in hidraw_write() |
326 |
+To: stable@××××××.org |
327 |
+Cc: Paul Stoffregen <paul@××××.com> |
328 |
+Message-ID: <alpine.LNX.1.10.0811112344180.24889@××××××××××.cz> |
329 |
+ |
330 |
+From: Jiri Kosina <jkosina@××××.cz> |
331 |
+ |
332 |
+upstream commit 2b107d629dc0c35de606bb7b010b829cd247a93a |
333 |
+ |
334 |
+From: Jiri Kosina <jkosina@××××.cz> |
335 |
+ |
336 |
+The bound check on the buffer length |
337 |
+ |
338 |
+ if (count > HID_MIN_BUFFER_SIZE) |
339 |
+ |
340 |
+is of course incorrent, the proper check is |
341 |
+ |
342 |
+ if (count > HID_MAX_BUFFER_SIZE) |
343 |
+ |
344 |
+Fix it. |
345 |
+ |
346 |
+Reported-by: Jerry Ryle <jerry@×××××××××.com> |
347 |
+Signed-off-by: Jiri Kosina <jkosina@××××.cz> |
348 |
+Cc: Paul Stoffregen <paul@××××.com> |
349 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
350 |
+ |
351 |
+--- |
352 |
+ drivers/hid/hidraw.c | 2 +- |
353 |
+ 1 file changed, 1 insertion(+), 1 deletion(-) |
354 |
+ |
355 |
+--- a/drivers/hid/hidraw.c |
356 |
++++ b/drivers/hid/hidraw.c |
357 |
+@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file |
358 |
+ if (!dev->hid_output_raw_report) |
359 |
+ return -ENODEV; |
360 |
+ |
361 |
+- if (count > HID_MIN_BUFFER_SIZE) { |
362 |
++ if (count > HID_MAX_BUFFER_SIZE) { |
363 |
+ printk(KERN_WARNING "hidraw: pid %d passed too large report\n", |
364 |
+ task_pid_nr(current)); |
365 |
+ return -EINVAL; |
366 |
|
367 |
Added: hardened/2.6/trunk/2.6.26/1405_i-oat-fix-async_tx.callback-checking.patch |
368 |
=================================================================== |
369 |
--- hardened/2.6/trunk/2.6.26/1405_i-oat-fix-async_tx.callback-checking.patch (rev 0) |
370 |
+++ hardened/2.6/trunk/2.6.26/1405_i-oat-fix-async_tx.callback-checking.patch 2008-12-03 00:31:33 UTC (rev 1413) |
371 |
@@ -0,0 +1,48 @@ |
372 |
+Added-By: Gordon Malm <gengor@g.o> |
373 |
+ |
374 |
+Note: Backported to earlier kernels. Original message included below. |
375 |
+ |
376 |
+--- |
377 |
+ |
378 |
+From jejb@××××××.org Tue Nov 11 10:17:05 2008 |
379 |
+From: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
380 |
+Date: Tue, 11 Nov 2008 17:50:05 GMT |
381 |
+Subject: I/OAT: fix async_tx.callback checking |
382 |
+To: jejb@××××××.org, stable@××××××.org |
383 |
+Message-ID: <200811111750.mABHo5Ai025612@×××××××××××.org> |
384 |
+ |
385 |
+From: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
386 |
+ |
387 |
+commit 12ccea24e309d815d058cdc6ee8bf2c4b85f0c5f upstream |
388 |
+ |
389 |
+async_tx.callback should be checked for the first |
390 |
+not the last descriptor in the chain. |
391 |
+ |
392 |
+Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
393 |
+Signed-off-by: David S. Miller <davem@×××××××××.net> |
394 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
395 |
+ |
396 |
+--- |
397 |
+ drivers/dma/ioat_dma.c | 4 ++-- |
398 |
+ 1 file changed, 2 insertions(+), 2 deletions(-) |
399 |
+ |
400 |
+--- a/drivers/dma/ioat_dma.c |
401 |
++++ b/drivers/dma/ioat_dma.c |
402 |
+@@ -251,7 +251,7 @@ static dma_cookie_t ioat1_tx_submit(stru |
403 |
+ } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan))); |
404 |
+ |
405 |
+ hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; |
406 |
+- if (new->async_tx.callback) { |
407 |
++ if (first->async_tx.callback) { |
408 |
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; |
409 |
+ if (first != new) { |
410 |
+ /* move callback into to last desc */ |
411 |
+@@ -336,7 +336,7 @@ static dma_cookie_t ioat2_tx_submit(stru |
412 |
+ } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan))); |
413 |
+ |
414 |
+ hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; |
415 |
+- if (new->async_tx.callback) { |
416 |
++ if (first->async_tx.callback) { |
417 |
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; |
418 |
+ if (first != new) { |
419 |
+ /* move callback into to last desc */ |
420 |
|
421 |
Added: hardened/2.6/trunk/2.6.26/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch |
422 |
=================================================================== |
423 |
--- hardened/2.6/trunk/2.6.26/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch (rev 0) |
424 |
+++ hardened/2.6/trunk/2.6.26/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch 2008-12-03 00:31:33 UTC (rev 1413) |
425 |
@@ -0,0 +1,54 @@ |
426 |
+Added-By: Gordon Malm <gengor@g.o> |
427 |
+ |
428 |
+Note: Backported to earlier kernels. Original message below. |
429 |
+ |
430 |
+--- |
431 |
+ |
432 |
+From jejb@××××××.org Tue Nov 11 10:15:37 2008 |
433 |
+From: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
434 |
+Date: Tue, 11 Nov 2008 17:50:09 GMT |
435 |
+Subject: I/OAT: fix channel resources free for not allocated channels |
436 |
+To: stable@××××××.org |
437 |
+Message-ID: <200811111750.mABHo9IU025655@×××××××××××.org> |
438 |
+ |
439 |
+From: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
440 |
+ |
441 |
+commit c3d4f44f50b65b0b0290e357f8739cfb3f4bcaca upstream |
442 |
+ |
443 |
+If the ioatdma driver is loaded but not used it does not allocate descriptors. |
444 |
+Before it frees channel resources it should first be sure |
445 |
+that they have been previously allocated. |
446 |
+ |
447 |
+Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
448 |
+Tested-by: Tom Picard <tom.s.picard@×××××.com> |
449 |
+Signed-off-by: Dan Williams <dan.j.williams@×××××.com> |
450 |
+Signed-off-by: David S. Miller <davem@×××××××××.net> |
451 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
452 |
+ |
453 |
+--- |
454 |
+ drivers/dma/ioat_dma.c | 7 +++++++ |
455 |
+ 1 file changed, 7 insertions(+) |
456 |
+ |
457 |
+--- a/drivers/dma/ioat_dma.c |
458 |
++++ b/drivers/dma/ioat_dma.c |
459 |
+@@ -524,6 +524,12 @@ static void ioat_dma_free_chan_resources |
460 |
+ struct ioat_desc_sw *desc, *_desc; |
461 |
+ int in_use_descs = 0; |
462 |
+ |
463 |
++ /* Before freeing channel resources first check |
464 |
++ * if they have been previously allocated for this channel. |
465 |
++ */ |
466 |
++ if (ioat_chan->desccount == 0) |
467 |
++ return; |
468 |
++ |
469 |
+ tasklet_disable(&ioat_chan->cleanup_task); |
470 |
+ ioat_dma_memcpy_cleanup(ioat_chan); |
471 |
+ |
472 |
+@@ -585,6 +591,7 @@ static void ioat_dma_free_chan_resources |
473 |
+ ioat_chan->last_completion = ioat_chan->completion_addr = 0; |
474 |
+ ioat_chan->pending = 0; |
475 |
+ ioat_chan->dmacount = 0; |
476 |
++ ioat_chan->desccount = 0; |
477 |
+ } |
478 |
+ |
479 |
+ /** |
480 |
|
481 |
Added: hardened/2.6/trunk/2.6.26/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch |
482 |
=================================================================== |
483 |
--- hardened/2.6/trunk/2.6.26/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch (rev 0) |
484 |
+++ hardened/2.6/trunk/2.6.26/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch 2008-12-03 00:31:33 UTC (rev 1413) |
485 |
@@ -0,0 +1,89 @@ |
486 |
+Added-By: Gordon Malm <gengor@g.o> |
487 |
+ |
488 |
+--- |
489 |
+ |
490 |
+From jejb@××××××.org Tue Nov 11 10:16:31 2008 |
491 |
+From: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
492 |
+Date: Tue, 11 Nov 2008 17:50:07 GMT |
493 |
+Subject: I/OAT: fix dma_pin_iovec_pages() error handling |
494 |
+To: stable@××××××.org |
495 |
+Message-ID: <200811111750.mABHo7v5025633@×××××××××××.org> |
496 |
+ |
497 |
+From: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
498 |
+ |
499 |
+commit c2c0b4c5434c0a25f7f7796b29155d53805909f5 upstream |
500 |
+ |
501 |
+Error handling needs to be modified in dma_pin_iovec_pages(). |
502 |
+It should return NULL instead of ERR_PTR |
503 |
+(pinned_list is checked for NULL in tcp_recvmsg() to determine |
504 |
+if iovec pages have been successfully pinned down). |
505 |
+In case of error for the first iovec, |
506 |
+local_list->nr_iovecs needs to be initialized. |
507 |
+ |
508 |
+Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com> |
509 |
+Signed-off-by: David S. Miller <davem@×××××××××.net> |
510 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
511 |
+ |
512 |
+--- |
513 |
+ drivers/dma/iovlock.c | 17 ++++++----------- |
514 |
+ 1 file changed, 6 insertions(+), 11 deletions(-) |
515 |
+ |
516 |
+--- a/drivers/dma/iovlock.c |
517 |
++++ b/drivers/dma/iovlock.c |
518 |
+@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pa |
519 |
+ int nr_iovecs = 0; |
520 |
+ int iovec_len_used = 0; |
521 |
+ int iovec_pages_used = 0; |
522 |
+- long err; |
523 |
+ |
524 |
+ /* don't pin down non-user-based iovecs */ |
525 |
+ if (segment_eq(get_fs(), KERNEL_DS)) |
526 |
+@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pa |
527 |
+ local_list = kmalloc(sizeof(*local_list) |
528 |
+ + (nr_iovecs * sizeof (struct dma_page_list)) |
529 |
+ + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); |
530 |
+- if (!local_list) { |
531 |
+- err = -ENOMEM; |
532 |
++ if (!local_list) |
533 |
+ goto out; |
534 |
+- } |
535 |
+ |
536 |
+ /* list of pages starts right after the page list array */ |
537 |
+ pages = (struct page **) &local_list->page_list[nr_iovecs]; |
538 |
+ |
539 |
++ local_list->nr_iovecs = 0; |
540 |
++ |
541 |
+ for (i = 0; i < nr_iovecs; i++) { |
542 |
+ struct dma_page_list *page_list = &local_list->page_list[i]; |
543 |
+ |
544 |
+ len -= iov[i].iov_len; |
545 |
+ |
546 |
+- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) { |
547 |
+- err = -EFAULT; |
548 |
++ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) |
549 |
+ goto unpin; |
550 |
+- } |
551 |
+ |
552 |
+ page_list->nr_pages = num_pages_spanned(&iov[i]); |
553 |
+ page_list->base_address = iov[i].iov_base; |
554 |
+@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pa |
555 |
+ NULL); |
556 |
+ up_read(¤t->mm->mmap_sem); |
557 |
+ |
558 |
+- if (ret != page_list->nr_pages) { |
559 |
+- err = -ENOMEM; |
560 |
++ if (ret != page_list->nr_pages) |
561 |
+ goto unpin; |
562 |
+- } |
563 |
+ |
564 |
+ local_list->nr_iovecs = i + 1; |
565 |
+ } |
566 |
+@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pa |
567 |
+ unpin: |
568 |
+ dma_unpin_iovec_pages(local_list); |
569 |
+ out: |
570 |
+- return ERR_PTR(err); |
571 |
++ return NULL; |
572 |
+ } |
573 |
+ |
574 |
+ void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) |
575 |
|
576 |
Added: hardened/2.6/trunk/2.6.26/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch |
577 |
=================================================================== |
578 |
--- hardened/2.6/trunk/2.6.26/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch (rev 0) |
579 |
+++ hardened/2.6/trunk/2.6.26/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch 2008-12-03 00:31:33 UTC (rev 1413) |
580 |
@@ -0,0 +1,51 @@ |
581 |
+Added-By: Gordon Malm <gengor@g.o> |
582 |
+ |
583 |
+--- |
584 |
+ |
585 |
+From jejb@××××××.org Tue Nov 11 09:53:44 2008 |
586 |
+From: David Woodhouse <David.Woodhouse@×××××.com> |
587 |
+Date: Fri, 7 Nov 2008 00:08:59 GMT |
588 |
+Subject: JFFS2: Fix lack of locking in thread_should_wake() |
589 |
+To: stable@××××××.org |
590 |
+Message-ID: <200811070008.mA708xQE008191@×××××××××××.org> |
591 |
+ |
592 |
+From: David Woodhouse <David.Woodhouse@×××××.com> |
593 |
+ |
594 |
+commit b27cf88e9592953ae292d05324887f2f44979433 upstream |
595 |
+ |
596 |
+The thread_should_wake() function trawls through the list of 'very |
597 |
+dirty' eraseblocks, determining whether the background GC thread should |
598 |
+wake. Doing this without holding the appropriate locks is a bad idea. |
599 |
+ |
600 |
+OLPC Trac #8615 |
601 |
+ |
602 |
+Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com> |
603 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
604 |
+ |
605 |
+--- |
606 |
+ fs/jffs2/background.c | 10 +++++----- |
607 |
+ 1 file changed, 5 insertions(+), 5 deletions(-) |
608 |
+ |
609 |
+--- a/fs/jffs2/background.c |
610 |
++++ b/fs/jffs2/background.c |
611 |
+@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread( |
612 |
+ for (;;) { |
613 |
+ allow_signal(SIGHUP); |
614 |
+ again: |
615 |
++ spin_lock(&c->erase_completion_lock); |
616 |
+ if (!jffs2_thread_should_wake(c)) { |
617 |
+ set_current_state (TASK_INTERRUPTIBLE); |
618 |
++ spin_unlock(&c->erase_completion_lock); |
619 |
+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n")); |
620 |
+- /* Yes, there's a race here; we checked jffs2_thread_should_wake() |
621 |
+- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't |
622 |
+- matter - We don't care if we miss a wakeup, because the GC thread |
623 |
+- is only an optimisation anyway. */ |
624 |
+ schedule(); |
625 |
+- } |
626 |
++ } else |
627 |
++ spin_unlock(&c->erase_completion_lock); |
628 |
++ |
629 |
+ |
630 |
+ /* This thread is purely an optimisation. But if it runs when |
631 |
+ other things could be running, it actually makes things a |
632 |
|
633 |
Added: hardened/2.6/trunk/2.6.26/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch |
634 |
=================================================================== |
635 |
--- hardened/2.6/trunk/2.6.26/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch (rev 0) |
636 |
+++ hardened/2.6/trunk/2.6.26/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch 2008-12-03 00:31:33 UTC (rev 1413) |
637 |
@@ -0,0 +1,70 @@ |
638 |
+Added-By: Gordon Malm <gengor@g.o> |
639 |
+ |
640 |
+--- |
641 |
+ |
642 |
+From jejb@××××××.org Tue Nov 11 09:53:08 2008 |
643 |
+From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com> |
644 |
+Date: Fri, 7 Nov 2008 00:08:19 GMT |
645 |
+Subject: JFFS2: fix race condition in jffs2_lzo_compress() |
646 |
+To: stable@××××××.org |
647 |
+Message-ID: <200811070008.mA708Jdo007031@×××××××××××.org> |
648 |
+ |
649 |
+From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com> |
650 |
+ |
651 |
+commit dc8a0843a435b2c0891e7eaea64faaf1ebec9b11 upstream |
652 |
+ |
653 |
+deflate_mutex protects the globals lzo_mem and lzo_compress_buf. However, |
654 |
+jffs2_lzo_compress() unlocks deflate_mutex _before_ it has copied out the |
655 |
+compressed data from lzo_compress_buf. Correct this by moving the mutex |
656 |
+unlock after the copy. |
657 |
+ |
658 |
+In addition, document what deflate_mutex actually protects. |
659 |
+ |
660 |
+Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com> |
661 |
+Acked-by: Richard Purdie <rpurdie@××××××××××.com> |
662 |
+Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org> |
663 |
+Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com> |
664 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
665 |
+ |
666 |
+--- |
667 |
+ fs/jffs2/compr_lzo.c | 15 +++++++++------ |
668 |
+ 1 file changed, 9 insertions(+), 6 deletions(-) |
669 |
+ |
670 |
+--- a/fs/jffs2/compr_lzo.c |
671 |
++++ b/fs/jffs2/compr_lzo.c |
672 |
+@@ -19,7 +19,7 @@ |
673 |
+ |
674 |
+ static void *lzo_mem; |
675 |
+ static void *lzo_compress_buf; |
676 |
+-static DEFINE_MUTEX(deflate_mutex); |
677 |
++static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */ |
678 |
+ |
679 |
+ static void free_workspace(void) |
680 |
+ { |
681 |
+@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned c |
682 |
+ |
683 |
+ mutex_lock(&deflate_mutex); |
684 |
+ ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); |
685 |
+- mutex_unlock(&deflate_mutex); |
686 |
+- |
687 |
+ if (ret != LZO_E_OK) |
688 |
+- return -1; |
689 |
++ goto fail; |
690 |
+ |
691 |
+ if (compress_size > *dstlen) |
692 |
+- return -1; |
693 |
++ goto fail; |
694 |
+ |
695 |
+ memcpy(cpage_out, lzo_compress_buf, compress_size); |
696 |
+- *dstlen = compress_size; |
697 |
++ mutex_unlock(&deflate_mutex); |
698 |
+ |
699 |
++ *dstlen = compress_size; |
700 |
+ return 0; |
701 |
++ |
702 |
++ fail: |
703 |
++ mutex_unlock(&deflate_mutex); |
704 |
++ return -1; |
705 |
+ } |
706 |
+ |
707 |
+ static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, |
708 |
|
709 |
Added: hardened/2.6/trunk/2.6.26/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch |
710 |
=================================================================== |
711 |
--- hardened/2.6/trunk/2.6.26/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch (rev 0) |
712 |
+++ hardened/2.6/trunk/2.6.26/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch 2008-12-03 00:31:33 UTC (rev 1413) |
713 |
@@ -0,0 +1,63 @@ |
714 |
+Added-By: Gordon Malm <gengor@g.o> |
715 |
+ |
716 |
+--- |
717 |
+ |
718 |
+From 1f8f5cf6e4f038552a3e47b66085452c08556d71 Mon Sep 17 00:00:00 2001 |
719 |
+From: David Howells <dhowells@××××××.com> |
720 |
+Date: Mon, 10 Nov 2008 19:00:05 +0000 |
721 |
+Subject: KEYS: Make request key instantiate the per-user keyrings |
722 |
+ |
723 |
+From: David Howells <dhowells@××××××.com> |
724 |
+ |
725 |
+commit 1f8f5cf6e4f038552a3e47b66085452c08556d71 upstream |
726 |
+ |
727 |
+Make request_key() instantiate the per-user keyrings so that it doesn't oops |
728 |
+if it needs to get hold of the user session keyring because there isn't a |
729 |
+session keyring in place. |
730 |
+ |
731 |
+Signed-off-by: David Howells <dhowells@××××××.com> |
732 |
+Tested-by: Steve French <smfrench@×××××.com> |
733 |
+Tested-by: Rutger Nijlunsing <rutger.nijlunsing@×××××.com> |
734 |
+Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
735 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
736 |
+ |
737 |
+--- |
738 |
+ security/keys/internal.h | 1 + |
739 |
+ security/keys/process_keys.c | 2 +- |
740 |
+ security/keys/request_key.c | 4 ++++ |
741 |
+ 3 files changed, 6 insertions(+), 1 deletion(-) |
742 |
+ |
743 |
+--- a/security/keys/internal.h |
744 |
++++ b/security/keys/internal.h |
745 |
+@@ -107,6 +107,7 @@ extern key_ref_t search_process_keyrings |
746 |
+ |
747 |
+ extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); |
748 |
+ |
749 |
++extern int install_user_keyrings(struct task_struct *tsk); |
750 |
+ extern int install_thread_keyring(struct task_struct *tsk); |
751 |
+ extern int install_process_keyring(struct task_struct *tsk); |
752 |
+ |
753 |
+--- a/security/keys/process_keys.c |
754 |
++++ b/security/keys/process_keys.c |
755 |
+@@ -40,7 +40,7 @@ struct key_user root_key_user = { |
756 |
+ /* |
757 |
+ * install user and user session keyrings for a particular UID |
758 |
+ */ |
759 |
+-static int install_user_keyrings(struct task_struct *tsk) |
760 |
++int install_user_keyrings(struct task_struct *tsk) |
761 |
+ { |
762 |
+ struct user_struct *user = tsk->user; |
763 |
+ struct key *uid_keyring, *session_keyring; |
764 |
+--- a/security/keys/request_key.c |
765 |
++++ b/security/keys/request_key.c |
766 |
+@@ -74,6 +74,10 @@ static int call_sbin_request_key(struct |
767 |
+ |
768 |
+ kenter("{%d},{%d},%s", key->serial, authkey->serial, op); |
769 |
+ |
770 |
++ ret = install_user_keyrings(tsk); |
771 |
++ if (ret < 0) |
772 |
++ goto error_alloc; |
773 |
++ |
774 |
+ /* allocate a new session keyring */ |
775 |
+ sprintf(desc, "_req.%u", key->serial); |
776 |
+ |
777 |
|
778 |
Added: hardened/2.6/trunk/2.6.26/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch |
779 |
=================================================================== |
780 |
--- hardened/2.6/trunk/2.6.26/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch (rev 0) |
781 |
+++ hardened/2.6/trunk/2.6.26/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch 2008-12-03 00:31:33 UTC (rev 1413) |
782 |
@@ -0,0 +1,51 @@ |
783 |
+Added-By: Gordon Malm <gengor@g.o> |
784 |
+ |
785 |
+Note: Changed patch slightly to eliminate fuzz. |
786 |
+ |
787 |
+--- |
788 |
+ |
789 |
+From jejb@××××××.org Tue Nov 11 09:47:32 2008 |
790 |
+From: Andre Noll <maan@×××××××××××.org> |
791 |
+Date: Fri, 7 Nov 2008 00:07:46 GMT |
792 |
+Subject: md: linear: Fix a division by zero bug for very small arrays. |
793 |
+To: stable@××××××.org |
794 |
+Message-ID: <200811070007.mA707k6d006270@×××××××××××.org> |
795 |
+ |
796 |
+From: Andre Noll <maan@×××××××××××.org> |
797 |
+ |
798 |
+commit f1cd14ae52985634d0389e934eba25b5ecf24565 upstream |
799 |
+ |
800 |
+Date: Thu, 6 Nov 2008 19:41:24 +1100 |
801 |
+Subject: md: linear: Fix a division by zero bug for very small arrays. |
802 |
+ |
803 |
+We currently oops with a divide error on starting a linear software |
804 |
+raid array consisting of at least two very small (< 500K) devices. |
805 |
+ |
806 |
+The bug is caused by the calculation of the hash table size which |
807 |
+tries to compute sector_div(sz, base) with "base" being zero due to |
808 |
+the small size of the component devices of the array. |
809 |
+ |
810 |
+Fix this by requiring the hash spacing to be at least one which |
811 |
+implies that also "base" is non-zero. |
812 |
+ |
813 |
+This bug has existed since about 2.6.14. |
814 |
+ |
815 |
+Signed-off-by: Andre Noll <maan@×××××××××××.org> |
816 |
+Signed-off-by: NeilBrown <neilb@××××.de> |
817 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
818 |
+ |
819 |
+--- |
820 |
+ drivers/md/linear.c | 2 ++ |
821 |
+ 1 file changed, 2 insertions(+) |
822 |
+ |
823 |
+--- a/drivers/md/linear.c |
824 |
++++ b/drivers/md/linear.c |
825 |
+@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_ |
826 |
+ |
827 |
+ min_spacing = conf->array_size; |
828 |
+ sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); |
829 |
++ if (min_spacing == 0) |
830 |
++ min_spacing = 1; |
831 |
+ |
832 |
+ /* min_spacing is the minimum spacing that will fit the hash |
833 |
+ * table in one PAGE. This may be much smaller than needed. |
834 |
|
835 |
Added: hardened/2.6/trunk/2.6.26/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch |
836 |
=================================================================== |
837 |
--- hardened/2.6/trunk/2.6.26/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch (rev 0) |
838 |
+++ hardened/2.6/trunk/2.6.26/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch 2008-12-03 00:31:33 UTC (rev 1413) |
839 |
@@ -0,0 +1,42 @@ |
840 |
+Added-By: Gordon Malm <gengor@g.o> |
841 |
+ |
842 |
+--- |
843 |
+ |
844 |
+From 493890e75d98810a3470b4aae23be628ee5e9667 Mon Sep 17 00:00:00 2001 |
845 |
+From: Pierre Ossman <drzeus@××××××.cx> |
846 |
+Date: Sun, 26 Oct 2008 12:37:25 +0100 |
847 |
+Subject: mmc: increase SD write timeout for crappy cards |
848 |
+ |
849 |
+From: Pierre Ossman <drzeus@××××××.cx> |
850 |
+ |
851 |
+commit 493890e75d98810a3470b4aae23be628ee5e9667 upstream. |
852 |
+ |
853 |
+It seems that some cards are slightly out of spec and occasionally |
854 |
+will not be able to complete a write in the alloted 250 ms [1]. |
855 |
+Incease the timeout slightly to allow even these cards to function |
856 |
+properly. |
857 |
+ |
858 |
+[1] http://lkml.org/lkml/2008/9/23/390 |
859 |
+ |
860 |
+Signed-off-by: Pierre Ossman <drzeus@××××××.cx> |
861 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
862 |
+ |
863 |
+--- |
864 |
+ drivers/mmc/core/core.c | 6 +++++- |
865 |
+ 1 file changed, 5 insertions(+), 1 deletion(-) |
866 |
+ |
867 |
+--- a/drivers/mmc/core/core.c |
868 |
++++ b/drivers/mmc/core/core.c |
869 |
+@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_dat |
870 |
+ (card->host->ios.clock / 1000); |
871 |
+ |
872 |
+ if (data->flags & MMC_DATA_WRITE) |
873 |
+- limit_us = 250000; |
874 |
++ /* |
875 |
++ * The limit is really 250 ms, but that is |
876 |
++ * insufficient for some crappy cards. |
877 |
++ */ |
878 |
++ limit_us = 300000; |
879 |
+ else |
880 |
+ limit_us = 100000; |
881 |
+ |
882 |
|
883 |
Added: hardened/2.6/trunk/2.6.26/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch |
884 |
=================================================================== |
885 |
--- hardened/2.6/trunk/2.6.26/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch (rev 0) |
886 |
+++ hardened/2.6/trunk/2.6.26/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch 2008-12-03 00:31:33 UTC (rev 1413) |
887 |
@@ -0,0 +1,213 @@ |
888 |
+Added-By: Gordon Malm <gengor@g.o> |
889 |
+ |
890 |
+Backported to earlier kernels. Original message included below. |
891 |
+ |
892 |
+--- |
893 |
+ |
894 |
+From jejb@××××××.org Tue Nov 11 09:59:05 2008 |
895 |
+From: Miklos Szeredi <mszeredi@××××.cz> |
896 |
+Date: Sun, 9 Nov 2008 19:50:02 GMT |
897 |
+Subject: net: unix: fix inflight counting bug in garbage collector |
898 |
+To: stable@××××××.org |
899 |
+Message-ID: <200811091950.mA9Jo2iL003804@×××××××××××.org> |
900 |
+ |
901 |
+From: Miklos Szeredi <mszeredi@××××.cz> |
902 |
+ |
903 |
+commit 6209344f5a3795d34b7f2c0061f49802283b6bdd upstream |
904 |
+ |
905 |
+Previously I assumed that the receive queues of candidates don't |
906 |
+change during the GC. This is only half true, nothing can be received |
907 |
+from the queues (see comment in unix_gc()), but buffers could be added |
908 |
+through the other half of the socket pair, which may still have file |
909 |
+descriptors referring to it. |
910 |
+ |
911 |
+This can result in inc_inflight_move_tail() erronously increasing the |
912 |
+"inflight" counter for a unix socket for which dec_inflight() wasn't |
913 |
+previously called. This in turn can trigger the "BUG_ON(total_refs < |
914 |
+inflight_refs)" in a later garbage collection run. |
915 |
+ |
916 |
+Fix this by only manipulating the "inflight" counter for sockets which |
917 |
+are candidates themselves. Duplicating the file references in |
918 |
+unix_attach_fds() is also needed to prevent a socket becoming a |
919 |
+candidate for GC while the skb that contains it is not yet queued. |
920 |
+ |
921 |
+Reported-by: Andrea Bittau <a.bittau@×××××××××.uk> |
922 |
+Signed-off-by: Miklos Szeredi <mszeredi@××××.cz> |
923 |
+Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
924 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
925 |
+ |
926 |
+--- |
927 |
+ include/net/af_unix.h | 1 + |
928 |
+ net/unix/af_unix.c | 31 ++++++++++++++++++++++++------- |
929 |
+ net/unix/garbage.c | 49 +++++++++++++++++++++++++++++++++++++------------ |
930 |
+ 3 files changed, 62 insertions(+), 19 deletions(-) |
931 |
+ |
932 |
+--- a/include/net/af_unix.h |
933 |
++++ b/include/net/af_unix.h |
934 |
+@@ -54,6 +54,7 @@ struct unix_sock { |
935 |
+ atomic_t inflight; |
936 |
+ spinlock_t lock; |
937 |
+ unsigned int gc_candidate : 1; |
938 |
++ unsigned int gc_maybe_cycle : 1; |
939 |
+ wait_queue_head_t peer_wait; |
940 |
+ }; |
941 |
+ #define unix_sk(__sk) ((struct unix_sock *)__sk) |
942 |
+--- a/net/unix/af_unix.c |
943 |
++++ b/net/unix/af_unix.c |
944 |
+@@ -1302,14 +1302,23 @@ static void unix_destruct_fds(struct sk_ |
945 |
+ sock_wfree(skb); |
946 |
+ } |
947 |
+ |
948 |
+-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
949 |
++static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
950 |
+ { |
951 |
+ int i; |
952 |
++ |
953 |
++ /* |
954 |
++ * Need to duplicate file references for the sake of garbage |
955 |
++ * collection. Otherwise a socket in the fps might become a |
956 |
++ * candidate for GC while the skb is not yet queued. |
957 |
++ */ |
958 |
++ UNIXCB(skb).fp = scm_fp_dup(scm->fp); |
959 |
++ if (!UNIXCB(skb).fp) |
960 |
++ return -ENOMEM; |
961 |
++ |
962 |
+ for (i=scm->fp->count-1; i>=0; i--) |
963 |
+ unix_inflight(scm->fp->fp[i]); |
964 |
+- UNIXCB(skb).fp = scm->fp; |
965 |
+ skb->destructor = unix_destruct_fds; |
966 |
+- scm->fp = NULL; |
967 |
++ return 0; |
968 |
+ } |
969 |
+ |
970 |
+ /* |
971 |
+@@ -1368,8 +1377,11 @@ static int unix_dgram_sendmsg(struct kio |
972 |
+ goto out; |
973 |
+ |
974 |
+ memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
975 |
+- if (siocb->scm->fp) |
976 |
+- unix_attach_fds(siocb->scm, skb); |
977 |
++ if (siocb->scm->fp) { |
978 |
++ err = unix_attach_fds(siocb->scm, skb); |
979 |
++ if (err) |
980 |
++ goto out_free; |
981 |
++ } |
982 |
+ unix_get_secdata(siocb->scm, skb); |
983 |
+ |
984 |
+ skb_reset_transport_header(skb); |
985 |
+@@ -1538,8 +1550,13 @@ static int unix_stream_sendmsg(struct ki |
986 |
+ size = min_t(int, size, skb_tailroom(skb)); |
987 |
+ |
988 |
+ memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
989 |
+- if (siocb->scm->fp) |
990 |
+- unix_attach_fds(siocb->scm, skb); |
991 |
++ if (siocb->scm->fp) { |
992 |
++ err = unix_attach_fds(siocb->scm, skb); |
993 |
++ if (err) { |
994 |
++ kfree_skb(skb); |
995 |
++ goto out_err; |
996 |
++ } |
997 |
++ } |
998 |
+ |
999 |
+ if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) { |
1000 |
+ kfree_skb(skb); |
1001 |
+--- a/net/unix/garbage.c |
1002 |
++++ b/net/unix/garbage.c |
1003 |
+@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x |
1004 |
+ */ |
1005 |
+ struct sock *sk = unix_get_socket(*fp++); |
1006 |
+ if (sk) { |
1007 |
+- hit = true; |
1008 |
+- func(unix_sk(sk)); |
1009 |
++ struct unix_sock *u = unix_sk(sk); |
1010 |
++ |
1011 |
++ /* |
1012 |
++ * Ignore non-candidates, they could |
1013 |
++ * have been added to the queues after |
1014 |
++ * starting the garbage collection |
1015 |
++ */ |
1016 |
++ if (u->gc_candidate) { |
1017 |
++ hit = true; |
1018 |
++ func(u); |
1019 |
++ } |
1020 |
+ } |
1021 |
+ } |
1022 |
+ if (hit && hitlist != NULL) { |
1023 |
+@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struc |
1024 |
+ { |
1025 |
+ atomic_inc(&u->inflight); |
1026 |
+ /* |
1027 |
+- * If this is still a candidate, move it to the end of the |
1028 |
+- * list, so that it's checked even if it was already passed |
1029 |
+- * over |
1030 |
++ * If this still might be part of a cycle, move it to the end |
1031 |
++ * of the list, so that it's checked even if it was already |
1032 |
++ * passed over |
1033 |
+ */ |
1034 |
+- if (u->gc_candidate) |
1035 |
++ if (u->gc_maybe_cycle) |
1036 |
+ list_move_tail(&u->link, &gc_candidates); |
1037 |
+ } |
1038 |
+ |
1039 |
+@@ -267,6 +276,7 @@ void unix_gc(void) |
1040 |
+ struct unix_sock *next; |
1041 |
+ struct sk_buff_head hitlist; |
1042 |
+ struct list_head cursor; |
1043 |
++ LIST_HEAD(not_cycle_list); |
1044 |
+ |
1045 |
+ spin_lock(&unix_gc_lock); |
1046 |
+ |
1047 |
+@@ -282,10 +292,14 @@ void unix_gc(void) |
1048 |
+ * |
1049 |
+ * Holding unix_gc_lock will protect these candidates from |
1050 |
+ * being detached, and hence from gaining an external |
1051 |
+- * reference. This also means, that since there are no |
1052 |
+- * possible receivers, the receive queues of these sockets are |
1053 |
+- * static during the GC, even though the dequeue is done |
1054 |
+- * before the detach without atomicity guarantees. |
1055 |
++ * reference. Since there are no possible receivers, all |
1056 |
++ * buffers currently on the candidates' queues stay there |
1057 |
++ * during the garbage collection. |
1058 |
++ * |
1059 |
++ * We also know that no new candidate can be added onto the |
1060 |
++ * receive queues. Other, non candidate sockets _can_ be |
1061 |
++ * added to queue, so we must make sure only to touch |
1062 |
++ * candidates. |
1063 |
+ */ |
1064 |
+ list_for_each_entry_safe(u, next, &gc_inflight_list, link) { |
1065 |
+ int total_refs; |
1066 |
+@@ -299,6 +313,7 @@ void unix_gc(void) |
1067 |
+ if (total_refs == inflight_refs) { |
1068 |
+ list_move_tail(&u->link, &gc_candidates); |
1069 |
+ u->gc_candidate = 1; |
1070 |
++ u->gc_maybe_cycle = 1; |
1071 |
+ } |
1072 |
+ } |
1073 |
+ |
1074 |
+@@ -325,14 +340,24 @@ void unix_gc(void) |
1075 |
+ list_move(&cursor, &u->link); |
1076 |
+ |
1077 |
+ if (atomic_read(&u->inflight) > 0) { |
1078 |
+- list_move_tail(&u->link, &gc_inflight_list); |
1079 |
+- u->gc_candidate = 0; |
1080 |
++ list_move_tail(&u->link, ¬_cycle_list); |
1081 |
++ u->gc_maybe_cycle = 0; |
1082 |
+ scan_children(&u->sk, inc_inflight_move_tail, NULL); |
1083 |
+ } |
1084 |
+ } |
1085 |
+ list_del(&cursor); |
1086 |
+ |
1087 |
+ /* |
1088 |
++ * not_cycle_list contains those sockets which do not make up a |
1089 |
++ * cycle. Restore these to the inflight list. |
1090 |
++ */ |
1091 |
++ while (!list_empty(¬_cycle_list)) { |
1092 |
++ u = list_entry(not_cycle_list.next, struct unix_sock, link); |
1093 |
++ u->gc_candidate = 0; |
1094 |
++ list_move_tail(&u->link, &gc_inflight_list); |
1095 |
++ } |
1096 |
++ |
1097 |
++ /* |
1098 |
+ * Now gc_candidates contains only garbage. Restore original |
1099 |
+ * inflight counters for these as well, and remove the skbuffs |
1100 |
+ * which are creating the cycle(s). |
1101 |
|
1102 |
Added: hardened/2.6/trunk/2.6.26/1414_acpi-avoid-empty-file-name-in-sysfs.patch |
1103 |
=================================================================== |
1104 |
--- hardened/2.6/trunk/2.6.26/1414_acpi-avoid-empty-file-name-in-sysfs.patch (rev 0) |
1105 |
+++ hardened/2.6/trunk/2.6.26/1414_acpi-avoid-empty-file-name-in-sysfs.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1106 |
@@ -0,0 +1,81 @@ |
1107 |
+Added-By: Gordon Malm <gengor@g.o> |
1108 |
+ |
1109 |
+--- |
1110 |
+ |
1111 |
+From 4feba70a2c1a1a0c96909f657f48b2e11e682370 Mon Sep 17 00:00:00 2001 |
1112 |
+From: Peter Gruber <nokos@×××.net> |
1113 |
+Date: Mon, 27 Oct 2008 23:59:36 -0400 |
1114 |
+Subject: ACPI: avoid empty file name in sysfs |
1115 |
+ |
1116 |
+From: Peter Gruber <nokos@×××.net> |
1117 |
+ |
1118 |
+commit 4feba70a2c1a1a0c96909f657f48b2e11e682370 upstream. |
1119 |
+ |
1120 |
+Since commit bc45b1d39a925b56796bebf8a397a0491489d85c acpi tables are |
1121 |
+allowed to have an empty signature and /sys/firmware/acpi/tables uses the |
1122 |
+signature as filename. Applications using naive recursion through /sys |
1123 |
+loop forever. A possible solution would be: (replacing the zero length |
1124 |
+filename with the string "NULL") |
1125 |
+ |
1126 |
+http://bugzilla.kernel.org/show_bug.cgi?id=11539 |
1127 |
+ |
1128 |
+Acked-by: Zhang Rui <rui.zhang@×××××.com> |
1129 |
+Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org> |
1130 |
+Signed-off-by: Len Brown <len.brown@×××××.com> |
1131 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1132 |
+ |
1133 |
+--- |
1134 |
+ drivers/acpi/system.c | 25 +++++++++++++++++-------- |
1135 |
+ 1 file changed, 17 insertions(+), 8 deletions(-) |
1136 |
+ |
1137 |
+--- a/drivers/acpi/system.c |
1138 |
++++ b/drivers/acpi/system.c |
1139 |
+@@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct ko |
1140 |
+ container_of(bin_attr, struct acpi_table_attr, attr); |
1141 |
+ struct acpi_table_header *table_header = NULL; |
1142 |
+ acpi_status status; |
1143 |
++ char name[ACPI_NAME_SIZE]; |
1144 |
++ |
1145 |
++ if (strncmp(table_attr->name, "NULL", 4)) |
1146 |
++ memcpy(name, table_attr->name, ACPI_NAME_SIZE); |
1147 |
++ else |
1148 |
++ memcpy(name, "\0\0\0\0", 4); |
1149 |
+ |
1150 |
+ status = |
1151 |
+- acpi_get_table(table_attr->name, table_attr->instance, |
1152 |
++ acpi_get_table(name, table_attr->instance, |
1153 |
+ &table_header); |
1154 |
+ if (ACPI_FAILURE(status)) |
1155 |
+ return -ENODEV; |
1156 |
+@@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct |
1157 |
+ struct acpi_table_header *header = NULL; |
1158 |
+ struct acpi_table_attr *attr = NULL; |
1159 |
+ |
1160 |
+- memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE); |
1161 |
++ if (table_header->signature[0] != '\0') |
1162 |
++ memcpy(table_attr->name, table_header->signature, |
1163 |
++ ACPI_NAME_SIZE); |
1164 |
++ else |
1165 |
++ memcpy(table_attr->name, "NULL", 4); |
1166 |
+ |
1167 |
+ list_for_each_entry(attr, &acpi_table_attr_list, node) { |
1168 |
+- if (!memcmp(table_header->signature, attr->name, |
1169 |
+- ACPI_NAME_SIZE)) |
1170 |
++ if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE)) |
1171 |
+ if (table_attr->instance < attr->instance) |
1172 |
+ table_attr->instance = attr->instance; |
1173 |
+ } |
1174 |
+ table_attr->instance++; |
1175 |
+ |
1176 |
+ if (table_attr->instance > 1 || (table_attr->instance == 1 && |
1177 |
+- !acpi_get_table(table_header-> |
1178 |
+- signature, 2, |
1179 |
+- &header))) |
1180 |
+- sprintf(table_attr->name + 4, "%d", table_attr->instance); |
1181 |
++ !acpi_get_table |
1182 |
++ (table_header->signature, 2, &header))) |
1183 |
++ sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", |
1184 |
++ table_attr->instance); |
1185 |
+ |
1186 |
+ table_attr->attr.size = 0; |
1187 |
+ table_attr->attr.read = acpi_table_show; |
1188 |
|
1189 |
Added: hardened/2.6/trunk/2.6.26/1415_block-fix-nr_phys_segments-miscalculation-bug.patch |
1190 |
=================================================================== |
1191 |
--- hardened/2.6/trunk/2.6.26/1415_block-fix-nr_phys_segments-miscalculation-bug.patch (rev 0) |
1192 |
+++ hardened/2.6/trunk/2.6.26/1415_block-fix-nr_phys_segments-miscalculation-bug.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1193 |
@@ -0,0 +1,126 @@ |
1194 |
+Added-By: Gordon Malm <gengor@g.o> |
1195 |
+ |
1196 |
+--- |
1197 |
+ |
1198 |
+From knikanth@××××.de Thu Nov 13 14:07:47 2008 |
1199 |
+From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp> |
1200 |
+Date: Wed, 12 Nov 2008 11:33:54 +0530 |
1201 |
+Subject: block: fix nr_phys_segments miscalculation bug |
1202 |
+To: Greg KH <greg@×××××.com> |
1203 |
+Cc: stable@××××××.org, FUJITA Tomonori <fujita.tomonori@××××××××××.jp> |
1204 |
+Message-ID: <200811121133.55404.knikanth@××××.de> |
1205 |
+Content-Disposition: inline |
1206 |
+ |
1207 |
+From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp> |
1208 |
+ |
1209 |
+commit 8677142710516d986d932d6f1fba7be8382c1fec upstream |
1210 |
+backported by Nikanth Karthikesan <knikanth@××××.de> to the 2.6.27.y tree. |
1211 |
+ |
1212 |
+block: fix nr_phys_segments miscalculation bug |
1213 |
+ |
1214 |
+This fixes the bug reported by Nikanth Karthikesan <knikanth@××××.de>: |
1215 |
+ |
1216 |
+http://lkml.org/lkml/2008/10/2/203 |
1217 |
+ |
1218 |
+The root cause of the bug is that blk_phys_contig_segment |
1219 |
+miscalculates q->max_segment_size. |
1220 |
+ |
1221 |
+blk_phys_contig_segment checks: |
1222 |
+ |
1223 |
+req->biotail->bi_size + next_req->bio->bi_size > q->max_segment_size |
1224 |
+ |
1225 |
+But blk_recalc_rq_segments might expect that req->biotail and the |
1226 |
+previous bio in the req are supposed be merged into one |
1227 |
+segment. blk_recalc_rq_segments might also expect that next_req->bio |
1228 |
+and the next bio in the next_req are supposed be merged into one |
1229 |
+segment. In such case, we merge two requests that can't be merged |
1230 |
+here. Later, blk_rq_map_sg gives more segments than it should. |
1231 |
+ |
1232 |
+We need to keep track of segment size in blk_recalc_rq_segments and |
1233 |
+use it to see if two requests can be merged. This patch implements it |
1234 |
+in the similar way that we used to do for hw merging (virtual |
1235 |
+merging). |
1236 |
+ |
1237 |
+Signed-off-by: FUJITA Tomonori <fujita.tomonori@××××××××××.jp> |
1238 |
+Signed-off-by: Jens Axboe <jens.axboe@××××××.com> |
1239 |
+Cc: Nikanth Karthikesan <knikanth@××××.de> |
1240 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1241 |
+ |
1242 |
+--- |
1243 |
+ block/blk-merge.c | 19 +++++++++++++++++-- |
1244 |
+ include/linux/bio.h | 7 +++++++ |
1245 |
+ 2 files changed, 24 insertions(+), 2 deletions(-) |
1246 |
+ |
1247 |
+--- a/block/blk-merge.c |
1248 |
++++ b/block/blk-merge.c |
1249 |
+@@ -95,6 +95,9 @@ new_hw_segment: |
1250 |
+ nr_hw_segs++; |
1251 |
+ } |
1252 |
+ |
1253 |
++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) |
1254 |
++ rq->bio->bi_seg_front_size = seg_size; |
1255 |
++ |
1256 |
+ nr_phys_segs++; |
1257 |
+ bvprv = bv; |
1258 |
+ seg_size = bv->bv_len; |
1259 |
+@@ -106,6 +109,10 @@ new_hw_segment: |
1260 |
+ rq->bio->bi_hw_front_size = hw_seg_size; |
1261 |
+ if (hw_seg_size > rq->biotail->bi_hw_back_size) |
1262 |
+ rq->biotail->bi_hw_back_size = hw_seg_size; |
1263 |
++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) |
1264 |
++ rq->bio->bi_seg_front_size = seg_size; |
1265 |
++ if (seg_size > rq->biotail->bi_seg_back_size) |
1266 |
++ rq->biotail->bi_seg_back_size = seg_size; |
1267 |
+ rq->nr_phys_segments = nr_phys_segs; |
1268 |
+ rq->nr_hw_segments = nr_hw_segs; |
1269 |
+ } |
1270 |
+@@ -133,7 +140,8 @@ static int blk_phys_contig_segment(struc |
1271 |
+ |
1272 |
+ if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt))) |
1273 |
+ return 0; |
1274 |
+- if (bio->bi_size + nxt->bi_size > q->max_segment_size) |
1275 |
++ if (bio->bi_seg_back_size + nxt->bi_seg_front_size > |
1276 |
++ q->max_segment_size) |
1277 |
+ return 0; |
1278 |
+ |
1279 |
+ /* |
1280 |
+@@ -377,6 +385,8 @@ static int ll_merge_requests_fn(struct r |
1281 |
+ { |
1282 |
+ int total_phys_segments; |
1283 |
+ int total_hw_segments; |
1284 |
++ unsigned int seg_size = |
1285 |
++ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size; |
1286 |
+ |
1287 |
+ /* |
1288 |
+ * First check if the either of the requests are re-queued |
1289 |
+@@ -392,8 +402,13 @@ static int ll_merge_requests_fn(struct r |
1290 |
+ return 0; |
1291 |
+ |
1292 |
+ total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; |
1293 |
+- if (blk_phys_contig_segment(q, req->biotail, next->bio)) |
1294 |
++ if (blk_phys_contig_segment(q, req->biotail, next->bio)) { |
1295 |
++ if (req->nr_phys_segments == 1) |
1296 |
++ req->bio->bi_seg_front_size = seg_size; |
1297 |
++ if (next->nr_phys_segments == 1) |
1298 |
++ next->biotail->bi_seg_back_size = seg_size; |
1299 |
+ total_phys_segments--; |
1300 |
++ } |
1301 |
+ |
1302 |
+ if (total_phys_segments > q->max_phys_segments) |
1303 |
+ return 0; |
1304 |
+--- a/include/linux/bio.h |
1305 |
++++ b/include/linux/bio.h |
1306 |
+@@ -98,6 +98,13 @@ struct bio { |
1307 |
+ unsigned int bi_size; /* residual I/O count */ |
1308 |
+ |
1309 |
+ /* |
1310 |
++ * To keep track of the max segment size, we account for the |
1311 |
++ * sizes of the first and last mergeable segments in this bio. |
1312 |
++ */ |
1313 |
++ unsigned int bi_seg_front_size; |
1314 |
++ unsigned int bi_seg_back_size; |
1315 |
++ |
1316 |
++ /* |
1317 |
+ * To keep track of the max hw size, we account for the |
1318 |
+ * sizes of the first and last virtually mergeable segments |
1319 |
+ * in this bio |
1320 |
|
1321 |
Added: hardened/2.6/trunk/2.6.26/1416_dm-raid1-flush-workqueue-before-destruction.patch |
1322 |
=================================================================== |
1323 |
--- hardened/2.6/trunk/2.6.26/1416_dm-raid1-flush-workqueue-before-destruction.patch (rev 0) |
1324 |
+++ hardened/2.6/trunk/2.6.26/1416_dm-raid1-flush-workqueue-before-destruction.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1325 |
@@ -0,0 +1,34 @@ |
1326 |
+Added-By: Gordon Malm <gengor@g.o> |
1327 |
+ |
1328 |
+--- |
1329 |
+ |
1330 |
+From 18776c7316545482a02bfaa2629a2aa1afc48357 Mon Sep 17 00:00:00 2001 |
1331 |
+From: Mikulas Patocka <mpatocka@××××××.com> |
1332 |
+Date: Thu, 13 Nov 2008 23:38:52 +0000 |
1333 |
+Subject: dm raid1: flush workqueue before destruction |
1334 |
+ |
1335 |
+From: Mikulas Patocka <mpatocka@××××××.com> |
1336 |
+ |
1337 |
+commit 18776c7316545482a02bfaa2629a2aa1afc48357 upstream. |
1338 |
+ |
1339 |
+We queue work on keventd queue --- so this queue must be flushed in the |
1340 |
+destructor. Otherwise, keventd could access mirror_set after it was freed. |
1341 |
+ |
1342 |
+Signed-off-by: Mikulas Patocka <mpatocka@××××××.com> |
1343 |
+Signed-off-by: Alasdair G Kergon <agk@××××××.com> |
1344 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1345 |
+ |
1346 |
+--- |
1347 |
+ drivers/md/dm-raid1.c | 1 + |
1348 |
+ 1 file changed, 1 insertion(+) |
1349 |
+ |
1350 |
+--- a/drivers/md/dm-raid1.c |
1351 |
++++ b/drivers/md/dm-raid1.c |
1352 |
+@@ -1598,6 +1598,7 @@ static void mirror_dtr(struct dm_target |
1353 |
+ |
1354 |
+ del_timer_sync(&ms->timer); |
1355 |
+ flush_workqueue(ms->kmirrord_wq); |
1356 |
++ flush_scheduled_work(); |
1357 |
+ dm_kcopyd_client_destroy(ms->kcopyd_client); |
1358 |
+ destroy_workqueue(ms->kmirrord_wq); |
1359 |
+ free_context(ms, ti, ms->nr_mirrors); |
1360 |
|
1361 |
Added: hardened/2.6/trunk/2.6.26/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch |
1362 |
=================================================================== |
1363 |
--- hardened/2.6/trunk/2.6.26/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch (rev 0) |
1364 |
+++ hardened/2.6/trunk/2.6.26/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1365 |
@@ -0,0 +1,104 @@ |
1366 |
+Added-By: Gordon Malm <gengor@g.o> |
1367 |
+ |
1368 |
+Note: Backported to earlier kernels. Original message included below. |
1369 |
+ |
1370 |
+--- |
1371 |
+ |
1372 |
+From b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 Mon Sep 17 00:00:00 2001 |
1373 |
+From: Eric Dumazet <dada1@×××××××××.com> |
1374 |
+Date: Mon, 10 Nov 2008 21:43:08 -0800 |
1375 |
+Subject: net: fix /proc/net/snmp as memory corruptor |
1376 |
+ |
1377 |
+From: Eric Dumazet <dada1@×××××××××.com> |
1378 |
+ |
1379 |
+commit b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 upstream. |
1380 |
+ |
1381 |
+icmpmsg_put() can happily corrupt kernel memory, using a static |
1382 |
+table and forgetting to reset an array index in a loop. |
1383 |
+ |
1384 |
+Remove the static array since its not safe without proper locking. |
1385 |
+ |
1386 |
+Signed-off-by: Alexey Dobriyan <adobriyan@×××××.com> |
1387 |
+Signed-off-by: Eric Dumazet <dada1@×××××××××.com> |
1388 |
+Signed-off-by: David S. Miller <davem@×××××××××.net> |
1389 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1390 |
+ |
1391 |
+--- |
1392 |
+ net/ipv4/proc.c | 58 ++++++++++++++++++++++++++++---------------------------- |
1393 |
+ 1 file changed, 30 insertions(+), 28 deletions(-) |
1394 |
+ |
1395 |
+--- a/net/ipv4/proc.c |
1396 |
++++ b/net/ipv4/proc.c |
1397 |
+@@ -262,42 +262,44 @@ static const struct snmp_mib snmp4_net_l |
1398 |
+ SNMP_MIB_SENTINEL |
1399 |
+ }; |
1400 |
+ |
1401 |
+-static void icmpmsg_put(struct seq_file *seq) |
1402 |
++static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals, |
1403 |
++ unsigned short *type, int count) |
1404 |
+ { |
1405 |
+-#define PERLINE 16 |
1406 |
+- |
1407 |
+- int j, i, count; |
1408 |
+- static int out[PERLINE]; |
1409 |
+- |
1410 |
+- count = 0; |
1411 |
+- for (i = 0; i < ICMPMSG_MIB_MAX; i++) { |
1412 |
+- |
1413 |
+- if (snmp_fold_field((void **) icmpmsg_statistics, i)) |
1414 |
+- out[count++] = i; |
1415 |
+- if (count < PERLINE) |
1416 |
+- continue; |
1417 |
++ int j; |
1418 |
+ |
1419 |
+- seq_printf(seq, "\nIcmpMsg:"); |
1420 |
+- for (j = 0; j < PERLINE; ++j) |
1421 |
+- seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In", |
1422 |
+- i & 0xff); |
1423 |
+- seq_printf(seq, "\nIcmpMsg: "); |
1424 |
+- for (j = 0; j < PERLINE; ++j) |
1425 |
+- seq_printf(seq, " %lu", |
1426 |
+- snmp_fold_field((void **) icmpmsg_statistics, |
1427 |
+- out[j])); |
1428 |
+- seq_putc(seq, '\n'); |
1429 |
+- } |
1430 |
+ if (count) { |
1431 |
+ seq_printf(seq, "\nIcmpMsg:"); |
1432 |
+ for (j = 0; j < count; ++j) |
1433 |
+- seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" : |
1434 |
+- "In", out[j] & 0xff); |
1435 |
++ seq_printf(seq, " %sType%u", |
1436 |
++ type[j] & 0x100 ? "Out" : "In", |
1437 |
++ type[j] & 0xff); |
1438 |
+ seq_printf(seq, "\nIcmpMsg:"); |
1439 |
+ for (j = 0; j < count; ++j) |
1440 |
+- seq_printf(seq, " %lu", snmp_fold_field((void **) |
1441 |
+- icmpmsg_statistics, out[j])); |
1442 |
++ seq_printf(seq, " %lu", vals[j]); |
1443 |
++ } |
1444 |
++} |
1445 |
++ |
1446 |
++static void icmpmsg_put(struct seq_file *seq) |
1447 |
++{ |
1448 |
++#define PERLINE 16 |
1449 |
++ |
1450 |
++ int i, count; |
1451 |
++ unsigned short type[PERLINE]; |
1452 |
++ unsigned long vals[PERLINE], val; |
1453 |
++ |
1454 |
++ count = 0; |
1455 |
++ for (i = 0; i < ICMPMSG_MIB_MAX; i++) { |
1456 |
++ val = snmp_fold_field((void **) icmpmsg_statistics, i); |
1457 |
++ if (val) { |
1458 |
++ type[count] = i; |
1459 |
++ vals[count++] = val; |
1460 |
++ } |
1461 |
++ if (count == PERLINE) { |
1462 |
++ icmpmsg_put_line(seq, vals, type, count); |
1463 |
++ count = 0; |
1464 |
++ } |
1465 |
+ } |
1466 |
++ icmpmsg_put_line(seq, vals, type, count); |
1467 |
+ |
1468 |
+ #undef PERLINE |
1469 |
+ } |
1470 |
|
1471 |
Added: hardened/2.6/trunk/2.6.26/1418_touch_mnt_namespace-when-the-mount-flags-change.patch |
1472 |
=================================================================== |
1473 |
--- hardened/2.6/trunk/2.6.26/1418_touch_mnt_namespace-when-the-mount-flags-change.patch (rev 0) |
1474 |
+++ hardened/2.6/trunk/2.6.26/1418_touch_mnt_namespace-when-the-mount-flags-change.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1475 |
@@ -0,0 +1,43 @@ |
1476 |
+Added-By: Gordon Malm <gengor@g.o> |
1477 |
+ |
1478 |
+--- |
1479 |
+ |
1480 |
+From 0e55a7cca4b66f625d67b292f80b6a976e77c51b Mon Sep 17 00:00:00 2001 |
1481 |
+From: Dan Williams <dan.j.williams@×××××.com> |
1482 |
+Date: Fri, 26 Sep 2008 19:01:20 -0700 |
1483 |
+Subject: touch_mnt_namespace when the mount flags change |
1484 |
+ |
1485 |
+From: Dan Williams <dan.j.williams@×××××.com> |
1486 |
+ |
1487 |
+commit 0e55a7cca4b66f625d67b292f80b6a976e77c51b upstream |
1488 |
+ |
1489 |
+Daemons that need to be launched while the rootfs is read-only can now |
1490 |
+poll /proc/mounts to be notified when their O_RDWR requests may no |
1491 |
+longer end in EROFS. |
1492 |
+ |
1493 |
+Cc: Kay Sievers <kay.sievers@××××.org> |
1494 |
+Cc: Neil Brown <neilb@××××.de> |
1495 |
+Signed-off-by: Dan Williams <dan.j.williams@×××××.com> |
1496 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1497 |
+ |
1498 |
+--- |
1499 |
+ fs/namespace.c | 7 ++++++- |
1500 |
+ 1 file changed, 6 insertions(+), 1 deletion(-) |
1501 |
+ |
1502 |
+--- a/fs/namespace.c |
1503 |
++++ b/fs/namespace.c |
1504 |
+@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct na |
1505 |
+ if (!err) |
1506 |
+ nd->path.mnt->mnt_flags = mnt_flags; |
1507 |
+ up_write(&sb->s_umount); |
1508 |
+- if (!err) |
1509 |
++ if (!err) { |
1510 |
+ security_sb_post_remount(nd->path.mnt, flags, data); |
1511 |
++ |
1512 |
++ spin_lock(&vfsmount_lock); |
1513 |
++ touch_mnt_namespace(nd->path.mnt->mnt_ns); |
1514 |
++ spin_unlock(&vfsmount_lock); |
1515 |
++ } |
1516 |
+ return err; |
1517 |
+ } |
1518 |
+ |
1519 |
|
1520 |
Added: hardened/2.6/trunk/2.6.26/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch |
1521 |
=================================================================== |
1522 |
--- hardened/2.6/trunk/2.6.26/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch (rev 0) |
1523 |
+++ hardened/2.6/trunk/2.6.26/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1524 |
@@ -0,0 +1,75 @@ |
1525 |
+Added-By: Gordon Malm <gengor@g.o> |
1526 |
+ |
1527 |
+Note: Backported to kernel 2.6.26. Original message included below. |
1528 |
+ |
1529 |
+--- |
1530 |
+ |
1531 |
+From 352d026338378b1f13f044e33c1047da6e470056 Mon Sep 17 00:00:00 2001 |
1532 |
+From: Alan Stern <stern@×××××××××××××××.edu> |
1533 |
+Date: Wed, 29 Oct 2008 15:16:58 -0400 |
1534 |
+Subject: USB: don't register endpoints for interfaces that are going away |
1535 |
+ |
1536 |
+From: Alan Stern <stern@×××××××××××××××.edu> |
1537 |
+ |
1538 |
+commit 352d026338378b1f13f044e33c1047da6e470056 upstream. |
1539 |
+ |
1540 |
+This patch (as1155) fixes a bug in usbcore. When interfaces are |
1541 |
+deleted, either because the device was disconnected or because of a |
1542 |
+configuration change, the extra attribute files and child endpoint |
1543 |
+devices may get left behind. This is because the core removes them |
1544 |
+before calling device_del(). But during device_del(), after the |
1545 |
+driver is unbound the core will reinstall altsetting 0 and recreate |
1546 |
+those extra attributes and children. |
1547 |
+ |
1548 |
+The patch prevents this by adding a flag to record when the interface |
1549 |
+is in the midst of being unregistered. When the flag is set, the |
1550 |
+attribute files and child devices will not be created. |
1551 |
+ |
1552 |
+Signed-off-by: Alan Stern <stern@×××××××××××××××.edu> |
1553 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1554 |
+ |
1555 |
+--- |
1556 |
+ drivers/usb/core/message.c | 1 + |
1557 |
+ drivers/usb/core/sysfs.c | 2 +- |
1558 |
+ include/linux/usb.h | 2 ++ |
1559 |
+ 3 files changed, 4 insertions(+), 1 deletion(-) |
1560 |
+ |
1561 |
+--- a/drivers/usb/core/message.c |
1562 |
++++ b/drivers/usb/core/message.c |
1563 |
+@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_devic |
1564 |
+ continue; |
1565 |
+ dev_dbg(&dev->dev, "unregistering interface %s\n", |
1566 |
+ interface->dev.bus_id); |
1567 |
++ interface->unregistering = 1; |
1568 |
+ usb_remove_sysfs_intf_files(interface); |
1569 |
+ device_del(&interface->dev); |
1570 |
+ } |
1571 |
+--- a/drivers/usb/core/sysfs.c |
1572 |
++++ b/drivers/usb/core/sysfs.c |
1573 |
+@@ -816,7 +816,7 @@ int usb_create_sysfs_intf_files(struct u |
1574 |
+ struct usb_host_interface *alt = intf->cur_altsetting; |
1575 |
+ int retval; |
1576 |
+ |
1577 |
+- if (intf->sysfs_files_created) |
1578 |
++ if (intf->sysfs_files_created || intf->unregistering) |
1579 |
+ return 0; |
1580 |
+ |
1581 |
+ /* The interface string may be present in some altsettings |
1582 |
+--- a/include/linux/usb.h |
1583 |
++++ b/include/linux/usb.h |
1584 |
+@@ -108,6 +108,7 @@ enum usb_interface_condition { |
1585 |
+ * (in probe()), bound to a driver, or unbinding (in disconnect()) |
1586 |
+ * @is_active: flag set when the interface is bound and not suspended. |
1587 |
+ * @sysfs_files_created: sysfs attributes exist |
1588 |
++ * @unregistering: flag set when the interface is being unregistered |
1589 |
+ * @needs_remote_wakeup: flag set when the driver requires remote-wakeup |
1590 |
+ * capability during autosuspend. |
1591 |
+ * @dev: driver model's view of this device |
1592 |
+@@ -159,6 +160,7 @@ struct usb_interface { |
1593 |
+ enum usb_interface_condition condition; /* state of binding */ |
1594 |
+ unsigned is_active:1; /* the interface is not suspended */ |
1595 |
+ unsigned sysfs_files_created:1; /* the sysfs attributes exist */ |
1596 |
++ unsigned unregistering:1; /* unregistration is in progress */ |
1597 |
+ unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ |
1598 |
+ |
1599 |
+ struct device dev; /* interface specific device info */ |
1600 |
|
1601 |
Added: hardened/2.6/trunk/2.6.26/1420_usb-ehci-fix-divide-by-zero-bug.patch |
1602 |
=================================================================== |
1603 |
--- hardened/2.6/trunk/2.6.26/1420_usb-ehci-fix-divide-by-zero-bug.patch (rev 0) |
1604 |
+++ hardened/2.6/trunk/2.6.26/1420_usb-ehci-fix-divide-by-zero-bug.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1605 |
@@ -0,0 +1,46 @@ |
1606 |
+Added-By: Gordon Malm <gengor@g.o> |
1607 |
+ |
1608 |
+--- |
1609 |
+ |
1610 |
+From 372dd6e8ed924e876f3beb598721e813ad7fa323 Mon Sep 17 00:00:00 2001 |
1611 |
+From: Alan Stern <stern@×××××××××××××××.edu> |
1612 |
+Date: Wed, 12 Nov 2008 17:02:57 -0500 |
1613 |
+Subject: USB: EHCI: fix divide-by-zero bug |
1614 |
+ |
1615 |
+From: Alan Stern <stern@×××××××××××××××.edu> |
1616 |
+ |
1617 |
+commit 372dd6e8ed924e876f3beb598721e813ad7fa323 upstream. |
1618 |
+ |
1619 |
+This patch (as1164) fixes a bug in the EHCI scheduler. The interval |
1620 |
+value it uses is already in linear format, not logarithmically coded. |
1621 |
+The existing code can sometimes crash the system by trying to divide |
1622 |
+by zero. |
1623 |
+ |
1624 |
+Signed-off-by: Alan Stern <stern@×××××××××××××××.edu> |
1625 |
+Cc: David Brownell <david-b@×××××××.net> |
1626 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1627 |
+ |
1628 |
+--- |
1629 |
+ drivers/usb/host/ehci-sched.c | 4 ++-- |
1630 |
+ 1 file changed, 2 insertions(+), 2 deletions(-) |
1631 |
+ |
1632 |
+--- a/drivers/usb/host/ehci-sched.c |
1633 |
++++ b/drivers/usb/host/ehci-sched.c |
1634 |
+@@ -918,7 +918,7 @@ iso_stream_init ( |
1635 |
+ */ |
1636 |
+ stream->usecs = HS_USECS_ISO (maxp); |
1637 |
+ bandwidth = stream->usecs * 8; |
1638 |
+- bandwidth /= 1 << (interval - 1); |
1639 |
++ bandwidth /= interval; |
1640 |
+ |
1641 |
+ } else { |
1642 |
+ u32 addr; |
1643 |
+@@ -951,7 +951,7 @@ iso_stream_init ( |
1644 |
+ } else |
1645 |
+ stream->raw_mask = smask_out [hs_transfers - 1]; |
1646 |
+ bandwidth = stream->usecs + stream->c_usecs; |
1647 |
+- bandwidth /= 1 << (interval + 2); |
1648 |
++ bandwidth /= interval << 3; |
1649 |
+ |
1650 |
+ /* stream->splits gets created from raw_mask later */ |
1651 |
+ stream->address = cpu_to_hc32(ehci, addr); |
1652 |
|
1653 |
Added: hardened/2.6/trunk/2.6.26/1421_usb-ehci-fix-handling-of-dead-controllers.patch |
1654 |
=================================================================== |
1655 |
--- hardened/2.6/trunk/2.6.26/1421_usb-ehci-fix-handling-of-dead-controllers.patch (rev 0) |
1656 |
+++ hardened/2.6/trunk/2.6.26/1421_usb-ehci-fix-handling-of-dead-controllers.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1657 |
@@ -0,0 +1,93 @@ |
1658 |
+Added-By: Gordon Malm <gengor@g.o> |
1659 |
+ |
1660 |
+--- |
1661 |
+ |
1662 |
+From 67b2e029743a52670d77864723b4d0d40f7733b5 Mon Sep 17 00:00:00 2001 |
1663 |
+From: Alan Stern <stern@×××××××××××××××.edu> |
1664 |
+Date: Wed, 12 Nov 2008 17:04:53 -0500 |
1665 |
+Subject: USB: EHCI: fix handling of dead controllers |
1666 |
+ |
1667 |
+From: Alan Stern <stern@×××××××××××××××.edu> |
1668 |
+ |
1669 |
+commit 67b2e029743a52670d77864723b4d0d40f7733b5 upstream. |
1670 |
+ |
1671 |
+This patch (as1165) makes a few small changes in the logic used by |
1672 |
+ehci-hcd when it encounters a controller error: |
1673 |
+ |
1674 |
+ Instead of printing out the masked status, it prints the |
1675 |
+ original status as read directly from the hardware. |
1676 |
+ |
1677 |
+ It doesn't check for the STS_HALT status bit before taking |
1678 |
+ action. The mere fact that the STS_FATAL bit is set means |
1679 |
+ that something bad has happened and the controller needs to |
1680 |
+ be reset. With the old code this test could never succeed |
1681 |
+ because the STS_HALT bit was masked out from the status. |
1682 |
+ |
1683 |
+I anticipate that this will prevent the occasional "irq X: nobody cared" |
1684 |
+problem people encounter when their EHCI controllers die. |
1685 |
+ |
1686 |
+Signed-off-by: Alan Stern <stern@×××××××××××××××.edu> |
1687 |
+Cc: David Brownell <david-b@×××××××.net> |
1688 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1689 |
+ |
1690 |
+--- |
1691 |
+ drivers/usb/host/ehci-hcd.c | 25 ++++++++++++------------- |
1692 |
+ 1 file changed, 12 insertions(+), 13 deletions(-) |
1693 |
+ |
1694 |
+--- a/drivers/usb/host/ehci-hcd.c |
1695 |
++++ b/drivers/usb/host/ehci-hcd.c |
1696 |
+@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd |
1697 |
+ static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
1698 |
+ { |
1699 |
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
1700 |
+- u32 status, pcd_status = 0, cmd; |
1701 |
++ u32 status, masked_status, pcd_status = 0, cmd; |
1702 |
+ int bh; |
1703 |
+ |
1704 |
+ spin_lock (&ehci->lock); |
1705 |
+@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_ |
1706 |
+ goto dead; |
1707 |
+ } |
1708 |
+ |
1709 |
+- status &= INTR_MASK; |
1710 |
+- if (!status) { /* irq sharing? */ |
1711 |
++ masked_status = status & INTR_MASK; |
1712 |
++ if (!masked_status) { /* irq sharing? */ |
1713 |
+ spin_unlock(&ehci->lock); |
1714 |
+ return IRQ_NONE; |
1715 |
+ } |
1716 |
+ |
1717 |
+ /* clear (just) interrupts */ |
1718 |
+- ehci_writel(ehci, status, &ehci->regs->status); |
1719 |
++ ehci_writel(ehci, masked_status, &ehci->regs->status); |
1720 |
+ cmd = ehci_readl(ehci, &ehci->regs->command); |
1721 |
+ bh = 0; |
1722 |
+ |
1723 |
+@@ -731,19 +731,18 @@ static irqreturn_t ehci_irq (struct usb_ |
1724 |
+ |
1725 |
+ /* PCI errors [4.15.2.4] */ |
1726 |
+ if (unlikely ((status & STS_FATAL) != 0)) { |
1727 |
++ ehci_err(ehci, "fatal error\n"); |
1728 |
+ dbg_cmd (ehci, "fatal", ehci_readl(ehci, |
1729 |
+ &ehci->regs->command)); |
1730 |
+ dbg_status (ehci, "fatal", status); |
1731 |
+- if (status & STS_HALT) { |
1732 |
+- ehci_err (ehci, "fatal error\n"); |
1733 |
++ ehci_halt(ehci); |
1734 |
+ dead: |
1735 |
+- ehci_reset (ehci); |
1736 |
+- ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
1737 |
+- /* generic layer kills/unlinks all urbs, then |
1738 |
+- * uses ehci_stop to clean up the rest |
1739 |
+- */ |
1740 |
+- bh = 1; |
1741 |
+- } |
1742 |
++ ehci_reset(ehci); |
1743 |
++ ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
1744 |
++ /* generic layer kills/unlinks all urbs, then |
1745 |
++ * uses ehci_stop to clean up the rest |
1746 |
++ */ |
1747 |
++ bh = 1; |
1748 |
+ } |
1749 |
+ |
1750 |
+ if (bh) |
1751 |
|
1752 |
Added: hardened/2.6/trunk/2.6.26/1422_usb-fix-ps3-usb-shutdown-problems.patch |
1753 |
=================================================================== |
1754 |
--- hardened/2.6/trunk/2.6.26/1422_usb-fix-ps3-usb-shutdown-problems.patch (rev 0) |
1755 |
+++ hardened/2.6/trunk/2.6.26/1422_usb-fix-ps3-usb-shutdown-problems.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1756 |
@@ -0,0 +1,64 @@ |
1757 |
+Added-By: Gordon Malm <gengor@g.o> |
1758 |
+ |
1759 |
+--- |
1760 |
+ |
1761 |
+From ddcb01ff9bf49c4dbbb058423559f7bc90b89374 Mon Sep 17 00:00:00 2001 |
1762 |
+From: Geoff Levand <geoffrey.levand@×××××××.com> |
1763 |
+Date: Fri, 31 Oct 2008 13:52:54 -0700 |
1764 |
+Subject: USB: Fix PS3 USB shutdown problems |
1765 |
+ |
1766 |
+From: Geoff Levand <geoffrey.levand@×××××××.com> |
1767 |
+ |
1768 |
+commit ddcb01ff9bf49c4dbbb058423559f7bc90b89374 upstream. |
1769 |
+ |
1770 |
+Add ehci_shutdown() or ohci_shutdown() calls to the USB |
1771 |
+PS3 bus glue. ehci_shutdown() and ohci_shutdown() do some |
1772 |
+controller specific cleanups not done by usb_remove_hcd(). |
1773 |
+ |
1774 |
+Fixes errors on shutdown or reboot similar to these: |
1775 |
+ |
1776 |
+ ps3-ehci-driver sb_07: HC died; cleaning up |
1777 |
+ irq 51: nobody cared (try booting with the "irqpoll" option) |
1778 |
+ |
1779 |
+Related bugzilla reports: |
1780 |
+ |
1781 |
+ http://bugzilla.kernel.org/show_bug.cgi?id=11819 |
1782 |
+ http://bugzilla.terrasoftsolutions.com/show_bug.cgi?id=317 |
1783 |
+ |
1784 |
+Signed-off-by: Geoff Levand <geoffrey.levand@×××××××.com> |
1785 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1786 |
+ |
1787 |
+--- |
1788 |
+ drivers/usb/host/ehci-ps3.c | 1 + |
1789 |
+ drivers/usb/host/ohci-ps3.c | 3 ++- |
1790 |
+ 2 files changed, 3 insertions(+), 1 deletion(-) |
1791 |
+ |
1792 |
+--- a/drivers/usb/host/ehci-ps3.c |
1793 |
++++ b/drivers/usb/host/ehci-ps3.c |
1794 |
+@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_sy |
1795 |
+ |
1796 |
+ tmp = hcd->irq; |
1797 |
+ |
1798 |
++ ehci_shutdown(hcd); |
1799 |
+ usb_remove_hcd(hcd); |
1800 |
+ |
1801 |
+ ps3_system_bus_set_driver_data(dev, NULL); |
1802 |
+--- a/drivers/usb/host/ohci-ps3.c |
1803 |
++++ b/drivers/usb/host/ohci-ps3.c |
1804 |
+@@ -192,7 +192,7 @@ fail_start: |
1805 |
+ return result; |
1806 |
+ } |
1807 |
+ |
1808 |
+-static int ps3_ohci_remove (struct ps3_system_bus_device *dev) |
1809 |
++static int ps3_ohci_remove(struct ps3_system_bus_device *dev) |
1810 |
+ { |
1811 |
+ unsigned int tmp; |
1812 |
+ struct usb_hcd *hcd = |
1813 |
+@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_s |
1814 |
+ |
1815 |
+ tmp = hcd->irq; |
1816 |
+ |
1817 |
++ ohci_shutdown(hcd); |
1818 |
+ usb_remove_hcd(hcd); |
1819 |
+ |
1820 |
+ ps3_system_bus_set_driver_data(dev, NULL); |
1821 |
|
1822 |
Added: hardened/2.6/trunk/2.6.26/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch |
1823 |
=================================================================== |
1824 |
--- hardened/2.6/trunk/2.6.26/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch (rev 0) |
1825 |
+++ hardened/2.6/trunk/2.6.26/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1826 |
@@ -0,0 +1,135 @@ |
1827 |
+Added-By: Gordon Malm <gengor@g.o> |
1828 |
+ |
1829 |
+--- |
1830 |
+ |
1831 |
+From 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 Mon Sep 17 00:00:00 2001 |
1832 |
+From: Mauro Carvalho Chehab <mchehab@××××××.com> |
1833 |
+Date: Fri, 14 Nov 2008 10:46:59 -0300 |
1834 |
+Subject: V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble |
1835 |
+ |
1836 |
+From: Mauro Carvalho Chehab <mchehab@××××××.com> |
1837 |
+ |
1838 |
+commit 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 upstream. |
1839 |
+ |
1840 |
+This bug were supposed to be fixed by 5ba2f67afb02c5302b2898949ed6fc3b3d37dcf1, |
1841 |
+where a call to NULL happens. |
1842 |
+ |
1843 |
+Not all tvaudio chips allow controlling bass/treble. So, the driver |
1844 |
+has a table with a flag to indicate if the chip does support it. |
1845 |
+ |
1846 |
+Unfortunately, the handling of this logic were broken for a very long |
1847 |
+time (probably since the first module version). Due to that, an OOPS |
1848 |
+were generated for devices that don't support bass/treble. |
1849 |
+ |
1850 |
+This were the resulting OOPS message before the patch, with debug messages |
1851 |
+enabled: |
1852 |
+ |
1853 |
+tvaudio' 1-005b: VIDIOC_S_CTRL |
1854 |
+BUG: unable to handle kernel NULL pointer dereference at 00000000 |
1855 |
+IP: [<00000000>] |
1856 |
+*pde = 22fda067 *pte = 00000000 |
1857 |
+Oops: 0000 [#1] SMP |
1858 |
+Modules linked in: snd_hda_intel snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device |
1859 |
+snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_hwdep snd soundcore tuner_simple tuner_types tea5767 tuner |
1860 |
+tvaudio bttv bridgebnep rfcomm l2cap bluetooth it87 hwmon_vid hwmon fuse sunrpc ipt_REJECT |
1861 |
+nf_conntrack_ipv4 iptable_filter ip_tables ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack |
1862 |
+ip6table_filter ip6_tables x_tables ipv6 dm_mirrordm_multipath dm_mod configfs videodev v4l1_compat |
1863 |
+ir_common 8139cp compat_ioctl32 v4l2_common 8139too videobuf_dma_sg videobuf_core mii btcx_risc tveeprom |
1864 |
+i915 button snd_page_alloc serio_raw drm pcspkr i2c_algo_bit i2c_i801 i2c_core iTCO_wdt |
1865 |
+iTCO_vendor_support sr_mod cdrom sg ata_generic pata_acpi ata_piix libata sd_mod scsi_mod ext3 jbdmbcache |
1866 |
+uhci_hcd ohci_hcd ehci_hcd [last unloaded: soundcore] |
1867 |
+ |
1868 |
+Pid: 15413, comm: qv4l2 Not tainted (2.6.25.14-108.fc9.i686 #1) |
1869 |
+EIP: 0060:[<00000000>] EFLAGS: 00210246 CPU: 0 |
1870 |
+EIP is at 0x0 |
1871 |
+EAX: 00008000 EBX: ebd21600 ECX: e2fd9ec4 EDX: 00200046 |
1872 |
+ESI: f8c0f0c4 EDI: f8c0f0c4 EBP: e2fd9d50 ESP: e2fd9d2c |
1873 |
+ DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 |
1874 |
+Process qv4l2 (pid: 15413, ti=e2fd9000 task=ebe44000 task.ti=e2fd9000) |
1875 |
+Stack: f8c0c6ae e2ff2a00 00000d00 e2fd9ec4 ebc4e000 e2fd9d5c f8c0c448 00000000 |
1876 |
+ f899c12a e2fd9d5c f899c154 e2fd9d68 e2fd9d80 c0560185 e2fd9d88 f8f3e1d8 |
1877 |
+ f8f3e1dc ebc4e034 f8f3e18c e2fd9ec4 00000000 e2fd9d90 f899c286 c008561c |
1878 |
+Call Trace: |
1879 |
+ [<f8c0c6ae>] ? chip_command+0x266/0x4b6 [tvaudio] |
1880 |
+ [<f8c0c448>] ? chip_command+0x0/0x4b6 [tvaudio] |
1881 |
+ [<f899c12a>] ? i2c_cmd+0x0/0x2f [i2c_core] |
1882 |
+ [<f899c154>] ? i2c_cmd+0x2a/0x2f [i2c_core] |
1883 |
+ [<c0560185>] ? device_for_each_child+0x21/0x49 |
1884 |
+ [<f899c286>] ? i2c_clients_command+0x1c/0x1e [i2c_core] |
1885 |
+ [<f8f283d8>] ? bttv_call_i2c_clients+0x14/0x16 [bttv] |
1886 |
+ [<f8f23601>] ? bttv_s_ctrl+0x1bc/0x313 [bttv] |
1887 |
+ [<f8f23445>] ? bttv_s_ctrl+0x0/0x313 [bttv] |
1888 |
+ [<f8b6096d>] ? __video_do_ioctl+0x1f84/0x3726 [videodev] |
1889 |
+ [<c05abb4e>] ? sock_aio_write+0x100/0x10d |
1890 |
+ [<c041b23e>] ? kmap_atomic_prot+0x1dd/0x1df |
1891 |
+ [<c043a0c9>] ? enqueue_hrtimer+0xc2/0xcd |
1892 |
+ [<c04f4fa4>] ? copy_from_user+0x39/0x121 |
1893 |
+ [<f8b622b9>] ? __video_ioctl2+0x1aa/0x24a [videodev] |
1894 |
+ [<c04054fd>] ? do_notify_resume+0x768/0x795 |
1895 |
+ [<c043c0f7>] ? getnstimeofday+0x34/0xd1 |
1896 |
+ [<c0437b77>] ? autoremove_wake_function+0x0/0x33 |
1897 |
+ [<f8b62368>] ? video_ioctl2+0xf/0x13 [videodev] |
1898 |
+ [<c048c6f0>] ? vfs_ioctl+0x50/0x69 |
1899 |
+ [<c048c942>] ? do_vfs_ioctl+0x239/0x24c |
1900 |
+ [<c048c995>] ? sys_ioctl+0x40/0x5b |
1901 |
+ [<c0405bf2>] ? syscall_call+0x7/0xb |
1902 |
+ [<c0620000>] ? cpuid4_cache_sysfs_exit+0x3d/0x69 |
1903 |
+ ======================= |
1904 |
+Code: Bad EIP value. |
1905 |
+EIP: [<00000000>] 0x0 SS:ESP 0068:e2fd9d2c |
1906 |
+ |
1907 |
+Signed-off-by: Mauro Carvalho Chehab <mchehab@××××××.com> |
1908 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
1909 |
+ |
1910 |
+--- |
1911 |
+ drivers/media/video/tvaudio.c | 15 +++++++-------- |
1912 |
+ 1 file changed, 7 insertions(+), 8 deletions(-) |
1913 |
+ |
1914 |
+--- a/drivers/media/video/tvaudio.c |
1915 |
++++ b/drivers/media/video/tvaudio.c |
1916 |
+@@ -1576,13 +1576,13 @@ static int tvaudio_get_ctrl(struct CHIPS |
1917 |
+ return 0; |
1918 |
+ } |
1919 |
+ case V4L2_CID_AUDIO_BASS: |
1920 |
+- if (desc->flags & CHIP_HAS_BASSTREBLE) |
1921 |
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
1922 |
+ break; |
1923 |
+ ctrl->value = chip->bass; |
1924 |
+ return 0; |
1925 |
+ case V4L2_CID_AUDIO_TREBLE: |
1926 |
+- if (desc->flags & CHIP_HAS_BASSTREBLE) |
1927 |
+- return -EINVAL; |
1928 |
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
1929 |
++ break; |
1930 |
+ ctrl->value = chip->treble; |
1931 |
+ return 0; |
1932 |
+ } |
1933 |
+@@ -1642,16 +1642,15 @@ static int tvaudio_set_ctrl(struct CHIPS |
1934 |
+ return 0; |
1935 |
+ } |
1936 |
+ case V4L2_CID_AUDIO_BASS: |
1937 |
+- if (desc->flags & CHIP_HAS_BASSTREBLE) |
1938 |
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
1939 |
+ break; |
1940 |
+ chip->bass = ctrl->value; |
1941 |
+ chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); |
1942 |
+ |
1943 |
+ return 0; |
1944 |
+ case V4L2_CID_AUDIO_TREBLE: |
1945 |
+- if (desc->flags & CHIP_HAS_BASSTREBLE) |
1946 |
+- return -EINVAL; |
1947 |
+- |
1948 |
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
1949 |
++ break; |
1950 |
+ chip->treble = ctrl->value; |
1951 |
+ chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); |
1952 |
+ |
1953 |
+@@ -1695,7 +1694,7 @@ static int chip_command(struct i2c_clien |
1954 |
+ break; |
1955 |
+ case V4L2_CID_AUDIO_BASS: |
1956 |
+ case V4L2_CID_AUDIO_TREBLE: |
1957 |
+- if (desc->flags & CHIP_HAS_BASSTREBLE) |
1958 |
++ if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
1959 |
+ return -EINVAL; |
1960 |
+ break; |
1961 |
+ default: |
1962 |
|
1963 |
Added: hardened/2.6/trunk/2.6.26/1503_inotify-fix-watch-removal-or-umount-races.patch |
1964 |
=================================================================== |
1965 |
--- hardened/2.6/trunk/2.6.26/1503_inotify-fix-watch-removal-or-umount-races.patch (rev 0) |
1966 |
+++ hardened/2.6/trunk/2.6.26/1503_inotify-fix-watch-removal-or-umount-races.patch 2008-12-03 00:31:33 UTC (rev 1413) |
1967 |
@@ -0,0 +1,571 @@ |
1968 |
+Added-By: Gordon Malm <gengor@g.o> |
1969 |
+ |
1970 |
+--- |
1971 |
+ |
1972 |
+From: Al Viro <viro@×××××××××××××××.uk> |
1973 |
+Date: Sat, 15 Nov 2008 01:15:43 +0000 (+0000) |
1974 |
+Subject: Fix inotify watch removal/umount races |
1975 |
+X-Git-Tag: v2.6.28-rc5~1 |
1976 |
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8f7b0ba1c853919b85b54774775f567f30006107 |
1977 |
+ |
1978 |
+Fix inotify watch removal/umount races |
1979 |
+ |
1980 |
+Inotify watch removals suck violently. |
1981 |
+ |
1982 |
+To kick the watch out we need (in this order) inode->inotify_mutex and |
1983 |
+ih->mutex. That's fine if we have a hold on inode; however, for all |
1984 |
+other cases we need to make damn sure we don't race with umount. We can |
1985 |
+*NOT* just grab a reference to a watch - inotify_unmount_inodes() will |
1986 |
+happily sail past it and we'll end with reference to inode potentially |
1987 |
+outliving its superblock. |
1988 |
+ |
1989 |
+Ideally we just want to grab an active reference to superblock if we |
1990 |
+can; that will make sure we won't go into inotify_umount_inodes() until |
1991 |
+we are done. Cleanup is just deactivate_super(). |
1992 |
+ |
1993 |
+However, that leaves a messy case - what if we *are* racing with |
1994 |
+umount() and active references to superblock can't be acquired anymore? |
1995 |
+We can bump ->s_count, grab ->s_umount, which will almost certainly wait |
1996 |
+until the superblock is shut down and the watch in question is pining |
1997 |
+for fjords. That's fine, but there is a problem - we might have hit the |
1998 |
+window between ->s_active getting to 0 / ->s_count - below S_BIAS (i.e. |
1999 |
+the moment when superblock is past the point of no return and is heading |
2000 |
+for shutdown) and the moment when deactivate_super() acquires |
2001 |
+->s_umount. |
2002 |
+ |
2003 |
+We could just do drop_super() yield() and retry, but that's rather |
2004 |
+antisocial and this stuff is luser-triggerable. OTOH, having grabbed |
2005 |
+->s_umount and having found that we'd got there first (i.e. that |
2006 |
+->s_root is non-NULL) we know that we won't race with |
2007 |
+inotify_umount_inodes(). |
2008 |
+ |
2009 |
+So we could grab a reference to watch and do the rest as above, just |
2010 |
+with drop_super() instead of deactivate_super(), right? Wrong. We had |
2011 |
+to drop ih->mutex before we could grab ->s_umount. So the watch |
2012 |
+could've been gone already. |
2013 |
+ |
2014 |
+That still can be dealt with - we need to save watch->wd, do idr_find() |
2015 |
+and compare its result with our pointer. If they match, we either have |
2016 |
+the damn thing still alive or we'd lost not one but two races at once, |
2017 |
+the watch had been killed and a new one got created with the same ->wd |
2018 |
+at the same address. That couldn't have happened in inotify_destroy(), |
2019 |
+but inotify_rm_wd() could run into that. Still, "new one got created" |
2020 |
+is not a problem - we have every right to kill it or leave it alone, |
2021 |
+whatever's more convenient. |
2022 |
+ |
2023 |
+So we can use idr_find(...) == watch && watch->inode->i_sb == sb as |
2024 |
+"grab it and kill it" check. If it's been our original watch, we are |
2025 |
+fine, if it's a newcomer - nevermind, just pretend that we'd won the |
2026 |
+race and kill the fscker anyway; we are safe since we know that its |
2027 |
+superblock won't be going away. |
2028 |
+ |
2029 |
+And yes, this is far beyond mere "not very pretty"; so's the entire |
2030 |
+concept of inotify to start with. |
2031 |
+ |
2032 |
+Signed-off-by: Al Viro <viro@×××××××××××××××.uk> |
2033 |
+Acked-by: Greg KH <greg@×××××.com> |
2034 |
+Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
2035 |
+--- |
2036 |
+ |
2037 |
+diff --git a/fs/inotify.c b/fs/inotify.c |
2038 |
+index 690e725..7bbed1b 100644 |
2039 |
+--- a/fs/inotify.c |
2040 |
++++ b/fs/inotify.c |
2041 |
+@@ -106,6 +106,20 @@ void get_inotify_watch(struct inotify_watch *watch) |
2042 |
+ } |
2043 |
+ EXPORT_SYMBOL_GPL(get_inotify_watch); |
2044 |
+ |
2045 |
++int pin_inotify_watch(struct inotify_watch *watch) |
2046 |
++{ |
2047 |
++ struct super_block *sb = watch->inode->i_sb; |
2048 |
++ spin_lock(&sb_lock); |
2049 |
++ if (sb->s_count >= S_BIAS) { |
2050 |
++ atomic_inc(&sb->s_active); |
2051 |
++ spin_unlock(&sb_lock); |
2052 |
++ atomic_inc(&watch->count); |
2053 |
++ return 1; |
2054 |
++ } |
2055 |
++ spin_unlock(&sb_lock); |
2056 |
++ return 0; |
2057 |
++} |
2058 |
++ |
2059 |
+ /** |
2060 |
+ * put_inotify_watch - decrements the ref count on a given watch. cleans up |
2061 |
+ * watch references if the count reaches zero. inotify_watch is freed by |
2062 |
+@@ -124,6 +138,13 @@ void put_inotify_watch(struct inotify_watch *watch) |
2063 |
+ } |
2064 |
+ EXPORT_SYMBOL_GPL(put_inotify_watch); |
2065 |
+ |
2066 |
++void unpin_inotify_watch(struct inotify_watch *watch) |
2067 |
++{ |
2068 |
++ struct super_block *sb = watch->inode->i_sb; |
2069 |
++ put_inotify_watch(watch); |
2070 |
++ deactivate_super(sb); |
2071 |
++} |
2072 |
++ |
2073 |
+ /* |
2074 |
+ * inotify_handle_get_wd - returns the next WD for use by the given handle |
2075 |
+ * |
2076 |
+@@ -479,6 +500,112 @@ void inotify_init_watch(struct inotify_watch *watch) |
2077 |
+ } |
2078 |
+ EXPORT_SYMBOL_GPL(inotify_init_watch); |
2079 |
+ |
2080 |
++/* |
2081 |
++ * Watch removals suck violently. To kick the watch out we need (in this |
2082 |
++ * order) inode->inotify_mutex and ih->mutex. That's fine if we have |
2083 |
++ * a hold on inode; however, for all other cases we need to make damn sure |
2084 |
++ * we don't race with umount. We can *NOT* just grab a reference to a |
2085 |
++ * watch - inotify_unmount_inodes() will happily sail past it and we'll end |
2086 |
++ * with reference to inode potentially outliving its superblock. Ideally |
2087 |
++ * we just want to grab an active reference to superblock if we can; that |
2088 |
++ * will make sure we won't go into inotify_umount_inodes() until we are |
2089 |
++ * done. Cleanup is just deactivate_super(). However, that leaves a messy |
2090 |
++ * case - what if we *are* racing with umount() and active references to |
2091 |
++ * superblock can't be acquired anymore? We can bump ->s_count, grab |
2092 |
++ * ->s_umount, which will almost certainly wait until the superblock is shut |
2093 |
++ * down and the watch in question is pining for fjords. That's fine, but |
2094 |
++ * there is a problem - we might have hit the window between ->s_active |
2095 |
++ * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock |
2096 |
++ * is past the point of no return and is heading for shutdown) and the |
2097 |
++ * moment when deactivate_super() acquires ->s_umount. We could just do |
2098 |
++ * drop_super() yield() and retry, but that's rather antisocial and this |
2099 |
++ * stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having |
2100 |
++ * found that we'd got there first (i.e. that ->s_root is non-NULL) we know |
2101 |
++ * that we won't race with inotify_umount_inodes(). So we could grab a |
2102 |
++ * reference to watch and do the rest as above, just with drop_super() instead |
2103 |
++ * of deactivate_super(), right? Wrong. We had to drop ih->mutex before we |
2104 |
++ * could grab ->s_umount. So the watch could've been gone already. |
2105 |
++ * |
2106 |
++ * That still can be dealt with - we need to save watch->wd, do idr_find() |
2107 |
++ * and compare its result with our pointer. If they match, we either have |
2108 |
++ * the damn thing still alive or we'd lost not one but two races at once, |
2109 |
++ * the watch had been killed and a new one got created with the same ->wd |
2110 |
++ * at the same address. That couldn't have happened in inotify_destroy(), |
2111 |
++ * but inotify_rm_wd() could run into that. Still, "new one got created" |
2112 |
++ * is not a problem - we have every right to kill it or leave it alone, |
2113 |
++ * whatever's more convenient. |
2114 |
++ * |
2115 |
++ * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as |
2116 |
++ * "grab it and kill it" check. If it's been our original watch, we are |
2117 |
++ * fine, if it's a newcomer - nevermind, just pretend that we'd won the |
2118 |
++ * race and kill the fscker anyway; we are safe since we know that its |
2119 |
++ * superblock won't be going away. |
2120 |
++ * |
2121 |
++ * And yes, this is far beyond mere "not very pretty"; so's the entire |
2122 |
++ * concept of inotify to start with. |
2123 |
++ */ |
2124 |
++ |
2125 |
++/** |
2126 |
++ * pin_to_kill - pin the watch down for removal |
2127 |
++ * @ih: inotify handle |
2128 |
++ * @watch: watch to kill |
2129 |
++ * |
2130 |
++ * Called with ih->mutex held, drops it. Possible return values: |
2131 |
++ * 0 - nothing to do, it has died |
2132 |
++ * 1 - remove it, drop the reference and deactivate_super() |
2133 |
++ * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid |
2134 |
++ * that variant, since it involved a lot of PITA, but that's the best that |
2135 |
++ * could've been done. |
2136 |
++ */ |
2137 |
++static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) |
2138 |
++{ |
2139 |
++ struct super_block *sb = watch->inode->i_sb; |
2140 |
++ s32 wd = watch->wd; |
2141 |
++ |
2142 |
++ spin_lock(&sb_lock); |
2143 |
++ if (sb->s_count >= S_BIAS) { |
2144 |
++ atomic_inc(&sb->s_active); |
2145 |
++ spin_unlock(&sb_lock); |
2146 |
++ get_inotify_watch(watch); |
2147 |
++ mutex_unlock(&ih->mutex); |
2148 |
++ return 1; /* the best outcome */ |
2149 |
++ } |
2150 |
++ sb->s_count++; |
2151 |
++ spin_unlock(&sb_lock); |
2152 |
++ mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ |
2153 |
++ down_read(&sb->s_umount); |
2154 |
++ if (likely(!sb->s_root)) { |
2155 |
++ /* fs is already shut down; the watch is dead */ |
2156 |
++ drop_super(sb); |
2157 |
++ return 0; |
2158 |
++ } |
2159 |
++ /* raced with the final deactivate_super() */ |
2160 |
++ mutex_lock(&ih->mutex); |
2161 |
++ if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) { |
2162 |
++ /* the watch is dead */ |
2163 |
++ mutex_unlock(&ih->mutex); |
2164 |
++ drop_super(sb); |
2165 |
++ return 0; |
2166 |
++ } |
2167 |
++ /* still alive or freed and reused with the same sb and wd; kill */ |
2168 |
++ get_inotify_watch(watch); |
2169 |
++ mutex_unlock(&ih->mutex); |
2170 |
++ return 2; |
2171 |
++} |
2172 |
++ |
2173 |
++static void unpin_and_kill(struct inotify_watch *watch, int how) |
2174 |
++{ |
2175 |
++ struct super_block *sb = watch->inode->i_sb; |
2176 |
++ put_inotify_watch(watch); |
2177 |
++ switch (how) { |
2178 |
++ case 1: |
2179 |
++ deactivate_super(sb); |
2180 |
++ break; |
2181 |
++ case 2: |
2182 |
++ drop_super(sb); |
2183 |
++ } |
2184 |
++} |
2185 |
++ |
2186 |
+ /** |
2187 |
+ * inotify_destroy - clean up and destroy an inotify instance |
2188 |
+ * @ih: inotify handle |
2189 |
+@@ -490,11 +617,15 @@ void inotify_destroy(struct inotify_handle *ih) |
2190 |
+ * pretty. We cannot do a simple iteration over the list, because we |
2191 |
+ * do not know the inode until we iterate to the watch. But we need to |
2192 |
+ * hold inode->inotify_mutex before ih->mutex. The following works. |
2193 |
++ * |
2194 |
++ * AV: it had to become even uglier to start working ;-/ |
2195 |
+ */ |
2196 |
+ while (1) { |
2197 |
+ struct inotify_watch *watch; |
2198 |
+ struct list_head *watches; |
2199 |
++ struct super_block *sb; |
2200 |
+ struct inode *inode; |
2201 |
++ int how; |
2202 |
+ |
2203 |
+ mutex_lock(&ih->mutex); |
2204 |
+ watches = &ih->watches; |
2205 |
+@@ -503,8 +634,10 @@ void inotify_destroy(struct inotify_handle *ih) |
2206 |
+ break; |
2207 |
+ } |
2208 |
+ watch = list_first_entry(watches, struct inotify_watch, h_list); |
2209 |
+- get_inotify_watch(watch); |
2210 |
+- mutex_unlock(&ih->mutex); |
2211 |
++ sb = watch->inode->i_sb; |
2212 |
++ how = pin_to_kill(ih, watch); |
2213 |
++ if (!how) |
2214 |
++ continue; |
2215 |
+ |
2216 |
+ inode = watch->inode; |
2217 |
+ mutex_lock(&inode->inotify_mutex); |
2218 |
+@@ -518,7 +651,7 @@ void inotify_destroy(struct inotify_handle *ih) |
2219 |
+ |
2220 |
+ mutex_unlock(&ih->mutex); |
2221 |
+ mutex_unlock(&inode->inotify_mutex); |
2222 |
+- put_inotify_watch(watch); |
2223 |
++ unpin_and_kill(watch, how); |
2224 |
+ } |
2225 |
+ |
2226 |
+ /* free this handle: the put matching the get in inotify_init() */ |
2227 |
+@@ -719,7 +852,9 @@ void inotify_evict_watch(struct inotify_watch *watch) |
2228 |
+ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) |
2229 |
+ { |
2230 |
+ struct inotify_watch *watch; |
2231 |
++ struct super_block *sb; |
2232 |
+ struct inode *inode; |
2233 |
++ int how; |
2234 |
+ |
2235 |
+ mutex_lock(&ih->mutex); |
2236 |
+ watch = idr_find(&ih->idr, wd); |
2237 |
+@@ -727,9 +862,12 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) |
2238 |
+ mutex_unlock(&ih->mutex); |
2239 |
+ return -EINVAL; |
2240 |
+ } |
2241 |
+- get_inotify_watch(watch); |
2242 |
++ sb = watch->inode->i_sb; |
2243 |
++ how = pin_to_kill(ih, watch); |
2244 |
++ if (!how) |
2245 |
++ return 0; |
2246 |
++ |
2247 |
+ inode = watch->inode; |
2248 |
+- mutex_unlock(&ih->mutex); |
2249 |
+ |
2250 |
+ mutex_lock(&inode->inotify_mutex); |
2251 |
+ mutex_lock(&ih->mutex); |
2252 |
+@@ -740,7 +878,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) |
2253 |
+ |
2254 |
+ mutex_unlock(&ih->mutex); |
2255 |
+ mutex_unlock(&inode->inotify_mutex); |
2256 |
+- put_inotify_watch(watch); |
2257 |
++ unpin_and_kill(watch, how); |
2258 |
+ |
2259 |
+ return 0; |
2260 |
+ } |
2261 |
+diff --git a/include/linux/inotify.h b/include/linux/inotify.h |
2262 |
+index bd57857..37ea289 100644 |
2263 |
+--- a/include/linux/inotify.h |
2264 |
++++ b/include/linux/inotify.h |
2265 |
+@@ -134,6 +134,8 @@ extern void inotify_remove_watch_locked(struct inotify_handle *, |
2266 |
+ struct inotify_watch *); |
2267 |
+ extern void get_inotify_watch(struct inotify_watch *); |
2268 |
+ extern void put_inotify_watch(struct inotify_watch *); |
2269 |
++extern int pin_inotify_watch(struct inotify_watch *); |
2270 |
++extern void unpin_inotify_watch(struct inotify_watch *); |
2271 |
+ |
2272 |
+ #else |
2273 |
+ |
2274 |
+@@ -228,6 +230,15 @@ static inline void put_inotify_watch(struct inotify_watch *watch) |
2275 |
+ { |
2276 |
+ } |
2277 |
+ |
2278 |
++extern inline int pin_inotify_watch(struct inotify_watch *watch) |
2279 |
++{ |
2280 |
++ return 0; |
2281 |
++} |
2282 |
++ |
2283 |
++extern inline void unpin_inotify_watch(struct inotify_watch *watch) |
2284 |
++{ |
2285 |
++} |
2286 |
++ |
2287 |
+ #endif /* CONFIG_INOTIFY */ |
2288 |
+ |
2289 |
+ #endif /* __KERNEL __ */ |
2290 |
+diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c |
2291 |
+index 8ba0e0d..8b50944 100644 |
2292 |
+--- a/kernel/audit_tree.c |
2293 |
++++ b/kernel/audit_tree.c |
2294 |
+@@ -24,6 +24,7 @@ struct audit_chunk { |
2295 |
+ struct list_head trees; /* with root here */ |
2296 |
+ int dead; |
2297 |
+ int count; |
2298 |
++ atomic_long_t refs; |
2299 |
+ struct rcu_head head; |
2300 |
+ struct node { |
2301 |
+ struct list_head list; |
2302 |
+@@ -56,7 +57,8 @@ static LIST_HEAD(prune_list); |
2303 |
+ * tree is refcounted; one reference for "some rules on rules_list refer to |
2304 |
+ * it", one for each chunk with pointer to it. |
2305 |
+ * |
2306 |
+- * chunk is refcounted by embedded inotify_watch. |
2307 |
++ * chunk is refcounted by embedded inotify_watch + .refs (non-zero refcount |
2308 |
++ * of watch contributes 1 to .refs). |
2309 |
+ * |
2310 |
+ * node.index allows to get from node.list to containing chunk. |
2311 |
+ * MSB of that sucker is stolen to mark taggings that we might have to |
2312 |
+@@ -121,6 +123,7 @@ static struct audit_chunk *alloc_chunk(int count) |
2313 |
+ INIT_LIST_HEAD(&chunk->hash); |
2314 |
+ INIT_LIST_HEAD(&chunk->trees); |
2315 |
+ chunk->count = count; |
2316 |
++ atomic_long_set(&chunk->refs, 1); |
2317 |
+ for (i = 0; i < count; i++) { |
2318 |
+ INIT_LIST_HEAD(&chunk->owners[i].list); |
2319 |
+ chunk->owners[i].index = i; |
2320 |
+@@ -129,9 +132,8 @@ static struct audit_chunk *alloc_chunk(int count) |
2321 |
+ return chunk; |
2322 |
+ } |
2323 |
+ |
2324 |
+-static void __free_chunk(struct rcu_head *rcu) |
2325 |
++static void free_chunk(struct audit_chunk *chunk) |
2326 |
+ { |
2327 |
+- struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head); |
2328 |
+ int i; |
2329 |
+ |
2330 |
+ for (i = 0; i < chunk->count; i++) { |
2331 |
+@@ -141,14 +143,16 @@ static void __free_chunk(struct rcu_head *rcu) |
2332 |
+ kfree(chunk); |
2333 |
+ } |
2334 |
+ |
2335 |
+-static inline void free_chunk(struct audit_chunk *chunk) |
2336 |
++void audit_put_chunk(struct audit_chunk *chunk) |
2337 |
+ { |
2338 |
+- call_rcu(&chunk->head, __free_chunk); |
2339 |
++ if (atomic_long_dec_and_test(&chunk->refs)) |
2340 |
++ free_chunk(chunk); |
2341 |
+ } |
2342 |
+ |
2343 |
+-void audit_put_chunk(struct audit_chunk *chunk) |
2344 |
++static void __put_chunk(struct rcu_head *rcu) |
2345 |
+ { |
2346 |
+- put_inotify_watch(&chunk->watch); |
2347 |
++ struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head); |
2348 |
++ audit_put_chunk(chunk); |
2349 |
+ } |
2350 |
+ |
2351 |
+ enum {HASH_SIZE = 128}; |
2352 |
+@@ -176,7 +180,7 @@ struct audit_chunk *audit_tree_lookup(const struct inode *inode) |
2353 |
+ |
2354 |
+ list_for_each_entry_rcu(p, list, hash) { |
2355 |
+ if (p->watch.inode == inode) { |
2356 |
+- get_inotify_watch(&p->watch); |
2357 |
++ atomic_long_inc(&p->refs); |
2358 |
+ return p; |
2359 |
+ } |
2360 |
+ } |
2361 |
+@@ -194,17 +198,49 @@ int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree) |
2362 |
+ |
2363 |
+ /* tagging and untagging inodes with trees */ |
2364 |
+ |
2365 |
+-static void untag_chunk(struct audit_chunk *chunk, struct node *p) |
2366 |
++static struct audit_chunk *find_chunk(struct node *p) |
2367 |
++{ |
2368 |
++ int index = p->index & ~(1U<<31); |
2369 |
++ p -= index; |
2370 |
++ return container_of(p, struct audit_chunk, owners[0]); |
2371 |
++} |
2372 |
++ |
2373 |
++static void untag_chunk(struct node *p) |
2374 |
+ { |
2375 |
++ struct audit_chunk *chunk = find_chunk(p); |
2376 |
+ struct audit_chunk *new; |
2377 |
+ struct audit_tree *owner; |
2378 |
+ int size = chunk->count - 1; |
2379 |
+ int i, j; |
2380 |
+ |
2381 |
++ if (!pin_inotify_watch(&chunk->watch)) { |
2382 |
++ /* |
2383 |
++ * Filesystem is shutting down; all watches are getting |
2384 |
++ * evicted, just take it off the node list for this |
2385 |
++ * tree and let the eviction logics take care of the |
2386 |
++ * rest. |
2387 |
++ */ |
2388 |
++ owner = p->owner; |
2389 |
++ if (owner->root == chunk) { |
2390 |
++ list_del_init(&owner->same_root); |
2391 |
++ owner->root = NULL; |
2392 |
++ } |
2393 |
++ list_del_init(&p->list); |
2394 |
++ p->owner = NULL; |
2395 |
++ put_tree(owner); |
2396 |
++ return; |
2397 |
++ } |
2398 |
++ |
2399 |
++ spin_unlock(&hash_lock); |
2400 |
++ |
2401 |
++ /* |
2402 |
++ * pin_inotify_watch() succeeded, so the watch won't go away |
2403 |
++ * from under us. |
2404 |
++ */ |
2405 |
+ mutex_lock(&chunk->watch.inode->inotify_mutex); |
2406 |
+ if (chunk->dead) { |
2407 |
+ mutex_unlock(&chunk->watch.inode->inotify_mutex); |
2408 |
+- return; |
2409 |
++ goto out; |
2410 |
+ } |
2411 |
+ |
2412 |
+ owner = p->owner; |
2413 |
+@@ -221,7 +257,7 @@ static void untag_chunk(struct audit_chunk *chunk, struct node *p) |
2414 |
+ inotify_evict_watch(&chunk->watch); |
2415 |
+ mutex_unlock(&chunk->watch.inode->inotify_mutex); |
2416 |
+ put_inotify_watch(&chunk->watch); |
2417 |
+- return; |
2418 |
++ goto out; |
2419 |
+ } |
2420 |
+ |
2421 |
+ new = alloc_chunk(size); |
2422 |
+@@ -263,7 +299,7 @@ static void untag_chunk(struct audit_chunk *chunk, struct node *p) |
2423 |
+ inotify_evict_watch(&chunk->watch); |
2424 |
+ mutex_unlock(&chunk->watch.inode->inotify_mutex); |
2425 |
+ put_inotify_watch(&chunk->watch); |
2426 |
+- return; |
2427 |
++ goto out; |
2428 |
+ |
2429 |
+ Fallback: |
2430 |
+ // do the best we can |
2431 |
+@@ -277,6 +313,9 @@ Fallback: |
2432 |
+ put_tree(owner); |
2433 |
+ spin_unlock(&hash_lock); |
2434 |
+ mutex_unlock(&chunk->watch.inode->inotify_mutex); |
2435 |
++out: |
2436 |
++ unpin_inotify_watch(&chunk->watch); |
2437 |
++ spin_lock(&hash_lock); |
2438 |
+ } |
2439 |
+ |
2440 |
+ static int create_chunk(struct inode *inode, struct audit_tree *tree) |
2441 |
+@@ -387,13 +426,6 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) |
2442 |
+ return 0; |
2443 |
+ } |
2444 |
+ |
2445 |
+-static struct audit_chunk *find_chunk(struct node *p) |
2446 |
+-{ |
2447 |
+- int index = p->index & ~(1U<<31); |
2448 |
+- p -= index; |
2449 |
+- return container_of(p, struct audit_chunk, owners[0]); |
2450 |
+-} |
2451 |
+- |
2452 |
+ static void kill_rules(struct audit_tree *tree) |
2453 |
+ { |
2454 |
+ struct audit_krule *rule, *next; |
2455 |
+@@ -431,17 +463,10 @@ static void prune_one(struct audit_tree *victim) |
2456 |
+ spin_lock(&hash_lock); |
2457 |
+ while (!list_empty(&victim->chunks)) { |
2458 |
+ struct node *p; |
2459 |
+- struct audit_chunk *chunk; |
2460 |
+ |
2461 |
+ p = list_entry(victim->chunks.next, struct node, list); |
2462 |
+- chunk = find_chunk(p); |
2463 |
+- get_inotify_watch(&chunk->watch); |
2464 |
+- spin_unlock(&hash_lock); |
2465 |
+- |
2466 |
+- untag_chunk(chunk, p); |
2467 |
+ |
2468 |
+- put_inotify_watch(&chunk->watch); |
2469 |
+- spin_lock(&hash_lock); |
2470 |
++ untag_chunk(p); |
2471 |
+ } |
2472 |
+ spin_unlock(&hash_lock); |
2473 |
+ put_tree(victim); |
2474 |
+@@ -469,7 +494,6 @@ static void trim_marked(struct audit_tree *tree) |
2475 |
+ |
2476 |
+ while (!list_empty(&tree->chunks)) { |
2477 |
+ struct node *node; |
2478 |
+- struct audit_chunk *chunk; |
2479 |
+ |
2480 |
+ node = list_entry(tree->chunks.next, struct node, list); |
2481 |
+ |
2482 |
+@@ -477,14 +501,7 @@ static void trim_marked(struct audit_tree *tree) |
2483 |
+ if (!(node->index & (1U<<31))) |
2484 |
+ break; |
2485 |
+ |
2486 |
+- chunk = find_chunk(node); |
2487 |
+- get_inotify_watch(&chunk->watch); |
2488 |
+- spin_unlock(&hash_lock); |
2489 |
+- |
2490 |
+- untag_chunk(chunk, node); |
2491 |
+- |
2492 |
+- put_inotify_watch(&chunk->watch); |
2493 |
+- spin_lock(&hash_lock); |
2494 |
++ untag_chunk(node); |
2495 |
+ } |
2496 |
+ if (!tree->root && !tree->goner) { |
2497 |
+ tree->goner = 1; |
2498 |
+@@ -878,7 +895,7 @@ static void handle_event(struct inotify_watch *watch, u32 wd, u32 mask, |
2499 |
+ static void destroy_watch(struct inotify_watch *watch) |
2500 |
+ { |
2501 |
+ struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch); |
2502 |
+- free_chunk(chunk); |
2503 |
++ call_rcu(&chunk->head, __put_chunk); |
2504 |
+ } |
2505 |
+ |
2506 |
+ static const struct inotify_operations rtree_inotify_ops = { |
2507 |
+diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c |
2508 |
+index b7d354e..9fd85a4 100644 |
2509 |
+--- a/kernel/auditfilter.c |
2510 |
++++ b/kernel/auditfilter.c |
2511 |
+@@ -1094,8 +1094,8 @@ static void audit_inotify_unregister(struct list_head *in_list) |
2512 |
+ list_for_each_entry_safe(p, n, in_list, ilist) { |
2513 |
+ list_del(&p->ilist); |
2514 |
+ inotify_rm_watch(audit_ih, &p->wdata); |
2515 |
+- /* the put matching the get in audit_do_del_rule() */ |
2516 |
+- put_inotify_watch(&p->wdata); |
2517 |
++ /* the unpin matching the pin in audit_do_del_rule() */ |
2518 |
++ unpin_inotify_watch(&p->wdata); |
2519 |
+ } |
2520 |
+ } |
2521 |
+ |
2522 |
+@@ -1389,9 +1389,13 @@ static inline int audit_del_rule(struct audit_entry *entry, |
2523 |
+ /* Put parent on the inotify un-registration |
2524 |
+ * list. Grab a reference before releasing |
2525 |
+ * audit_filter_mutex, to be released in |
2526 |
+- * audit_inotify_unregister(). */ |
2527 |
+- list_add(&parent->ilist, &inotify_list); |
2528 |
+- get_inotify_watch(&parent->wdata); |
2529 |
++ * audit_inotify_unregister(). |
2530 |
++ * If filesystem is going away, just leave |
2531 |
++ * the sucker alone, eviction will take |
2532 |
++ * care of it. |
2533 |
++ */ |
2534 |
++ if (pin_inotify_watch(&parent->wdata)) |
2535 |
++ list_add(&parent->ilist, &inotify_list); |
2536 |
+ } |
2537 |
+ } |
2538 |
+ } |
2539 |
|
2540 |
Added: hardened/2.6/trunk/2.6.26/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch |
2541 |
=================================================================== |
2542 |
--- hardened/2.6/trunk/2.6.26/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch (rev 0) |
2543 |
+++ hardened/2.6/trunk/2.6.26/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch 2008-12-03 00:31:33 UTC (rev 1413) |
2544 |
@@ -0,0 +1,32 @@ |
2545 |
+From: Gordon Malm <gengor@g.o> |
2546 |
+ |
2547 |
+Make selection of PAX_REFCOUNT depend on X86. |
2548 |
+PAX_REFCOUNT is an X86-only feature. |
2549 |
+ |
2550 |
+Fixes bug #246763. |
2551 |
+ |
2552 |
+Thanks to Tom Lloyd for reporting. |
2553 |
+ |
2554 |
+This patch is present in upstream grsecurity patches as of |
2555 |
+grsecurity-2.1.12-2.6.27.7-200811201849.patch. |
2556 |
+ |
2557 |
+--- a/grsecurity/Kconfig |
2558 |
++++ b/grsecurity/Kconfig |
2559 |
+@@ -77,7 +77,7 @@ config GRKERNSEC_MEDIUM |
2560 |
+ select PAX_RANDUSTACK |
2561 |
+ select PAX_ASLR |
2562 |
+ select PAX_RANDMMAP |
2563 |
+- select PAX_REFCOUNT |
2564 |
++ select PAX_REFCOUNT if (X86) |
2565 |
+ |
2566 |
+ help |
2567 |
+ If you say Y here, several features in addition to those included |
2568 |
+@@ -155,7 +155,7 @@ config GRKERNSEC_HIGH |
2569 |
+ select PAX_EMUTRAMP if (PARISC) |
2570 |
+ select PAX_EMUSIGRT if (PARISC) |
2571 |
+ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) |
2572 |
+- select PAX_REFCOUNT |
2573 |
++ select PAX_REFCOUNT if (X86) |
2574 |
+ help |
2575 |
+ If you say Y here, many of the features of grsecurity will be |
2576 |
+ enabled, which will protect you against many kinds of attacks |
2577 |
|
2578 |
Added: hardened/2.6/trunk/2.6.26/4460_pax-fix-mmap-BUG_ON-task-size-check.patch |
2579 |
=================================================================== |
2580 |
--- hardened/2.6/trunk/2.6.26/4460_pax-fix-mmap-BUG_ON-task-size-check.patch (rev 0) |
2581 |
+++ hardened/2.6/trunk/2.6.26/4460_pax-fix-mmap-BUG_ON-task-size-check.patch 2008-12-03 00:31:33 UTC (rev 1413) |
2582 |
@@ -0,0 +1,22 @@ |
2583 |
+From: Gordon Malm <gengor@g.o> |
2584 |
+ |
2585 |
+Fix incorrect vma task size check under SEGMEXEC. |
2586 |
+ |
2587 |
+Fixes bug #246607. |
2588 |
+ |
2589 |
+Thanks to Hugo Mildenberger for reporting and PaX Team for the fix. |
2590 |
+ |
2591 |
+This patch is present in upstream grsecurity patches as of |
2592 |
+pax-linux-2.6.27.7-test22.patch. |
2593 |
+ |
2594 |
+--- a/mm/mmap.c |
2595 |
++++ b/mm/mmap.c |
2596 |
+@@ -1719,7 +1719,7 @@ struct vm_area_struct *pax_find_mirror_v |
2597 |
+ BUG_ON(vma->vm_mirror); |
2598 |
+ return NULL; |
2599 |
+ } |
2600 |
+- BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1); |
2601 |
++ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end); |
2602 |
+ vma_m = vma->vm_mirror; |
2603 |
+ BUG_ON(!vma_m || vma_m->vm_mirror != vma); |
2604 |
+ BUG_ON(vma->vm_file != vma_m->vm_file); |
2605 |
|
2606 |
Added: hardened/2.6/trunk/2.6.26/4465_pax-fix-false-RLIMIT_STACK-warnings.patch |
2607 |
=================================================================== |
2608 |
--- hardened/2.6/trunk/2.6.26/4465_pax-fix-false-RLIMIT_STACK-warnings.patch (rev 0) |
2609 |
+++ hardened/2.6/trunk/2.6.26/4465_pax-fix-false-RLIMIT_STACK-warnings.patch 2008-12-03 00:31:33 UTC (rev 1413) |
2610 |
@@ -0,0 +1,88 @@ |
2611 |
+From: Gordon Malm <gengor@g.o> |
2612 |
+ |
2613 |
+Fix false-positive RLIMIT_STACK warnings. |
2614 |
+ |
2615 |
+Thanks to PaX Team for the heads up. |
2616 |
+ |
2617 |
+This patch is present in upstream grsecurity patches as of |
2618 |
+pax-linux-2.6.27.7-test22.patch. |
2619 |
+ |
2620 |
+--- a/arch/x86/mm/fault.c |
2621 |
++++ b/arch/x86/mm/fault.c |
2622 |
+@@ -844,16 +844,14 @@ not_pax_fault: |
2623 |
+ goto good_area; |
2624 |
+ if (!(vma->vm_flags & VM_GROWSDOWN)) |
2625 |
+ goto bad_area; |
2626 |
+- if (error_code & PF_USER) { |
2627 |
+- /* |
2628 |
+- * Accessing the stack below %sp is always a bug. |
2629 |
+- * The large cushion allows instructions like enter |
2630 |
+- * and pusha to work. ("enter $65535,$31" pushes |
2631 |
+- * 32 pointers and then decrements %sp by 65535.) |
2632 |
+- */ |
2633 |
+- if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp) |
2634 |
+- goto bad_area; |
2635 |
+- } |
2636 |
++ /* |
2637 |
++ * Accessing the stack below %sp is always a bug. |
2638 |
++ * The large cushion allows instructions like enter |
2639 |
++ * and pusha to work. ("enter $65535,$31" pushes |
2640 |
++ * 32 pointers and then decrements %sp by 65535.) |
2641 |
++ */ |
2642 |
++ if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp) |
2643 |
++ goto bad_area; |
2644 |
+ |
2645 |
+ #ifdef CONFIG_PAX_SEGMEXEC |
2646 |
+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1) |
2647 |
+--- a/kernel/exit.c |
2648 |
++++ b/kernel/exit.c |
2649 |
+@@ -39,7 +39,6 @@ |
2650 |
+ #include <linux/cn_proc.h> |
2651 |
+ #include <linux/mutex.h> |
2652 |
+ #include <linux/futex.h> |
2653 |
+-#include <linux/compat.h> |
2654 |
+ #include <linux/pipe_fs_i.h> |
2655 |
+ #include <linux/audit.h> /* for audit_free() */ |
2656 |
+ #include <linux/resource.h> |
2657 |
+@@ -1058,14 +1057,6 @@ NORET_TYPE void do_exit(long code) |
2658 |
+ exit_itimers(tsk->signal); |
2659 |
+ } |
2660 |
+ acct_collect(code, group_dead); |
2661 |
+-#ifdef CONFIG_FUTEX |
2662 |
+- if (unlikely(tsk->robust_list)) |
2663 |
+- exit_robust_list(tsk); |
2664 |
+-#ifdef CONFIG_COMPAT |
2665 |
+- if (unlikely(tsk->compat_robust_list)) |
2666 |
+- compat_exit_robust_list(tsk); |
2667 |
+-#endif |
2668 |
+-#endif |
2669 |
+ if (group_dead) |
2670 |
+ tty_audit_exit(); |
2671 |
+ if (unlikely(tsk->audit_context)) |
2672 |
+--- a/kernel/fork.c |
2673 |
++++ b/kernel/fork.c |
2674 |
+@@ -36,6 +36,7 @@ |
2675 |
+ #include <linux/syscalls.h> |
2676 |
+ #include <linux/jiffies.h> |
2677 |
+ #include <linux/futex.h> |
2678 |
++#include <linux/compat.h> |
2679 |
+ #include <linux/task_io_accounting_ops.h> |
2680 |
+ #include <linux/rcupdate.h> |
2681 |
+ #include <linux/ptrace.h> |
2682 |
+@@ -514,6 +515,16 @@ void mm_release(struct task_struct *tsk, |
2683 |
+ { |
2684 |
+ struct completion *vfork_done = tsk->vfork_done; |
2685 |
+ |
2686 |
++ /* Get rid of any futexes when releasing the mm */ |
2687 |
++#ifdef CONFIG_FUTEX |
2688 |
++ if (unlikely(tsk->robust_list)) |
2689 |
++ exit_robust_list(tsk); |
2690 |
++#ifdef CONFIG_COMPAT |
2691 |
++ if (unlikely(tsk->compat_robust_list)) |
2692 |
++ compat_exit_robust_list(tsk); |
2693 |
++#endif |
2694 |
++#endif |
2695 |
++ |
2696 |
+ /* Get rid of any cached register state */ |
2697 |
+ deactivate_mm(tsk, mm); |
2698 |
+ |
2699 |
\ No newline at end of file |