1 Hot Fix 32.7 for Linux Kernel 2.4.30 - 2006/07/28 (interdiff'ed against 32.3)
2 From Willy Tarreau - EXOSEC < wtarreau at exosec.net >
4 http://linux.exosec.net/kernel/2.4-hf/
20 --- linux-2.4.30/arch/x86_64/kernel/process.c 2006-03-18 00:34:06.000000000 +0100
21 +++ linux-2.4.30-hf32.7/arch/x86_64/kernel/process.c 2006-07-28 13:53:36 +0200
23 *next = &next_p->thread;
24 struct tss_struct *tss = init_tss + smp_processor_id();
29 * Reload rsp0, LDT and the page table pointer:
32 loadsegment(ds, next->ds);
35 + * Must be after DS reload for AMD workaround.
43 --- linux-2.4.30/arch/i386/kernel/i387.c 2005-04-14 09:43:32 +0200
44 +++ linux-2.4.30-hf32.7/arch/i386/kernel/i387.c 2006-07-28 13:53:35 +0200
46 #include <linux/config.h>
47 #include <linux/sched.h>
48 #include <linux/init.h>
49 +#include <linux/kernel_stat.h>
50 #include <asm/processor.h>
52 #include <asm/math_emu.h>
54 static inline void __save_init_fpu( struct task_struct *tsk )
57 - asm volatile( "fxsave %0 ; fnclex"
58 + asm volatile( "fxsave %0"
59 : "=m" (tsk->thread.i387.fxsave) );
60 + if (tsk->thread.i387.fxsave.swd & (1<<7))
61 + asm volatile("fnclex");
62 + /* AMD CPUs leak F?P. Clear it here */
63 + asm volatile("ffree %%st(7) ; fildl %0" :: "m" (kstat.context_swtch));
65 asm volatile( "fnsave %0 ; fwait"
66 : "=m" (tsk->thread.i387.fsave) );
67 --- linux-2.4.30/arch/x86_64/kernel/signal.c 2005-01-27 18:57:31 +0100
68 +++ linux-2.4.30-hf32.7/arch/x86_64/kernel/signal.c 2006-07-28 13:53:35 +0200
72 #define COPY(x) err |= __get_user(regs->x, &sc->x)
73 -#define COPY_CANON(x) \
75 - if ((regs->x >> 48) != 0 && (regs->x >> 48) != 0xffff) \
78 /* fs and gs are ignored because we cannot handle the 64bit base easily */
80 - COPY(rdi); COPY(rsi); COPY(rbp); COPY_CANON(rsp); COPY(rbx);
81 - COPY(rdx); COPY(rcx); COPY_CANON(rip);
82 + COPY(rdi); COPY(rsi); COPY(rbp); COPY(rsp); COPY(rbx);
83 + COPY(rdx); COPY(rcx);
85 + if (regs->rip >= TASK_SIZE && regs->rip < VSYSCALL_START) {
93 regs->rdx = (unsigned long)&frame->uc;
94 regs->rsp = (unsigned long) frame;
95 regs->rip = (unsigned long) ka->sa.sa_handler;
96 + if (regs->rip >= TASK_SIZE) {
98 + ka->sa.sa_handler = SIG_DFL;
101 regs->cs = __USER_CS;
102 regs->ss = __USER_DS;
104 --- linux-2.4.30/drivers/acpi/system.c 2004-11-17 12:54:21 +0100
105 +++ linux-2.4.30-hf32.7/drivers/acpi/system.c 2006-07-28 13:53:35 +0200
108 state = simple_strtoul(state_string, NULL, 0);
110 - if (!system->states[state])
111 + if (state >= ACPI_S_STATE_COUNT || !system->states[state])
112 return_VALUE(-ENODEV);
115 --- linux-2.4.30/drivers/cdrom/cdrom.c 2005-01-27 18:57:31 +0100
116 +++ linux-2.4.30-hf32.7/drivers/cdrom/cdrom.c 2006-07-28 13:53:35 +0200
117 @@ -1259,7 +1259,7 @@
118 init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
119 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
120 cgc.cmd[7] = s->type;
121 - cgc.cmd[9] = cgc.buflen = 0xff;
122 + cgc.cmd[9] = cgc.buflen & 0xff;
124 if ((ret = cdo->generic_packet(cdi, &cgc)))
126 --- linux-2.4.30/drivers/net/via-rhine.c 2004-08-08 01:26:05 +0200
127 +++ linux-2.4.30-hf32.7/drivers/net/via-rhine.c 2006-07-28 13:53:35 +0200
130 LK1.1.19 (Roger Luethi)
131 - Increase Tx threshold for unspecified errors
132 + - Craig Brind: Zero padded aligned buffers for short packets
136 @@ -1308,10 +1309,14 @@
137 np->stats.tx_dropped++;
140 + /* Padding is not copied and so must be redone. */
141 skb_copy_and_csum_dev(skb, np->tx_buf[entry]);
142 + if (skb->len < ETH_ZLEN)
143 + memset(np->tx_buf[entry] + skb->len, 0,
144 + ETH_ZLEN - skb->len);
145 np->tx_skbuff_dma[entry] = 0;
146 np->tx_ring[entry].addr = cpu_to_le32(np->tx_bufs_dma +
147 - (np->tx_buf[entry] - np->tx_bufs));
148 + (np->tx_buf[entry] - np->tx_bufs));
150 np->tx_skbuff_dma[entry] =
151 pci_map_single(np->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
152 --- linux-2.4.30/drivers/usb/gadget/rndis.c 2005-01-27 18:57:33 +0100
153 +++ linux-2.4.30-hf32.7/drivers/usb/gadget/rndis.c 2006-07-28 13:53:35 +0200
157 * we need more memory:
158 - * oid_supported_list is the largest answer
159 + * gen_ndis_query_resp expects enough space for
160 + * rndis_query_cmplt_type followed by data.
161 + * oid_supported_list is the largest data reply
163 - r = rndis_add_response (configNr, sizeof (oid_supported_list));
164 + r = rndis_add_response (configNr,
165 + sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type));
167 if (!r) return -ENOMEM;
168 resp = (rndis_query_cmplt_type *) r->buf;
169 --- linux-2.4.30/fs/ext2/namei.c 2001-10-04 07:57:36 +0200
170 +++ linux-2.4.30-hf32.7/fs/ext2/namei.c 2006-07-28 13:53:36 +0200
172 ext2_inc_count(new_dir);
176 + * Like most other Unix systems, set the ctime for inodes on a
177 + * rename. Note that other 2.4 FS as well as EXT2 on 2.2 and 2.6
178 + * do this. ext2_dec_count() will mark the inode dirty.
180 + old_inode->i_ctime = CURRENT_TIME;
182 ext2_delete_entry (old_de, old_page);
183 ext2_dec_count(old_inode);
185 --- linux-2.4.30/fs/ext3/inode.c 2004-08-08 01:26:05 +0200
186 +++ linux-2.4.30-hf32.7/fs/ext3/inode.c 2006-07-28 13:53:36 +0200
189 branch[0].key = cpu_to_le32(parent);
192 for (n = 1; n < num; n++) {
193 struct buffer_head *bh;
194 /* Allocate the next block */
195 --- linux-2.4.30/fs/jbd/recovery.c 2003-06-13 16:51:37 +0200
196 +++ linux-2.4.30-hf32.7/fs/jbd/recovery.c 2006-07-28 13:53:35 +0200
201 - J_ASSERT (offset < journal->j_maxlen);
203 + if (offset >= journal->j_maxlen) {
204 + printk(KERN_ERR "JBD: corrupted journal superblock\n");
208 err = journal_bmap(journal, offset, &blocknr);
213 jbd_debug(3, "Unrecognised magic %d, end of scan.\n",
219 --- linux-2.4.30/fs/namei.c 2005-04-14 09:43:34 +0200
220 +++ linux-2.4.30-hf32.7/fs/namei.c 2006-07-28 13:53:35 +0200
221 @@ -1478,27 +1478,34 @@
222 int vfs_unlink(struct inode *dir, struct dentry *dentry)
225 + struct inode *inode;
227 - down(&dir->i_zombie);
228 error = may_delete(dir, dentry, 0);
231 - if (dir->i_op && dir->i_op->unlink) {
233 - if (d_mountpoint(dentry))
237 - error = dir->i_op->unlink(dir, dentry);
245 + inode = dentry->d_inode;
246 + atomic_inc(&inode->i_count);
247 + double_down(&dir->i_zombie, &inode->i_zombie);
250 + if (dir->i_op && dir->i_op->unlink) {
252 + if (d_mountpoint(dentry))
256 + error = dir->i_op->unlink(dir, dentry);
260 - up(&dir->i_zombie);
262 + double_up(&dir->i_zombie, &inode->i_zombie);
267 inode_dir_notify(dir, DN_DELETE);
272 @@ -1607,18 +1614,19 @@
276 - down(&dir->i_zombie);
278 inode = old_dentry->d_inode;
282 - error = may_create(dir, new_dentry);
288 if (dir->i_dev != inode->i_dev)
291 + double_down(&dir->i_zombie, &old_dentry->d_inode->i_zombie);
293 + error = may_create(dir, new_dentry);
298 @@ -1636,9 +1644,10 @@
302 - up(&dir->i_zombie);
303 + double_up(&dir->i_zombie, &old_dentry->d_inode->i_zombie);
305 inode_dir_notify(dir, DN_CREATE);
310 --- linux-2.4.30/fs/nfs/inode.c 2004-04-14 15:05:40 +0200
311 +++ linux-2.4.30-hf32.7/fs/nfs/inode.c 2006-07-28 13:53:36 +0200
312 @@ -1047,6 +1047,13 @@
316 + /* set the invalid flag if the last attempt at invalidating
317 + * the inode didn't empty the clean_pages list */
318 + if ( NFS_FLAGS(inode) & NFS_INO_MAPPED) {
319 + NFS_FLAGS(inode) &= ~NFS_INO_MAPPED;
324 * If we have pending writebacks, things can get
326 @@ -1092,6 +1099,12 @@
327 NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
328 NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
329 invalidate_inode_pages(inode);
330 + if (! list_empty(&inode->i_mapping->clean_pages)) {
331 + dfprintk(PAGECACHE,
332 + "NFS: clean_pages for %x/%ld is not empty\n",
333 + inode->i_dev, inode->i_ino);
334 + NFS_FLAGS(inode) |= NFS_INO_MAPPED;
336 memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
337 } else if (time_after(jiffies, NFS_ATTRTIMEO_UPDATE(inode)+NFS_ATTRTIMEO(inode))) {
338 if ((NFS_ATTRTIMEO(inode) <<= 1) > NFS_MAXATTRTIMEO(inode))
339 --- linux-2.4.30/fs/partitions/msdos.c 2002-11-29 00:53:15 +0100
340 +++ linux-2.4.30-hf32.7/fs/partitions/msdos.c 2006-07-28 13:53:36 +0200
342 put_dev_sector(sect);
346 + * Now that the 55aa signature is present, this is probably
347 + * either the boot sector of a FAT filesystem or a DOS-type
348 + * partition table. Reject this in case the boot indicator
349 + * is not 0 or 0x80.
351 + p = (struct partition *) (data + 0x1be);
352 + for (i = 1; i <= 4; i++, p++) {
353 + if (p->boot_ind != 0 && p->boot_ind != 0x80) {
354 + put_dev_sector(sect);
358 p = (struct partition *) (data + 0x1be);
361 --- linux-2.4.30/fs/quota_v2.c 2003-08-25 13:44:43 +0200
362 +++ linux-2.4.30-hf32.7/fs/quota_v2.c 2006-07-28 13:53:36 +0200
364 #include <asm/byteorder.h>
365 #include <asm/uaccess.h>
367 +MODULE_AUTHOR("Jan Kara");
368 +MODULE_DESCRIPTION("Quota format v2 support");
369 +MODULE_LICENSE("GPL");
371 #define __QUOTA_V2_PARANOIA
373 typedef char *dqbuf_t;
374 --- linux-2.4.30/fs/smbfs/dir.c 2004-02-18 14:36:31 +0100
375 +++ linux-2.4.30-hf32.7/fs/smbfs/dir.c 2006-07-28 13:53:35 +0200
377 if (dentry->d_name.len > SMB_MAXNAMELEN)
380 + /* Do not allow lookup of names with backslashes in */
382 + if (memchr(dentry->d_name.name, '\\', dentry->d_name.len))
385 error = smb_proc_getattr(dentry, &finfo);
386 #ifdef SMBFS_PARANOIA
387 if (error && error != -ENOENT)
388 --- linux-2.4.30/include/asm-x86_64/i387.h 2004-08-08 01:26:06 +0200
389 +++ linux-2.4.30-hf32.7/include/asm-x86_64/i387.h 2006-07-28 13:53:35 +0200
392 static inline void save_init_fpu( struct task_struct *tsk )
394 - asm volatile( "fxsave %0 ; fnclex"
395 + asm volatile( "fxsave %0"
396 : "=m" (tsk->thread.i387.fxsave));
397 + if (tsk->thread.i387.fxsave.swd & (1<<7))
398 + asm volatile("fnclex");
399 + /* AMD CPUs leak F?P through FXSAVE. Clear it here */
400 + asm volatile("ffree %st(7) ; fildl %gs:0");
401 tsk->flags &= ~PF_USEDFPU;
404 --- linux-2.4.30/include/linux/nfs_fs_i.h 2006-07-18 18:23:37 +0200
405 +++ linux-2.4.30-hf32.7/include/linux/nfs_fs_i.h 2006-07-28 13:53:36 +0200
407 #define NFS_INO_REVALIDATING 0x0004 /* revalidating attrs */
408 #define NFS_IS_SNAPSHOT 0x0010 /* a snapshot file */
409 #define NFS_INO_FLUSH 0x0020 /* inode is due for flushing */
410 +#define NFS_INO_MAPPED 0x0040 /* page invalidation failed */
414 --- linux-2.4.30/include/net/sctp/sctp.h 2006-06-19 18:47:31 +0200
415 +++ linux-2.4.30-hf32.7/include/net/sctp/sctp.h 2006-07-28 13:53:35 +0200
416 @@ -466,12 +466,12 @@
417 * there is room for a param header too.
419 #define sctp_walk_params(pos, chunk, member)\
420 -_sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)), member)
421 +_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
423 #define _sctp_walk_params(pos, chunk, end, member)\
424 for (pos.v = chunk->member;\
425 pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
426 - pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\
427 + pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
428 ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
429 pos.v += WORD_ROUND(ntohs(pos.p->length)))
432 for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
433 sizeof(sctp_chunkhdr_t));\
434 (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
435 - (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\
436 + (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
437 ntohs(err->length) >= sizeof(sctp_errhdr_t); \
438 err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
440 --- linux-2.4.30/ipc/shm.c 2002-08-03 02:39:46 +0200
441 +++ linux-2.4.30-hf32.7/ipc/shm.c 2006-07-28 13:53:35 +0200
444 UPDATE_ATIME(file->f_dentry->d_inode);
445 vma->vm_ops = &shm_vm_ops;
446 + if (!(vma->vm_flags & VM_WRITE))
447 + vma->vm_flags &= ~VM_MAYWRITE;
448 shm_inc(file->f_dentry->d_inode->i_ino);
451 --- linux-2.4.30/net/8021q/vlan.c 2004-02-18 14:36:32 +0100
452 +++ linux-2.4.30-hf32.7/net/8021q/vlan.c 2006-07-28 13:53:36 +0200
455 case GET_VLAN_REALDEV_NAME_CMD:
456 err = vlan_dev_get_realdev_name(args.device1, args.u.device2);
459 if (copy_to_user((void*)arg, &args,
460 sizeof(struct vlan_ioctl_args))) {
464 case GET_VLAN_VID_CMD:
465 err = vlan_dev_get_vid(args.device1, &vid);
469 if (copy_to_user((void*)arg, &args,
470 sizeof(struct vlan_ioctl_args))) {
472 __FUNCTION__, args.cmd);
480 --- linux-2.4.30/net/core/ethtool.c 2004-08-08 01:26:06 +0200
481 +++ linux-2.4.30-hf32.7/net/core/ethtool.c 2006-07-28 13:53:35 +0200
484 struct ethtool_coalesce coalesce;
486 - if (!dev->ethtool_ops->get_coalesce)
487 + if (!dev->ethtool_ops->set_coalesce)
490 if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
493 struct ethtool_pauseparam pauseparam;
495 - if (!dev->ethtool_ops->get_pauseparam)
496 + if (!dev->ethtool_ops->set_pauseparam)
499 if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam)))
500 --- linux-2.4.30/net/core/neighbour.c 2005-04-14 09:43:35 +0200
501 +++ linux-2.4.30-hf32.7/net/core/neighbour.c 2006-07-28 13:53:36 +0200
503 * Vitaly E. Lavrov releasing NULL neighbor in neigh_add.
504 * Harald Welte Add neighbour cache statistics like rtstat
505 * Harald Welte port neighbour cache rework from 2.6.9-rcX
506 + * Pradeep Vincent Move neighbour cache entry to stale state
509 #include <linux/config.h>
515 + /* Mark it stale - To be reconfirmed later when used */
516 + if (n->nud_state & NUD_REACHABLE &&
517 + now - n->confirmed > n->parms->reachable_time) {
518 + n->nud_state = NUD_STALE;
522 write_unlock(&n->lock);
525 --- linux-2.4.30/net/ipv4/netfilter/arp_tables.c 2004-11-17 12:54:22 +0100
526 +++ linux-2.4.30-hf32.7/net/ipv4/netfilter/arp_tables.c 2006-07-28 13:53:35 +0200
528 if (len != sizeof(tmp) + tmp.size)
531 + /* overflow check */
532 + if (tmp.size >= (INT_MAX - sizeof(struct arpt_table_info)) / NR_CPUS -
535 + if (tmp.num_counters >= INT_MAX / sizeof(struct arpt_counters))
538 /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
539 if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
544 write_lock_bh(&t->lock);
545 - if (t->private->number != paddc->num_counters) {
546 + if (t->private->number != tmp.num_counters) {
550 --- linux-2.4.30/net/ipv4/netfilter/ip_nat_snmp_basic.c 2004-11-17 12:54:22 +0100
551 +++ linux-2.4.30-hf32.7/net/ipv4/netfilter/ip_nat_snmp_basic.c 2006-07-28 13:53:35 +0200
552 @@ -996,12 +996,12 @@
557 + kfree((unsigned long *)trap->ip_address);
563 - kfree((unsigned long *)trap->ip_address);
568 @@ -1119,11 +1119,10 @@
569 struct snmp_v1_trap trap;
570 unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
572 - /* Discard trap allocations regardless */
574 - kfree((unsigned long *)trap.ip_address);
579 + kfree((unsigned long *)trap.ip_address);
584 --- linux-2.4.30/net/ipv4/netfilter/ip_tables.c 2005-04-14 09:43:35 +0200
585 +++ linux-2.4.30-hf32.7/net/ipv4/netfilter/ip_tables.c 2006-07-28 13:53:35 +0200
586 @@ -1066,6 +1066,13 @@
587 if (len != sizeof(tmp) + tmp.size)
590 + /* overflow check */
591 + if (tmp.size >= (INT_MAX - sizeof(struct ipt_table_info)) / NR_CPUS -
594 + if (tmp.num_counters >= INT_MAX / sizeof(struct ipt_counters))
597 /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
598 if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
600 @@ -1195,7 +1202,7 @@
603 write_lock_bh(&t->lock);
604 - if (t->private->number != paddc->num_counters) {
605 + if (t->private->number != tmp.num_counters) {
609 --- linux-2.4.30/net/ipv4/netfilter/ipt_recent.c 2005-04-14 09:43:35 +0200
610 +++ linux-2.4.30-hf32.7/net/ipv4/netfilter/ipt_recent.c 2006-07-28 13:53:35 +0200
612 /* Create our proc 'status' entry. */
613 curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent);
614 if (!curr_table->status_proc) {
616 printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n");
617 /* Destroy the created table */
618 spin_lock_bh(&recent_lock);
620 spin_unlock_bh(&recent_lock);
621 vfree(curr_table->time_info);
622 vfree(curr_table->hash_table);
624 vfree(curr_table->table);
627 --- linux-2.4.30/net/ipv4/route.c 2004-11-17 12:54:22 +0100
628 +++ linux-2.4.30-hf32.7/net/ipv4/route.c 2006-07-28 13:53:35 +0200
629 @@ -2214,7 +2214,10 @@
630 /* Reserve room for dummy headers, this skb can pass
631 through good chunk of routing engine.
633 - skb->mac.raw = skb->data;
634 + skb->mac.raw = skb->nh.raw = skb->data;
636 + /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */
637 + skb->nh.iph->protocol = IPPROTO_ICMP;
638 skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
640 if (rta[RTA_SRC - 1])
641 --- linux-2.4.30/net/ipv6/netfilter/ip6_tables.c 2005-04-14 09:43:35 +0200
642 +++ linux-2.4.30-hf32.7/net/ipv6/netfilter/ip6_tables.c 2006-07-28 13:53:35 +0200
643 @@ -1151,6 +1151,13 @@
644 if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
647 + /* overflow check */
648 + if (tmp.size >= (INT_MAX - sizeof(struct ip6t_table_info)) / NR_CPUS -
651 + if (tmp.num_counters >= INT_MAX / sizeof(struct ip6t_counters))
654 newinfo = vmalloc(sizeof(struct ip6t_table_info)
655 + SMP_ALIGN(tmp.size) * smp_num_cpus);
657 @@ -1276,7 +1283,7 @@
660 write_lock_bh(&t->lock);
661 - if (t->private->number != paddc->num_counters) {
662 + if (t->private->number != tmp.num_counters) {
666 --- linux-2.4.30/net/sctp/sm_statefuns.c 2005-01-27 18:57:34 +0100
667 +++ linux-2.4.30-hf32.7/net/sctp/sm_statefuns.c 2006-07-28 13:53:35 +0200
670 chunk->subh.cookie_hdr =
671 (struct sctp_signed_cookie *)chunk->skb->data;
672 - skb_pull(chunk->skb,
673 - ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
674 + if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
675 + sizeof(sctp_chunkhdr_t)))
678 /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint
679 * "Z" will reply with a COOKIE ACK chunk after building a TCB
682 chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
683 paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
684 - skb_pull(chunk->skb, paylen);
685 + if (!pskb_pull(chunk->skb, paylen))
688 reply = sctp_make_heartbeat_ack(asoc, chunk,
689 chunk->subh.hb_hdr, paylen);
690 @@ -1012,6 +1014,12 @@
693 hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
694 + /* Make sure that the length of the parameter is what we expect */
695 + if (ntohs(hbinfo->param_hdr.length) !=
696 + sizeof(sctp_sender_hb_info_t)) {
697 + return SCTP_DISPOSITION_DISCARD;
700 from_addr = hbinfo->daddr;
701 link = sctp_assoc_lookup_paddr(asoc, &from_addr);
703 @@ -1832,8 +1840,9 @@
706 chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
707 - skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
708 - sizeof(sctp_chunkhdr_t));
709 + if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
710 + sizeof(sctp_chunkhdr_t)))
713 /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
714 * of a duplicate COOKIE ECHO match the Verification Tags of the
715 --- linux-2.4.30/net/sctp/sm_statetable.c 2005-01-27 18:57:34 +0100
716 +++ linux-2.4.30-hf32.7/net/sctp/sm_statetable.c 2006-07-28 13:53:35 +0200
718 /* SCTP_STATE_EMPTY */ \
719 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
720 /* SCTP_STATE_CLOSED */ \
721 - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
722 + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
723 /* SCTP_STATE_COOKIE_WAIT */ \
724 - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
725 + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
726 /* SCTP_STATE_COOKIE_ECHOED */ \
727 {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
728 /* SCTP_STATE_ESTABLISHED */ \
730 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
731 {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
732 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
733 - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
734 + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
735 } /* TYPE_SCTP_ECN_ECNE */
737 #define TYPE_SCTP_ECN_CWR { \
739 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
740 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
741 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
742 - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
743 + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
744 } /* TYPE_SCTP_ECN_CWR */
746 #define TYPE_SCTP_SHUTDOWN_COMPLETE { \
748 /* SCTP_STATE_EMPTY */ \
749 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
750 /* SCTP_STATE_CLOSED */ \
751 - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
752 + {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
753 /* SCTP_STATE_COOKIE_WAIT */ \
754 {.fn = sctp_sf_do_prm_requestheartbeat, \
755 .name = "sctp_sf_do_prm_requestheartbeat"}, \
756 --- linux-2.4.30/net/sctp/ulpqueue.c 2005-01-27 18:57:34 +0100
757 +++ linux-2.4.30-hf32.7/net/sctp/ulpqueue.c 2006-07-28 13:53:35 +0200
759 static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff *f_frag, struct sk_buff *l_frag)
762 + struct sk_buff *new = NULL;
763 struct sctp_ulpevent *event;
764 struct sk_buff *pnext, *last;
765 struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
766 @@ -291,11 +292,33 @@
771 - skb_shinfo(f_frag)->frag_list = pos;
773 + if (skb_cloned(f_frag)) {
774 + /* This is a cloned skb, we can't just modify
775 + * the frag_list. We need a new skb to do that.
776 + * Instead of calling skb_unshare(), we'll do it
777 + * ourselves since we need to delay the free.
779 + new = skb_copy(f_frag, GFP_ATOMIC);
781 + return NULL; /* try again later */
783 + new->sk = f_frag->sk;
785 + skb_shinfo(new)->frag_list = pos;
787 + skb_shinfo(f_frag)->frag_list = pos;
790 /* Remove the first fragment from the reassembly queue. */
791 __skb_unlink(f_frag, f_frag->list);
793 + /* if we did unshare, then free the old skb and re-assign */
802 --- linux-2.4.30/scripts/ver_linux 2004-02-18 14:36:32 +0100
803 +++ linux-2.4.30-hf32.7/scripts/ver_linux 2006-07-28 13:53:36 +0200
805 '/GNU Make/{print "Gnu make ",$NF}'
807 ld -v 2>&1 | awk -F\) '{print $1}' | awk \
808 - '/BFD/{print "binutils ",$NF}'
809 + '/BFD/{print "binutils ",$NF} \
810 + /^GNU/{print "binutils ",$4}'
812 fdformat --version | awk -F\- '{print "util-linux ", $NF}'