Date: Thu, 5 Oct 2017 11:01:19 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r324300 - stable/11/sys/i386/i386 Message-ID: <201710051101.v95B1JDu002184@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Oct 5 11:01:19 2017 New Revision: 324300 URL: https://svnweb.freebsd.org/changeset/base/324300 Log: MFC r324080: Zero segment registers which contained invalid usermode selectors, when returning to kernel. Modified: stable/11/sys/i386/i386/exception.s stable/11/sys/i386/i386/genassym.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/i386/i386/exception.s ============================================================================== --- stable/11/sys/i386/i386/exception.s Thu Oct 5 11:00:04 2017 (r324299) +++ stable/11/sys/i386/i386/exception.s Thu Oct 5 11:01:19 2017 (r324300) @@ -425,8 +425,16 @@ doreti_iret: * doreti_iret_fault and friends. Alternative return code for * the case where we get a fault in the doreti_exit code * above. trap() (i386/i386/trap.c) catches this specific - * case, sends the process a signal and continues in the - * corresponding place in the code below. + * case, and continues in the corresponding place in the code + * below. + * + * If the fault occured during return to usermode, we recreate + * the trap frame and call trap() to send a signal. Otherwise + * the kernel was tricked into fault by attempt to restore invalid + * usermode segment selectors on return from nested fault or + * interrupt, where interrupted kernel entry code not yet loaded + * kernel selectors. In the latter case, emulate iret and zero + * the invalid selector. */ ALIGN_TEXT .globl doreti_iret_fault @@ -437,18 +445,35 @@ doreti_iret_fault: movw %ds,(%esp) .globl doreti_popl_ds_fault doreti_popl_ds_fault: + testb $SEL_RPL_MASK,TF_CS-TF_DS(%esp) + jz doreti_popl_ds_kfault pushl $0 movw %es,(%esp) .globl doreti_popl_es_fault doreti_popl_es_fault: + testb $SEL_RPL_MASK,TF_CS-TF_ES(%esp) + jz doreti_popl_es_kfault pushl $0 movw %fs,(%esp) .globl doreti_popl_fs_fault doreti_popl_fs_fault: + testb $SEL_RPL_MASK,TF_CS-TF_FS(%esp) + jz doreti_popl_fs_kfault sti movl $0,TF_ERR(%esp) /* XXX should be the error code */ movl $T_PROTFLT,TF_TRAPNO(%esp) jmp alltraps_with_regs_pushed + +doreti_popl_ds_kfault: + movl $0,(%esp) + jmp doreti_popl_ds +doreti_popl_es_kfault: + movl $0,(%esp) + jmp doreti_popl_es +doreti_popl_fs_kfault: + movl $0,(%esp) + jmp doreti_popl_fs + #ifdef HWPMC_HOOKS doreti_nmi: /* Modified: stable/11/sys/i386/i386/genassym.c ============================================================================== --- stable/11/sys/i386/i386/genassym.c Thu Oct 5 11:00:04 2017 (r324299) +++ stable/11/sys/i386/i386/genassym.c Thu Oct 5 11:01:19 2017 (r324300) @@ -160,11 +160,15 @@ ASSYM(PCB_IDT, offsetof(struct pcb, pcb_idt)); ASSYM(PCB_LDT, offsetof(struct pcb, pcb_ldt)); ASSYM(PCB_TR, offsetof(struct pcb, pcb_tr)); +ASSYM(TF_FS, offsetof(struct trapframe, tf_fs)); +ASSYM(TF_ES, offsetof(struct trapframe, tf_es)); +ASSYM(TF_DS, offsetof(struct trapframe, tf_ds)); ASSYM(TF_TRAPNO, offsetof(struct trapframe, tf_trapno)); ASSYM(TF_ERR, offsetof(struct trapframe, tf_err)); ASSYM(TF_EIP, offsetof(struct trapframe, tf_eip)); ASSYM(TF_CS, offsetof(struct trapframe, tf_cs)); ASSYM(TF_EFLAGS, offsetof(struct trapframe, tf_eflags)); + ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler)); #ifdef COMPAT_43 ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201710051101.v95B1JDu002184>