From: Roland McGrath <[EMAIL PROTECTED]>
Date: Mon, 16 Jul 2007 08:03:16 +0000 (-0700)
Subject: Handle bogus %cs selector in single-step instruction decoding
Patch-mainline: 2.6.23-rc1
References: 326270, CVE-2007-3731

Handle bogus %cs selector in single-step instruction decoding

The code for LDT segment selectors was not robust in the face of a bogus
selector set in %cs via ptrace before the single-step was done.

Signed-off-by: Roland McGrath <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
Acked-by: Jeff Mahoney <[EMAIL PROTECTED]>
---

 arch/i386/kernel/ptrace.c   |   22 +++++++++++++++-------
 arch/x86_64/kernel/ptrace.c |   23 ++++++++++++++++-------
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 1c075f5..0c8f00e 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -164,14 +164,22 @@ static unsigned long
convert_eip_to_linear(struct task_struct *child, struct pt_
                u32 *desc;
                unsigned long base;

-               down(&child->mm->context.sem);
-               desc = child->mm->context.ldt + (seg & ~7);
-               base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 
0xff000000);
+               seg &= ~7UL;

-               /* 16-bit code segment? */
-               if (!((desc[1] >> 22) & 1))
-                       addr &= 0xffff;
-               addr += base;
+               down(&child->mm->context.sem);
+               if (unlikely((seg >> 3) >= child->mm->context.size))
+                       addr = -1L; /* bogus selector, access would fault */
+               else {
+                       desc = child->mm->context.ldt + seg;
+                       base = ((desc[0] >> 16) |
+                               ((desc[1] & 0xff) << 16) |
+                               (desc[1] & 0xff000000));
+
+                       /* 16-bit code segment? */
+                       if (!((desc[1] >> 22) & 1))
+                               addr &= 0xffff;
+                       addr += base;
+               }
                up(&child->mm->context.sem);
        }
        return addr;
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index fa6775e..e83cc67 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -102,16 +102,25 @@ unsigned long convert_rip_to_linear(struct
task_struct *child, struct pt_regs *r
                u32 *desc;
                unsigned long base;

-               down(&child->mm->context.sem);
-               desc = child->mm->context.ldt + (seg & ~7);
-               base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 
0xff000000);
+               seg &= ~7UL;

-               /* 16-bit code segment? */
-               if (!((desc[1] >> 22) & 1))
-                       addr &= 0xffff;
-               addr += base;
+               down(&child->mm->context.sem);
+               if (unlikely((seg >> 3) >= child->mm->context.size))
+                       addr = -1L; /* bogus selector, access would fault */
+               else {
+                       desc = child->mm->context.ldt + seg;
+                       base = ((desc[0] >> 16) |
+                               ((desc[1] & 0xff) << 16) |
+                               (desc[1] & 0xff000000));
+
+                       /* 16-bit code segment? */
+                       if (!((desc[1] >> 22) & 1))
+                               addr &= 0xffff;
+                       addr += base;
+               }
                up(&child->mm->context.sem);
        }
+
        return addr;
 }



On 2/2/08, Oliver Pinter (Pintér Olivér) <[EMAIL PROTECTED]> wrote:
> mainline: 29eb51101c02df517ca64ec472d7501127ad1da8
>
>
> --
> Thanks,
> Oliver
>


-- 
Thanks,
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to