Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=bb72c481e970dc1b4034ddccbe8302ff39e0d948
Commit:     bb72c481e970dc1b4034ddccbe8302ff39e0d948
Parent:     99ddef9bfe714c3273e3fce4c6b6a2a99e7d0bf8
Author:     Paul Mackerras <[EMAIL PROTECTED]>
AuthorDate: Mon Feb 19 11:42:42 2007 +1100
Committer:  Paul Mackerras <[EMAIL PROTECTED]>
CommitDate: Thu Mar 8 15:31:43 2007 +1100

    [POWERPC] Harden validate_sp against stack corruption
    
    If something has overflowed or corrupted the stack and causes an oops,
    and we try to print a stack trace, that will call validate_sp, which
    can itself cause an oops if the cpu field of the thread_info struct at
    the bottom of the stack has been corrupted (if CONFIG_IRQSTACKS is
    set).  This makes debugging harder.
    
    To avoid the second oops, this adds a check to make sure that the cpu
    number is reasonable before using it to check whether the stack is on
    the softirq or hardirq stack.
    
    Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
 arch/powerpc/kernel/process.c |   43 ++++++++++++++++++++++++++++------------
 1 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index f3d4dd5..972b2ac 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -818,6 +818,35 @@ out:
        return error;
 }
 
+#ifdef CONFIG_IRQSTACKS
+static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
+                                 unsigned long nbytes)
+{
+       unsigned long stack_page;
+       unsigned long cpu = task_cpu(p);
+
+       /*
+        * Avoid crashing if the stack has overflowed and corrupted
+        * task_cpu(p), which is in the thread_info struct.
+        */
+       if (cpu < NR_CPUS && cpu_possible(cpu)) {
+               stack_page = (unsigned long) hardirq_ctx[cpu];
+               if (sp >= stack_page + sizeof(struct thread_struct)
+                   && sp <= stack_page + THREAD_SIZE - nbytes)
+                       return 1;
+
+               stack_page = (unsigned long) softirq_ctx[cpu];
+               if (sp >= stack_page + sizeof(struct thread_struct)
+                   && sp <= stack_page + THREAD_SIZE - nbytes)
+                       return 1;
+       }
+       return 0;
+}
+
+#else
+#define valid_irq_stack(sp, p, nb)     0
+#endif /* CONFIG_IRQSTACKS */
+
 int validate_sp(unsigned long sp, struct task_struct *p,
                       unsigned long nbytes)
 {
@@ -827,19 +856,7 @@ int validate_sp(unsigned long sp, struct task_struct *p,
            && sp <= stack_page + THREAD_SIZE - nbytes)
                return 1;
 
-#ifdef CONFIG_IRQSTACKS
-       stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
-       if (sp >= stack_page + sizeof(struct thread_struct)
-           && sp <= stack_page + THREAD_SIZE - nbytes)
-               return 1;
-
-       stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
-       if (sp >= stack_page + sizeof(struct thread_struct)
-           && sp <= stack_page + THREAD_SIZE - nbytes)
-               return 1;
-#endif
-
-       return 0;
+       return valid_irq_stack(sp, p, nbytes);
 }
 
 #ifdef CONFIG_PPC64
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to