From: Imre Kaloz Date: Thu, 24 Aug 2006 10:40:14 +0000 (+0000) Subject: add new hotfixes patch X-Git-Tag: whiterussian_rc6~161 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=094891377424a2cb593afc88a59b5bf2a842960b;p=openwrt%2Fsvn-archive%2Fopenwrt.git add new hotfixes patch SVN-Revision: 4649 --- diff --git a/openwrt/target/linux/linux-2.4/patches/generic/902-hot_fixes-32.7.patch b/openwrt/target/linux/linux-2.4/patches/generic/902-hot_fixes-32.7.patch new file mode 100644 index 0000000000..6c79469780 --- /dev/null +++ b/openwrt/target/linux/linux-2.4/patches/generic/902-hot_fixes-32.7.patch @@ -0,0 +1,813 @@ +Hot Fix 32.7 for Linux Kernel 2.4.30 - 2006/07/28 (interdiff'ed against 32.3) +From Willy Tarreau - EXOSEC < wtarreau at exosec.net > + +http://linux.exosec.net/kernel/2.4-hf/ + +- CVE-2006-0741 +- CVE-2006-1524 +- CVE-2006-1056 +- CVE-2006-1864 +- CVE-2006-2444 +- CVE-2006-0039 +- CVE-2006-1525 +- CVE-2006-1857 +- CVE-2006-1858 +- CVE-2006-2271 +- CVE-2006-2272 +- CVE-2006-2274 +- CVE-2006-2935 + +--- linux-2.4.30/arch/x86_64/kernel/process.c 2006-03-18 00:34:06.000000000 +0100 ++++ linux-2.4.30-hf32.7/arch/x86_64/kernel/process.c 2006-07-28 13:53:36 +0200 +@@ -565,8 +565,6 @@ + *next = &next_p->thread; + struct tss_struct *tss = init_tss + smp_processor_id(); + +- unlazy_fpu(prev_p); +- + /* + * Reload rsp0, LDT and the page table pointer: + */ +@@ -584,6 +582,11 @@ + loadsegment(ds, next->ds); + + /* ++ * Must be after DS reload for AMD workaround. ++ */ ++ unlazy_fpu(prev_p); ++ ++ /* + * Switch FS and GS. + */ + { +--- linux-2.4.30/arch/i386/kernel/i387.c 2005-04-14 09:43:32 +0200 ++++ linux-2.4.30-hf32.7/arch/i386/kernel/i387.c 2006-07-28 13:53:35 +0200 +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -70,8 +71,12 @@ + static inline void __save_init_fpu( struct task_struct *tsk ) + { + if ( cpu_has_fxsr ) { +- asm volatile( "fxsave %0 ; fnclex" ++ asm volatile( "fxsave %0" + : "=m" (tsk->thread.i387.fxsave) ); ++ if (tsk->thread.i387.fxsave.swd & (1<<7)) ++ asm volatile("fnclex"); ++ /* AMD CPUs leak F?P. Clear it here */ ++ asm volatile("ffree %%st(7) ; fildl %0" :: "m" (kstat.context_swtch)); + } else { + asm volatile( "fnsave %0 ; fwait" + : "=m" (tsk->thread.i387.fsave) ); +--- linux-2.4.30/arch/x86_64/kernel/signal.c 2005-01-27 18:57:31 +0100 ++++ linux-2.4.30-hf32.7/arch/x86_64/kernel/signal.c 2006-07-28 13:53:35 +0200 +@@ -137,15 +137,16 @@ + + + #define COPY(x) err |= __get_user(regs->x, &sc->x) +-#define COPY_CANON(x) \ +- COPY(x); \ +- if ((regs->x >> 48) != 0 && (regs->x >> 48) != 0xffff) \ +- regs->x = 0; + + /* fs and gs are ignored because we cannot handle the 64bit base easily */ + +- COPY(rdi); COPY(rsi); COPY(rbp); COPY_CANON(rsp); COPY(rbx); +- COPY(rdx); COPY(rcx); COPY_CANON(rip); ++ COPY(rdi); COPY(rsi); COPY(rbp); COPY(rsp); COPY(rbx); ++ COPY(rdx); COPY(rcx); ++ COPY(rip); ++ if (regs->rip >= TASK_SIZE && regs->rip < VSYSCALL_START) { ++ regs->rip = 0; ++ return -EFAULT; ++ } + COPY(r8); + COPY(r9); + COPY(r10); +@@ -357,6 +358,11 @@ + regs->rdx = (unsigned long)&frame->uc; + regs->rsp = (unsigned long) frame; + regs->rip = (unsigned long) ka->sa.sa_handler; ++ if (regs->rip >= TASK_SIZE) { ++ if (sig == SIGSEGV) ++ ka->sa.sa_handler = SIG_DFL; ++ regs->rip = 0; ++ } + regs->cs = __USER_CS; + regs->ss = __USER_DS; + +--- linux-2.4.30/drivers/acpi/system.c 2004-11-17 12:54:21 +0100 ++++ linux-2.4.30-hf32.7/drivers/acpi/system.c 2006-07-28 13:53:35 +0200 +@@ -748,7 +748,7 @@ + + state = simple_strtoul(state_string, NULL, 0); + +- if (!system->states[state]) ++ if (state >= ACPI_S_STATE_COUNT || !system->states[state]) + return_VALUE(-ENODEV); + + /* +--- linux-2.4.30/drivers/cdrom/cdrom.c 2005-01-27 18:57:31 +0100 ++++ linux-2.4.30-hf32.7/drivers/cdrom/cdrom.c 2006-07-28 13:53:35 +0200 +@@ -1259,7 +1259,7 @@ + init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); + cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; + cgc.cmd[7] = s->type; +- cgc.cmd[9] = cgc.buflen = 0xff; ++ cgc.cmd[9] = cgc.buflen & 0xff; + + if ((ret = cdo->generic_packet(cdi, &cgc))) + return ret; +--- linux-2.4.30/drivers/net/via-rhine.c 2004-08-08 01:26:05 +0200 ++++ linux-2.4.30-hf32.7/drivers/net/via-rhine.c 2006-07-28 13:53:35 +0200 +@@ -124,6 +124,7 @@ + + LK1.1.19 (Roger Luethi) + - Increase Tx threshold for unspecified errors ++ - Craig Brind: Zero padded aligned buffers for short packets + + */ + +@@ -1308,10 +1309,14 @@ + np->stats.tx_dropped++; + return 0; + } ++ /* Padding is not copied and so must be redone. */ + skb_copy_and_csum_dev(skb, np->tx_buf[entry]); ++ if (skb->len < ETH_ZLEN) ++ memset(np->tx_buf[entry] + skb->len, 0, ++ ETH_ZLEN - skb->len); + np->tx_skbuff_dma[entry] = 0; + np->tx_ring[entry].addr = cpu_to_le32(np->tx_bufs_dma + +- (np->tx_buf[entry] - np->tx_bufs)); ++ (np->tx_buf[entry] - np->tx_bufs)); + } else { + np->tx_skbuff_dma[entry] = + pci_map_single(np->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); +--- linux-2.4.30/drivers/usb/gadget/rndis.c 2005-01-27 18:57:33 +0100 ++++ linux-2.4.30-hf32.7/drivers/usb/gadget/rndis.c 2006-07-28 13:53:35 +0200 +@@ -853,9 +853,12 @@ + + /* + * we need more memory: +- * oid_supported_list is the largest answer ++ * gen_ndis_query_resp expects enough space for ++ * rndis_query_cmplt_type followed by data. ++ * oid_supported_list is the largest data reply + */ +- r = rndis_add_response (configNr, sizeof (oid_supported_list)); ++ r = rndis_add_response (configNr, ++ sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type)); + + if (!r) return -ENOMEM; + resp = (rndis_query_cmplt_type *) r->buf; +--- linux-2.4.30/fs/ext2/namei.c 2001-10-04 07:57:36 +0200 ++++ linux-2.4.30-hf32.7/fs/ext2/namei.c 2006-07-28 13:53:36 +0200 +@@ -313,6 +313,13 @@ + ext2_inc_count(new_dir); + } + ++ /* ++ * Like most other Unix systems, set the ctime for inodes on a ++ * rename. Note that other 2.4 FS as well as EXT2 on 2.2 and 2.6 ++ * do this. ext2_dec_count() will mark the inode dirty. ++ */ ++ old_inode->i_ctime = CURRENT_TIME; ++ + ext2_delete_entry (old_de, old_page); + ext2_dec_count(old_inode); + +--- linux-2.4.30/fs/ext3/inode.c 2004-08-08 01:26:05 +0200 ++++ linux-2.4.30-hf32.7/fs/ext3/inode.c 2006-07-28 13:53:36 +0200 +@@ -570,6 +570,7 @@ + + branch[0].key = cpu_to_le32(parent); + if (parent) { ++ keys = 1; + for (n = 1; n < num; n++) { + struct buffer_head *bh; + /* Allocate the next block */ +--- linux-2.4.30/fs/jbd/recovery.c 2003-06-13 16:51:37 +0200 ++++ linux-2.4.30-hf32.7/fs/jbd/recovery.c 2006-07-28 13:53:35 +0200 +@@ -138,8 +138,11 @@ + + *bhp = NULL; + +- J_ASSERT (offset < journal->j_maxlen); +- ++ if (offset >= journal->j_maxlen) { ++ printk(KERN_ERR "JBD: corrupted journal superblock\n"); ++ return -EIO; ++ } ++ + err = journal_bmap(journal, offset, &blocknr); + + if (err) { +@@ -534,6 +537,7 @@ + default: + jbd_debug(3, "Unrecognised magic %d, end of scan.\n", + blocktype); ++ brelse(bh); + goto done; + } + } +--- linux-2.4.30/fs/namei.c 2005-04-14 09:43:34 +0200 ++++ linux-2.4.30-hf32.7/fs/namei.c 2006-07-28 13:53:35 +0200 +@@ -1478,27 +1478,34 @@ + int vfs_unlink(struct inode *dir, struct dentry *dentry) + { + int error; ++ struct inode *inode; + +- down(&dir->i_zombie); + error = may_delete(dir, dentry, 0); +- if (!error) { +- error = -EPERM; +- if (dir->i_op && dir->i_op->unlink) { +- DQUOT_INIT(dir); +- if (d_mountpoint(dentry)) +- error = -EBUSY; +- else { +- lock_kernel(); +- error = dir->i_op->unlink(dir, dentry); +- unlock_kernel(); +- if (!error) +- d_delete(dentry); +- } ++ if (error) ++ return error; ++ ++ inode = dentry->d_inode; ++ atomic_inc(&inode->i_count); ++ double_down(&dir->i_zombie, &inode->i_zombie); ++ ++ error = -EPERM; ++ if (dir->i_op && dir->i_op->unlink) { ++ DQUOT_INIT(dir); ++ if (d_mountpoint(dentry)) ++ error = -EBUSY; ++ else { ++ lock_kernel(); ++ error = dir->i_op->unlink(dir, dentry); ++ unlock_kernel(); + } + } +- up(&dir->i_zombie); +- if (!error) ++ double_up(&dir->i_zombie, &inode->i_zombie); ++ iput(inode); ++ ++ if (!error) { ++ d_delete(dentry); + inode_dir_notify(dir, DN_DELETE); ++ } + return error; + } + +@@ -1607,18 +1614,19 @@ + struct inode *inode; + int error; + +- down(&dir->i_zombie); + error = -ENOENT; + inode = old_dentry->d_inode; + if (!inode) +- goto exit_lock; +- +- error = may_create(dir, new_dentry); +- if (error) +- goto exit_lock; ++ goto exit; + + error = -EXDEV; + if (dir->i_dev != inode->i_dev) ++ goto exit; ++ ++ double_down(&dir->i_zombie, &old_dentry->d_inode->i_zombie); ++ ++ error = may_create(dir, new_dentry); ++ if (error) + goto exit_lock; + + /* +@@ -1636,9 +1644,10 @@ + unlock_kernel(); + + exit_lock: +- up(&dir->i_zombie); ++ double_up(&dir->i_zombie, &old_dentry->d_inode->i_zombie); + if (!error) + inode_dir_notify(dir, DN_CREATE); ++exit: + return error; + } + +--- linux-2.4.30/fs/nfs/inode.c 2004-04-14 15:05:40 +0200 ++++ linux-2.4.30-hf32.7/fs/nfs/inode.c 2006-07-28 13:53:36 +0200 +@@ -1047,6 +1047,13 @@ + invalid = 0; + } + ++ /* set the invalid flag if the last attempt at invalidating ++ * the inode didn't empty the clean_pages list */ ++ if ( NFS_FLAGS(inode) & NFS_INO_MAPPED) { ++ NFS_FLAGS(inode) &= ~NFS_INO_MAPPED; ++ invalid = 1; ++ } ++ + /* + * If we have pending writebacks, things can get + * messy. +@@ -1092,6 +1099,12 @@ + NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); + NFS_ATTRTIMEO_UPDATE(inode) = jiffies; + invalidate_inode_pages(inode); ++ if (! list_empty(&inode->i_mapping->clean_pages)) { ++ dfprintk(PAGECACHE, ++ "NFS: clean_pages for %x/%ld is not empty\n", ++ inode->i_dev, inode->i_ino); ++ NFS_FLAGS(inode) |= NFS_INO_MAPPED; ++ } + memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); + } else if (time_after(jiffies, NFS_ATTRTIMEO_UPDATE(inode)+NFS_ATTRTIMEO(inode))) { + if ((NFS_ATTRTIMEO(inode) <<= 1) > NFS_MAXATTRTIMEO(inode)) +--- linux-2.4.30/fs/partitions/msdos.c 2002-11-29 00:53:15 +0100 ++++ linux-2.4.30-hf32.7/fs/partitions/msdos.c 2006-07-28 13:53:36 +0200 +@@ -572,6 +572,19 @@ + put_dev_sector(sect); + return 0; + } ++ /* ++ * Now that the 55aa signature is present, this is probably ++ * either the boot sector of a FAT filesystem or a DOS-type ++ * partition table. Reject this in case the boot indicator ++ * is not 0 or 0x80. ++ */ ++ p = (struct partition *) (data + 0x1be); ++ for (i = 1; i <= 4; i++, p++) { ++ if (p->boot_ind != 0 && p->boot_ind != 0x80) { ++ put_dev_sector(sect); ++ return 0; ++ } ++ } + p = (struct partition *) (data + 0x1be); + + /* +--- linux-2.4.30/fs/quota_v2.c 2003-08-25 13:44:43 +0200 ++++ linux-2.4.30-hf32.7/fs/quota_v2.c 2006-07-28 13:53:36 +0200 +@@ -14,6 +14,10 @@ + #include + #include + ++MODULE_AUTHOR("Jan Kara"); ++MODULE_DESCRIPTION("Quota format v2 support"); ++MODULE_LICENSE("GPL"); ++ + #define __QUOTA_V2_PARANOIA + + typedef char *dqbuf_t; +--- linux-2.4.30/fs/smbfs/dir.c 2004-02-18 14:36:31 +0100 ++++ linux-2.4.30-hf32.7/fs/smbfs/dir.c 2006-07-28 13:53:35 +0200 +@@ -416,6 +416,11 @@ + if (dentry->d_name.len > SMB_MAXNAMELEN) + goto out; + ++ /* Do not allow lookup of names with backslashes in */ ++ error = -EINVAL; ++ if (memchr(dentry->d_name.name, '\\', dentry->d_name.len)) ++ goto out; ++ + error = smb_proc_getattr(dentry, &finfo); + #ifdef SMBFS_PARANOIA + if (error && error != -ENOENT) +--- linux-2.4.30/include/asm-x86_64/i387.h 2004-08-08 01:26:06 +0200 ++++ linux-2.4.30-hf32.7/include/asm-x86_64/i387.h 2006-07-28 13:53:35 +0200 +@@ -125,8 +125,12 @@ + + static inline void save_init_fpu( struct task_struct *tsk ) + { +- asm volatile( "fxsave %0 ; fnclex" ++ asm volatile( "fxsave %0" + : "=m" (tsk->thread.i387.fxsave)); ++ if (tsk->thread.i387.fxsave.swd & (1<<7)) ++ asm volatile("fnclex"); ++ /* AMD CPUs leak F?P through FXSAVE. Clear it here */ ++ asm volatile("ffree %st(7) ; fildl %gs:0"); + tsk->flags &= ~PF_USEDFPU; + stts(); + } +--- linux-2.4.30/include/linux/nfs_fs_i.h 2006-07-18 18:23:37 +0200 ++++ linux-2.4.30-hf32.7/include/linux/nfs_fs_i.h 2006-07-28 13:53:36 +0200 +@@ -85,6 +85,7 @@ + #define NFS_INO_REVALIDATING 0x0004 /* revalidating attrs */ + #define NFS_IS_SNAPSHOT 0x0010 /* a snapshot file */ + #define NFS_INO_FLUSH 0x0020 /* inode is due for flushing */ ++#define NFS_INO_MAPPED 0x0040 /* page invalidation failed */ + + /* + * NFS lock info +--- linux-2.4.30/include/net/sctp/sctp.h 2006-06-19 18:47:31 +0200 ++++ linux-2.4.30-hf32.7/include/net/sctp/sctp.h 2006-07-28 13:53:35 +0200 +@@ -466,12 +466,12 @@ + * there is room for a param header too. + */ + #define sctp_walk_params(pos, chunk, member)\ +-_sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)), member) ++_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member) + + #define _sctp_walk_params(pos, chunk, end, member)\ + for (pos.v = chunk->member;\ + pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\ +- pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\ ++ pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\ + ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\ + pos.v += WORD_ROUND(ntohs(pos.p->length))) + +@@ -482,7 +482,7 @@ + for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \ + sizeof(sctp_chunkhdr_t));\ + (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\ +- (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\ ++ (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\ + ntohs(err->length) >= sizeof(sctp_errhdr_t); \ + err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length)))) + +--- linux-2.4.30/ipc/shm.c 2002-08-03 02:39:46 +0200 ++++ linux-2.4.30-hf32.7/ipc/shm.c 2006-07-28 13:53:35 +0200 +@@ -161,6 +161,8 @@ + { + UPDATE_ATIME(file->f_dentry->d_inode); + vma->vm_ops = &shm_vm_ops; ++ if (!(vma->vm_flags & VM_WRITE)) ++ vma->vm_flags &= ~VM_MAYWRITE; + shm_inc(file->f_dentry->d_inode->i_ino); + return 0; + } +--- linux-2.4.30/net/8021q/vlan.c 2004-02-18 14:36:32 +0100 ++++ linux-2.4.30-hf32.7/net/8021q/vlan.c 2006-07-28 13:53:36 +0200 +@@ -757,6 +757,8 @@ + + case GET_VLAN_REALDEV_NAME_CMD: + err = vlan_dev_get_realdev_name(args.device1, args.u.device2); ++ if (err) ++ goto out; + if (copy_to_user((void*)arg, &args, + sizeof(struct vlan_ioctl_args))) { + err = -EFAULT; +@@ -765,6 +767,8 @@ + + case GET_VLAN_VID_CMD: + err = vlan_dev_get_vid(args.device1, &vid); ++ if (err) ++ goto out; + args.u.VID = vid; + if (copy_to_user((void*)arg, &args, + sizeof(struct vlan_ioctl_args))) { +@@ -778,7 +782,7 @@ + __FUNCTION__, args.cmd); + return -EINVAL; + }; +- ++out: + return err; + } + +--- linux-2.4.30/net/core/ethtool.c 2004-08-08 01:26:06 +0200 ++++ linux-2.4.30-hf32.7/net/core/ethtool.c 2006-07-28 13:53:35 +0200 +@@ -349,7 +349,7 @@ + { + struct ethtool_coalesce coalesce; + +- if (!dev->ethtool_ops->get_coalesce) ++ if (!dev->ethtool_ops->set_coalesce) + return -EOPNOTSUPP; + + if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) +@@ -403,7 +403,7 @@ + { + struct ethtool_pauseparam pauseparam; + +- if (!dev->ethtool_ops->get_pauseparam) ++ if (!dev->ethtool_ops->set_pauseparam) + return -EOPNOTSUPP; + + if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) +--- linux-2.4.30/net/core/neighbour.c 2005-04-14 09:43:35 +0200 ++++ linux-2.4.30-hf32.7/net/core/neighbour.c 2006-07-28 13:53:36 +0200 +@@ -14,6 +14,7 @@ + * Vitaly E. Lavrov releasing NULL neighbor in neigh_add. + * Harald Welte Add neighbour cache statistics like rtstat + * Harald Welte port neighbour cache rework from 2.6.9-rcX ++ * Pradeep Vincent Move neighbour cache entry to stale state + */ + + #include +@@ -705,6 +706,14 @@ + neigh_release(n); + continue; + } ++ ++ /* Mark it stale - To be reconfirmed later when used */ ++ if (n->nud_state & NUD_REACHABLE && ++ now - n->confirmed > n->parms->reachable_time) { ++ n->nud_state = NUD_STALE; ++ neigh_suspect(n); ++ } ++ + write_unlock(&n->lock); + + next_elt: +--- linux-2.4.30/net/ipv4/netfilter/arp_tables.c 2004-11-17 12:54:22 +0100 ++++ linux-2.4.30-hf32.7/net/ipv4/netfilter/arp_tables.c 2006-07-28 13:53:35 +0200 +@@ -871,6 +871,13 @@ + if (len != sizeof(tmp) + tmp.size) + return -ENOPROTOOPT; + ++ /* overflow check */ ++ if (tmp.size >= (INT_MAX - sizeof(struct arpt_table_info)) / NR_CPUS - ++ SMP_CACHE_BYTES) ++ return -ENOMEM; ++ if (tmp.num_counters >= INT_MAX / sizeof(struct arpt_counters)) ++ return -ENOMEM; ++ + /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ + if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) + return -ENOMEM; +@@ -991,7 +998,7 @@ + goto free; + + write_lock_bh(&t->lock); +- if (t->private->number != paddc->num_counters) { ++ if (t->private->number != tmp.num_counters) { + ret = -EINVAL; + goto unlock_up_free; + } +--- linux-2.4.30/net/ipv4/netfilter/ip_nat_snmp_basic.c 2004-11-17 12:54:22 +0100 ++++ linux-2.4.30-hf32.7/net/ipv4/netfilter/ip_nat_snmp_basic.c 2006-07-28 13:53:35 +0200 +@@ -996,12 +996,12 @@ + + return 1; + ++err_addr_free: ++ kfree((unsigned long *)trap->ip_address); ++ + err_id_free: + kfree(trap->id); + +-err_addr_free: +- kfree((unsigned long *)trap->ip_address); +- + return 0; + } + +@@ -1119,11 +1119,10 @@ + struct snmp_v1_trap trap; + unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check); + +- /* Discard trap allocations regardless */ +- kfree(trap.id); +- kfree((unsigned long *)trap.ip_address); +- +- if (!ret) ++ if (ret) { ++ kfree(trap.id); ++ kfree((unsigned long *)trap.ip_address); ++ } else + return ret; + + } else { +--- linux-2.4.30/net/ipv4/netfilter/ip_tables.c 2005-04-14 09:43:35 +0200 ++++ linux-2.4.30-hf32.7/net/ipv4/netfilter/ip_tables.c 2006-07-28 13:53:35 +0200 +@@ -1066,6 +1066,13 @@ + if (len != sizeof(tmp) + tmp.size) + return -ENOPROTOOPT; + ++ /* overflow check */ ++ if (tmp.size >= (INT_MAX - sizeof(struct ipt_table_info)) / NR_CPUS - ++ SMP_CACHE_BYTES) ++ return -ENOMEM; ++ if (tmp.num_counters >= INT_MAX / sizeof(struct ipt_counters)) ++ return -ENOMEM; ++ + /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ + if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) + return -ENOMEM; +@@ -1195,7 +1202,7 @@ + goto free; + + write_lock_bh(&t->lock); +- if (t->private->number != paddc->num_counters) { ++ if (t->private->number != tmp.num_counters) { + ret = -EINVAL; + goto unlock_up_free; + } +--- linux-2.4.30/net/ipv4/netfilter/ipt_recent.c 2005-04-14 09:43:35 +0200 ++++ linux-2.4.30-hf32.7/net/ipv4/netfilter/ipt_recent.c 2006-07-28 13:53:35 +0200 +@@ -820,6 +820,7 @@ + /* Create our proc 'status' entry. */ + curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent); + if (!curr_table->status_proc) { ++ vfree(hold); + printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n"); + /* Destroy the created table */ + spin_lock_bh(&recent_lock); +@@ -844,7 +845,6 @@ + spin_unlock_bh(&recent_lock); + vfree(curr_table->time_info); + vfree(curr_table->hash_table); +- vfree(hold); + vfree(curr_table->table); + vfree(curr_table); + return 0; +--- linux-2.4.30/net/ipv4/route.c 2004-11-17 12:54:22 +0100 ++++ linux-2.4.30-hf32.7/net/ipv4/route.c 2006-07-28 13:53:35 +0200 +@@ -2214,7 +2214,10 @@ + /* Reserve room for dummy headers, this skb can pass + through good chunk of routing engine. + */ +- skb->mac.raw = skb->data; ++ skb->mac.raw = skb->nh.raw = skb->data; ++ ++ /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ ++ skb->nh.iph->protocol = IPPROTO_ICMP; + skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); + + if (rta[RTA_SRC - 1]) +--- linux-2.4.30/net/ipv6/netfilter/ip6_tables.c 2005-04-14 09:43:35 +0200 ++++ linux-2.4.30-hf32.7/net/ipv6/netfilter/ip6_tables.c 2006-07-28 13:53:35 +0200 +@@ -1151,6 +1151,13 @@ + if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) + return -ENOMEM; + ++ /* overflow check */ ++ if (tmp.size >= (INT_MAX - sizeof(struct ip6t_table_info)) / NR_CPUS - ++ SMP_CACHE_BYTES) ++ return -ENOMEM; ++ if (tmp.num_counters >= INT_MAX / sizeof(struct ip6t_counters)) ++ return -ENOMEM; ++ + newinfo = vmalloc(sizeof(struct ip6t_table_info) + + SMP_ALIGN(tmp.size) * smp_num_cpus); + if (!newinfo) +@@ -1276,7 +1283,7 @@ + goto free; + + write_lock_bh(&t->lock); +- if (t->private->number != paddc->num_counters) { ++ if (t->private->number != tmp.num_counters) { + ret = -EINVAL; + goto unlock_up_free; + } +--- linux-2.4.30/net/sctp/sm_statefuns.c 2005-01-27 18:57:34 +0100 ++++ linux-2.4.30-hf32.7/net/sctp/sm_statefuns.c 2006-07-28 13:53:35 +0200 +@@ -619,8 +619,9 @@ + */ + chunk->subh.cookie_hdr = + (struct sctp_signed_cookie *)chunk->skb->data; +- skb_pull(chunk->skb, +- ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); ++ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - ++ sizeof(sctp_chunkhdr_t))) ++ goto nomem; + + /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint + * "Z" will reply with a COOKIE ACK chunk after building a TCB +@@ -949,7 +950,8 @@ + */ + chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; + paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); +- skb_pull(chunk->skb, paylen); ++ if (!pskb_pull(chunk->skb, paylen)) ++ goto nomem; + + reply = sctp_make_heartbeat_ack(asoc, chunk, + chunk->subh.hb_hdr, paylen); +@@ -1012,6 +1014,12 @@ + commands); + + hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; ++ /* Make sure that the length of the parameter is what we expect */ ++ if (ntohs(hbinfo->param_hdr.length) != ++ sizeof(sctp_sender_hb_info_t)) { ++ return SCTP_DISPOSITION_DISCARD; ++ } ++ + from_addr = hbinfo->daddr; + link = sctp_assoc_lookup_paddr(asoc, &from_addr); + +@@ -1832,8 +1840,9 @@ + * are in good shape. + */ + chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; +- skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - +- sizeof(sctp_chunkhdr_t)); ++ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - ++ sizeof(sctp_chunkhdr_t))) ++ goto nomem; + + /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie + * of a duplicate COOKIE ECHO match the Verification Tags of the +--- linux-2.4.30/net/sctp/sm_statetable.c 2005-01-27 18:57:34 +0100 ++++ linux-2.4.30-hf32.7/net/sctp/sm_statetable.c 2006-07-28 13:53:35 +0200 +@@ -366,9 +366,9 @@ + /* SCTP_STATE_EMPTY */ \ + {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ + /* SCTP_STATE_CLOSED */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + /* SCTP_STATE_COOKIE_WAIT */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + /* SCTP_STATE_COOKIE_ECHOED */ \ + {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ + /* SCTP_STATE_ESTABLISHED */ \ +@@ -380,7 +380,7 @@ + /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ + {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ + /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + } /* TYPE_SCTP_ECN_ECNE */ + + #define TYPE_SCTP_ECN_CWR { \ +@@ -401,7 +401,7 @@ + /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + } /* TYPE_SCTP_ECN_CWR */ + + #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ +@@ -647,7 +647,7 @@ + /* SCTP_STATE_EMPTY */ \ + {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + /* SCTP_STATE_CLOSED */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ + /* SCTP_STATE_COOKIE_WAIT */ \ + {.fn = sctp_sf_do_prm_requestheartbeat, \ + .name = "sctp_sf_do_prm_requestheartbeat"}, \ +--- linux-2.4.30/net/sctp/ulpqueue.c 2005-01-27 18:57:34 +0100 ++++ linux-2.4.30-hf32.7/net/sctp/ulpqueue.c 2006-07-28 13:53:35 +0200 +@@ -273,6 +273,7 @@ + static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff *f_frag, struct sk_buff *l_frag) + { + struct sk_buff *pos; ++ struct sk_buff *new = NULL; + struct sctp_ulpevent *event; + struct sk_buff *pnext, *last; + struct sk_buff *list = skb_shinfo(f_frag)->frag_list; +@@ -291,11 +292,33 @@ + */ + if (last) + last->next = pos; +- else +- skb_shinfo(f_frag)->frag_list = pos; ++ else { ++ if (skb_cloned(f_frag)) { ++ /* This is a cloned skb, we can't just modify ++ * the frag_list. We need a new skb to do that. ++ * Instead of calling skb_unshare(), we'll do it ++ * ourselves since we need to delay the free. ++ */ ++ new = skb_copy(f_frag, GFP_ATOMIC); ++ if (!new) ++ return NULL; /* try again later */ ++ ++ new->sk = f_frag->sk; ++ ++ skb_shinfo(new)->frag_list = pos; ++ } else ++ skb_shinfo(f_frag)->frag_list = pos; ++ } + + /* Remove the first fragment from the reassembly queue. */ + __skb_unlink(f_frag, f_frag->list); ++ ++ /* if we did unshare, then free the old skb and re-assign */ ++ if (new) { ++ kfree_skb(f_frag); ++ f_frag = new; ++ } ++ + while (pos) { + + pnext = pos->next; +--- linux-2.4.30/scripts/ver_linux 2004-02-18 14:36:32 +0100 ++++ linux-2.4.30-hf32.7/scripts/ver_linux 2006-07-28 13:53:36 +0200 +@@ -22,7 +22,8 @@ + '/GNU Make/{print "Gnu make ",$NF}' + + ld -v 2>&1 | awk -F\) '{print $1}' | awk \ +- '/BFD/{print "binutils ",$NF}' ++ '/BFD/{print "binutils ",$NF} \ ++ /^GNU/{print "binutils ",$4}' + + fdformat --version | awk -F\- '{print "util-linux ", $NF}' +