Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Mar 2019 16:33:45 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r345067 - in stable/12: lib/libc/sys sys/amd64/amd64 sys/arm/arm sys/arm64/arm64 sys/compat/freebsd32 sys/compat/ia32 sys/i386/i386 sys/kern sys/mips/mips sys/powerpc/powerpc sys/riscv/...
Message-ID:  <201903121633.x2CGXjll043779@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Mar 12 16:33:44 2019
New Revision: 345067
URL: https://svnweb.freebsd.org/changeset/base/345067

Log:
  MFC r343964, r344121, r344128, r344593, r344594:
  ASLR.

Added:
  stable/12/usr.bin/proccontrol/proccontrol.1
     - copied unchanged from r344594, head/usr.bin/proccontrol/proccontrol.1
Modified:
  stable/12/lib/libc/sys/procctl.2
  stable/12/sys/amd64/amd64/elf_machdep.c
  stable/12/sys/arm/arm/elf_machdep.c
  stable/12/sys/arm64/arm64/elf_machdep.c
  stable/12/sys/compat/freebsd32/freebsd32_misc.c
  stable/12/sys/compat/ia32/ia32_sysvec.c
  stable/12/sys/i386/i386/elf_machdep.c
  stable/12/sys/kern/imgact_elf.c
  stable/12/sys/kern/kern_exec.c
  stable/12/sys/kern/kern_fork.c
  stable/12/sys/kern/kern_procctl.c
  stable/12/sys/mips/mips/elf_machdep.c
  stable/12/sys/powerpc/powerpc/elf32_machdep.c
  stable/12/sys/powerpc/powerpc/elf64_machdep.c
  stable/12/sys/riscv/riscv/elf_machdep.c
  stable/12/sys/sparc64/sparc64/elf_machdep.c
  stable/12/sys/sys/imgact.h
  stable/12/sys/sys/proc.h
  stable/12/sys/sys/procctl.h
  stable/12/sys/sys/sysent.h
  stable/12/sys/vm/vm_map.c
  stable/12/sys/vm/vm_map.h
  stable/12/usr.bin/proccontrol/Makefile
  stable/12/usr.bin/proccontrol/proccontrol.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/lib/libc/sys/procctl.2
==============================================================================
--- stable/12/lib/libc/sys/procctl.2	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/lib/libc/sys/procctl.2	Tue Mar 12 16:33:44 2019	(r345067)
@@ -72,6 +72,46 @@ The control request to perform is specified by the
 argument.
 The following commands are supported:
 .Bl -tag -width PROC_TRAPCAP_STATUS
+.It Dv PROC_ASLR_CTL
+Controls the Address Space Layout Randomization (ASLR) in the program
+images created
+by
+.Xr execve 2
+in the specified process or its descendants that did not changed
+the control nor modified it by other means.
+The
+.Va arg
+parameter must point to the integer variable holding one of the following
+values:
+.Bl -tag -width PROC_ASLR_FORCE_DISABLE
+.It Dv PROC_ASLR_FORCE_ENABLE
+Request that ASLR is enabled after execution, even if it is disabled
+system-wide.
+The image flag and set-uid might prevent ASLR enablement still.
+.It Dv PROC_ASLR_FORCE_DISABLE
+Request that ASLR is disabled after execution.
+Same notes as for
+.Dv PROC_ASKR_FORCE_ENABLE
+apply.
+.It Dv PROC_ASLR_NOFORCE
+Use system-wide configured policy for ASLR.
+.El
+.It Dv PROC_ASLR_STATUS
+Returns the current status of ASLR enablement for the target process.
+The
+.Va arg
+parameter must point to the integer variable, where one of the
+following values is written:
+.Bl -tag -width PROC_ASLR_FORCE_DISABLE
+.It Dv PROC_ASLR_FORCE_ENABLE
+.It Dv PROC_ASLR_FORCE_DISABLE
+.It Dv PROC_ASLR_NOFORCE
+.El
+.Pp
+If the currently executed image in the process itself has ASLR enabled,
+the
+.Dv PROC_ASLR_ACTIVE
+flag is or-ed with the value listed above.
 .It Dv PROC_SPROTECT
 Set process protection state.
 This is used to mark a process as protected from being killed if the system
@@ -543,11 +583,16 @@ The
 .Fn procctl
 function appeared in
 .Fx 10.0 .
+.Pp
 The reaper facility is based on a similar feature of Linux and
 DragonflyBSD, and first appeared in
 .Fx 10.2 .
+.Pp
 The
 .Dv PROC_PDEATHSIG_CTL
 facility is based on the prctl(PR_SET_PDEATHSIG, ...) feature of Linux,
 and first appeared in
 .Fx 11.2 .
+.Pp
+The ASLR support was added to system for the checklists compliance in
+.Fx 13.0 .

Modified: stable/12/sys/amd64/amd64/elf_machdep.c
==============================================================================
--- stable/12/sys/amd64/amd64/elf_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/amd64/amd64/elf_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -74,7 +74,8 @@ struct sysentvec elf64_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_TIMEKEEP,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_LP64 | SV_SHP |
+			    SV_TIMEKEEP,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/arm/arm/elf_machdep.c
==============================================================================
--- stable/12/sys/arm/arm/elf_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/arm/arm/elf_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -83,9 +83,9 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_maxssiz	= NULL,
 	.sv_flags	=
 #if __ARM_ARCH >= 6
