diff -purN linux-2.4.30-hf3/Makefile linux-2.4.30-hf4/Makefile --- linux-2.4.30-hf3/Makefile Sun May 29 23:16:01 2005 +++ linux-2.4.30-hf4/Makefile Sat Jul 2 01:03:10 2005 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 30 -EXTRAVERSION = -hf3 +EXTRAVERSION = -hf4 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -purN linux-2.4.30-hf3/arch/i386/kernel/apm.c linux-2.4.30-hf4/arch/i386/kernel/apm.c --- linux-2.4.30-hf3/arch/i386/kernel/apm.c Sat Sep 13 07:57:17 2003 +++ linux-2.4.30-hf4/arch/i386/kernel/apm.c Sat Jul 2 01:03:11 2005 @@ -327,7 +327,7 @@ extern int (*console_blank_hook)(int); * Save a segment register away */ #define savesegment(seg, where) \ - __asm__ __volatile__("movl %%" #seg ",%0" : "=m" (where)) + __asm__ __volatile__("mov %%" #seg ",%0" : "=m" (where)) /* * Maximum number of events stored @@ -553,7 +553,7 @@ static inline void apm_restore_cpus(unsi #ifdef APM_ZERO_SEGS # define APM_DECL_SEGS \ - unsigned int saved_fs; unsigned int saved_gs; + unsigned short saved_fs; unsigned short saved_gs; # define APM_DO_SAVE_SEGS \ savesegment(fs, saved_fs); savesegment(gs, saved_gs) # define APM_DO_ZERO_SEGS \ diff -purN linux-2.4.30-hf3/arch/i386/kernel/process.c linux-2.4.30-hf4/arch/i386/kernel/process.c --- linux-2.4.30-hf3/arch/i386/kernel/process.c Sun Sep 12 18:30:58 2004 +++ linux-2.4.30-hf4/arch/i386/kernel/process.c Sat Jul 2 01:03:11 2005 @@ -544,7 +544,7 @@ void release_thread(struct task_struct * * Save a segment. */ #define savesegment(seg,value) \ - asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value))) + asm volatile("mov %%" #seg ",%0":"=m" (value)) int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, unsigned long unused, @@ -661,8 +661,8 @@ void fastcall __switch_to(struct task_st * Save away %fs and %gs. No need to save %es and %ds, as * those are always kernel segments while inside the kernel. */ - asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->fs)); - asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs)); + asm volatile("mov %%fs,%0":"=m" (prev->fs)); + asm volatile("mov %%gs,%0":"=m" (prev->gs)); /* * Restore %fs and %gs. diff -purN linux-2.4.30-hf3/arch/ia64/ia32/sys_ia32.c linux-2.4.30-hf4/arch/ia64/ia32/sys_ia32.c --- linux-2.4.30-hf3/arch/ia64/ia32/sys_ia32.c Sun Apr 17 15:32:22 2005 +++ linux-2.4.30-hf4/arch/ia64/ia32/sys_ia32.c Sat Jul 2 01:03:11 2005 @@ -94,7 +94,7 @@ asmlinkage unsigned long sys_brk(unsigne static DECLARE_MUTEX(ia32_mmap_sem); static int -nargs (unsigned int arg, char **ap) +nargs (unsigned int arg, char **ap, int max) { unsigned int addr; int n, err; @@ -107,6 +107,8 @@ nargs (unsigned int arg, char **ap) err = get_user(addr, (unsigned int *)A(arg)); if (err) return err; + if (n > max) + return -E2BIG; if (ap) *ap++ = (char *) A(addr); arg += sizeof(unsigned int); @@ -128,10 +130,11 @@ sys32_execve (char *filename, unsigned i int na, ne, len; long r; - na = nargs(argv, NULL); + /* Allocates upto 2x MAX_ARG_PAGES */ + na = nargs(argv, NULL, (MAX_ARG_PAGES*PAGE_SIZE) / sizeof(char *) - 1); if (na < 0) return na; - ne = nargs(envp, NULL); + ne = nargs(envp, NULL, (MAX_ARG_PAGES*PAGE_SIZE) / sizeof(char *) - 1 ); if (ne < 0) return ne; len = (na + ne + 2) * sizeof(*av); @@ -143,10 +146,10 @@ sys32_execve (char *filename, unsigned i av[na] = NULL; ae[ne] = NULL; - r = nargs(argv, av); + r = nargs(argv, av, na); if (r < 0) goto out; - r = nargs(envp, ae); + r = nargs(envp, ae, ne); if (r < 0) goto out; diff -purN linux-2.4.30-hf3/arch/sparc64/solaris/socket.c linux-2.4.30-hf4/arch/sparc64/solaris/socket.c --- linux-2.4.30-hf3/arch/sparc64/solaris/socket.c Sat Dec 1 18:27:13 2001 +++ linux-2.4.30-hf4/arch/sparc64/solaris/socket.c Sat Jul 2 01:03:11 2005 @@ -410,8 +410,10 @@ asmlinkage int solaris_sendmsg(int fd, s unsigned long *kcmsg; __kernel_size_t32 cmlen; - if(kern_msg.msg_controllen > sizeof(ctl) && - kern_msg.msg_controllen <= 256) { + if (kern_msg.msg_controllen <= sizeof(__kernel_size_t32)) + return -EINVAL; + + if(kern_msg.msg_controllen > sizeof(ctl)) { err = -ENOBUFS; ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL); if(!ctl_buf) diff -purN linux-2.4.30-hf3/arch/x86_64/ia32/sys_ia32.c linux-2.4.30-hf4/arch/x86_64/ia32/sys_ia32.c --- linux-2.4.30-hf3/arch/x86_64/ia32/sys_ia32.c Sun Dec 19 21:18:24 2004 +++ linux-2.4.30-hf4/arch/x86_64/ia32/sys_ia32.c Sat Jul 2 01:03:11 2005 @@ -2200,7 +2200,7 @@ asmlinkage long sys32_ustat(dev_t dev, s return ret; } -static int nargs(u32 src, char **dst) +static int nargs(u32 src, char **dst, int max) { int cnt; u32 val; @@ -2210,13 +2210,13 @@ static int nargs(u32 src, char **dst) int ret = get_user(val, (__u32 *)(u64)src); if (ret) return ret; + if (cnt > max) + return -E2BIG; if (dst) dst[cnt] = (char *)(u64)val; cnt++; src += 4; - if (cnt >= (MAX_ARG_PAGES * PAGE_SIZE) / sizeof(char *)) - return -E2BIG; - } while(val); + } while(val); if (dst) dst[cnt-1] = 0; return cnt; @@ -2230,13 +2230,14 @@ asmlinkage long sys32_execve(char *name, int ret; unsigned sz = 0; + /* Can actually allocate 2*MAX_ARG_PAGES */ if (argv) { - na = nargs(argv, NULL); + na = nargs(argv, NULL, (MAX_ARG_PAGES * PAGE_SIZE)/sizeof(char*) - 1); if (na < 0) return -EFAULT; } if (envp) { - ne = nargs(envp, NULL); + ne = nargs(envp, NULL, (MAX_ARG_PAGES * PAGE_SIZE)/sizeof(char*) - 1); if (ne < 0) return -EFAULT; } @@ -2252,13 +2253,13 @@ asmlinkage long sys32_execve(char *name, } if (argv) { - ret = nargs(argv, buf); + ret = nargs(argv, buf, na); if (ret < 0) goto free; } if (envp) { - ret = nargs(envp, buf + na); + ret = nargs(envp, buf + na, ne); if (ret < 0) goto free; } diff -purN linux-2.4.30-hf3/arch/x86_64/kernel/process.c linux-2.4.30-hf4/arch/x86_64/kernel/process.c --- linux-2.4.30-hf3/arch/x86_64/kernel/process.c Sun Mar 28 16:12:41 2004 +++ linux-2.4.30-hf4/arch/x86_64/kernel/process.c Sat Jul 2 01:03:11 2005 @@ -527,10 +527,10 @@ int copy_thread(int nr, unsigned long cl p->thread.fs = me->thread.fs; p->thread.gs = me->thread.gs; - asm("movl %%gs,%0" : "=m" (p->thread.gsindex)); - asm("movl %%fs,%0" : "=m" (p->thread.fsindex)); - asm("movl %%es,%0" : "=m" (p->thread.es)); - asm("movl %%ds,%0" : "=m" (p->thread.ds)); + asm("mov %%gs,%0" : "=m" (p->thread.gsindex)); + asm("mov %%fs,%0" : "=m" (p->thread.fsindex)); + asm("mov %%es,%0" : "=m" (p->thread.es)); + asm("mov %%ds,%0" : "=m" (p->thread.ds)); unlazy_fpu(current); p->thread.i387 = current->thread.i387; @@ -575,11 +575,11 @@ struct task_struct *__switch_to(struct t /* * Switch DS and ES. */ - asm volatile("movl %%es,%0" : "=m" (prev->es)); + asm volatile("mov %%es,%0" : "=m" (prev->es)); if (unlikely(next->es | prev->es)) loadsegment(es, next->es); - asm volatile ("movl %%ds,%0" : "=m" (prev->ds)); + asm volatile ("mov %%ds,%0" : "=m" (prev->ds)); if (unlikely(next->ds | prev->ds)) loadsegment(ds, next->ds); @@ -588,7 +588,7 @@ struct task_struct *__switch_to(struct t */ { unsigned fsindex; - asm volatile("movl %%fs,%0" : "=g" (fsindex)); + asm volatile("movl %%fs,%0" : "=r" (fsindex)); /* segment register != 0 always requires a reload. also reload when it has changed. when prev process used 64bit base always reload @@ -609,7 +609,7 @@ struct task_struct *__switch_to(struct t } { unsigned gsindex; - asm volatile("movl %%gs,%0" : "=g" (gsindex)); + asm volatile("movl %%gs,%0" : "=r" (gsindex)); if (unlikely((gsindex | next->gsindex) || prev->gs)) { load_gs_index(next->gsindex); if (gsindex) diff -purN linux-2.4.30-hf3/arch/x86_64/kernel/ptrace.c linux-2.4.30-hf4/arch/x86_64/kernel/ptrace.c --- linux-2.4.30-hf3/arch/x86_64/kernel/ptrace.c Mon Apr 21 22:41:00 2003 +++ linux-2.4.30-hf4/arch/x86_64/kernel/ptrace.c Sat Jul 2 01:03:11 2005 @@ -114,13 +114,13 @@ static int putreg(struct task_struct *ch child->thread.es = value & 0xffff; return 0; case offsetof(struct user_regs_struct,fs_base): - if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) - return -EIO; + if (value >= TASK_SIZE) + return -EIO; child->thread.fs = value; return 0; case offsetof(struct user_regs_struct,gs_base): - if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) - return -EIO; + if (value >= TASK_SIZE) + return -EIO; child->thread.gs = value; return 0; case offsetof(struct user_regs_struct, eflags): @@ -139,6 +139,11 @@ static int putreg(struct task_struct *ch return -EIO; value &= 0xffff; break; + case offsetof(struct user_regs_struct, rip): + /* Check if the new RIP address is canonical */ + if (value >= TASK_SIZE) + return -EIO; + break; } put_stack_long(child, regno - sizeof(struct pt_regs), value); return 0; diff -purN linux-2.4.30-hf3/arch/x86_64/kernel/traps.c linux-2.4.30-hf4/arch/x86_64/kernel/traps.c --- linux-2.4.30-hf3/arch/x86_64/kernel/traps.c Sun Mar 28 16:12:41 2004 +++ linux-2.4.30-hf4/arch/x86_64/kernel/traps.c Sat Jul 2 01:03:11 2005 @@ -857,7 +857,7 @@ void __init trap_init(void) set_intr_gate(9,&coprocessor_segment_overrun); set_intr_gate(10,&invalid_TSS); set_intr_gate(11,&segment_not_present); - set_intr_gate_ist(12,&stack_segment,STACKFAULT_STACK); + set_intr_gate(12,&stack_segment); set_intr_gate(13,&general_protection); set_intr_gate(14,&page_fault); set_intr_gate(15,&spurious_interrupt_bug); diff -purN linux-2.4.30-hf3/drivers/bluetooth/bfusb.c linux-2.4.30-hf4/drivers/bluetooth/bfusb.c --- linux-2.4.30-hf3/drivers/bluetooth/bfusb.c Sun May 9 15:33:49 2004 +++ linux-2.4.30-hf4/drivers/bluetooth/bfusb.c Sat Jul 2 01:03:11 2005 @@ -470,11 +470,10 @@ static int bfusb_close(struct hci_dev *h return 0; write_lock_irqsave(&bfusb->lock, flags); + write_unlock_irqrestore(&bfusb->lock, flags); bfusb_unlink_urbs(bfusb); bfusb_flush(hdev); - - write_unlock_irqrestore(&bfusb->lock, flags); MOD_DEC_USE_COUNT; diff -purN linux-2.4.30-hf3/drivers/bluetooth/hci_usb.c linux-2.4.30-hf4/drivers/bluetooth/hci_usb.c --- linux-2.4.30-hf3/drivers/bluetooth/hci_usb.c Sat Aug 7 23:00:08 2004 +++ linux-2.4.30-hf4/drivers/bluetooth/hci_usb.c Sat Jul 2 01:03:11 2005 @@ -398,12 +398,12 @@ static int hci_usb_close(struct hci_dev BT_DBG("%s", hdev->name); + /* Synchronize with completion handlers */ write_lock_irqsave(&husb->completion_lock, flags); - + write_unlock_irqrestore(&husb->completion_lock, flags); + hci_usb_unlink_urbs(husb); hci_usb_flush(hdev); - - write_unlock_irqrestore(&husb->completion_lock, flags); MOD_DEC_USE_COUNT; return 0; diff -purN linux-2.4.30-hf3/include/asm-i386/system.h linux-2.4.30-hf4/include/asm-i386/system.h --- linux-2.4.30-hf3/include/asm-i386/system.h Wed Jun 1 06:31:27 2005 +++ linux-2.4.30-hf4/include/asm-i386/system.h Sat Jul 2 01:03:11 2005 @@ -84,7 +84,7 @@ static inline unsigned long _get_base(ch #define loadsegment(seg,value) \ asm volatile("\n" \ "1:\t" \ - "movl %0,%%" #seg "\n" \ + "mov %0,%%" #seg "\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3:\t" \ @@ -96,7 +96,7 @@ static inline unsigned long _get_base(ch ".align 4\n\t" \ ".long 1b,3b\n" \ ".previous" \ - : :"m" (*(unsigned int *)&(value))) + : :"m" (value)) /* * Clear and set 'TS' bit respectively diff -purN linux-2.4.30-hf3/include/asm-x86_64/processor.h linux-2.4.30-hf4/include/asm-x86_64/processor.h --- linux-2.4.30-hf3/include/asm-x86_64/processor.h Sun Mar 28 16:12:41 2004 +++ linux-2.4.30-hf4/include/asm-x86_64/processor.h Sat Jul 2 01:03:11 2005 @@ -325,10 +325,9 @@ struct thread_struct { #define INIT_MMAP \ { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } -#define STACKFAULT_STACK 1 -#define DOUBLEFAULT_STACK 2 -#define NMI_STACK 3 -#define N_EXCEPTION_STACKS 3 /* hw limit: 7 */ +#define DOUBLEFAULT_STACK 1 +#define NMI_STACK 2 +#define N_EXCEPTION_STACKS 2 /* hw limit: 7 */ #define EXCEPTION_STKSZ PAGE_SIZE #define EXCEPTION_STK_ORDER 0 diff -purN linux-2.4.30-hf3/net/netlink/af_netlink.c linux-2.4.30-hf4/net/netlink/af_netlink.c --- linux-2.4.30-hf3/net/netlink/af_netlink.c Sun Apr 17 15:32:24 2005 +++ linux-2.4.30-hf4/net/netlink/af_netlink.c Sat Jul 2 01:03:11 2005 @@ -330,9 +330,9 @@ static void netlink_remove(struct sock * u32 pid = nlk_sk(sk)->pid; netlink_table_grab(); - hash->entries--; for (skp = nl_pid_hashfn(hash, pid); *skp; skp = &((*skp)->next)) { if (*skp == sk) { + hash->entries--; *skp = sk->next; __sock_put(sk); break; @@ -450,7 +450,7 @@ retry: err = netlink_insert(sk, pid); if (err == -EADDRINUSE) goto retry; - return 0; + return err; } static inline int netlink_capable(struct socket *sock, unsigned int flag)