Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/compat/netbsd32 PR/55547: Dan Plassche: Fix BSD/OS binar...
details: https://anonhg.NetBSD.org/src/rev/06292d55d68c
branches: trunk
changeset: 974686:06292d55d68c
user: christos <christos%NetBSD.org@localhost>
date: Sat Aug 08 19:08:48 2020 +0000
description:
PR/55547: Dan Plassche: Fix BSD/OS binary emulation.
Centralize lcall sniffer and recognize the BSD/OS flavor.
diffstat:
sys/arch/i386/i386/trap.c | 18 +++++++-----------
sys/arch/x86/include/cpu.h | 3 ++-
sys/arch/x86/x86/cpu.c | 27 +++++++++++++++++++++++++--
sys/compat/netbsd32/netbsd32_mod.c | 27 +++++++++++++--------------
4 files changed, 47 insertions(+), 28 deletions(-)
diffs (165 lines):
diff -r cde8ee1ad6fc -r 06292d55d68c sys/arch/i386/i386/trap.c
--- a/sys/arch/i386/i386/trap.c Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/arch/i386/i386/trap.c Sat Aug 08 19:08:48 2020 +0000
@@ -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 @@
/* 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);
diff -r cde8ee1ad6fc -r 06292d55d68c sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/arch/x86/include/cpu.h Sat Aug 08 19:08:48 2020 +0000
@@ -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 @@
/* 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 *);
diff -r cde8ee1ad6fc -r 06292d55d68c sys/arch/x86/x86/cpu.c
--- a/sys/arch/x86/x86/cpu.c Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/arch/x86/x86/cpu.c Sat Aug 08 19:08:48 2020 +0000
@@ -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 @@
{
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;
+ }
+}
diff -r cde8ee1ad6fc -r 06292d55d68c sys/compat/netbsd32/netbsd32_mod.c
--- a/sys/compat/netbsd32/netbsd32_mod.c Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/compat/netbsd32/netbsd32_mod.c Sat Aug 08 19:08:48 2020 +0000
@@ -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 @@
};
#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__) */
Home |
Main Index |
Thread Index |
Old Index