lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 17 Jul 2006 19:58:41 -0400 From: Chuck Ebbert <76306.1226@...puserve.com> To: linux-kernel <linux-kernel@...r.kernel.org> Cc: Krzysztof Halasa <khc@...waw.pl>, Andrew Morton <akpm@...l.org>, Andi Kleen <ak@...e.de>, Linus Torvalds <torvalds@...l.org> Subject: [patch] i386: fix recursive faults during oops when current is invalid Fix recursive faults during oops caused by invalid value in current by using __get_user()/__put_user() when dereferencing it. Reported by Krzysztof Halasa <khc@...waw.pl> Signed-off-by: Chuck Ebbert <76306.1226@...puserve.com> --- If this is OK I'll do x86_64 next. arch/i386/kernel/traps.c | 17 +++++++++++++---- arch/i386/mm/fault.c | 7 ++++--- 2 files changed, 17 insertions(+), 7 deletions(-) --- 2.6.18-rc1-32.orig/arch/i386/mm/fault.c +++ 2.6.18-rc1-32/arch/i386/mm/fault.c @@ -585,9 +585,10 @@ no_context: printk(KERN_ALERT "*pte = %08lx\n", page); } #endif - tsk->thread.cr2 = address; - tsk->thread.trap_no = 14; - tsk->thread.error_code = error_code; + /* avoid possible fault here if tsk is garbage */ + __put_user(address, &tsk->thread.cr2); + __put_user(14, &tsk->thread.trap_no); + __put_user(error_code, &tsk->thread.error_code); die("Oops", regs, error_code); bust_spinlocks(0); do_exit(SIGKILL); --- 2.6.18-rc1-32.orig/arch/i386/kernel/traps.c +++ 2.6.18-rc1-32/arch/i386/kernel/traps.c @@ -267,8 +267,16 @@ void show_registers(struct pt_regs *regs int i; int in_kernel = 1; unsigned long esp; + char *comm = "<bad task>"; + pid_t pid = 0; + void *thread_info = 0; unsigned short ss; + __get_user(thread_info, ¤t->thread_info); + __get_user(pid, ¤t->pid); + if (!__get_user(comm, (char **)current->comm)) + comm = current->comm; + esp = (unsigned long) (®s->esp); savesegment(ss, ss); if (user_mode_vm(regs)) { @@ -291,8 +299,8 @@ void show_registers(struct pt_regs *regs printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", regs->xds & 0xffff, regs->xes & 0xffff, ss); printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", - TASK_COMM_LEN, current->comm, current->pid, - current_thread_info(), current, current->thread_info); + TASK_COMM_LEN, comm, pid, + current_thread_info(), current, thread_info); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. @@ -371,6 +379,7 @@ void die(const char * str, struct pt_reg }; static int die_counter; unsigned long flags; + unsigned long trap_no = 0; /* default if task pointer is corrupt */ oops_enter(); @@ -409,8 +418,8 @@ void die(const char * str, struct pt_reg #endif if (nl) printk("\n"); - if (notify_die(DIE_OOPS, str, regs, err, - current->thread.trap_no, SIGSEGV) != + __get_user(trap_no, ¤t->thread.trap_no); + if (notify_die(DIE_OOPS, str, regs, err, trap_no, SIGSEGV) != NOTIFY_STOP) { show_registers(regs); /* Executive summary in case the oops scrolled away */ -- Chuck - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists