--- zzzz-none-000/linux-2.6.19.2/arch/i386/kernel/ptrace.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/arch/i386/kernel/ptrace.c 2007-01-19 14:42:56.000000000 +0000 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -169,15 +170,15 @@ * and APM bios ones we just ignore here. */ if (seg & LDT_SEGMENT) { - u32 *desc; + struct desc_struct *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); + desc = &child->mm->context.ldt[seg >> 3]; + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000); /* 16-bit code segment? */ - if (!((desc[1] >> 22) & 1)) + if (!((desc->b >> 22) & 1)) addr &= 0xffff; addr += base; up(&child->mm->context.sem); @@ -342,6 +343,11 @@ if (copy_from_user(&info, user_desc, sizeof(info))) return -EFAULT; +#ifdef CONFIG_PAX_SEGMEXEC + if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) + return -EINVAL; +#endif + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) return -EINVAL; @@ -432,6 +438,17 @@ if(addr == (long) &dummy->u_debugreg[5]) break; if(addr < (long) &dummy->u_debugreg[4] && ((unsigned long) data) >= TASK_SIZE-3) break; + +#ifdef CONFIG_GRKERNSEC + if(addr >= (long) &dummy->u_debugreg[0] && + addr <= (long) &dummy->u_debugreg[3]){ + long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2; + long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3; + long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3; + if((type & 1) && (data & align)) + break; + } +#endif /* Sanity-check data. Take one half-byte at once with * check = (val >> (16 + 4*i)) & 0xf. It contains the @@ -648,7 +665,7 @@ info.si_code = TRAP_BRKPT; /* User-mode eip? */ - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL; + info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL; /* Send us the fakey SIGTRAP */ force_sig_info(SIGTRAP, &info, tsk);