Contents of /trunk/kernel26-magellan-server/patches-2.6.24-r7/0102-2.6.24.3-all-fixes.patch
Parent Directory | Revision Log
Revision 589 -
(show annotations)
(download)
Fri May 9 12:49:26 2008 UTC (16 years, 5 months ago) by niro
File size: 47775 byte(s)
Fri May 9 12:49:26 2008 UTC (16 years, 5 months ago) by niro
File size: 47775 byte(s)
-2.6.24-magellan-r7; updated to linux-2.6.24.7
1 | diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c |
2 | index 0340a34..759c2ac 100644 |
3 | --- a/arch/powerpc/platforms/chrp/pci.c |
4 | +++ b/arch/powerpc/platforms/chrp/pci.c |
5 | @@ -354,7 +354,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, |
6 | * mode as well. The same fixup must be done to the class-code property in |
7 | * the IDE node /pci@80000000/ide@C,1 |
8 | */ |
9 | -static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
10 | +static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
11 | { |
12 | u8 progif; |
13 | struct pci_dev *viaisa; |
14 | @@ -375,4 +375,4 @@ static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) |
15 | |
16 | pci_dev_put(viaisa); |
17 | } |
18 | -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); |
19 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); |
20 | diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c |
21 | index ba931be..5169ecc 100644 |
22 | --- a/arch/powerpc/platforms/powermac/feature.c |
23 | +++ b/arch/powerpc/platforms/powermac/feature.c |
24 | @@ -2565,6 +2565,8 @@ static void __init probe_uninorth(void) |
25 | |
26 | /* Locate core99 Uni-N */ |
27 | uninorth_node = of_find_node_by_name(NULL, "uni-n"); |
28 | + uninorth_maj = 1; |
29 | + |
30 | /* Locate G5 u3 */ |
31 | if (uninorth_node == NULL) { |
32 | uninorth_node = of_find_node_by_name(NULL, "u3"); |
33 | @@ -2575,8 +2577,10 @@ static void __init probe_uninorth(void) |
34 | uninorth_node = of_find_node_by_name(NULL, "u4"); |
35 | uninorth_maj = 4; |
36 | } |
37 | - if (uninorth_node == NULL) |
38 | + if (uninorth_node == NULL) { |
39 | + uninorth_maj = 0; |
40 | return; |
41 | + } |
42 | |
43 | addrp = of_get_property(uninorth_node, "reg", NULL); |
44 | if (addrp == NULL) |
45 | @@ -3029,3 +3033,8 @@ void pmac_resume_agp_for_card(struct pci_dev *dev) |
46 | pmac_agp_resume(pmac_agp_bridge); |
47 | } |
48 | EXPORT_SYMBOL(pmac_resume_agp_for_card); |
49 | + |
50 | +int pmac_get_uninorth_variant(void) |
51 | +{ |
52 | + return uninorth_maj; |
53 | +} |
54 | diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c |
55 | index 28c4500..d2ffbad 100644 |
56 | --- a/arch/s390/lib/uaccess_std.c |
57 | +++ b/arch/s390/lib/uaccess_std.c |
58 | @@ -293,10 +293,10 @@ int futex_atomic_cmpxchg_std(int __user *uaddr, int oldval, int newval) |
59 | |
60 | asm volatile( |
61 | " sacf 256\n" |
62 | - " cs %1,%4,0(%5)\n" |
63 | - "0: lr %0,%1\n" |
64 | - "1: sacf 0\n" |
65 | - EX_TABLE(0b,1b) |
66 | + "0: cs %1,%4,0(%5)\n" |
67 | + "1: lr %0,%1\n" |
68 | + "2: sacf 0\n" |
69 | + EX_TABLE(0b,2b) EX_TABLE(1b,2b) |
70 | : "=d" (ret), "+d" (oldval), "=m" (*uaddr) |
71 | : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) |
72 | : "cc", "memory" ); |
73 | diff --git a/arch/sparc/lib/rwsem.S b/arch/sparc/lib/rwsem.S |
74 | index 2065774..f406b1f 100644 |
75 | --- a/arch/sparc/lib/rwsem.S |
76 | +++ b/arch/sparc/lib/rwsem.S |
77 | @@ -7,7 +7,7 @@ |
78 | #include <asm/ptrace.h> |
79 | #include <asm/psr.h> |
80 | |
81 | - .section .sched.text |
82 | + .section .sched.text, "ax" |
83 | .align 4 |
84 | |
85 | .globl ___down_read |
86 | diff --git a/arch/sparc64/lib/rwsem.S b/arch/sparc64/lib/rwsem.S |
87 | index 75f0e6b..1a4cc56 100644 |
88 | --- a/arch/sparc64/lib/rwsem.S |
89 | +++ b/arch/sparc64/lib/rwsem.S |
90 | @@ -6,7 +6,7 @@ |
91 | |
92 | #include <asm/rwsem-const.h> |
93 | |
94 | - .section .sched.text |
95 | + .section .sched.text, "ax" |
96 | |
97 | .globl __down_read |
98 | __down_read: |
99 | diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c |
100 | index c40afba..f636c1e 100644 |
101 | --- a/arch/x86/mm/pageattr_64.c |
102 | +++ b/arch/x86/mm/pageattr_64.c |
103 | @@ -207,7 +207,7 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) |
104 | if (__pa(address) < KERNEL_TEXT_SIZE) { |
105 | unsigned long addr2; |
106 | pgprot_t prot2; |
107 | - addr2 = __START_KERNEL_map + __pa(address); |
108 | + addr2 = __START_KERNEL_map + __pa(address) - phys_base; |
109 | /* Make sure the kernel mappings stay executable */ |
110 | prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); |
111 | err = __change_page_attr(addr2, pfn, prot2, |
112 | diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c |
113 | index d409f67..1ebe7a3 100644 |
114 | --- a/drivers/macintosh/smu.c |
115 | +++ b/drivers/macintosh/smu.c |
116 | @@ -85,6 +85,7 @@ struct smu_device { |
117 | u32 cmd_buf_abs; /* command buffer absolute */ |
118 | struct list_head cmd_list; |
119 | struct smu_cmd *cmd_cur; /* pending command */ |
120 | + int broken_nap; |
121 | struct list_head cmd_i2c_list; |
122 | struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ |
123 | struct timer_list i2c_timer; |
124 | @@ -135,6 +136,19 @@ static void smu_start_cmd(void) |
125 | fend = faddr + smu->cmd_buf->length + 2; |
126 | flush_inval_dcache_range(faddr, fend); |
127 | |
128 | + |
129 | + /* We also disable NAP mode for the duration of the command |
130 | + * on U3 based machines. |
131 | + * This is slightly racy as it can be written back to 1 by a sysctl |
132 | + * but that never happens in practice. There seem to be an issue with |
133 | + * U3 based machines such as the iMac G5 where napping for the |
134 | + * whole duration of the command prevents the SMU from fetching it |
135 | + * from memory. This might be related to the strange i2c based |
136 | + * mechanism the SMU uses to access memory. |
137 | + */ |
138 | + if (smu->broken_nap) |
139 | + powersave_nap = 0; |
140 | + |
141 | /* This isn't exactly a DMA mapping here, I suspect |
142 | * the SMU is actually communicating with us via i2c to the |
143 | * northbridge or the CPU to access RAM. |
144 | @@ -211,6 +225,10 @@ static irqreturn_t smu_db_intr(int irq, void *arg) |
145 | misc = cmd->misc; |
146 | mb(); |
147 | cmd->status = rc; |
148 | + |
149 | + /* Re-enable NAP mode */ |
150 | + if (smu->broken_nap) |
151 | + powersave_nap = 1; |
152 | bail: |
153 | /* Start next command if any */ |
154 | smu_start_cmd(); |
155 | @@ -461,7 +479,7 @@ int __init smu_init (void) |
156 | if (np == NULL) |
157 | return -ENODEV; |
158 | |
159 | - printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); |
160 | + printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR); |
161 | |
162 | if (smu_cmdbuf_abs == 0) { |
163 | printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
164 | @@ -533,6 +551,11 @@ int __init smu_init (void) |
165 | goto fail; |
166 | } |
167 | |
168 | + /* U3 has an issue with NAP mode when issuing SMU commands */ |
169 | + smu->broken_nap = pmac_get_uninorth_variant() < 4; |
170 | + if (smu->broken_nap) |
171 | + printk(KERN_INFO "SMU: using NAP mode workaround\n"); |
172 | + |
173 | sys_ctrler = SYS_CTRLER_SMU; |
174 | return 0; |
175 | |
176 | diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c |
177 | index 49a1982..75efa8b 100644 |
178 | --- a/drivers/net/bonding/bond_main.c |
179 | +++ b/drivers/net/bonding/bond_main.c |
180 | @@ -4883,14 +4883,16 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond |
181 | down_write(&bonding_rwsem); |
182 | |
183 | /* Check to see if the bond already exists. */ |
184 | - list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) |
185 | - if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { |
186 | - printk(KERN_ERR DRV_NAME |
187 | + if (name) { |
188 | + list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) |
189 | + if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { |
190 | + printk(KERN_ERR DRV_NAME |
191 | ": cannot add bond %s; it already exists\n", |
192 | - name); |
193 | - res = -EPERM; |
194 | - goto out_rtnl; |
195 | - } |
196 | + name); |
197 | + res = -EPERM; |
198 | + goto out_rtnl; |
199 | + } |
200 | + } |
201 | |
202 | bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", |
203 | ether_setup); |
204 | diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h |
205 | index d66c605..266ec87 100644 |
206 | --- a/drivers/net/dl2k.h |
207 | +++ b/drivers/net/dl2k.h |
208 | @@ -388,8 +388,8 @@ enum _mii_mssr { |
209 | MII_MSSR_CFG_RES = 0x4000, |
210 | MII_MSSR_LOCAL_RCV_STATUS = 0x2000, |
211 | MII_MSSR_REMOTE_RCVR = 0x1000, |
212 | - MII_MSSR_LP_1000BT_HD = 0x0800, |
213 | - MII_MSSR_LP_1000BT_FD = 0x0400, |
214 | + MII_MSSR_LP_1000BT_FD = 0x0800, |
215 | + MII_MSSR_LP_1000BT_HD = 0x0400, |
216 | MII_MSSR_IDLE_ERR_COUNT = 0x00ff, |
217 | }; |
218 | |
219 | diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c |
220 | index c9868e9..e94434f 100644 |
221 | --- a/drivers/net/pcmcia/smc91c92_cs.c |
222 | +++ b/drivers/net/pcmcia/smc91c92_cs.c |
223 | @@ -559,8 +559,16 @@ static int mhz_setup(struct pcmcia_device *link) |
224 | |
225 | /* Read the station address from the CIS. It is stored as the last |
226 | (fourth) string in the Version 1 Version/ID tuple. */ |
227 | - if (link->prod_id[3]) { |
228 | - station_addr = link->prod_id[3]; |
229 | + tuple->DesiredTuple = CISTPL_VERS_1; |
230 | + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { |
231 | + rc = -1; |
232 | + goto free_cfg_mem; |
233 | + } |
234 | + /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ |
235 | + if (next_tuple(link, tuple, parse) != CS_SUCCESS) |
236 | + first_tuple(link, tuple, parse); |
237 | + if (parse->version_1.ns > 3) { |
238 | + station_addr = parse->version_1.str + parse->version_1.ofs[3]; |
239 | if (cvt_ascii_address(dev, station_addr) == 0) { |
240 | rc = 0; |
241 | goto free_cfg_mem; |
242 | diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c |
243 | index b253b8c..8eb78be 100644 |
244 | --- a/drivers/scsi/gdth.c |
245 | +++ b/drivers/scsi/gdth.c |
246 | @@ -4838,6 +4838,9 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios) |
247 | if (error) |
248 | goto out_free_coal_stat; |
249 | list_add_tail(&ha->list, &gdth_instances); |
250 | + |
251 | + scsi_scan_host(shp); |
252 | + |
253 | return 0; |
254 | |
255 | out_free_coal_stat: |
256 | @@ -4965,6 +4968,9 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) |
257 | if (error) |
258 | goto out_free_coal_stat; |
259 | list_add_tail(&ha->list, &gdth_instances); |
260 | + |
261 | + scsi_scan_host(shp); |
262 | + |
263 | return 0; |
264 | |
265 | out_free_ccb_phys: |
266 | @@ -5102,6 +5108,9 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) |
267 | if (error) |
268 | goto out_free_coal_stat; |
269 | list_add_tail(&ha->list, &gdth_instances); |
270 | + |
271 | + scsi_scan_host(shp); |
272 | + |
273 | return 0; |
274 | |
275 | out_free_coal_stat: |
276 | diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c |
277 | index a69b155..cfd859a 100644 |
278 | --- a/drivers/scsi/sd.c |
279 | +++ b/drivers/scsi/sd.c |
280 | @@ -907,6 +907,7 @@ static int sd_done(struct scsi_cmnd *SCpnt) |
281 | unsigned int xfer_size = SCpnt->request_bufflen; |
282 | unsigned int good_bytes = result ? 0 : xfer_size; |
283 | u64 start_lba = SCpnt->request->sector; |
284 | + u64 end_lba = SCpnt->request->sector + (xfer_size / 512); |
285 | u64 bad_lba; |
286 | struct scsi_sense_hdr sshdr; |
287 | int sense_valid = 0; |
288 | @@ -945,26 +946,23 @@ static int sd_done(struct scsi_cmnd *SCpnt) |
289 | goto out; |
290 | if (xfer_size <= SCpnt->device->sector_size) |
291 | goto out; |
292 | - switch (SCpnt->device->sector_size) { |
293 | - case 256: |
294 | + if (SCpnt->device->sector_size < 512) { |
295 | + /* only legitimate sector_size here is 256 */ |
296 | start_lba <<= 1; |
297 | - break; |
298 | - case 512: |
299 | - break; |
300 | - case 1024: |
301 | - start_lba >>= 1; |
302 | - break; |
303 | - case 2048: |
304 | - start_lba >>= 2; |
305 | - break; |
306 | - case 4096: |
307 | - start_lba >>= 3; |
308 | - break; |
309 | - default: |
310 | - /* Print something here with limiting frequency. */ |
311 | - goto out; |
312 | - break; |
313 | + end_lba <<= 1; |
314 | + } else { |
315 | + /* be careful ... don't want any overflows */ |
316 | + u64 factor = SCpnt->device->sector_size / 512; |
317 | + do_div(start_lba, factor); |
318 | + do_div(end_lba, factor); |
319 | } |
320 | + |
321 | + if (bad_lba < start_lba || bad_lba >= end_lba) |
322 | + /* the bad lba was reported incorrectly, we have |
323 | + * no idea where the error is |
324 | + */ |
325 | + goto out; |
326 | + |
327 | /* This computation should always be done in terms of |
328 | * the resolution of the device's medium. |
329 | */ |
330 | diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c |
331 | index ad632f2..0647164 100644 |
332 | --- a/drivers/usb/class/usblp.c |
333 | +++ b/drivers/usb/class/usblp.c |
334 | @@ -428,6 +428,7 @@ static int usblp_open(struct inode *inode, struct file *file) |
335 | usblp->rcomplete = 0; |
336 | |
337 | if (handle_bidir(usblp) < 0) { |
338 | + usb_autopm_put_interface(intf); |
339 | usblp->used = 0; |
340 | file->private_data = NULL; |
341 | retval = -EIO; |
342 | diff --git a/fs/inotify_user.c b/fs/inotify_user.c |
343 | index 5e00933..7253ffd 100644 |
344 | --- a/fs/inotify_user.c |
345 | +++ b/fs/inotify_user.c |
346 | @@ -269,7 +269,7 @@ static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask, |
347 | /* we can safely put the watch as we don't reference it while |
348 | * generating the event |
349 | */ |
350 | - if (mask & IN_IGNORED || mask & IN_ONESHOT) |
351 | + if (mask & IN_IGNORED || w->mask & IN_ONESHOT) |
352 | put_inotify_watch(w); /* final put */ |
353 | |
354 | /* coalescing: drop this event if it is a dupe of the previous */ |
355 | diff --git a/fs/nfs/write.c b/fs/nfs/write.c |
356 | index 51cc1bd..855b6d5 100644 |
357 | --- a/fs/nfs/write.c |
358 | +++ b/fs/nfs/write.c |
359 | @@ -701,6 +701,17 @@ int nfs_flush_incompatible(struct file *file, struct page *page) |
360 | } |
361 | |
362 | /* |
363 | + * If the page cache is marked as unsafe or invalid, then we can't rely on |
364 | + * the PageUptodate() flag. In this case, we will need to turn off |
365 | + * write optimisations that depend on the page contents being correct. |
366 | + */ |
367 | +static int nfs_write_pageuptodate(struct page *page, struct inode *inode) |
368 | +{ |
369 | + return PageUptodate(page) && |
370 | + !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA)); |
371 | +} |
372 | + |
373 | +/* |
374 | * Update and possibly write a cached page of an NFS file. |
375 | * |
376 | * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad |
377 | @@ -721,10 +732,13 @@ int nfs_updatepage(struct file *file, struct page *page, |
378 | (long long)(page_offset(page) +offset)); |
379 | |
380 | /* If we're not using byte range locks, and we know the page |
381 | - * is entirely in cache, it may be more efficient to avoid |
382 | - * fragmenting write requests. |
383 | + * is up to date, it may be more efficient to extend the write |
384 | + * to cover the entire page in order to avoid fragmentation |
385 | + * inefficiencies. |
386 | */ |
387 | - if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { |
388 | + if (nfs_write_pageuptodate(page, inode) && |
389 | + inode->i_flock == NULL && |
390 | + !(file->f_mode & O_SYNC)) { |
391 | count = max(count + offset, nfs_page_length(page)); |
392 | offset = 0; |
393 | } |
394 | diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c |
395 | index 21a1c2b..edab1ff 100644 |
396 | --- a/fs/xfs/linux-2.6/xfs_file.c |
397 | +++ b/fs/xfs/linux-2.6/xfs_file.c |
398 | @@ -350,8 +350,8 @@ xfs_file_readdir( |
399 | |
400 | size = buf.used; |
401 | de = (struct hack_dirent *)buf.dirent; |
402 | - curr_offset = de->offset /* & 0x7fffffff */; |
403 | while (size > 0) { |
404 | + curr_offset = de->offset /* & 0x7fffffff */; |
405 | if (filldir(dirent, de->name, de->namlen, |
406 | curr_offset & 0x7fffffff, |
407 | de->ino, de->d_type)) { |
408 | @@ -362,7 +362,6 @@ xfs_file_readdir( |
409 | sizeof(u64)); |
410 | size -= reclen; |
411 | de = (struct hack_dirent *)((char *)de + reclen); |
412 | - curr_offset = de->offset /* & 0x7fffffff */; |
413 | } |
414 | } |
415 | |
416 | diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h |
417 | index 26bcb0a..877c35a 100644 |
418 | --- a/include/asm-powerpc/pmac_feature.h |
419 | +++ b/include/asm-powerpc/pmac_feature.h |
420 | @@ -392,6 +392,14 @@ extern u32 __iomem *uninorth_base; |
421 | #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) |
422 | #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) |
423 | |
424 | +/* Uninorth variant: |
425 | + * |
426 | + * 0 = not uninorth |
427 | + * 1 = U1.x or U2.x |
428 | + * 3 = U3 |
429 | + * 4 = U4 |
430 | + */ |
431 | +extern int pmac_get_uninorth_variant(void); |
432 | |
433 | #endif /* __ASM_POWERPC_PMAC_FEATURE_H */ |
434 | #endif /* __KERNEL__ */ |
435 | diff --git a/include/linux/Kbuild b/include/linux/Kbuild |
436 | index f30fa92..4b32bb1 100644 |
437 | --- a/include/linux/Kbuild |
438 | +++ b/include/linux/Kbuild |
439 | @@ -217,6 +217,7 @@ unifdef-y += i2o-dev.h |
440 | unifdef-y += icmp.h |
441 | unifdef-y += icmpv6.h |
442 | unifdef-y += if_addr.h |
443 | +unifdef-y += if_addrlabel.h |
444 | unifdef-y += if_arp.h |
445 | unifdef-y += if_bridge.h |
446 | unifdef-y += if_ec.h |
447 | diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h |
448 | index 7a9398e..540799b 100644 |
449 | --- a/include/linux/hrtimer.h |
450 | +++ b/include/linux/hrtimer.h |
451 | @@ -300,7 +300,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); |
452 | |
453 | /* Precise sleep: */ |
454 | extern long hrtimer_nanosleep(struct timespec *rqtp, |
455 | - struct timespec *rmtp, |
456 | + struct timespec __user *rmtp, |
457 | const enum hrtimer_mode mode, |
458 | const clockid_t clockid); |
459 | extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); |
460 | diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h |
461 | index 30d606a..7ca198b 100644 |
462 | --- a/include/linux/hugetlb.h |
463 | +++ b/include/linux/hugetlb.h |
464 | @@ -17,6 +17,7 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) |
465 | } |
466 | |
467 | int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); |
468 | +int hugetlb_overcommit_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); |
469 | int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); |
470 | int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); |
471 | int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int); |
472 | diff --git a/include/linux/ktime.h b/include/linux/ktime.h |
473 | index a6ddec1..816cf4e 100644 |
474 | --- a/include/linux/ktime.h |
475 | +++ b/include/linux/ktime.h |
476 | @@ -310,6 +310,8 @@ static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec) |
477 | return ktime_sub_ns(kt, usec * 1000); |
478 | } |
479 | |
480 | +extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs); |
481 | + |
482 | /* |
483 | * The resolution of the clocks. The resolution value is returned in |
484 | * the clock_getres() system call to give application programmers an |
485 | diff --git a/kernel/audit.c b/kernel/audit.c |
486 | index f93c271..801c946 100644 |
487 | --- a/kernel/audit.c |
488 | +++ b/kernel/audit.c |
489 | @@ -1200,13 +1200,17 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, |
490 | static inline int audit_expand(struct audit_buffer *ab, int extra) |
491 | { |
492 | struct sk_buff *skb = ab->skb; |
493 | - int ret = pskb_expand_head(skb, skb_headroom(skb), extra, |
494 | - ab->gfp_mask); |
495 | + int oldtail = skb_tailroom(skb); |
496 | + int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask); |
497 | + int newtail = skb_tailroom(skb); |
498 | + |
499 | if (ret < 0) { |
500 | audit_log_lost("out of memory in audit_expand"); |
501 | return 0; |
502 | } |
503 | - return skb_tailroom(skb); |
504 | + |
505 | + skb->truesize += newtail - oldtail; |
506 | + return newtail; |
507 | } |
508 | |
509 | /* |
510 | diff --git a/kernel/compat.c b/kernel/compat.c |
511 | index 42a1ed4..f2a2975 100644 |
512 | --- a/kernel/compat.c |
513 | +++ b/kernel/compat.c |
514 | @@ -40,10 +40,36 @@ int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user |
515 | __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; |
516 | } |
517 | |
518 | +static long compat_nanosleep_restart(struct restart_block *restart) |
519 | +{ |
520 | + struct compat_timespec __user *rmtp; |
521 | + struct timespec rmt; |
522 | + mm_segment_t oldfs; |
523 | + long ret; |
524 | + |
525 | + rmtp = (struct compat_timespec __user *)(restart->arg1); |
526 | + restart->arg1 = (unsigned long)&rmt; |
527 | + oldfs = get_fs(); |
528 | + set_fs(KERNEL_DS); |
529 | + ret = hrtimer_nanosleep_restart(restart); |
530 | + set_fs(oldfs); |
531 | + |
532 | + if (ret) { |
533 | + restart->fn = compat_nanosleep_restart; |
534 | + restart->arg1 = (unsigned long)rmtp; |
535 | + |
536 | + if (rmtp && put_compat_timespec(&rmt, rmtp)) |
537 | + return -EFAULT; |
538 | + } |
539 | + |
540 | + return ret; |
541 | +} |
542 | + |
543 | asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, |
544 | struct compat_timespec __user *rmtp) |
545 | { |
546 | struct timespec tu, rmt; |
547 | + mm_segment_t oldfs; |
548 | long ret; |
549 | |
550 | if (get_compat_timespec(&tu, rqtp)) |
551 | @@ -52,11 +78,21 @@ asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, |
552 | if (!timespec_valid(&tu)) |
553 | return -EINVAL; |
554 | |
555 | - ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, |
556 | - CLOCK_MONOTONIC); |
557 | + oldfs = get_fs(); |
558 | + set_fs(KERNEL_DS); |
559 | + ret = hrtimer_nanosleep(&tu, |
560 | + rmtp ? (struct timespec __user *)&rmt : NULL, |
561 | + HRTIMER_MODE_REL, CLOCK_MONOTONIC); |
562 | + set_fs(oldfs); |
563 | + |
564 | + if (ret) { |
565 | + struct restart_block *restart |
566 | + = ¤t_thread_info()->restart_block; |
567 | + |
568 | + restart->fn = compat_nanosleep_restart; |
569 | + restart->arg1 = (unsigned long)rmtp; |
570 | |
571 | - if (ret && rmtp) { |
572 | - if (put_compat_timespec(&rmt, rmtp)) |
573 | + if (rmtp && put_compat_timespec(&rmt, rmtp)) |
574 | return -EFAULT; |
575 | } |
576 | |
577 | diff --git a/kernel/futex.c b/kernel/futex.c |
578 | index db9824d..55d78b5 100644 |
579 | --- a/kernel/futex.c |
580 | +++ b/kernel/futex.c |
581 | @@ -2094,7 +2094,7 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, |
582 | |
583 | t = timespec_to_ktime(ts); |
584 | if (cmd == FUTEX_WAIT) |
585 | - t = ktime_add(ktime_get(), t); |
586 | + t = ktime_add_safe(ktime_get(), t); |
587 | tp = &t; |
588 | } |
589 | /* |
590 | diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c |
591 | index 0a43def..8682c79 100644 |
592 | --- a/kernel/futex_compat.c |
593 | +++ b/kernel/futex_compat.c |
594 | @@ -175,7 +175,7 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, |
595 | |
596 | t = timespec_to_ktime(ts); |
597 | if (cmd == FUTEX_WAIT) |
598 | - t = ktime_add(ktime_get(), t); |
599 | + t = ktime_add_safe(ktime_get(), t); |
600 | tp = &t; |
601 | } |
602 | if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) |
603 | diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c |
604 | index f994bb8..2429893 100644 |
605 | --- a/kernel/hrtimer.c |
606 | +++ b/kernel/hrtimer.c |
607 | @@ -325,6 +325,24 @@ unsigned long ktime_divns(const ktime_t kt, s64 div) |
608 | } |
609 | #endif /* BITS_PER_LONG >= 64 */ |
610 | |
611 | +/* |
612 | + * Add two ktime values and do a safety check for overflow: |
613 | + */ |
614 | + |
615 | +ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) |
616 | +{ |
617 | + ktime_t res = ktime_add(lhs, rhs); |
618 | + |
619 | + /* |
620 | + * We use KTIME_SEC_MAX here, the maximum timeout which we can |
621 | + * return to user space in a timespec: |
622 | + */ |
623 | + if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) |
624 | + res = ktime_set(KTIME_SEC_MAX, 0); |
625 | + |
626 | + return res; |
627 | +} |
628 | + |
629 | /* High resolution timer related functions */ |
630 | #ifdef CONFIG_HIGH_RES_TIMERS |
631 | |
632 | @@ -409,6 +427,8 @@ static int hrtimer_reprogram(struct hrtimer *timer, |
633 | ktime_t expires = ktime_sub(timer->expires, base->offset); |
634 | int res; |
635 | |
636 | + WARN_ON_ONCE(timer->expires.tv64 < 0); |
637 | + |
638 | /* |
639 | * When the callback is running, we do not reprogram the clock event |
640 | * device. The timer callback is either running on a different CPU or |
641 | @@ -419,6 +439,15 @@ static int hrtimer_reprogram(struct hrtimer *timer, |
642 | if (hrtimer_callback_running(timer)) |
643 | return 0; |
644 | |
645 | + /* |
646 | + * CLOCK_REALTIME timer might be requested with an absolute |
647 | + * expiry time which is less than base->offset. Nothing wrong |
648 | + * about that, just avoid to call into the tick code, which |
649 | + * has now objections against negative expiry values. |
650 | + */ |
651 | + if (expires.tv64 < 0) |
652 | + return -ETIME; |
653 | + |
654 | if (expires.tv64 >= expires_next->tv64) |
655 | return 0; |
656 | |
657 | @@ -682,13 +711,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) |
658 | */ |
659 | orun++; |
660 | } |
661 | - timer->expires = ktime_add(timer->expires, interval); |
662 | - /* |
663 | - * Make sure, that the result did not wrap with a very large |
664 | - * interval. |
665 | - */ |
666 | - if (timer->expires.tv64 < 0) |
667 | - timer->expires = ktime_set(KTIME_SEC_MAX, 0); |
668 | + timer->expires = ktime_add_safe(timer->expires, interval); |
669 | |
670 | return orun; |
671 | } |
672 | @@ -839,7 +862,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) |
673 | new_base = switch_hrtimer_base(timer, base); |
674 | |
675 | if (mode == HRTIMER_MODE_REL) { |
676 | - tim = ktime_add(tim, new_base->get_time()); |
677 | + tim = ktime_add_safe(tim, new_base->get_time()); |
678 | /* |
679 | * CONFIG_TIME_LOW_RES is a temporary way for architectures |
680 | * to signal that they simply return xtime in |
681 | @@ -848,16 +871,8 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) |
682 | * timeouts. This will go away with the GTOD framework. |
683 | */ |
684 | #ifdef CONFIG_TIME_LOW_RES |
685 | - tim = ktime_add(tim, base->resolution); |
686 | + tim = ktime_add_safe(tim, base->resolution); |
687 | #endif |
688 | - /* |
689 | - * Careful here: User space might have asked for a |
690 | - * very long sleep, so the add above might result in a |
691 | - * negative number, which enqueues the timer in front |
692 | - * of the queue. |
693 | - */ |
694 | - if (tim.tv64 < 0) |
695 | - tim.tv64 = KTIME_MAX; |
696 | } |
697 | timer->expires = tim; |
698 | |
699 | @@ -1291,11 +1306,26 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod |
700 | return t->task == NULL; |
701 | } |
702 | |
703 | +static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp) |
704 | +{ |
705 | + struct timespec rmt; |
706 | + ktime_t rem; |
707 | + |
708 | + rem = ktime_sub(timer->expires, timer->base->get_time()); |
709 | + if (rem.tv64 <= 0) |
710 | + return 0; |
711 | + rmt = ktime_to_timespec(rem); |
712 | + |
713 | + if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) |
714 | + return -EFAULT; |
715 | + |
716 | + return 1; |
717 | +} |
718 | + |
719 | long __sched hrtimer_nanosleep_restart(struct restart_block *restart) |
720 | { |
721 | struct hrtimer_sleeper t; |
722 | - struct timespec *rmtp; |
723 | - ktime_t time; |
724 | + struct timespec __user *rmtp; |
725 | |
726 | restart->fn = do_no_restart_syscall; |
727 | |
728 | @@ -1305,12 +1335,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) |
729 | if (do_nanosleep(&t, HRTIMER_MODE_ABS)) |
730 | return 0; |
731 | |
732 | - rmtp = (struct timespec *)restart->arg1; |
733 | + rmtp = (struct timespec __user *)restart->arg1; |
734 | if (rmtp) { |
735 | - time = ktime_sub(t.timer.expires, t.timer.base->get_time()); |
736 | - if (time.tv64 <= 0) |
737 | - return 0; |
738 | - *rmtp = ktime_to_timespec(time); |
739 | + int ret = update_rmtp(&t.timer, rmtp); |
740 | + if (ret <= 0) |
741 | + return ret; |
742 | } |
743 | |
744 | restart->fn = hrtimer_nanosleep_restart; |
745 | @@ -1319,12 +1348,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) |
746 | return -ERESTART_RESTARTBLOCK; |
747 | } |
748 | |
749 | -long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, |
750 | +long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, |
751 | const enum hrtimer_mode mode, const clockid_t clockid) |
752 | { |
753 | struct restart_block *restart; |
754 | struct hrtimer_sleeper t; |
755 | - ktime_t rem; |
756 | |
757 | hrtimer_init(&t.timer, clockid, mode); |
758 | t.timer.expires = timespec_to_ktime(*rqtp); |
759 | @@ -1336,10 +1364,9 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, |
760 | return -ERESTARTNOHAND; |
761 | |
762 | if (rmtp) { |
763 | - rem = ktime_sub(t.timer.expires, t.timer.base->get_time()); |
764 | - if (rem.tv64 <= 0) |
765 | - return 0; |
766 | - *rmtp = ktime_to_timespec(rem); |
767 | + int ret = update_rmtp(&t.timer, rmtp); |
768 | + if (ret <= 0) |
769 | + return ret; |
770 | } |
771 | |
772 | restart = ¤t_thread_info()->restart_block; |
773 | @@ -1355,8 +1382,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, |
774 | asmlinkage long |
775 | sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) |
776 | { |
777 | - struct timespec tu, rmt; |
778 | - int ret; |
779 | + struct timespec tu; |
780 | |
781 | if (copy_from_user(&tu, rqtp, sizeof(tu))) |
782 | return -EFAULT; |
783 | @@ -1364,15 +1390,7 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) |
784 | if (!timespec_valid(&tu)) |
785 | return -EINVAL; |
786 | |
787 | - ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, |
788 | - CLOCK_MONOTONIC); |
789 | - |
790 | - if (ret && rmtp) { |
791 | - if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) |
792 | - return -EFAULT; |
793 | - } |
794 | - |
795 | - return ret; |
796 | + return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); |
797 | } |
798 | |
799 | /* |
800 | diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c |
801 | index 44019ce..465c69c 100644 |
802 | --- a/kernel/irq/chip.c |
803 | +++ b/kernel/irq/chip.c |
804 | @@ -246,6 +246,17 @@ static unsigned int default_startup(unsigned int irq) |
805 | } |
806 | |
807 | /* |
808 | + * default shutdown function |
809 | + */ |
810 | +static void default_shutdown(unsigned int irq) |
811 | +{ |
812 | + struct irq_desc *desc = irq_desc + irq; |
813 | + |
814 | + desc->chip->mask(irq); |
815 | + desc->status |= IRQ_MASKED; |
816 | +} |
817 | + |
818 | +/* |
819 | * Fixup enable/disable function pointers |
820 | */ |
821 | void irq_chip_set_defaults(struct irq_chip *chip) |
822 | @@ -256,8 +267,15 @@ void irq_chip_set_defaults(struct irq_chip *chip) |
823 | chip->disable = default_disable; |
824 | if (!chip->startup) |
825 | chip->startup = default_startup; |
826 | + /* |
827 | + * We use chip->disable, when the user provided its own. When |
828 | + * we have default_disable set for chip->disable, then we need |
829 | + * to use default_shutdown, otherwise the irq line is not |
830 | + * disabled on free_irq(): |
831 | + */ |
832 | if (!chip->shutdown) |
833 | - chip->shutdown = chip->disable; |
834 | + chip->shutdown = chip->disable != default_disable ? |
835 | + chip->disable : default_shutdown; |
836 | if (!chip->name) |
837 | chip->name = chip->typename; |
838 | if (!chip->end) |
839 | diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c |
840 | index 35b4bbf..9076432 100644 |
841 | --- a/kernel/posix-timers.c |
842 | +++ b/kernel/posix-timers.c |
843 | @@ -766,9 +766,11 @@ common_timer_set(struct k_itimer *timr, int flags, |
844 | /* SIGEV_NONE timers are not queued ! See common_timer_get */ |
845 | if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { |
846 | /* Setup correct expiry time for relative timers */ |
847 | - if (mode == HRTIMER_MODE_REL) |
848 | - timer->expires = ktime_add(timer->expires, |
849 | - timer->base->get_time()); |
850 | + if (mode == HRTIMER_MODE_REL) { |
851 | + timer->expires = |
852 | + ktime_add_safe(timer->expires, |
853 | + timer->base->get_time()); |
854 | + } |
855 | return 0; |
856 | } |
857 | |
858 | @@ -981,20 +983,9 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) |
859 | static int common_nsleep(const clockid_t which_clock, int flags, |
860 | struct timespec *tsave, struct timespec __user *rmtp) |
861 | { |
862 | - struct timespec rmt; |
863 | - int ret; |
864 | - |
865 | - ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL, |
866 | - flags & TIMER_ABSTIME ? |
867 | - HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
868 | - which_clock); |
869 | - |
870 | - if (ret && rmtp) { |
871 | - if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) |
872 | - return -EFAULT; |
873 | - } |
874 | - |
875 | - return ret; |
876 | + return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ? |
877 | + HRTIMER_MODE_ABS : HRTIMER_MODE_REL, |
878 | + which_clock); |
879 | } |
880 | |
881 | asmlinkage long |
882 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c |
883 | index c68f68d..e3e0ee3 100644 |
884 | --- a/kernel/sysctl.c |
885 | +++ b/kernel/sysctl.c |
886 | @@ -910,7 +910,7 @@ static struct ctl_table vm_table[] = { |
887 | .data = &nr_overcommit_huge_pages, |
888 | .maxlen = sizeof(nr_overcommit_huge_pages), |
889 | .mode = 0644, |
890 | - .proc_handler = &proc_doulongvec_minmax, |
891 | + .proc_handler = &hugetlb_overcommit_handler, |
892 | }, |
893 | #endif |
894 | { |
895 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
896 | index db861d8..9c746cb 100644 |
897 | --- a/mm/hugetlb.c |
898 | +++ b/mm/hugetlb.c |
899 | @@ -605,6 +605,16 @@ int hugetlb_treat_movable_handler(struct ctl_table *table, int write, |
900 | return 0; |
901 | } |
902 | |
903 | +int hugetlb_overcommit_handler(struct ctl_table *table, int write, |
904 | + struct file *file, void __user *buffer, |
905 | + size_t *length, loff_t *ppos) |
906 | +{ |
907 | + spin_lock(&hugetlb_lock); |
908 | + proc_doulongvec_minmax(table, write, file, buffer, length, ppos); |
909 | + spin_unlock(&hugetlb_lock); |
910 | + return 0; |
911 | +} |
912 | + |
913 | #endif /* CONFIG_SYSCTL */ |
914 | |
915 | int hugetlb_report_meminfo(char *buf) |
916 | diff --git a/mm/memory.c b/mm/memory.c |
917 | index 4b0144b..da8b74b 100644 |
918 | --- a/mm/memory.c |
919 | +++ b/mm/memory.c |
920 | @@ -980,6 +980,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
921 | int i; |
922 | unsigned int vm_flags; |
923 | |
924 | + if (len <= 0) |
925 | + return 0; |
926 | /* |
927 | * Require read or write permissions. |
928 | * If 'force' is set, we only require the "MAY" flags. |
929 | diff --git a/mm/slub.c b/mm/slub.c |
930 | index 474945e..c432f68 100644 |
931 | --- a/mm/slub.c |
932 | +++ b/mm/slub.c |
933 | @@ -2592,6 +2592,7 @@ EXPORT_SYMBOL(ksize); |
934 | void kfree(const void *x) |
935 | { |
936 | struct page *page; |
937 | + void *object = (void *)x; |
938 | |
939 | if (unlikely(ZERO_OR_NULL_PTR(x))) |
940 | return; |
941 | @@ -2601,7 +2602,7 @@ void kfree(const void *x) |
942 | put_page(page); |
943 | return; |
944 | } |
945 | - slab_free(page->slab, page, (void *)x, __builtin_return_address(0)); |
946 | + slab_free(page->slab, page, object, __builtin_return_address(0)); |
947 | } |
948 | EXPORT_SYMBOL(kfree); |
949 | |
950 | diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c |
951 | index 17f7fb7..2726adc 100644 |
952 | --- a/net/bluetooth/hci_sysfs.c |
953 | +++ b/net/bluetooth/hci_sysfs.c |
954 | @@ -12,6 +12,8 @@ |
955 | #undef BT_DBG |
956 | #define BT_DBG(D...) |
957 | #endif |
958 | +static struct workqueue_struct *btaddconn; |
959 | +static struct workqueue_struct *btdelconn; |
960 | |
961 | static inline char *typetostr(int type) |
962 | { |
963 | @@ -279,6 +281,7 @@ static void add_conn(struct work_struct *work) |
964 | struct hci_conn *conn = container_of(work, struct hci_conn, work); |
965 | int i; |
966 | |
967 | + flush_workqueue(btdelconn); |
968 | if (device_add(&conn->dev) < 0) { |
969 | BT_ERR("Failed to register connection device"); |
970 | return; |
971 | @@ -313,6 +316,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn) |
972 | |
973 | INIT_WORK(&conn->work, add_conn); |
974 | |
975 | + queue_work(btaddconn, &conn->work); |
976 | schedule_work(&conn->work); |
977 | } |
978 | |
979 | @@ -349,6 +353,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn) |
980 | |
981 | INIT_WORK(&conn->work, del_conn); |
982 | |
983 | + queue_work(btdelconn, &conn->work); |
984 | schedule_work(&conn->work); |
985 | } |
986 | |
987 | @@ -398,31 +403,52 @@ int __init bt_sysfs_init(void) |
988 | { |
989 | int err; |
990 | |
991 | + btaddconn = create_singlethread_workqueue("btaddconn"); |
992 | + if (!btaddconn) { |
993 | + err = -ENOMEM; |
994 | + goto out; |
995 | + } |
996 | + btdelconn = create_singlethread_workqueue("btdelconn"); |
997 | + if (!btdelconn) { |
998 | + err = -ENOMEM; |
999 | + goto out_del; |
1000 | + } |
1001 | + |
1002 | bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); |
1003 | - if (IS_ERR(bt_platform)) |
1004 | - return PTR_ERR(bt_platform); |
1005 | + if (IS_ERR(bt_platform)) { |
1006 | + err = PTR_ERR(bt_platform); |
1007 | + goto out_platform; |
1008 | + } |
1009 | |
1010 | err = bus_register(&bt_bus); |
1011 | - if (err < 0) { |
1012 | - platform_device_unregister(bt_platform); |
1013 | - return err; |
1014 | - } |
1015 | + if (err < 0) |
1016 | + goto out_bus; |
1017 | |
1018 | bt_class = class_create(THIS_MODULE, "bluetooth"); |
1019 | if (IS_ERR(bt_class)) { |
1020 | - bus_unregister(&bt_bus); |
1021 | - platform_device_unregister(bt_platform); |
1022 | - return PTR_ERR(bt_class); |
1023 | + err = PTR_ERR(bt_class); |
1024 | + goto out_class; |
1025 | } |
1026 | |
1027 | return 0; |
1028 | + |
1029 | +out_class: |
1030 | + bus_unregister(&bt_bus); |
1031 | +out_bus: |
1032 | + platform_device_unregister(bt_platform); |
1033 | +out_platform: |
1034 | + destroy_workqueue(btdelconn); |
1035 | +out_del: |
1036 | + destroy_workqueue(btaddconn); |
1037 | +out: |
1038 | + return err; |
1039 | } |
1040 | |
1041 | void bt_sysfs_cleanup(void) |
1042 | { |
1043 | + destroy_workqueue(btaddconn); |
1044 | + destroy_workqueue(btdelconn); |
1045 | class_destroy(bt_class); |
1046 | - |
1047 | bus_unregister(&bt_bus); |
1048 | - |
1049 | platform_device_unregister(bt_platform); |
1050 | } |
1051 | diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c |
1052 | index 0dfee27..2f78e1e 100644 |
1053 | --- a/net/ipv4/fib_hash.c |
1054 | +++ b/net/ipv4/fib_hash.c |
1055 | @@ -434,19 +434,43 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) |
1056 | |
1057 | if (fa && fa->fa_tos == tos && |
1058 | fa->fa_info->fib_priority == fi->fib_priority) { |
1059 | - struct fib_alias *fa_orig; |
1060 | + struct fib_alias *fa_first, *fa_match; |
1061 | |
1062 | err = -EEXIST; |
1063 | if (cfg->fc_nlflags & NLM_F_EXCL) |
1064 | goto out; |
1065 | |
1066 | + /* We have 2 goals: |
1067 | + * 1. Find exact match for type, scope, fib_info to avoid |
1068 | + * duplicate routes |
1069 | + * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it |
1070 | + */ |
1071 | + fa_match = NULL; |
1072 | + fa_first = fa; |
1073 | + fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1074 | + list_for_each_entry_continue(fa, &f->fn_alias, fa_list) { |
1075 | + if (fa->fa_tos != tos) |
1076 | + break; |
1077 | + if (fa->fa_info->fib_priority != fi->fib_priority) |
1078 | + break; |
1079 | + if (fa->fa_type == cfg->fc_type && |
1080 | + fa->fa_scope == cfg->fc_scope && |
1081 | + fa->fa_info == fi) { |
1082 | + fa_match = fa; |
1083 | + break; |
1084 | + } |
1085 | + } |
1086 | + |
1087 | if (cfg->fc_nlflags & NLM_F_REPLACE) { |
1088 | struct fib_info *fi_drop; |
1089 | u8 state; |
1090 | |
1091 | - if (fi->fib_treeref > 1) |
1092 | + fa = fa_first; |
1093 | + if (fa_match) { |
1094 | + if (fa == fa_match) |
1095 | + err = 0; |
1096 | goto out; |
1097 | - |
1098 | + } |
1099 | write_lock_bh(&fib_hash_lock); |
1100 | fi_drop = fa->fa_info; |
1101 | fa->fa_info = fi; |
1102 | @@ -469,20 +493,11 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) |
1103 | * uses the same scope, type, and nexthop |
1104 | * information. |
1105 | */ |
1106 | - fa_orig = fa; |
1107 | - fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1108 | - list_for_each_entry_continue(fa, &f->fn_alias, fa_list) { |
1109 | - if (fa->fa_tos != tos) |
1110 | - break; |
1111 | - if (fa->fa_info->fib_priority != fi->fib_priority) |
1112 | - break; |
1113 | - if (fa->fa_type == cfg->fc_type && |
1114 | - fa->fa_scope == cfg->fc_scope && |
1115 | - fa->fa_info == fi) |
1116 | - goto out; |
1117 | - } |
1118 | + if (fa_match) |
1119 | + goto out; |
1120 | + |
1121 | if (!(cfg->fc_nlflags & NLM_F_APPEND)) |
1122 | - fa = fa_orig; |
1123 | + fa = fa_first; |
1124 | } |
1125 | |
1126 | err = -ENOENT; |
1127 | diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c |
1128 | index 1010b46..fd46509 100644 |
1129 | --- a/net/ipv4/fib_trie.c |
1130 | +++ b/net/ipv4/fib_trie.c |
1131 | @@ -1203,20 +1203,45 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1132 | * and we need to allocate a new one of those as well. |
1133 | */ |
1134 | |
1135 | - if (fa && fa->fa_info->fib_priority == fi->fib_priority) { |
1136 | - struct fib_alias *fa_orig; |
1137 | + if (fa && fa->fa_tos == tos && |
1138 | + fa->fa_info->fib_priority == fi->fib_priority) { |
1139 | + struct fib_alias *fa_first, *fa_match; |
1140 | |
1141 | err = -EEXIST; |
1142 | if (cfg->fc_nlflags & NLM_F_EXCL) |
1143 | goto out; |
1144 | |
1145 | + /* We have 2 goals: |
1146 | + * 1. Find exact match for type, scope, fib_info to avoid |
1147 | + * duplicate routes |
1148 | + * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it |
1149 | + */ |
1150 | + fa_match = NULL; |
1151 | + fa_first = fa; |
1152 | + fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1153 | + list_for_each_entry_continue(fa, fa_head, fa_list) { |
1154 | + if (fa->fa_tos != tos) |
1155 | + break; |
1156 | + if (fa->fa_info->fib_priority != fi->fib_priority) |
1157 | + break; |
1158 | + if (fa->fa_type == cfg->fc_type && |
1159 | + fa->fa_scope == cfg->fc_scope && |
1160 | + fa->fa_info == fi) { |
1161 | + fa_match = fa; |
1162 | + break; |
1163 | + } |
1164 | + } |
1165 | + |
1166 | if (cfg->fc_nlflags & NLM_F_REPLACE) { |
1167 | struct fib_info *fi_drop; |
1168 | u8 state; |
1169 | |
1170 | - if (fi->fib_treeref > 1) |
1171 | + fa = fa_first; |
1172 | + if (fa_match) { |
1173 | + if (fa == fa_match) |
1174 | + err = 0; |
1175 | goto out; |
1176 | - |
1177 | + } |
1178 | err = -ENOBUFS; |
1179 | new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); |
1180 | if (new_fa == NULL) |
1181 | @@ -1228,7 +1253,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1182 | new_fa->fa_type = cfg->fc_type; |
1183 | new_fa->fa_scope = cfg->fc_scope; |
1184 | state = fa->fa_state; |
1185 | - new_fa->fa_state &= ~FA_S_ACCESSED; |
1186 | + new_fa->fa_state = state & ~FA_S_ACCESSED; |
1187 | |
1188 | list_replace_rcu(&fa->fa_list, &new_fa->fa_list); |
1189 | alias_free_mem_rcu(fa); |
1190 | @@ -1245,20 +1270,11 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1191 | * uses the same scope, type, and nexthop |
1192 | * information. |
1193 | */ |
1194 | - fa_orig = fa; |
1195 | - list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) { |
1196 | - if (fa->fa_tos != tos) |
1197 | - break; |
1198 | - if (fa->fa_info->fib_priority != fi->fib_priority) |
1199 | - break; |
1200 | - if (fa->fa_type == cfg->fc_type && |
1201 | - fa->fa_scope == cfg->fc_scope && |
1202 | - fa->fa_info == fi) { |
1203 | - goto out; |
1204 | - } |
1205 | - } |
1206 | + if (fa_match) |
1207 | + goto out; |
1208 | + |
1209 | if (!(cfg->fc_nlflags & NLM_F_APPEND)) |
1210 | - fa = fa_orig; |
1211 | + fa = fa_first; |
1212 | } |
1213 | err = -ENOENT; |
1214 | if (!(cfg->fc_nlflags & NLM_F_CREATE)) |
1215 | @@ -1614,9 +1630,8 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) |
1216 | pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t); |
1217 | |
1218 | fa_to_delete = NULL; |
1219 | - fa_head = fa->fa_list.prev; |
1220 | - |
1221 | - list_for_each_entry(fa, fa_head, fa_list) { |
1222 | + fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); |
1223 | + list_for_each_entry_continue(fa, fa_head, fa_list) { |
1224 | struct fib_info *fi = fa->fa_info; |
1225 | |
1226 | if (fa->fa_tos != tos) |
1227 | diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c |
1228 | index e468e7a..6d2979c 100644 |
1229 | --- a/net/ipv4/inet_diag.c |
1230 | +++ b/net/ipv4/inet_diag.c |
1231 | @@ -259,8 +259,10 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, |
1232 | const struct inet_diag_handler *handler; |
1233 | |
1234 | handler = inet_diag_lock_handler(nlh->nlmsg_type); |
1235 | - if (!handler) |
1236 | - return -ENOENT; |
1237 | + if (IS_ERR(handler)) { |
1238 | + err = PTR_ERR(handler); |
1239 | + goto unlock; |
1240 | + } |
1241 | |
1242 | hashinfo = handler->idiag_hashinfo; |
1243 | err = -EINVAL; |
1244 | @@ -708,8 +710,8 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) |
1245 | struct inet_hashinfo *hashinfo; |
1246 | |
1247 | handler = inet_diag_lock_handler(cb->nlh->nlmsg_type); |
1248 | - if (!handler) |
1249 | - goto no_handler; |
1250 | + if (IS_ERR(handler)) |
1251 | + goto unlock; |
1252 | |
1253 | hashinfo = handler->idiag_hashinfo; |
1254 | |
1255 | @@ -838,7 +840,6 @@ done: |
1256 | cb->args[2] = num; |
1257 | unlock: |
1258 | inet_diag_unlock_handler(handler); |
1259 | -no_handler: |
1260 | return skb->len; |
1261 | } |
1262 | |
1263 | diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
1264 | index bc9e575..61c60cf 100644 |
1265 | --- a/net/ipv4/ip_output.c |
1266 | +++ b/net/ipv4/ip_output.c |
1267 | @@ -462,6 +462,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
1268 | if (skb_shinfo(skb)->frag_list) { |
1269 | struct sk_buff *frag; |
1270 | int first_len = skb_pagelen(skb); |
1271 | + int truesizes = 0; |
1272 | |
1273 | if (first_len - hlen > mtu || |
1274 | ((first_len - hlen) & 7) || |
1275 | @@ -485,7 +486,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
1276 | sock_hold(skb->sk); |
1277 | frag->sk = skb->sk; |
1278 | frag->destructor = sock_wfree; |
1279 | - skb->truesize -= frag->truesize; |
1280 | + truesizes += frag->truesize; |
1281 | } |
1282 | } |
1283 | |
1284 | @@ -496,6 +497,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
1285 | frag = skb_shinfo(skb)->frag_list; |
1286 | skb_shinfo(skb)->frag_list = NULL; |
1287 | skb->data_len = first_len - skb_headlen(skb); |
1288 | + skb->truesize -= truesizes; |
1289 | skb->len = first_len; |
1290 | iph->tot_len = htons(first_len); |
1291 | iph->frag_off = htons(IP_MF); |
1292 | diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c |
1293 | index 2c44a94..80cab8c 100644 |
1294 | --- a/net/ipv4/ipcomp.c |
1295 | +++ b/net/ipv4/ipcomp.c |
1296 | @@ -74,6 +74,7 @@ out: |
1297 | |
1298 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
1299 | { |
1300 | + int nexthdr; |
1301 | int err = -ENOMEM; |
1302 | struct ip_comp_hdr *ipch; |
1303 | |
1304 | @@ -84,13 +85,15 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
1305 | |
1306 | /* Remove ipcomp header and decompress original payload */ |
1307 | ipch = (void *)skb->data; |
1308 | + nexthdr = ipch->nexthdr; |
1309 | + |
1310 | skb->transport_header = skb->network_header + sizeof(*ipch); |
1311 | __skb_pull(skb, sizeof(*ipch)); |
1312 | err = ipcomp_decompress(x, skb); |
1313 | if (err) |
1314 | goto out; |
1315 | |
1316 | - err = ipch->nexthdr; |
1317 | + err = nexthdr; |
1318 | |
1319 | out: |
1320 | return err; |
1321 | diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c |
1322 | index bec6fe8..16e04b7 100644 |
1323 | --- a/net/ipv4/sysctl_net_ipv4.c |
1324 | +++ b/net/ipv4/sysctl_net_ipv4.c |
1325 | @@ -248,7 +248,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam |
1326 | |
1327 | tcp_get_available_congestion_control(tbl.data, tbl.maxlen); |
1328 | ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen); |
1329 | - if (ret == 0 && newval && newlen) |
1330 | + if (ret == 1 && newval && newlen) |
1331 | ret = tcp_set_allowed_congestion_control(tbl.data); |
1332 | kfree(tbl.data); |
1333 | |
1334 | diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c |
1335 | index 3268451..152f83d 100644 |
1336 | --- a/net/ipv4/xfrm4_tunnel.c |
1337 | +++ b/net/ipv4/xfrm4_tunnel.c |
1338 | @@ -50,7 +50,7 @@ static struct xfrm_type ipip_type = { |
1339 | |
1340 | static int xfrm_tunnel_rcv(struct sk_buff *skb) |
1341 | { |
1342 | - return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr); |
1343 | + return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr); |
1344 | } |
1345 | |
1346 | static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) |
1347 | diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
1348 | index 3bef30e..2f59baa 100644 |
1349 | --- a/net/ipv6/ip6_output.c |
1350 | +++ b/net/ipv6/ip6_output.c |
1351 | @@ -609,6 +609,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
1352 | |
1353 | if (skb_shinfo(skb)->frag_list) { |
1354 | int first_len = skb_pagelen(skb); |
1355 | + int truesizes = 0; |
1356 | |
1357 | if (first_len - hlen > mtu || |
1358 | ((first_len - hlen) & 7) || |
1359 | @@ -631,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
1360 | sock_hold(skb->sk); |
1361 | frag->sk = skb->sk; |
1362 | frag->destructor = sock_wfree; |
1363 | - skb->truesize -= frag->truesize; |
1364 | + truesizes += frag->truesize; |
1365 | } |
1366 | } |
1367 | |
1368 | @@ -662,6 +663,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
1369 | |
1370 | first_len = skb_pagelen(skb); |
1371 | skb->data_len = first_len - skb_headlen(skb); |
1372 | + skb->truesize -= truesizes; |
1373 | skb->len = first_len; |
1374 | ipv6_hdr(skb)->payload_len = htons(first_len - |
1375 | sizeof(struct ipv6hdr)); |
1376 | diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c |
1377 | index 0cd4056..1c5b09f 100644 |
1378 | --- a/net/ipv6/ipcomp6.c |
1379 | +++ b/net/ipv6/ipcomp6.c |
1380 | @@ -64,6 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list); |
1381 | |
1382 | static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
1383 | { |
1384 | + int nexthdr; |
1385 | int err = -ENOMEM; |
1386 | struct ip_comp_hdr *ipch; |
1387 | int plen, dlen; |
1388 | @@ -79,6 +80,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
1389 | |
1390 | /* Remove ipcomp header and decompress original payload */ |
1391 | ipch = (void *)skb->data; |
1392 | + nexthdr = ipch->nexthdr; |
1393 | + |
1394 | skb->transport_header = skb->network_header + sizeof(*ipch); |
1395 | __skb_pull(skb, sizeof(*ipch)); |
1396 | |
1397 | @@ -108,7 +111,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
1398 | skb->truesize += dlen - plen; |
1399 | __skb_put(skb, dlen - plen); |
1400 | skb_copy_to_linear_data(skb, scratch, dlen); |
1401 | - err = ipch->nexthdr; |
1402 | + err = nexthdr; |
1403 | |
1404 | out_put_cpu: |
1405 | put_cpu(); |
1406 | diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c |
1407 | index 7a3f64c..17ef459 100644 |
1408 | --- a/net/netfilter/nf_conntrack_proto_tcp.c |
1409 | +++ b/net/netfilter/nf_conntrack_proto_tcp.c |
1410 | @@ -135,7 +135,7 @@ enum tcp_bit_set { |
1411 | * CLOSE_WAIT: ACK seen (after FIN) |
1412 | * LAST_ACK: FIN seen (after FIN) |
1413 | * TIME_WAIT: last ACK seen |
1414 | - * CLOSE: closed connection |
1415 | + * CLOSE: closed connection (RST) |
1416 | * |
1417 | * LISTEN state is not used. |
1418 | * |
1419 | @@ -834,8 +834,21 @@ static int tcp_packet(struct nf_conn *conntrack, |
1420 | case TCP_CONNTRACK_SYN_SENT: |
1421 | if (old_state < TCP_CONNTRACK_TIME_WAIT) |
1422 | break; |
1423 | - if ((conntrack->proto.tcp.seen[!dir].flags & |
1424 | - IP_CT_TCP_FLAG_CLOSE_INIT) |
1425 | + /* RFC 1122: "When a connection is closed actively, |
1426 | + * it MUST linger in TIME-WAIT state for a time 2xMSL |
1427 | + * (Maximum Segment Lifetime). However, it MAY accept |
1428 | + * a new SYN from the remote TCP to reopen the connection |
1429 | + * directly from TIME-WAIT state, if..." |
1430 | + * We ignore the conditions because we are in the |
1431 | + * TIME-WAIT state anyway. |
1432 | + * |
1433 | + * Handle aborted connections: we and the server |
1434 | + * think there is an existing connection but the client |
1435 | + * aborts it and starts a new one. |
1436 | + */ |
1437 | + if (((conntrack->proto.tcp.seen[dir].flags |
1438 | + | conntrack->proto.tcp.seen[!dir].flags) |
1439 | + & IP_CT_TCP_FLAG_CLOSE_INIT) |
1440 | || (conntrack->proto.tcp.last_dir == dir |
1441 | && conntrack->proto.tcp.last_index == TCP_RST_SET)) { |
1442 | /* Attempt to reopen a closed/aborted connection. |
1443 | @@ -848,18 +861,25 @@ static int tcp_packet(struct nf_conn *conntrack, |
1444 | } |
1445 | /* Fall through */ |
1446 | case TCP_CONNTRACK_IGNORE: |
1447 | - /* Ignored packets: |
1448 | + /* Ignored packets: |
1449 | + * |
1450 | + * Our connection entry may be out of sync, so ignore |
1451 | + * packets which may signal the real connection between |
1452 | + * the client and the server. |
1453 | * |
1454 | * a) SYN in ORIGINAL |
1455 | * b) SYN/ACK in REPLY |
1456 | * c) ACK in reply direction after initial SYN in original. |
1457 | + * |
1458 | + * If the ignored packet is invalid, the receiver will send |
1459 | + * a RST we'll catch below. |
1460 | */ |
1461 | if (index == TCP_SYNACK_SET |
1462 | && conntrack->proto.tcp.last_index == TCP_SYN_SET |
1463 | && conntrack->proto.tcp.last_dir != dir |
1464 | && ntohl(th->ack_seq) == |
1465 | conntrack->proto.tcp.last_end) { |
1466 | - /* This SYN/ACK acknowledges a SYN that we earlier |
1467 | + /* b) This SYN/ACK acknowledges a SYN that we earlier |
1468 | * ignored as invalid. This means that the client and |
1469 | * the server are both in sync, while the firewall is |
1470 | * not. We kill this session and block the SYN/ACK so |
1471 | @@ -884,7 +904,7 @@ static int tcp_packet(struct nf_conn *conntrack, |
1472 | write_unlock_bh(&tcp_lock); |
1473 | if (LOG_INVALID(IPPROTO_TCP)) |
1474 | nf_log_packet(pf, 0, skb, NULL, NULL, NULL, |
1475 | - "nf_ct_tcp: invalid packed ignored "); |
1476 | + "nf_ct_tcp: invalid packet ignored "); |
1477 | return NF_ACCEPT; |
1478 | case TCP_CONNTRACK_MAX: |
1479 | /* Invalid packet */ |
1480 | @@ -938,8 +958,7 @@ static int tcp_packet(struct nf_conn *conntrack, |
1481 | |
1482 | conntrack->proto.tcp.state = new_state; |
1483 | if (old_state != new_state |
1484 | - && (new_state == TCP_CONNTRACK_FIN_WAIT |
1485 | - || new_state == TCP_CONNTRACK_CLOSE)) |
1486 | + && new_state == TCP_CONNTRACK_FIN_WAIT) |
1487 | conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; |
1488 | timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans |
1489 | && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans |
1490 | diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c |
1491 | index ceda889..4d5ce77 100644 |
1492 | --- a/net/sched/em_meta.c |
1493 | +++ b/net/sched/em_meta.c |
1494 | @@ -719,11 +719,13 @@ static int em_meta_match(struct sk_buff *skb, struct tcf_ematch *m, |
1495 | |
1496 | static inline void meta_delete(struct meta_match *meta) |
1497 | { |
1498 | - struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); |
1499 | + if (meta) { |
1500 | + struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); |
1501 | |
1502 | - if (ops && ops->destroy) { |
1503 | - ops->destroy(&meta->lvalue); |
1504 | - ops->destroy(&meta->rvalue); |
1505 | + if (ops && ops->destroy) { |
1506 | + ops->destroy(&meta->lvalue); |
1507 | + ops->destroy(&meta->rvalue); |
1508 | + } |
1509 | } |
1510 | |
1511 | kfree(meta); |
1512 | diff --git a/net/sched/ematch.c b/net/sched/ematch.c |
1513 | index f3a104e..c856031 100644 |
1514 | --- a/net/sched/ematch.c |
1515 | +++ b/net/sched/ematch.c |
1516 | @@ -305,10 +305,9 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, |
1517 | struct tcf_ematch_tree_hdr *tree_hdr; |
1518 | struct tcf_ematch *em; |
1519 | |
1520 | - if (!rta) { |
1521 | - memset(tree, 0, sizeof(*tree)); |
1522 | + memset(tree, 0, sizeof(*tree)); |
1523 | + if (!rta) |
1524 | return 0; |
1525 | - } |
1526 | |
1527 | if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0) |
1528 | goto errout; |
1529 | diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c |
1530 | index 4bf715d..3a16aba 100644 |
1531 | --- a/security/selinux/ss/services.c |
1532 | +++ b/security/selinux/ss/services.c |
1533 | @@ -2629,7 +2629,6 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) |
1534 | |
1535 | netlbl_sid_to_secattr_failure: |
1536 | POLICY_RDUNLOCK; |
1537 | - netlbl_secattr_destroy(secattr); |
1538 | return rc; |
1539 | } |
1540 | #endif /* CONFIG_NETLABEL */ |