svn commit: r324300 - stable/11/sys/i386/i386
Konstantin Belousov
kib at FreeBSD.org
Thu Oct 5 11:01:21 UTC 2017
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));
More information about the svn-src-all
mailing list