From: Chris Wright Date: Sun, 5 Nov 2006 22:26:42 +0000 (-0800) Subject: patches queued for next 2.6.18 -stable X-Git-Tag: v2.6.18.3~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dbf5742d67c3d0029f88b0163f9c0349f9910205;p=thirdparty%2Fkernel%2Fstable-queue.git patches queued for next 2.6.18 -stable --- diff --git a/queue-2.6.18/fix-sys_move_pages-when-a-null-node-list-is-passed.patch b/queue-2.6.18/fix-sys_move_pages-when-a-null-node-list-is-passed.patch new file mode 100644 index 00000000000..54bf2fcddef --- /dev/null +++ b/queue-2.6.18/fix-sys_move_pages-when-a-null-node-list-is-passed.patch @@ -0,0 +1,39 @@ +From stable-bounces@linux.kernel.org Thu Nov 2 19:46:17 2006 +Date: Fri, 3 Nov 2006 14:42:43 +1100 +From: Stephen Rothwell +To: Christoph Lameter +Message-Id: <20061103144243.4601ba76.sfr@canb.auug.org.au> +Cc: Andrew Morton , linux-mm@kvack.org, LKML , stable@kernel.org +Subject: Fix sys_move_pages when a NULL node list is passed. + +sys_move_pages() uses vmalloc() to allocate an array of structures +that is fills with information passed from user mode and then passes to +do_stat_pages() (in the case the node list is NULL). do_stat_pages() +depends on a marker in the node field of the structure to decide how large +the array is and this marker is correctly inserted into the last element +of the array. However, vmalloc() doesn't zero the memory it allocates +and if the user passes NULL for the node list, then the node fields are +not filled in (except for the end marker). If the memory the vmalloc() +returned happend to have a word with the marker value in it in just the +right place, do_pages_stat will fail to fill the status field of part +of the array and we will return (random) kernel data to user mode. + +Signed-off-by: Stephen Rothwell +Acked-by: Christoph Lameter +Signed-off-by: Chris Wright +--- + mm/migrate.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- linux-2.6.18.2.orig/mm/migrate.c ++++ linux-2.6.18.2/mm/migrate.c +@@ -950,7 +950,8 @@ asmlinkage long sys_move_pages(pid_t pid + goto out; + + pm[i].node = node; +- } ++ } else ++ pm[i].node = 0; /* anything to not match MAX_NUMNODES */ + } + /* End marker */ + pm[nr_pages].node = MAX_NUMNODES; diff --git a/queue-2.6.18/make-alignment-exception-always-check-exception-table.patch b/queue-2.6.18/make-alignment-exception-always-check-exception-table.patch new file mode 100644 index 00000000000..7677ea99df3 --- /dev/null +++ b/queue-2.6.18/make-alignment-exception-always-check-exception-table.patch @@ -0,0 +1,91 @@ +From 4393c4f6788cee65095dd838cfeca6edefbfeb52 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Message-Id: <1162416427.25682.429.camel@localhost.localdomain> +Date: Wed, 1 Nov 2006 15:11:39 +1100 +Subject: POWERPC: Make alignment exception always check exception table + +The alignment exception used to only check the exception table for +-EFAULT, not for other errors. That opens an oops window if we can +coerce the kernel into getting an alignment exception for other reasons +in what would normally be a user-protected accessor, which can be done +via some of the futex ops. This fixes it by always checking the +exception tables. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Paul Mackerras +Signed-off-by: Chris Wright +--- + arch/powerpc/kernel/traps.c | 18 ++++++++++-------- + arch/ppc/kernel/traps.c | 18 ++++++++++-------- + 2 files changed, 20 insertions(+), 16 deletions(-) + +--- linux-2.6.18.2.orig/arch/powerpc/kernel/traps.c ++++ linux-2.6.18.2/arch/powerpc/kernel/traps.c +@@ -818,7 +818,7 @@ void __kprobes program_check_exception(s + + void alignment_exception(struct pt_regs *regs) + { +- int fixed = 0; ++ int sig, code, fixed = 0; + + /* we don't implement logging of alignment exceptions */ + if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) +@@ -832,14 +832,16 @@ void alignment_exception(struct pt_regs + + /* Operand address was bad */ + if (fixed == -EFAULT) { +- if (user_mode(regs)) +- _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); +- else +- /* Search exception table */ +- bad_page_fault(regs, regs->dar, SIGSEGV); +- return; ++ sig = SIGSEGV; ++ code = SEGV_ACCERR; ++ } else { ++ sig = SIGBUS; ++ code = BUS_ADRALN; + } +- _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); ++ if (user_mode(regs)) ++ _exception(sig, regs, code, regs->dar); ++ else ++ bad_page_fault(regs, regs->dar, sig); + } + + void StackOverflow(struct pt_regs *regs) +--- linux-2.6.18.2.orig/arch/ppc/kernel/traps.c ++++ linux-2.6.18.2/arch/ppc/kernel/traps.c +@@ -708,7 +708,7 @@ void single_step_exception(struct pt_reg + + void alignment_exception(struct pt_regs *regs) + { +- int fixed; ++ int sig, code, fixed = 0; + + fixed = fix_alignment(regs); + if (fixed == 1) { +@@ -717,14 +717,16 @@ void alignment_exception(struct pt_regs + return; + } + if (fixed == -EFAULT) { +- /* fixed == -EFAULT means the operand address was bad */ +- if (user_mode(regs)) +- _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); +- else +- bad_page_fault(regs, regs->dar, SIGSEGV); +- return; ++ sig = SIGSEGV; ++ code = SEGV_ACCERR; ++ } else { ++ sig = SIGBUS; ++ code = BUS_ADRALN; + } +- _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); ++ if (user_mode(regs)) ++ _exception(sig, regs, code, regs->dar); ++ else ++ bad_page_fault(regs, regs->dar, sig); + } + + void StackOverflow(struct pt_regs *regs) diff --git a/queue-2.6.18/s390-user-readable-uninitialised-kernel-memory-take-2.patch b/queue-2.6.18/s390-user-readable-uninitialised-kernel-memory-take-2.patch new file mode 100644 index 00000000000..b033ec21f06 --- /dev/null +++ b/queue-2.6.18/s390-user-readable-uninitialised-kernel-memory-take-2.patch @@ -0,0 +1,53 @@ +From schwidefsky@de.ibm.com Fri Nov 3 06:46:40 2006 +Date: Fri, 03 Nov 2006 15:43:36 +0100 +From: Martin Schwidefsky +Message-Id: <1162565016.7416.7.camel@localhost> +To: chrisw@sous-sol.org +Cc: greg@kroah.com, stable@kernel.org +Subject: S390: user readable uninitialised kernel memory, take 2. + +The previous patch to correct the copy_from_user padding is quite +broken. The execute instruction needs to be done via the register %r4, +not via %r2 and 31 bit doesn't know the instructions lgr and ahji. + +Signed-off-by: Martin Schwidefsky +Signed-off-by: Chris Wright +--- + arch/s390/lib/uaccess.S | 10 +++++----- + arch/s390/lib/uaccess64.S | 2 +- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- linux-2.6.18.2.orig/arch/s390/lib/uaccess64.S ++++ linux-2.6.18.2/arch/s390/lib/uaccess64.S +@@ -49,7 +49,7 @@ __copy_from_user_asm: + la %r2,256(%r2) + 8: aghi %r5,-256 + jnm 7b +- ex %r5,0(%r2) ++ ex %r5,0(%r4) + 9: lgr %r2,%r3 + br %r14 + .section __ex_table,"a" +--- linux-2.6.18.2.orig/arch/s390/lib/uaccess.S ++++ linux-2.6.18.2/arch/s390/lib/uaccess.S +@@ -41,15 +41,15 @@ __copy_from_user_asm: + 5: mvcp 0(%r5,%r2),0(%r4),%r0 + slr %r3,%r5 + alr %r2,%r5 +-6: lgr %r5,%r3 # copy remaining size ++6: lr %r5,%r3 # copy remaining size + ahi %r5,-1 # subtract 1 for xc loop + bras %r4,8f +- xc 0(1,%2),0(%2) +-7: xc 0(256,%2),0(%2) ++ xc 0(1,%r2),0(%r2) ++7: xc 0(256,%r2),0(%r2) + la %r2,256(%r2) +-8: ahji %r5,-256 ++8: ahi %r5,-256 + jnm 7b +- ex %r5,0(%r2) ++ ex %r5,0(%r4) + 9: lr %r2,%r3 + br %r14 + .section __ex_table,"a" diff --git a/queue-2.6.18/series b/queue-2.6.18/series new file mode 100644 index 00000000000..470596f8d9c --- /dev/null +++ b/queue-2.6.18/series @@ -0,0 +1,5 @@ +s390-user-readable-uninitialised-kernel-memory-take-2.patch +make-alignment-exception-always-check-exception-table.patch +sparc64-fix-futex_atomic_cmpxchg_inatomic-implementation.patch +fix-sys_move_pages-when-a-null-node-list-is-passed.patch +splice-fix-problem-introduced-with-inode-diet.patch diff --git a/queue-2.6.18/sparc64-fix-futex_atomic_cmpxchg_inatomic-implementation.patch b/queue-2.6.18/sparc64-fix-futex_atomic_cmpxchg_inatomic-implementation.patch new file mode 100644 index 00000000000..8ea9908e202 --- /dev/null +++ b/queue-2.6.18/sparc64-fix-futex_atomic_cmpxchg_inatomic-implementation.patch @@ -0,0 +1,56 @@ +From stable-bounces@linux.kernel.org Wed Nov 1 21:58:18 2006 +Date: Wed, 01 Nov 2006 21:55:00 -0800 (PST) +Message-Id: <20061101.215500.63127619.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Subject: SPARC64: Fix futex_atomic_cmpxchg_inatomic implementation. + +I copied the logic from ll/sc arch implementations, but that +was wrong and makes no sense at all. Just do a straight +compare-exchange instruction, just like x86. + +Based upon bug reports from Dennis Gilmore and Fabio Massimo. + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + +--- + include/asm-sparc64/futex.h | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +--- linux-2.6.18.2.orig/include/asm-sparc64/futex.h ++++ linux-2.6.18.2/include/asm-sparc64/futex.h +@@ -87,24 +87,22 @@ static inline int + futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) + { + __asm__ __volatile__( +- "\n1: lduwa [%2] %%asi, %0\n" +- "2: casa [%2] %%asi, %0, %1\n" +- "3:\n" ++ "\n1: casa [%3] %%asi, %2, %0\n" ++ "2:\n" + " .section .fixup,#alloc,#execinstr\n" + " .align 4\n" +- "4: ba 3b\n" +- " mov %3, %0\n" ++ "3: ba 2b\n" ++ " mov %4, %0\n" + " .previous\n" + " .section __ex_table,\"a\"\n" + " .align 4\n" +- " .word 1b, 4b\n" +- " .word 2b, 4b\n" ++ " .word 1b, 3b\n" + " .previous\n" +- : "=&r" (oldval) +- : "r" (newval), "r" (uaddr), "i" (-EFAULT) ++ : "=r" (newval) ++ : "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT) + : "memory"); + +- return oldval; ++ return newval; + } + + #endif /* !(_SPARC64_FUTEX_H) */ diff --git a/queue-2.6.18/splice-fix-problem-introduced-with-inode-diet.patch b/queue-2.6.18/splice-fix-problem-introduced-with-inode-diet.patch new file mode 100644 index 00000000000..0a0e9be7528 --- /dev/null +++ b/queue-2.6.18/splice-fix-problem-introduced-with-inode-diet.patch @@ -0,0 +1,91 @@ +From stable-bounces@linux.kernel.org Sun Nov 5 03:41:17 2006 +Date: Sun, 5 Nov 2006 12:39:51 +0100 +From: Jens Axboe +To: stable@kernel.org +Subject: splice: fix problem introduced with inode diet + +After the inode slimming patch that unionised i_pipe/i_bdev/i_cdev, it's +no longer enough to check for existance of ->i_pipe to verify that this +is a pipe. + +Original patch from Eric Dumazet +Final solution suggested by Linus. + +Signed-off-by: Jens Axboe +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +--- + + fs/splice.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +--- linux-2.6.18.2.orig/fs/splice.c ++++ linux-2.6.18.2/fs/splice.c +@@ -1042,6 +1042,19 @@ out_release: + EXPORT_SYMBOL(do_splice_direct); + + /* ++ * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same ++ * location, so checking ->i_pipe is not enough to verify that this is a ++ * pipe. ++ */ ++static inline struct pipe_inode_info *pipe_info(struct inode *inode) ++{ ++ if (S_ISFIFO(inode->i_mode)) ++ return inode->i_pipe; ++ ++ return NULL; ++} ++ ++/* + * Determine where to splice to/from. + */ + static long do_splice(struct file *in, loff_t __user *off_in, +@@ -1052,7 +1065,7 @@ static long do_splice(struct file *in, l + loff_t offset, *off; + long ret; + +- pipe = in->f_dentry->d_inode->i_pipe; ++ pipe = pipe_info(in->f_dentry->d_inode); + if (pipe) { + if (off_in) + return -ESPIPE; +@@ -1073,7 +1086,7 @@ static long do_splice(struct file *in, l + return ret; + } + +- pipe = out->f_dentry->d_inode->i_pipe; ++ pipe = pipe_info(out->f_dentry->d_inode); + if (pipe) { + if (off_out) + return -ESPIPE; +@@ -1231,7 +1244,7 @@ static int get_iovec_page_array(const st + static long do_vmsplice(struct file *file, const struct iovec __user *iov, + unsigned long nr_segs, unsigned int flags) + { +- struct pipe_inode_info *pipe = file->f_dentry->d_inode->i_pipe; ++ struct pipe_inode_info *pipe; + struct page *pages[PIPE_BUFFERS]; + struct partial_page partial[PIPE_BUFFERS]; + struct splice_pipe_desc spd = { +@@ -1241,7 +1254,8 @@ static long do_vmsplice(struct file *fil + .ops = &user_page_pipe_buf_ops, + }; + +- if (unlikely(!pipe)) ++ pipe = pipe_info(file->f_dentry->d_inode); ++ if (!pipe) + return -EBADF; + if (unlikely(nr_segs > UIO_MAXIOV)) + return -EINVAL; +@@ -1475,8 +1489,8 @@ static int link_pipe(struct pipe_inode_i + static long do_tee(struct file *in, struct file *out, size_t len, + unsigned int flags) + { +- struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe; +- struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe; ++ struct pipe_inode_info *ipipe = pipe_info(in->f_dentry->d_inode); ++ struct pipe_inode_info *opipe = pipe_info(out->f_dentry->d_inode); + int ret = -EINVAL; + + /*