Module Name:    src
Committed By:   christos
Date:           Sat Aug  8 19:08:48 UTC 2020

Modified Files:
        src/sys/arch/i386/i386: trap.c
        src/sys/arch/x86/include: cpu.h
        src/sys/arch/x86/x86: cpu.c
        src/sys/compat/netbsd32: netbsd32_mod.c

Log Message:
PR/55547: Dan Plassche: Fix BSD/OS binary emulation.
Centralize lcall sniffer and recognize the BSD/OS flavor.


To generate a diff of this commit:
cvs rdiff -u -r1.304 -r1.305 src/sys/arch/i386/i386/trap.c
cvs rdiff -u -r1.128 -r1.129 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.196 -r1.197 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.22 -r1.23 src/sys/compat/netbsd32/netbsd32_mod.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/i386/i386/trap.c
diff -u src/sys/arch/i386/i386/trap.c:1.304 src/sys/arch/i386/i386/trap.c:1.305
--- src/sys/arch/i386/i386/trap.c:1.304	Mon Jul 13 20:45:52 2020
+++ src/sys/arch/i386/i386/trap.c	Sat Aug  8 15:08:48 2020
@@ -1,5 +1,5 @@
 
-/*	$NetBSD: trap.c,v 1.304 2020/07/14 00:45:52 yamaguchi Exp $	*/
+/*	$NetBSD: trap.c,v 1.305 2020/08/08 19:08:48 christos Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.304 2020/07/14 00:45:52 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.305 2020/08/08 19:08:48 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -447,19 +447,15 @@ kernelfault:
 		/* NOTREACHED */
 
 	case T_PROTFLT|T_USER:		/* protection fault */
-#if defined(COMPAT_10)
+#if defined(COMPAT_10) || defined(COMPAT_NOMID)
 	{
-		static const char lcall[7] = { 0x9a, 0, 0, 0, 0, 7, 0 };
-		const size_t sz = sizeof(lcall);
-		char tmp[sizeof(lcall)];
-
+#define LCALLSZ 7
 		/* Check for the osyscall lcall instruction. */
-		if (frame->tf_eip < VM_MAXUSER_ADDRESS - sz &&
-		    copyin((void *)frame->tf_eip, tmp, sz) == 0 &&
-		    memcmp(tmp, lcall, sz) == 0) {
+		if (frame->tf_eip < VM_MAXUSER_ADDRESS - LCALLSZ &&
+		    x86_cpu_is_lcall((const void *)frame->tf_eip)) {
 
 			/* Advance past the lcall. */
-			frame->tf_eip += sz;
+			frame->tf_eip += LCALLSZ;
 
 			/* Do the syscall. */
 			p->p_md.md_syscall(frame);

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.128 src/sys/arch/x86/include/cpu.h:1.129
--- src/sys/arch/x86/include/cpu.h:1.128	Sun Jul 19 09:55:09 2020
+++ src/sys/arch/x86/include/cpu.h	Sat Aug  8 15:08:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.128 2020/07/19 13:55:09 maxv Exp $	*/
+/*	$NetBSD: cpu.h,v 1.129 2020/08/08 19:08:48 christos Exp $	*/
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -564,6 +564,7 @@ extern void (*x86_delay)(unsigned int);
 
 /* cpu.c */
 void	cpu_probe_features(struct cpu_info *);
+int	x86_cpu_is_lcall(const void *);
 
 /* vm_machdep.c */
 void	cpu_proc_fork(struct proc *, struct proc *);

Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.196 src/sys/arch/x86/x86/cpu.c:1.197
--- src/sys/arch/x86/x86/cpu.c:1.196	Tue Jul 28 10:49:55 2020
+++ src/sys/arch/x86/x86/cpu.c	Sat Aug  8 15:08:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.196 2020/07/28 14:49:55 fcambus Exp $	*/
+/*	$NetBSD: cpu.c,v 1.197 2020/08/08 19:08:48 christos Exp $	*/
 
 /*
  * Copyright (c) 2000-2020 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.196 2020/07/28 14:49:55 fcambus Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.197 2020/08/08 19:08:48 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"		/* for MPDEBUG */
@@ -1451,3 +1451,26 @@ cpu_kick(struct cpu_info *ci)
 {
 	x86_send_ipi(ci, X86_IPI_AST);
 }
+
+int
+x86_cpu_is_lcall(const void *ip)
+{
+        static const uint8_t lcall[] = { 0x9a, 0, 0, 0, 0 };
+	int error;
+        const size_t sz = sizeof(lcall) + 2;
+        uint8_t tmp[sizeof(lcall) + 2];
+
+	if ((error = copyin(ip, tmp, sz)) != 0)
+		return error;
+
+	if (memcmp(tmp, lcall, sizeof(lcall)) != 0 || tmp[sz - 1] != 0)
+		return EINVAL;
+
+	switch (tmp[sz - 2]) {
+        case (uint8_t)0x07: /* NetBSD */
+	case (uint8_t)0x87: /* BSD/OS */
+		return 0;
+	default:
+		return EINVAL;
+        }
+}

Index: src/sys/compat/netbsd32/netbsd32_mod.c
diff -u src/sys/compat/netbsd32/netbsd32_mod.c:1.22 src/sys/compat/netbsd32/netbsd32_mod.c:1.23
--- src/sys/compat/netbsd32/netbsd32_mod.c:1.22	Sat Mar 21 12:17:08 2020
+++ src/sys/compat/netbsd32/netbsd32_mod.c	Sat Aug  8 15:08:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_mod.c,v 1.22 2020/03/21 16:17:08 pgoyette Exp $	*/
+/*	$NetBSD: netbsd32_mod.c,v 1.23 2020/08/08 19:08:48 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_mod.c,v 1.22 2020/03/21 16:17:08 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_mod.c,v 1.23 2020/08/08 19:08:48 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_execfmt.h"
@@ -131,29 +131,28 @@ static struct execsw netbsd32_execsw[] =
 };
 
 #if defined(__amd64__)
+#include <x86/cpu.h>
 
 /* This code was moved here, from $SRC/arch/amd64/amd64/trap.c */
 
 static int
 amd64_oosyscall_handle(struct proc *p, struct trapframe *frame)
 {
-
-	static const char lcall[7] = { 0x9a, 0, 0, 0, 0, 7, 0 };
-	const size_t sz = sizeof(lcall);
-	char tmp[sizeof(lcall) /* Avoids VLA */];
+	int error = EPASSTHROUGH;
+#define LCALLSZ	7
 
 	/* Check for the oosyscall lcall instruction. */
 	if (p->p_emul == &emul_netbsd32 &&
-	    frame->tf_rip < VM_MAXUSER_ADDRESS32 - sz &&
-	    copyin((void *)frame->tf_rip, tmp, sz) == 0 &&
-	    memcmp(tmp, lcall, sz) == 0) {
-
+	    frame->tf_rip < VM_MAXUSER_ADDRESS32 - LCALLSZ && 
+	    (error = x86_cpu_is_lcall((void *)frame->tf_rip)) == 0)
+	{
 		/* Advance past the lcall and save instruction size. */
-		frame->tf_rip += sz;
-		frame->tf_err = sz;
+		frame->tf_rip += LCALLSZ;
+		frame->tf_err = LCALLSZ;
 		return 0;
-	} else
-		return EPASSTHROUGH;
+	}
+
+	return error;
 }
 #endif /* defined(__amd64__) */
 

Reply via email to