From owner-svn-src-head@freebsd.org Sat Mar 16 11:44:39 2019 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3756B1527409; Sat, 16 Mar 2019 11:44:39 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id C50F284DE8; Sat, 16 Mar 2019 11:44:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B215921927; Sat, 16 Mar 2019 11:44:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x2GBicH0041262; Sat, 16 Mar 2019 11:44:38 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x2GBiYms041236; Sat, 16 Mar 2019 11:44:34 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201903161144.x2GBiYms041236@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Sat, 16 Mar 2019 11:44:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r345228 - in head/sys: amd64/amd64 amd64/include arm/arm arm/include arm64/arm64 arm64/include compat/freebsd32 i386/i386 i386/include kern mips/include mips/mips powerpc/include powerp... X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in head/sys: amd64/amd64 amd64/include arm/arm arm/include arm64/arm64 arm64/include compat/freebsd32 i386/i386 i386/include kern mips/include mips/mips powerpc/include powerpc/powerpc riscv/include r... X-SVN-Commit-Revision: 345228 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: C50F284DE8 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.96)[-0.964,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Mar 2019 11:44:39 -0000 Author: kib Date: Sat Mar 16 11:44:33 2019 New Revision: 345228 URL: https://svnweb.freebsd.org/changeset/base/345228 Log: amd64 KPTI: add control from procctl(2). Add the infrastructure to allow MD procctl(2) commands, and use it to introduce amd64 PTI control and reporting. PTI mode cannot be modified for existing pmap, the knob controls PTI of the new vmspace created on exec. Requested by: jhb Reviewed by: jhb, markj (previous version) Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D19514 Added: head/sys/amd64/include/procctl.h (contents, props changed) head/sys/arm/include/procctl.h (contents, props changed) head/sys/arm64/include/procctl.h (contents, props changed) head/sys/i386/include/procctl.h (contents, props changed) head/sys/mips/include/procctl.h (contents, props changed) head/sys/powerpc/include/procctl.h (contents, props changed) head/sys/riscv/include/procctl.h (contents, props changed) head/sys/sparc64/include/procctl.h (contents, props changed) head/sys/x86/include/procctl.h (contents, props changed) Modified: head/sys/amd64/amd64/vm_machdep.c head/sys/arm/arm/vm_machdep.c head/sys/arm64/arm64/vm_machdep.c head/sys/compat/freebsd32/freebsd32_misc.c head/sys/i386/i386/vm_machdep.c head/sys/kern/kern_procctl.c head/sys/mips/mips/vm_machdep.c head/sys/powerpc/powerpc/vm_machdep.c head/sys/riscv/riscv/vm_machdep.c head/sys/sparc64/sparc64/vm_machdep.c head/sys/sys/proc.h head/sys/sys/procctl.h Modified: head/sys/amd64/amd64/vm_machdep.c ============================================================================== --- head/sys/amd64/amd64/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/amd64/amd64/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -59,13 +59,16 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include #include #include #include +#include #include #include @@ -375,6 +378,66 @@ cpu_exec_vmspace_reuse(struct proc *p, vm_map_t map) return (((curproc->p_md.md_flags & P_MD_KPTI) != 0) == (vm_map_pmap(map)->pm_ucr3 != PMAP_NO_CR3)); +} + +static void +cpu_procctl_kpti(struct proc *p, int com, int *val) +{ + + if (com == PROC_KPTI_CTL) { + if (pti && *val == PROC_KPTI_CTL_ENABLE_ON_EXEC) + p->p_md.md_flags |= P_MD_KPTI; + if (*val == PROC_KPTI_CTL_DISABLE_ON_EXEC) + p->p_md.md_flags &= ~P_MD_KPTI; + } else /* PROC_KPTI_STATUS */ { + *val = (p->p_md.md_flags & P_MD_KPTI) != 0 ? + PROC_KPTI_CTL_ENABLE_ON_EXEC: + PROC_KPTI_CTL_DISABLE_ON_EXEC; + if (vmspace_pmap(p->p_vmspace)->pm_ucr3 != PMAP_NO_CR3) + *val |= PROC_KPTI_STATUS_ACTIVE; + } +} + +int +cpu_procctl(struct thread *td, int idtype, id_t id, int com, void *data) +{ + struct proc *p; + int error, val; + + switch (com) { + case PROC_KPTI_CTL: + case PROC_KPTI_STATUS: + if (idtype != P_PID) { + error = EINVAL; + break; + } + if (com == PROC_KPTI_CTL) { + /* sad but true and not a joke */ + error = priv_check(td, PRIV_IO); + if (error != 0) + break; + error = copyin(data, &val, sizeof(val)); + if (error != 0) + break; + if (val != PROC_KPTI_CTL_ENABLE_ON_EXEC && + val != PROC_KPTI_CTL_DISABLE_ON_EXEC) { + error = EINVAL; + break; + } + } + error = pget(id, PGET_CANSEE | PGET_NOTWEXIT | PGET_NOTID, &p); + if (error == 0) { + cpu_procctl_kpti(p, com, &val); + PROC_UNLOCK(p); + if (com == PROC_KPTI_STATUS) + error = copyout(&val, data, sizeof(val)); + } + break; + default: + error = EINVAL; + break; + } + return (error); } void Added: head/sys/amd64/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/amd64/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,6 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ + +#include Modified: head/sys/arm/arm/vm_machdep.c ============================================================================== --- head/sys/arm/arm/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/arm/arm/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -352,3 +352,10 @@ cpu_exec_vmspace_reuse(struct proc *p __unused, vm_map return (true); } +int +cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, + int com __unused, void *data __unused) +{ + + return (EINVAL); +} Added: head/sys/arm/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,4 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ Modified: head/sys/arm64/arm64/vm_machdep.c ============================================================================== --- head/sys/arm64/arm64/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/arm64/arm64/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -286,6 +286,14 @@ cpu_exec_vmspace_reuse(struct proc *p __unused, vm_map return (true); } +int +cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, + int com __unused, void *data __unused) +{ + + return (EINVAL); +} + void swi_vm(void *v) { Added: head/sys/arm64/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm64/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,4 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ Modified: head/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_misc.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/compat/freebsd32/freebsd32_misc.c Sat Mar 16 11:44:33 2019 (r345228) @@ -3327,6 +3327,10 @@ freebsd32_procctl(struct thread *td, struct freebsd32_ } x32; int error, error1, flags, signum; + if (uap->com >= PROC_PROCCTL_MD_MIN) + return (cpu_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id), + uap->com, PTRIN(uap->data))); + switch (uap->com) { case PROC_ASLR_CTL: case PROC_SPROTECT: Modified: head/sys/i386/i386/vm_machdep.c ============================================================================== --- head/sys/i386/i386/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/i386/i386/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -389,6 +389,14 @@ cpu_exec_vmspace_reuse(struct proc *p __unused, vm_map return (true); } +int +cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, + int com __unused, void *data __unused) +{ + + return (EINVAL); +} + void cpu_set_syscall_retval(struct thread *td, int error) { Added: head/sys/i386/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/i386/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,6 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ + +#include Modified: head/sys/kern/kern_procctl.c ============================================================================== --- head/sys/kern/kern_procctl.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/kern/kern_procctl.c Sat Mar 16 11:44:33 2019 (r345228) @@ -494,6 +494,10 @@ sys_procctl(struct thread *td, struct procctl_args *ua } x; int error, error1, flags, signum; + if (uap->com >= PROC_PROCCTL_MD_MIN) + return (cpu_procctl(td, uap->idtype, uap->id, + uap->com, uap->data)); + switch (uap->com) { case PROC_ASLR_CTL: case PROC_SPROTECT: Added: head/sys/mips/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,4 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ Modified: head/sys/mips/mips/vm_machdep.c ============================================================================== --- head/sys/mips/mips/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/mips/mips/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -460,6 +460,14 @@ cpu_exec_vmspace_reuse(struct proc *p __unused, vm_map return (true); } +int +cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, + int com __unused, void *data __unused) +{ + + return (EINVAL); +} + /* * Software interrupt handler for queued VM system processing. */ Added: head/sys/powerpc/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/powerpc/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,4 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ Modified: head/sys/powerpc/powerpc/vm_machdep.c ============================================================================== --- head/sys/powerpc/powerpc/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/powerpc/powerpc/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -256,3 +256,10 @@ cpu_exec_vmspace_reuse(struct proc *p __unused, vm_map return (true); } +int +cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, + int com __unused, void *data __unused) +{ + + return (EINVAL); +} Added: head/sys/riscv/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/riscv/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,4 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ Modified: head/sys/riscv/riscv/vm_machdep.c ============================================================================== --- head/sys/riscv/riscv/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/riscv/riscv/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -271,6 +271,14 @@ cpu_exec_vmspace_reuse(struct proc *p __unused, vm_map return (true); } +int +cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, + int com __unused, void *data __unused) +{ + + return (EINVAL); +} + void swi_vm(void *v) { Added: head/sys/sparc64/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/sparc64/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,4 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ Modified: head/sys/sparc64/sparc64/vm_machdep.c ============================================================================== --- head/sys/sparc64/sparc64/vm_machdep.c Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/sparc64/sparc64/vm_machdep.c Sat Mar 16 11:44:33 2019 (r345228) @@ -381,6 +381,14 @@ cpu_exec_vmspace_reuse(struct proc *p __unused, vm_map } int +cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, + int com __unused, void *data __unused) +{ + + return (EINVAL); +} + +int is_physical_memory(vm_paddr_t addr) { struct ofw_mem_region *mr; Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/sys/proc.h Sat Mar 16 11:44:33 2019 (r345228) @@ -1097,6 +1097,8 @@ bool cpu_exec_vmspace_reuse(struct proc *p, struct vm_ int cpu_fetch_syscall_args(struct thread *td); void cpu_fork(struct thread *, struct proc *, struct thread *, int); void cpu_fork_kthread_handler(struct thread *, void (*)(void *), void *); +int cpu_procctl(struct thread *td, int idtype, id_t id, int com, + void *data); void cpu_set_syscall_retval(struct thread *, int); void cpu_set_upcall(struct thread *, void (*)(void *), void *, stack_t *); Modified: head/sys/sys/procctl.h ============================================================================== --- head/sys/sys/procctl.h Sat Mar 16 11:31:01 2019 (r345227) +++ head/sys/sys/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -41,6 +41,10 @@ #include #endif +/* MD PROCCTL verbs start at 0x10000000 */ +#define PROC_PROCCTL_MD_MIN 0x10000000 +#include + #define PROC_SPROTECT 1 /* set protected state */ #define PROC_REAP_ACQUIRE 2 /* reaping enable */ #define PROC_REAP_RELEASE 3 /* reaping disable */ Added: head/sys/x86/include/procctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/x86/include/procctl.h Sat Mar 16 11:44:33 2019 (r345228) @@ -0,0 +1,43 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 The FreeBSD Foundation + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _X86_PROCCTL_H +#define _X86_PROCCTL_H + +#define PROC_KPTI_CTL (PROC_PROCCTL_MD_MIN + 0) +#define PROC_KPTI_STATUS (PROC_PROCCTL_MD_MIN + 1) + +#define PROC_KPTI_CTL_ENABLE_ON_EXEC 1 +#define PROC_KPTI_CTL_DISABLE_ON_EXEC 2 +#define PROC_KPTI_STATUS_ACTIVE 0x80000000 + +#endif