-			  SV_SHP | SV_TIMEKEEP |
+			  SV_ASLR | SV_SHP | SV_TIMEKEEP |
 #endif
-			  SV_ABI_FREEBSD | SV_ILP32,
+			  SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/arm64/arm64/elf_machdep.c
==============================================================================
--- stable/12/sys/arm64/arm64/elf_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/arm64/arm64/elf_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -80,7 +80,8 @@ static struct sysentvec elf64_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_SHP | SV_TIMEKEEP | SV_ABI_FREEBSD | SV_LP64,
+	.sv_flags	= SV_SHP | SV_TIMEKEEP | SV_ABI_FREEBSD | SV_LP64 |
+	    SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- stable/12/sys/compat/freebsd32/freebsd32_misc.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/compat/freebsd32/freebsd32_misc.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -3351,6 +3351,7 @@ freebsd32_procctl(struct thread *td, struct freebsd32_
 	int error, error1, flags, signum;
 
 	switch (uap->com) {
+	case PROC_ASLR_CTL:
 	case PROC_SPROTECT:
 	case PROC_TRACE_CTL:
 	case PROC_TRAPCAP_CTL:
@@ -3382,6 +3383,7 @@ freebsd32_procctl(struct thread *td, struct freebsd32_
 			return (error);
 		data = &x.rk;
 		break;
+	case PROC_ASLR_STATUS:
 	case PROC_TRACE_STATUS:
 	case PROC_TRAPCAP_STATUS:
 		data = &flags;
@@ -3410,6 +3412,7 @@ freebsd32_procctl(struct thread *td, struct freebsd32_
 		if (error == 0)
 			error = error1;
 		break;
+	case PROC_ASLR_STATUS:
 	case PROC_TRACE_STATUS:
 	case PROC_TRAPCAP_STATUS:
 		if (error == 0)

Modified: stable/12/sys/compat/ia32/ia32_sysvec.c
==============================================================================
--- stable/12/sys/compat/ia32/ia32_sysvec.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/compat/ia32/ia32_sysvec.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -120,7 +120,7 @@ struct sysentvec ia32_freebsd_sysvec = {
 	.sv_setregs	= ia32_setregs,
 	.sv_fixlimit	= ia32_fixlimit,
 	.sv_maxssiz	= &ia32_maxssiz,
-	.sv_flags	= SV_ABI_FREEBSD | SV_IA32 | SV_ILP32 |
+	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_IA32 | SV_ILP32 |
 			    SV_SHP | SV_TIMEKEEP,
 	.sv_set_syscall_retval = ia32_set_syscall_retval,
 	.sv_fetch_syscall_args = ia32_fetch_syscall_args,

Modified: stable/12/sys/i386/i386/elf_machdep.c
==============================================================================
--- stable/12/sys/i386/i386/elf_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/i386/i386/elf_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -76,8 +76,8 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_IA32 | SV_ILP32 | SV_SHP |
-			    SV_TIMEKEEP,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_IA32 | SV_ILP32 |
+			    SV_SHP | SV_TIMEKEEP,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/kern/imgact_elf.c
==============================================================================
--- stable/12/sys/kern/imgact_elf.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/kern/imgact_elf.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -137,6 +137,27 @@ SYSCTL_INT(_kern_elf32, OID_AUTO, read_exec, CTLFLAG_R
 #endif
 #endif
 
+SYSCTL_NODE(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, aslr, CTLFLAG_RW, 0,
+    "");
+#define	ASLR_NODE_OID	__CONCAT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), _aslr)
+
+static int __elfN(aslr_enabled) = 0;
+SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, enable, CTLFLAG_RWTUN,
+    &__elfN(aslr_enabled), 0,
+    __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
+    ": enable address map randomization");
+
+static int __elfN(pie_aslr_enabled) = 0;
+SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, pie_enable, CTLFLAG_RWTUN,
+    &__elfN(pie_aslr_enabled), 0,
+    __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
+    ": enable address map randomization for PIE binaries");
+
+static int __elfN(aslr_honor_sbrk) = 1;
+SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, honor_sbrk, CTLFLAG_RW,
+    &__elfN(aslr_honor_sbrk), 0,
+    __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) ": assume sbrk is used");
+
 static Elf_Brandinfo *elf_brand_list[MAX_BRANDS];
 
 #define	trunc_page_ps(va, ps)	rounddown2(va, ps)
@@ -774,6 +795,36 @@ fail:
 	return (error);
 }
 
+static u_long
+__CONCAT(rnd_, __elfN(base))(vm_map_t map __unused, u_long minv, u_long maxv,
+    u_int align)
+{
+	u_long rbase, res;
+
+	MPASS(vm_map_min(map) <= minv);
+	MPASS(maxv <= vm_map_max(map));
+	MPASS(minv < maxv);
+	MPASS(minv + align < maxv);
+	arc4rand(&rbase, sizeof(rbase), 0);
+	res = roundup(minv, (u_long)align) + rbase % (maxv - minv);
+	res &= ~((u_long)align - 1);
+	if (res >= maxv)
+		res -= align;
+	KASSERT(res >= minv,
+	    ("res %#lx < minv %#lx, maxv %#lx rbase %#lx",
+	    res, minv, maxv, rbase));
+	KASSERT(res < maxv,
+	    ("res %#lx > maxv %#lx, minv %#lx rbase %#lx",
+	    res, maxv, minv, rbase));
+	return (res);
+}
+
+/*
+ * Impossible et_dyn_addr initial value indicating that the real base
+ * must be calculated later with some randomization applied.
+ */
+#define	ET_DYN_ADDR_RAND	1
+
 static int
 __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
 {
@@ -782,6 +833,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	const Elf_Phdr *phdr;
 	Elf_Auxargs *elf_auxargs;
 	struct vmspace *vmspace;
+	vm_map_t map;
 	const char *err_str, *newinterp;
 	char *interp, *interp_buf, *path;
 	Elf_Brandinfo *brand_info;
@@ -789,6 +841,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	vm_prot_t prot;
 	u_long text_size, data_size, total_size, text_addr, data_addr;
 	u_long seg_size, seg_addr, addr, baddr, et_dyn_addr, entry, proghdr;
+	u_long maxalign, mapsz, maxv, maxv1;
 	uint32_t fctl0;
 	int32_t osrel;
 	int error, i, n, interp_name_len, have_interp;
@@ -832,12 +885,17 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	err_str = newinterp = NULL;
 	interp = interp_buf = NULL;
 	td = curthread;
+	maxalign = PAGE_SIZE;
+	mapsz = 0;
 
 	for (i = 0; i < hdr->e_phnum; i++) {
 		switch (phdr[i].p_type) {
 		case PT_LOAD:
 			if (n == 0)
 				baddr = phdr[i].p_vaddr;
+			if (phdr[i].p_align > maxalign)
+				maxalign = phdr[i].p_align;
+			mapsz += phdr[i].p_memsz;
 			n++;
 			break;
 		case PT_INTERP:
@@ -898,6 +956,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 		error = ENOEXEC;
 		goto ret;
 	}
+	sv = brand_info->sysvec;
 	et_dyn_addr = 0;
 	if (hdr->e_type == ET_DYN) {
 		if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) {
@@ -909,10 +968,18 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 		 * Honour the base load address from the dso if it is
 		 * non-zero for some reason.
 		 */
-		if (baddr == 0)
-			et_dyn_addr = ET_DYN_LOAD_ADDR;
+		if (baddr == 0) {
+			if ((sv->sv_flags & SV_ASLR) == 0 ||
+			    (fctl0 & NT_FREEBSD_FCTL_ASLR_DISABLE) != 0)
+				et_dyn_addr = ET_DYN_LOAD_ADDR;
+			else if ((__elfN(pie_aslr_enabled) &&
+			    (imgp->proc->p_flag2 & P2_ASLR_DISABLE) == 0) ||
+			    (imgp->proc->p_flag2 & P2_ASLR_ENABLE) != 0)
+				et_dyn_addr = ET_DYN_ADDR_RAND;
+			else
+				et_dyn_addr = ET_DYN_LOAD_ADDR;
+		}
 	}
-	sv = brand_info->sysvec;
 	if (interp != NULL && brand_info->interp_newpath != NULL)
 		newinterp = brand_info->interp_newpath;
 
@@ -929,9 +996,54 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	 */
 	VOP_UNLOCK(imgp->vp, 0);
 
+	/*
+	 * Decide whether to enable randomization of user mappings.
+	 * First, reset user preferences for the setid binaries.
+	 * Then, account for the support of the randomization by the
+	 * ABI, by user preferences, and make special treatment for
+	 * PIE binaries.
+	 */
+	if (imgp->credential_setid) {
+		PROC_LOCK(imgp->proc);
+		imgp->proc->p_flag2 &= ~(P2_ASLR_ENABLE | P2_ASLR_DISABLE);
+		PROC_UNLOCK(imgp->proc);
+	}
+	if ((sv->sv_flags & SV_ASLR) == 0 ||
+	    (imgp->proc->p_flag2 & P2_ASLR_DISABLE) != 0 ||
+	    (fctl0 & NT_FREEBSD_FCTL_ASLR_DISABLE) != 0) {
+		KASSERT(et_dyn_addr != ET_DYN_ADDR_RAND,
+		    ("et_dyn_addr == RAND and !ASLR"));
+	} else if ((imgp->proc->p_flag2 & P2_ASLR_ENABLE) != 0 ||
+	    (__elfN(aslr_enabled) && hdr->e_type == ET_EXEC) ||
+	    et_dyn_addr == ET_DYN_ADDR_RAND) {
+		imgp->map_flags |= MAP_ASLR;
+		/*
+		 * If user does not care about sbrk, utilize the bss
+		 * grow region for mappings as well.  We can select
+		 * the base for the image anywere and still not suffer
+		 * from the fragmentation.
+		 */
+		if (!__elfN(aslr_honor_sbrk) ||
+		    (imgp->proc->p_flag2 & P2_ASLR_IGNSTART) != 0)
+			imgp->map_flags |= MAP_ASLR_IGNSTART;
+	}
+
 	error = exec_new_vmspace(imgp, sv);
+	vmspace = imgp->proc->p_vmspace;
+	map = &vmspace->vm_map;
+
 	imgp->proc->p_sysent = sv;
 
+	maxv = vm_map_max(map) - lim_max(td, RLIMIT_STACK);
+	if (et_dyn_addr == ET_DYN_ADDR_RAND) {
+		KASSERT((map->flags & MAP_ASLR) != 0,
+		    ("ET_DYN_ADDR_RAND but !MAP_ASLR"));
+		et_dyn_addr = __CONCAT(rnd_, __elfN(base))(map,
+		    vm_map_min(map) + mapsz + lim_max(td, RLIMIT_DATA),
+		    /* reserve half of the address space to interpreter */
+		    maxv / 2, 1UL << flsl(maxalign));
+	}
+
 	vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
 	if (error != 0)
 		goto ret;
@@ -1023,7 +1135,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 		goto ret;
 	}
 
-	vmspace = imgp->proc->p_vmspace;
 	vmspace->vm_tsize = text_size >> PAGE_SHIFT;
 	vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr;
 	vmspace->vm_dsize = data_size >> PAGE_SHIFT;
@@ -1037,6 +1148,14 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	 */
 	addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(td,
 	    RLIMIT_DATA));
+	if ((map->flags & MAP_ASLR) != 0) {
+		maxv1 = maxv / 2 + addr / 2;
+		MPASS(maxv1 >= addr);	/* No overflow */
+		map->anon_loc = __CONCAT(rnd_, __elfN(base))(map, addr, maxv1,
+		    MAXPAGESIZES > 1 ? pagesizes[1] : pagesizes[0]);
+	} else {
+		map->anon_loc = addr;
+	}
 	PROC_UNLOCK(imgp->proc);
 
 	imgp->entry_addr = entry;
@@ -1044,6 +1163,13 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	if (interp != NULL) {
 		have_interp = FALSE;
 		VOP_UNLOCK(imgp->vp, 0);
+		if ((map->flags & MAP_ASLR) != 0) {
+			/* Assume that interpeter fits into 1/4 of AS */
+			maxv1 = maxv / 2 + addr / 2;
+			MPASS(maxv1 >= addr);	/* No overflow */
+			addr = __CONCAT(rnd_, __elfN(base))(map, addr,
+			    maxv1, PAGE_SIZE);
+		}
 		if (brand_info->emul_path != NULL &&
 		    brand_info->emul_path[0] != '\0') {
 			path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);

Modified: stable/12/sys/kern/kern_exec.c
==============================================================================
--- stable/12/sys/kern/kern_exec.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/kern/kern_exec.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -1104,9 +1104,13 @@ exec_new_vmspace(struct image_params *imgp, struct sys
 		shmexit(vmspace);
 		pmap_remove_pages(vmspace_pmap(vmspace));
 		vm_map_remove(map, vm_map_min(map), vm_map_max(map));
-		/* An exec terminates mlockall(MCL_FUTURE). */
+		/*
+		 * An exec terminates mlockall(MCL_FUTURE), ASLR state
+		 * must be re-evaluated.
+		 */
 		vm_map_lock(map);
-		vm_map_modflags(map, 0, MAP_WIREFUTURE);
+		vm_map_modflags(map, 0, MAP_WIREFUTURE | MAP_ASLR |
+		    MAP_ASLR_IGNSTART);
 		vm_map_unlock(map);
 	} else {
 		error = vmspace_exec(p, sv_minuser, sv->sv_maxuser);
@@ -1115,6 +1119,7 @@ exec_new_vmspace(struct image_params *imgp, struct sys
 		vmspace = p->p_vmspace;
 		map = &vmspace->vm_map;
 	}
+	map->flags |= imgp->map_flags;
 
 	/* Map a shared page */
 	obj = sv->sv_shared_page_obj;

Modified: stable/12/sys/kern/kern_fork.c
==============================================================================
--- stable/12/sys/kern/kern_fork.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/kern/kern_fork.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -507,7 +507,8 @@ do_fork(struct thread *td, struct fork_req *fr, struct
 	 * Increase reference counts on shared objects.
 	 */
 	p2->p_flag = P_INMEM;
-	p2->p_flag2 = p1->p_flag2 & (P2_NOTRACE | P2_NOTRACE_EXEC | P2_TRAPCAP);
+	p2->p_flag2 = p1->p_flag2 & (P2_ASLR_DISABLE | P2_ASLR_ENABLE |
+	    P2_ASLR_IGNSTART | P2_NOTRACE | P2_NOTRACE_EXEC | P2_TRAPCAP);
 	p2->p_swtick = ticks;
 	if (p1->p_flag & P_PROFIL)
 		startprofclock(p2);

Modified: stable/12/sys/kern/kern_procctl.c
==============================================================================
--- stable/12/sys/kern/kern_procctl.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/kern/kern_procctl.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -43,6 +43,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysproto.h>
 #include <sys/wait.h>
 
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+
 static int
 protect_setchild(struct thread *td, struct proc *p, int flags)
 {
@@ -413,6 +418,62 @@ trapcap_status(struct thread *td, struct proc *p, int 
 	return (0);
 }
 
+static int
+aslr_ctl(struct thread *td, struct proc *p, int state)
+{
+
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+
+	switch (state) {
+	case PROC_ASLR_FORCE_ENABLE:
+		p->p_flag2 &= ~P2_ASLR_DISABLE;
+		p->p_flag2 |= P2_ASLR_ENABLE;
+		break;
+	case PROC_ASLR_FORCE_DISABLE:
+		p->p_flag2 |= P2_ASLR_DISABLE;
+		p->p_flag2 &= ~P2_ASLR_ENABLE;
+		break;
+	case PROC_ASLR_NOFORCE:
+		p->p_flag2 &= ~(P2_ASLR_ENABLE | P2_ASLR_DISABLE);
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static int
+aslr_status(struct thread *td, struct proc *p, int *data)
+{
+	struct vmspace *vm;
+	int d;
+
+	switch (p->p_flag2 & (P2_ASLR_ENABLE | P2_ASLR_DISABLE)) {
+	case 0:
+		d = PROC_ASLR_NOFORCE;
+		break;
+	case P2_ASLR_ENABLE:
+		d = PROC_ASLR_FORCE_ENABLE;
+		break;
+	case P2_ASLR_DISABLE:
+		d = PROC_ASLR_FORCE_DISABLE;
+		break;
+	}
+	if ((p->p_flag & P_WEXIT) == 0) {
+		_PHOLD(p);
+		PROC_UNLOCK(p);
+		vm = vmspace_acquire_ref(p);
+		if (vm != NULL && (vm->vm_map.flags & MAP_ASLR) != 0) {
+			d |= PROC_ASLR_ACTIVE;
+			vmspace_free(vm);
+		}
+		PROC_LOCK(p);
+		_PRELE(p);
+	}
+	*data = d;
+	return (0);
+}
+
 #ifndef _SYS_SYSPROTO_H_
 struct procctl_args {
 	idtype_t idtype;
@@ -434,6 +495,7 @@ sys_procctl(struct thread *td, struct procctl_args *ua
 	int error, error1, flags, signum;
 
 	switch (uap->com) {
+	case PROC_ASLR_CTL:
 	case PROC_SPROTECT:
 	case PROC_TRACE_CTL:
 	case PROC_TRAPCAP_CTL:
@@ -463,6 +525,7 @@ sys_procctl(struct thread *td, struct procctl_args *ua
 			return (error);
 		data = &x.rk;
 		break;
+	case PROC_ASLR_STATUS:
 	case PROC_TRACE_STATUS:
 	case PROC_TRAPCAP_STATUS:
 		data = &flags;
@@ -490,6 +553,7 @@ sys_procctl(struct thread *td, struct procctl_args *ua
 		if (error == 0)
 			error = error1;
 		break;
+	case PROC_ASLR_STATUS:
 	case PROC_TRACE_STATUS:
 	case PROC_TRAPCAP_STATUS:
 		if (error == 0)
@@ -509,6 +573,10 @@ kern_procctl_single(struct thread *td, struct proc *p,
 
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	switch (com) {
+	case PROC_ASLR_CTL:
+		return (aslr_ctl(td, p, *(int *)data));
+	case PROC_ASLR_STATUS:
+		return (aslr_status(td, p, data));
 	case PROC_SPROTECT:
 		return (protect_set(td, p, *(int *)data));
 	case PROC_REAP_ACQUIRE:
@@ -544,6 +612,8 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t 
 	bool tree_locked;
 
 	switch (com) {
+	case PROC_ASLR_CTL:
+	case PROC_ASLR_STATUS:
 	case PROC_REAP_ACQUIRE:
 	case PROC_REAP_RELEASE:
 	case PROC_REAP_STATUS:
@@ -593,6 +663,8 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t 
 		sx_xlock(&proctree_lock);
 		tree_locked = true;
 		break;
+	case PROC_ASLR_CTL:
+	case PROC_ASLR_STATUS:
 	case PROC_TRACE_STATUS:
 	case PROC_TRAPCAP_STATUS:
 		tree_locked = false;

Modified: stable/12/sys/mips/mips/elf_machdep.c
==============================================================================
--- stable/12/sys/mips/mips/elf_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/mips/mips/elf_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -77,7 +77,7 @@ struct sysentvec elf64_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64,
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,
@@ -133,7 +133,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/powerpc/powerpc/elf32_machdep.c
==============================================================================
--- stable/12/sys/powerpc/powerpc/elf32_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/powerpc/powerpc/elf32_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -116,7 +116,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_fixlimit	= NULL,
 #endif
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_SHP,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_shared_page_base = FREEBSD32_SHAREDPAGE,

Modified: stable/12/sys/powerpc/powerpc/elf64_machdep.c
==============================================================================
--- stable/12/sys/powerpc/powerpc/elf64_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/powerpc/powerpc/elf64_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -80,7 +80,7 @@ struct sysentvec elf64_freebsd_sysvec_v1 = {
 	.sv_setregs	= exec_setregs_funcdesc,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_SHP,
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/riscv/riscv/elf_machdep.c
==============================================================================
--- stable/12/sys/riscv/riscv/elf_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/riscv/riscv/elf_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -83,7 +83,7 @@ struct sysentvec elf64_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64,
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/sparc64/sparc64/elf_machdep.c
==============================================================================
--- stable/12/sys/sparc64/sparc64/elf_machdep.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/sparc64/sparc64/elf_machdep.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -81,7 +81,7 @@ static struct sysentvec elf64_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64,
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: stable/12/sys/sys/imgact.h
==============================================================================
--- stable/12/sys/sys/imgact.h	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/sys/imgact.h	Tue Mar 12 16:33:44 2019	(r345067)
@@ -88,6 +88,7 @@ struct image_params {
 	u_long stack_sz;
 	struct ucred *newcred;		/* new credentials if changing */
 	bool credential_setid;		/* true if becoming setid */
+	u_int map_flags;
 };
 
 #ifdef _KERNEL

Modified: stable/12/sys/sys/proc.h
==============================================================================
--- stable/12/sys/sys/proc.h	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/sys/proc.h	Tue Mar 12 16:33:44 2019	(r345067)
@@ -752,6 +752,9 @@ struct proc {
 #define	P2_AST_SU	0x00000008	/* Handles SU ast for kthreads. */
 #define	P2_PTRACE_FSTP	0x00000010 /* SIGSTOP from PT_ATTACH not yet handled. */
 #define	P2_TRAPCAP	0x00000020	/* SIGTRAP on ENOTCAPABLE */
+#define	P2_ASLR_ENABLE	0x00000040	/* Force enable ASLR. */
+#define	P2_ASLR_DISABLE	0x00000080	/* Force disable ASLR. */
+#define	P2_ASLR_IGNSTART 0x00000100	/* Enable ASLR to consume sbrk area. */
 
 /* Flags protected by proctree_lock, kept in p_treeflags. */
 #define	P_TREE_ORPHANED		0x00000001	/* Reparented, on orphan list */

Modified: stable/12/sys/sys/procctl.h
==============================================================================
--- stable/12/sys/sys/procctl.h	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/sys/procctl.h	Tue Mar 12 16:33:44 2019	(r345067)
@@ -53,6 +53,8 @@
 #define	PROC_TRAPCAP_STATUS	10	/* query trap capability status */
 #define	PROC_PDEATHSIG_CTL	11	/* set parent death signal */
 #define	PROC_PDEATHSIG_STATUS	12	/* get parent death signal */
+#define	PROC_ASLR_CTL		13	/* en/dis ASLR */
+#define	PROC_ASLR_STATUS	14	/* query ASLR status */
 
 /* Operations for PROC_SPROTECT (passed in integer arg). */
 #define	PPROT_OP(x)	((x) & 0xf)
@@ -115,6 +117,11 @@ struct procctl_reaper_kill {
 
 #define	PROC_TRAPCAP_CTL_ENABLE		1
 #define	PROC_TRAPCAP_CTL_DISABLE	2
+
+#define	PROC_ASLR_FORCE_ENABLE		1
+#define	PROC_ASLR_FORCE_DISABLE		2
+#define	PROC_ASLR_NOFORCE		3
+#define	PROC_ASLR_ACTIVE		0x80000000
 
 #ifndef _KERNEL
 __BEGIN_DECLS

Modified: stable/12/sys/sys/sysent.h
==============================================================================
--- stable/12/sys/sys/sysent.h	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/sys/sysent.h	Tue Mar 12 16:33:44 2019	(r345067)
@@ -145,6 +145,7 @@ struct sysentvec {
 #define	SV_SHP		0x010000	/* Shared page. */
 #define	SV_CAPSICUM	0x020000	/* Force cap_enter() on startup. */
 #define	SV_TIMEKEEP	0x040000	/* Shared page timehands. */
+#define	SV_ASLR		0x080000	/* ASLR allowed. */
 
 #define	SV_ABI_MASK	0xff
 #define	SV_ABI_ERRNO(p, e)	((p)->p_sysent->sv_errsize <= 0 ? e :	\

Modified: stable/12/sys/vm/vm_map.c
==============================================================================
--- stable/12/sys/vm/vm_map.c	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/vm/vm_map.c	Tue Mar 12 16:33:44 2019	(r345067)
@@ -801,6 +801,7 @@ _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t mi
 	map->root = NULL;
 	map->timestamp = 0;
 	map->busy = 0;
+	map->anon_loc = 0;
 }
 
 void
@@ -1480,6 +1481,36 @@ vm_map_fixed(vm_map_t map, vm_object_t object, vm_ooff
 	return (result);
 }
 
+static const int aslr_pages_rnd_64[2] = {0x1000, 0x10};
+static const int aslr_pages_rnd_32[2] = {0x100, 0x4};
+
+static int cluster_anon = 1;
+SYSCTL_INT(_vm, OID_AUTO, cluster_anon, CTLFLAG_RW,
+    &cluster_anon, 0,
+    "Cluster anonymous mappings: 0 = no, 1 = yes if no hint, 2 = always");
+
+static bool
+clustering_anon_allowed(vm_offset_t addr)
+{
+
+	switch (cluster_anon) {
+	case 0:
+		return (false);
+	case 1:
+		return (addr == 0);
+	case 2:
+	default:
+		return (true);
+	}
+}
+
+static long aslr_restarts;
+SYSCTL_LONG(_vm, OID_AUTO, aslr_restarts, CTLFLAG_RD,
+    &aslr_restarts, 0,
+    "Number of aslr failures");
+
+#define	MAP_32BIT_MAX_ADDR	((vm_offset_t)1 << 31)
+
 /*
  * Searches for the specified amount of free space in the given map with the
  * specified alignment.  Performs an address-ordered, first-fit search from
@@ -1559,8 +1590,9 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffs
 	    vm_size_t length, vm_offset_t max_addr, int find_space,
 	    vm_prot_t prot, vm_prot_t max, int cow)
 {
-	vm_offset_t alignment, min_addr;
-	int rv;
+	vm_offset_t alignment, curr_min_addr, min_addr;
+	int gap, pidx, rv, try;
+	bool cluster, en_aslr, update_anon;
 
 	KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 ||
 	    object == NULL,
@@ -1575,24 +1607,96 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffs
 		alignment = (vm_offset_t)1 << (find_space >> 8);
 	} else
 		alignment = 0;
+	en_aslr = (map->flags & MAP_ASLR) != 0;
+	update_anon = cluster = clustering_anon_allowed(*addr) &&
+	    (map->flags & MAP_IS_SUB_MAP) == 0 && max_addr == 0 &&
+	    find_space != VMFS_NO_SPACE && object == NULL &&
+	    (cow & (MAP_INHERIT_SHARE | MAP_STACK_GROWS_UP |
+	    MAP_STACK_GROWS_DOWN)) == 0 && prot != PROT_NONE;
+	curr_min_addr = min_addr = *addr;
+	if (en_aslr && min_addr == 0 && !cluster &&
+	    find_space != VMFS_NO_SPACE &&
+	    (map->flags & MAP_ASLR_IGNSTART) != 0)
+		curr_min_addr = min_addr = vm_map_min(map);
+	try = 0;
 	vm_map_lock(map);
+	if (cluster) {
+		curr_min_addr = map->anon_loc;
+		if (curr_min_addr == 0)
+			cluster = false;
+	}
 	if (find_space != VMFS_NO_SPACE) {
 		KASSERT(find_space == VMFS_ANY_SPACE ||
 		    find_space == VMFS_OPTIMAL_SPACE ||
 		    find_space == VMFS_SUPER_SPACE ||
 		    alignment != 0, ("unexpected VMFS flag"));
-		min_addr = *addr;
 again:
-		if (vm_map_findspace(map, min_addr, length, addr) ||
+		/*
+		 * When creating an anonymous mapping, try clustering
+		 * with an existing anonymous mapping first.
+		 *
+		 * We make up to two attempts to find address space
+		 * for a given find_space value. The first attempt may
+		 * apply randomization or may cluster with an existing
+		 * anonymous mapping. If this first attempt fails,
+		 * perform a first-fit search of the available address
+		 * space.
+		 *
+		 * If all tries failed, and find_space is
+		 * VMFS_OPTIMAL_SPACE, fallback to VMFS_ANY_SPACE.
+		 * Again enable clustering and randomization.
+		 */
+		try++;
+		MPASS(try <= 2);
+
+		if (try == 2) {
+			/*
+			 * Second try: we failed either to find a
+			 * suitable region for randomizing the
+			 * allocation, or to cluster with an existing
+			 * mapping.  Retry with free run.
+			 */
+			curr_min_addr = (map->flags & MAP_ASLR_IGNSTART) != 0 ?
+			    vm_map_min(map) : min_addr;
+			atomic_add_long(&aslr_restarts, 1);
+		}
+
+		if (try == 1 && en_aslr && !cluster) {
+			/*
+			 * Find space for allocation, including
+			 * gap needed for later randomization.
+			 */
+			pidx = MAXPAGESIZES > 1 && pagesizes[1] != 0 &&
+			    (find_space == VMFS_SUPER_SPACE || find_space ==
+			    VMFS_OPTIMAL_SPACE) ? 1 : 0;
+			gap = vm_map_max(map) > MAP_32BIT_MAX_ADDR &&
+			    (max_addr == 0 || max_addr > MAP_32BIT_MAX_ADDR) ?
+			    aslr_pages_rnd_64[pidx] : aslr_pages_rnd_32[pidx];
+			if (vm_map_findspace(map, curr_min_addr, length +
+			    gap * pagesizes[pidx], addr) ||
+			    (max_addr != 0 && *addr + length > max_addr))
+				goto again;
+			/* And randomize the start address. */
+			*addr += (arc4random() % gap) * pagesizes[pidx];
+		} else if (vm_map_findspace(map, curr_min_addr, length, addr) ||
 		    (max_addr != 0 && *addr + length > max_addr)) {
+			if (cluster) {
+				cluster = false;
+				MPASS(try == 1);
+				goto again;
+			}
 			rv = KERN_NO_SPACE;
 			goto done;
 		}
+
 		if (find_space != VMFS_ANY_SPACE &&
 		    (rv = vm_map_alignspace(map, object, offset, addr, length,
 		    max_addr, alignment)) != KERN_SUCCESS) {
 			if (find_space == VMFS_OPTIMAL_SPACE) {
 				find_space = VMFS_ANY_SPACE;
+				curr_min_addr = min_addr;
+				cluster = update_anon;
+				try = 0;
 				goto again;
 			}
 			goto done;
@@ -1613,6 +1717,8 @@ again:
 		rv = vm_map_insert(map, object, offset, *addr, *addr + length,
 		    prot, max, cow);
 	}
+	if (rv == KERN_SUCCESS && update_anon)
+		map->anon_loc = *addr + length;
 done:
 	vm_map_unlock(map);
 	return (rv);
@@ -1922,8 +2028,14 @@ vm_map_submap(
 	vm_map_t submap)
 {
 	vm_map_entry_t entry;
-	int result = KERN_INVALID_ARGUMENT;
+	int result;
 
+	result = KERN_INVALID_ARGUMENT;
+
+	vm_map_lock(submap);
+	submap->flags |= MAP_IS_SUB_MAP;
+	vm_map_unlock(submap);
+
 	vm_map_lock(map);
 
 	VM_MAP_RANGE_CHECK(map, start, end);
@@ -1944,6 +2056,11 @@ vm_map_submap(
 	}
 	vm_map_unlock(map);
 
+	if (result != KERN_SUCCESS) {
+		vm_map_lock(submap);
+		submap->flags &= ~MAP_IS_SUB_MAP;
+		vm_map_unlock(submap);
+	}
 	return (result);
 }
 
@@ -3170,6 +3287,9 @@ vm_map_delete(vm_map_t map, vm_offset_t start, vm_offs
 		    entry->object.vm_object != NULL)
 			pmap_remove(map->pmap, entry->start, entry->end);
 
+		if (entry->end == map->anon_loc)
+			map->anon_loc = entry->start;
+
 		/*
 		 * Delete the entry only after removing all pmap
 		 * entries pointing to its pages.  (Otherwise, its
@@ -3452,6 +3572,8 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_c
 		vmspace_free(vm2);
 		return (NULL);
 	}
+
+	new_map->anon_loc = old_map->anon_loc;
 
 	old_entry = old_map->header.next;
 

Modified: stable/12/sys/vm/vm_map.h
==============================================================================
--- stable/12/sys/vm/vm_map.h	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/sys/vm/vm_map.h	Tue Mar 12 16:33:44 2019	(r345067)
@@ -202,6 +202,7 @@ struct vm_map {
 	vm_flags_t flags;		/* flags for this vm_map */
 	vm_map_entry_t root;		/* Root of a binary search tree */
 	pmap_t pmap;			/* (c) Physical map */
+	vm_offset_t anon_loc;
 	int busy;
 };
 
@@ -210,6 +211,9 @@ struct vm_map {
  */
 #define MAP_WIREFUTURE		0x01	/* wire all future pages */
 #define	MAP_BUSY_WAKEUP		0x02
+#define	MAP_IS_SUB_MAP		0x04	/* has parent */
+#define	MAP_ASLR		0x08	/* enabled ASLR */
+#define	MAP_ASLR_IGNSTART	0x10
 
 #ifdef	_KERNEL
 #if defined(KLD_MODULE) && !defined(KLD_TIED)

Modified: stable/12/usr.bin/proccontrol/Makefile
==============================================================================
--- stable/12/usr.bin/proccontrol/Makefile	Tue Mar 12 16:21:39 2019	(r345066)
+++ stable/12/usr.bin/proccontrol/Makefile	Tue Mar 12 16:33:44 2019	(r345067)
@@ -2,6 +2,5 @@
 
 PROG=   proccontrol
 WARNS?=	6
-MAN=
 
 .include <bsd.prog.mk>

Copied: stable/12/usr.bin/proccontrol/proccontrol.1 (from r344594, head/usr.bin/proccontrol/proccontrol.1)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/usr.bin/proccontrol/proccontrol.1	Tue Mar 12 16:33:44 2019	(r345067, copy of r344594, head/usr.bin/proccontrol/proccontrol.1)
@@ -0,0 +1,123 @@
+.\" Copyright (c) 2019 The FreeBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This documentation was written by
+.\" Konstantin Belousov <kib@FreeBSD.org> 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 AUTHORS 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 AUTHORS 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$
+.\"
+.Dd February 22, 2019
+.Dt PROCCONTROL 1
+.Os
+.Sh NAME
+.Nm proccontrol
+.Nd Control some process execution aspects
+.Sh SYNOPSIS
+.Nm
+.Fl m Ar mode
+.Op Fl s Ar control
+.Op Fl q
+.Fl p Ar pid | command
+.Sh DESCRIPTION
+The
+.Nm
+command modifies the execution parameter of existing process
+specified by the
+.Ar pid
+argument, or starts execution of the new program
+.Ar command
+with the execution parameter set for it.
+.Pp
+Which execution parameter is changed, selected by the mandatory
+parameter
+.Ar mode .
+Possible values for
+.Ar mode
+are:
+.Bl -tag -width trapcap
+.It Ar aslr
+Control the Address Space Layout Randomization.
+Only applicable to the new process spawned.
+.It Ar trace
+Control the permission for debuggers to attach.
+.It Ar trapcap
+Controls the signalling of capability mode access violations.
+.El
+.Pp
+The
+Ar control
+specifies if the selected
+.Ar mode
+should be enabled or disabled.
+Possible values are
+.Ar enable
+and
+.Ar disable ,
+with the default value being
+.Ar enable
+if not specified.
+See
+.Xr procctl 2
+for detailed description of each mode effects and interaction with other
+process control facilities.
+.Pp
+The
+.Op Fl q
+switch makes the utility query and print the current setting for
+the selected mode.
+.Sh EXIT STATUS

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903121633.x2CGXjll043779>