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-stable mailing list