xref: /freebsd/sys/security/mac/mac_process.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
17bc82500SRobert Watson /*-
22087a58cSRobert Watson  * Copyright (c) 1999-2002, 2008-2009 Robert N. M. Watson
37bc82500SRobert Watson  * Copyright (c) 2001 Ilmar S. Habibulin
4f6a41092SRobert Watson  * Copyright (c) 2001-2003 Networks Associates Technology, Inc.
530d239bcSRobert Watson  * Copyright (c) 2006 SPARTA, Inc.
66356dba0SRobert Watson  * Copyright (c) 2008 Apple Inc.
77bc82500SRobert Watson  * All rights reserved.
87bc82500SRobert Watson  *
97bc82500SRobert Watson  * This software was developed by Robert Watson and Ilmar Habibulin for the
107bc82500SRobert Watson  * TrustedBSD Project.
117bc82500SRobert Watson  *
126201265bSRobert Watson  * This software was developed for the FreeBSD Project in part by Network
136201265bSRobert Watson  * Associates Laboratories, the Security Research Division of Network
146201265bSRobert Watson  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
156201265bSRobert Watson  * as part of the DARPA CHATS research program.
167bc82500SRobert Watson  *
1730d239bcSRobert Watson  * This software was enhanced by SPARTA ISSO under SPAWAR contract
1830d239bcSRobert Watson  * N66001-04-C-6019 ("SEFOS").
1930d239bcSRobert Watson  *
202087a58cSRobert Watson  * This software was developed at the University of Cambridge Computer
212087a58cSRobert Watson  * Laboratory with support from a grant from Google, Inc.
222087a58cSRobert Watson  *
237bc82500SRobert Watson  * Redistribution and use in source and binary forms, with or without
247bc82500SRobert Watson  * modification, are permitted provided that the following conditions
257bc82500SRobert Watson  * are met:
267bc82500SRobert Watson  * 1. Redistributions of source code must retain the above copyright
277bc82500SRobert Watson  *    notice, this list of conditions and the following disclaimer.
287bc82500SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
297bc82500SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
307bc82500SRobert Watson  *    documentation and/or other materials provided with the distribution.
317bc82500SRobert Watson  *
327bc82500SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
337bc82500SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
347bc82500SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
357bc82500SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
367bc82500SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
377bc82500SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
387bc82500SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
397bc82500SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
407bc82500SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
417bc82500SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
427bc82500SRobert Watson  * SUCH DAMAGE.
437bc82500SRobert Watson  */
44677b542eSDavid E. O'Brien 
45677b542eSDavid E. O'Brien #include <sys/cdefs.h>
467bc82500SRobert Watson #include "opt_mac.h"
47f9d0d524SRobert Watson 
487bc82500SRobert Watson #include <sys/param.h>
49a96acd1aSRobert Watson #include <sys/condvar.h>
50670cb89bSRobert Watson #include <sys/imgact.h>
5195fab37eSRobert Watson #include <sys/kernel.h>
5295fab37eSRobert Watson #include <sys/lock.h>
53b656366bSBruce Evans #include <sys/malloc.h>
5495fab37eSRobert Watson #include <sys/mac.h>
5595fab37eSRobert Watson #include <sys/proc.h>
5689f6b863SAttilio Rao #include <sys/rwlock.h>
57f51e5803SRobert Watson #include <sys/sbuf.h>
582087a58cSRobert Watson #include <sys/sdt.h>
5995fab37eSRobert Watson #include <sys/systm.h>
6095fab37eSRobert Watson #include <sys/vnode.h>
6195fab37eSRobert Watson #include <sys/mount.h>
6295fab37eSRobert Watson #include <sys/file.h>
6395fab37eSRobert Watson #include <sys/namei.h>
6495fab37eSRobert Watson #include <sys/sysctl.h>
6595fab37eSRobert Watson 
6695fab37eSRobert Watson #include <vm/vm.h>
6795fab37eSRobert Watson #include <vm/pmap.h>
6895fab37eSRobert Watson #include <vm/vm_map.h>
6995fab37eSRobert Watson #include <vm/vm_object.h>
7095fab37eSRobert Watson 
71aed55708SRobert Watson #include <security/mac/mac_framework.h>
725a9c1aaaSRobert Watson #include <security/mac/mac_internal.h>
730efd6615SRobert Watson #include <security/mac/mac_policy.h>
7495fab37eSRobert Watson 
75c0f39905SRobert Watson static int	mac_mmap_revocation = 1;
76c0f39905SRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
77c0f39905SRobert Watson     &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
78c0f39905SRobert Watson     "relabel");
795a9c1aaaSRobert Watson 
8099fa64f8SRobert Watson static int	mac_mmap_revocation_via_cow = 0;
8195fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
8295fab37eSRobert Watson     &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
8395fab37eSRobert Watson     "copy-on-write semantics, or by removing all write access");
8495fab37eSRobert Watson 
859215889dSRobert Watson static void	mac_proc_vm_revoke_recurse(struct thread *td,
8695fab37eSRobert Watson 		    struct ucred *cred, struct vm_map *map);
8795fab37eSRobert Watson 
88eca8a663SRobert Watson static struct label *
mac_proc_label_alloc(void)89eca8a663SRobert Watson mac_proc_label_alloc(void)
90eca8a663SRobert Watson {
91eca8a663SRobert Watson 	struct label *label;
92eca8a663SRobert Watson 
93eca8a663SRobert Watson 	label = mac_labelzone_alloc(M_WAITOK);
94fa765671SRobert Watson 	MAC_POLICY_PERFORM(proc_init_label, label);
95eca8a663SRobert Watson 	return (label);
96f7b951a8SRobert Watson }
97f7b951a8SRobert Watson 
98f7b951a8SRobert Watson void
mac_proc_init(struct proc * p)9930d239bcSRobert Watson mac_proc_init(struct proc *p)
1002555374cSRobert Watson {
1012555374cSRobert Watson 
1026356dba0SRobert Watson 	if (mac_labeled & MPC_OBJECT_PROC)
103eca8a663SRobert Watson 		p->p_label = mac_proc_label_alloc();
1046356dba0SRobert Watson 	else
1056356dba0SRobert Watson 		p->p_label = NULL;
1062555374cSRobert Watson }
1072555374cSRobert Watson 
108eca8a663SRobert Watson static void
mac_proc_label_free(struct label * label)109eca8a663SRobert Watson mac_proc_label_free(struct label *label)
110eca8a663SRobert Watson {
111eca8a663SRobert Watson 
112fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(proc_destroy_label, label);
113eca8a663SRobert Watson 	mac_labelzone_free(label);
114f7b951a8SRobert Watson }
115f7b951a8SRobert Watson 
116f7b951a8SRobert Watson void
mac_proc_destroy(struct proc * p)11730d239bcSRobert Watson mac_proc_destroy(struct proc *p)
1182555374cSRobert Watson {
1192555374cSRobert Watson 
1206356dba0SRobert Watson 	if (p->p_label != NULL) {
121eca8a663SRobert Watson 		mac_proc_label_free(p->p_label);
122eca8a663SRobert Watson 		p->p_label = NULL;
1232555374cSRobert Watson 	}
1246356dba0SRobert Watson }
1252555374cSRobert Watson 
12669bbb5b1SRobert Watson void
mac_thread_userret(struct thread * td)12769bbb5b1SRobert Watson mac_thread_userret(struct thread *td)
12869bbb5b1SRobert Watson {
12969bbb5b1SRobert Watson 
130fa765671SRobert Watson 	MAC_POLICY_PERFORM(thread_userret, td);
13169bbb5b1SRobert Watson }
13269bbb5b1SRobert Watson 
133670cb89bSRobert Watson int
mac_execve_enter(struct image_params * imgp,struct mac * mac_p)134eca8a663SRobert Watson mac_execve_enter(struct image_params *imgp, struct mac *mac_p)
135670cb89bSRobert Watson {
136eca8a663SRobert Watson 	struct label *label;
137670cb89bSRobert Watson 	struct mac mac;
138670cb89bSRobert Watson 	char *buffer;
139670cb89bSRobert Watson 	int error;
140670cb89bSRobert Watson 
141670cb89bSRobert Watson 	if (mac_p == NULL)
142670cb89bSRobert Watson 		return (0);
143670cb89bSRobert Watson 
1446356dba0SRobert Watson 	if (!(mac_labeled & MPC_OBJECT_CRED))
1456356dba0SRobert Watson 		return (EINVAL);
1466356dba0SRobert Watson 
147670cb89bSRobert Watson 	error = copyin(mac_p, &mac, sizeof(mac));
148670cb89bSRobert Watson 	if (error)
149670cb89bSRobert Watson 		return (error);
150670cb89bSRobert Watson 
151670cb89bSRobert Watson 	error = mac_check_structmac_consistent(&mac);
152670cb89bSRobert Watson 	if (error)
153670cb89bSRobert Watson 		return (error);
154670cb89bSRobert Watson 
155a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
156670cb89bSRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
157670cb89bSRobert Watson 	if (error) {
158670cb89bSRobert Watson 		free(buffer, M_MACTEMP);
159670cb89bSRobert Watson 		return (error);
160670cb89bSRobert Watson 	}
161670cb89bSRobert Watson 
162eca8a663SRobert Watson 	label = mac_cred_label_alloc();
16330d239bcSRobert Watson 	error = mac_cred_internalize_label(label, buffer);
164670cb89bSRobert Watson 	free(buffer, M_MACTEMP);
165670cb89bSRobert Watson 	if (error) {
166eca8a663SRobert Watson 		mac_cred_label_free(label);
167670cb89bSRobert Watson 		return (error);
168670cb89bSRobert Watson 	}
169eca8a663SRobert Watson 	imgp->execlabel = label;
170670cb89bSRobert Watson 	return (0);
171670cb89bSRobert Watson }
172670cb89bSRobert Watson 
17395fab37eSRobert Watson void
mac_execve_exit(struct image_params * imgp)174670cb89bSRobert Watson mac_execve_exit(struct image_params *imgp)
175670cb89bSRobert Watson {
176eca8a663SRobert Watson 	if (imgp->execlabel != NULL) {
177eca8a663SRobert Watson 		mac_cred_label_free(imgp->execlabel);
178eca8a663SRobert Watson 		imgp->execlabel = NULL;
179eca8a663SRobert Watson 	}
180670cb89bSRobert Watson }
181670cb89bSRobert Watson 
1826356dba0SRobert Watson void
mac_execve_interpreter_enter(struct vnode * interpvp,struct label ** interpvplabel)1836356dba0SRobert Watson mac_execve_interpreter_enter(struct vnode *interpvp,
1846356dba0SRobert Watson     struct label **interpvplabel)
1856356dba0SRobert Watson {
1866356dba0SRobert Watson 
1876356dba0SRobert Watson 	if (mac_labeled & MPC_OBJECT_VNODE) {
1886356dba0SRobert Watson 		*interpvplabel = mac_vnode_label_alloc();
1896356dba0SRobert Watson 		mac_vnode_copy_label(interpvp->v_label, *interpvplabel);
1906356dba0SRobert Watson 	} else
1916356dba0SRobert Watson 		*interpvplabel = NULL;
1926356dba0SRobert Watson }
1936356dba0SRobert Watson 
1946356dba0SRobert Watson void
mac_execve_interpreter_exit(struct label * interpvplabel)1956356dba0SRobert Watson mac_execve_interpreter_exit(struct label *interpvplabel)
1966356dba0SRobert Watson {
1976356dba0SRobert Watson 
1986356dba0SRobert Watson 	if (interpvplabel != NULL)
1996356dba0SRobert Watson 		mac_vnode_label_free(interpvplabel);
2006356dba0SRobert Watson }
2016356dba0SRobert Watson 
20295fab37eSRobert Watson /*
20395fab37eSRobert Watson  * When relabeling a process, call out to the policies for the maximum
2041f00b646SRobert Watson  * permission allowed for each object type we know about in its memory space,
2051f00b646SRobert Watson  * and revoke access (in the least surprising ways we know) when necessary.
2061f00b646SRobert Watson  * The process lock is not held here.
20795fab37eSRobert Watson  */
2084d10c0ceSRobert Watson void
mac_proc_vm_revoke(struct thread * td)2099215889dSRobert Watson mac_proc_vm_revoke(struct thread *td)
21095fab37eSRobert Watson {
2119215889dSRobert Watson 	struct ucred *cred;
2129215889dSRobert Watson 
2139215889dSRobert Watson 	PROC_LOCK(td->td_proc);
2149215889dSRobert Watson 	cred = crhold(td->td_proc->p_ucred);
2159215889dSRobert Watson 	PROC_UNLOCK(td->td_proc);
21695fab37eSRobert Watson 
21795fab37eSRobert Watson 	/* XXX freeze all other threads */
2189215889dSRobert Watson 	mac_proc_vm_revoke_recurse(td, cred,
21995fab37eSRobert Watson 	    &td->td_proc->p_vmspace->vm_map);
22095fab37eSRobert Watson 	/* XXX allow other threads to continue */
2219215889dSRobert Watson 
2229215889dSRobert Watson 	crfree(cred);
22395fab37eSRobert Watson }
22495fab37eSRobert Watson 
22595fab37eSRobert Watson static __inline const char *
prot2str(vm_prot_t prot)22695fab37eSRobert Watson prot2str(vm_prot_t prot)
22795fab37eSRobert Watson {
22895fab37eSRobert Watson 
22995fab37eSRobert Watson 	switch (prot & VM_PROT_ALL) {
23095fab37eSRobert Watson 	case VM_PROT_READ:
23195fab37eSRobert Watson 		return ("r--");
23295fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_WRITE:
23395fab37eSRobert Watson 		return ("rw-");
23495fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_EXECUTE:
23595fab37eSRobert Watson 		return ("r-x");
23695fab37eSRobert Watson 	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
23795fab37eSRobert Watson 		return ("rwx");
23895fab37eSRobert Watson 	case VM_PROT_WRITE:
23995fab37eSRobert Watson 		return ("-w-");
24095fab37eSRobert Watson 	case VM_PROT_EXECUTE:
24195fab37eSRobert Watson 		return ("--x");
24295fab37eSRobert Watson 	case VM_PROT_WRITE | VM_PROT_EXECUTE:
24395fab37eSRobert Watson 		return ("-wx");
24495fab37eSRobert Watson 	default:
24595fab37eSRobert Watson 		return ("---");
24695fab37eSRobert Watson 	}
24795fab37eSRobert Watson }
24895fab37eSRobert Watson 
24995fab37eSRobert Watson static void
mac_proc_vm_revoke_recurse(struct thread * td,struct ucred * cred,struct vm_map * map)2509215889dSRobert Watson mac_proc_vm_revoke_recurse(struct thread *td, struct ucred *cred,
25195fab37eSRobert Watson     struct vm_map *map)
25295fab37eSRobert Watson {
25383704cc2SDoug Moore 	vm_map_entry_t prev, vme;
2545050aa86SKonstantin Belousov 	int result;
255e183f80eSRobert Watson 	vm_prot_t revokeperms;
256a5b7fde7SChristian S.J. Peron 	vm_object_t backing_object, object;
25795fab37eSRobert Watson 	vm_ooffset_t offset;
25895fab37eSRobert Watson 	struct vnode *vp;
2593b582b4eSTor Egge 	struct mount *mp;
26095fab37eSRobert Watson 
261c0f39905SRobert Watson 	if (!mac_mmap_revocation)
262c0f39905SRobert Watson 		return;
263c0f39905SRobert Watson 
26483704cc2SDoug Moore 	prev = &map->header;
2651361cdc6SAlan Cox 	vm_map_lock(map);
26683704cc2SDoug Moore 	for (vme = vm_map_entry_first(map); vme != &map->header;
26783704cc2SDoug Moore 	    prev = vme, vme = vm_map_entry_succ(prev)) {
26895fab37eSRobert Watson 		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2699215889dSRobert Watson 			mac_proc_vm_revoke_recurse(td, cred,
27095fab37eSRobert Watson 			    vme->object.sub_map);
27195fab37eSRobert Watson 			continue;
27295fab37eSRobert Watson 		}
27395fab37eSRobert Watson 		/*
27495fab37eSRobert Watson 		 * Skip over entries that obviously are not shared.
27595fab37eSRobert Watson 		 */
27695fab37eSRobert Watson 		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
27795fab37eSRobert Watson 		    !vme->max_protection)
27895fab37eSRobert Watson 			continue;
27995fab37eSRobert Watson 		/*
28095fab37eSRobert Watson 		 * Drill down to the deepest backing object.
28195fab37eSRobert Watson 		 */
28295fab37eSRobert Watson 		offset = vme->offset;
28395fab37eSRobert Watson 		object = vme->object.vm_object;
28495fab37eSRobert Watson 		if (object == NULL)
28595fab37eSRobert Watson 			continue;
286a42159f0SAlan Cox 		VM_OBJECT_RLOCK(object);
287a5b7fde7SChristian S.J. Peron 		while ((backing_object = object->backing_object) != NULL) {
288a42159f0SAlan Cox 			VM_OBJECT_RLOCK(backing_object);
28995fab37eSRobert Watson 			offset += object->backing_object_offset;
290a42159f0SAlan Cox 			VM_OBJECT_RUNLOCK(object);
291a5b7fde7SChristian S.J. Peron 			object = backing_object;
29295fab37eSRobert Watson 		}
293a42159f0SAlan Cox 		VM_OBJECT_RUNLOCK(object);
29495fab37eSRobert Watson 		/*
2951f00b646SRobert Watson 		 * At the moment, vm_maps and objects aren't considered by
2961f00b646SRobert Watson 		 * the MAC system, so only things with backing by a normal
2971f00b646SRobert Watson 		 * object (read: vnodes) are checked.
29895fab37eSRobert Watson 		 */
29995fab37eSRobert Watson 		if (object->type != OBJT_VNODE)
30095fab37eSRobert Watson 			continue;
30195fab37eSRobert Watson 		vp = (struct vnode *)object->handle;
302cb05b60aSAttilio Rao 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
303e183f80eSRobert Watson 		result = vme->max_protection;
30430d239bcSRobert Watson 		mac_vnode_check_mmap_downgrade(cred, vp, &result);
305*b249ce48SMateusz Guzik 		VOP_UNLOCK(vp);
30695fab37eSRobert Watson 		/*
3071f00b646SRobert Watson 		 * Find out what maximum protection we may be allowing now
3081f00b646SRobert Watson 		 * but a policy needs to get removed.
30995fab37eSRobert Watson 		 */
31095fab37eSRobert Watson 		revokeperms = vme->max_protection & ~result;
3115050aa86SKonstantin Belousov 		if (!revokeperms)
31295fab37eSRobert Watson 			continue;
313b656366bSBruce Evans 		printf("pid %ld: revoking %s perms from %#lx:%ld "
314b656366bSBruce Evans 		    "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
315b656366bSBruce Evans 		    prot2str(revokeperms), (u_long)vme->start,
316b656366bSBruce Evans 		    (long)(vme->end - vme->start),
31795fab37eSRobert Watson 		    prot2str(vme->max_protection), prot2str(vme->protection));
31895fab37eSRobert Watson 		/*
31995fab37eSRobert Watson 		 * This is the really simple case: if a map has more
32095fab37eSRobert Watson 		 * max_protection than is allowed, but it's not being
3211f00b646SRobert Watson 		 * actually used (that is, the current protection is still
3221f00b646SRobert Watson 		 * allowed), we can just wipe it out and do nothing more.
32395fab37eSRobert Watson 		 */
32495fab37eSRobert Watson 		if ((vme->protection & revokeperms) == 0) {
32595fab37eSRobert Watson 			vme->max_protection -= revokeperms;
32695fab37eSRobert Watson 		} else {
32795fab37eSRobert Watson 			if (revokeperms & VM_PROT_WRITE) {
32895fab37eSRobert Watson 				/*
32995fab37eSRobert Watson 				 * In the more complicated case, flush out all
33095fab37eSRobert Watson 				 * pending changes to the object then turn it
33195fab37eSRobert Watson 				 * copy-on-write.
33295fab37eSRobert Watson 				 */
33395fab37eSRobert Watson 				vm_object_reference(object);
3343b582b4eSTor Egge 				(void) vn_start_write(vp, &mp, V_WAIT);
335cb05b60aSAttilio Rao 				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
33689f6b863SAttilio Rao 				VM_OBJECT_WLOCK(object);
33717f3095dSAlan Cox 				vm_object_page_clean(object, offset, offset +
33817f3095dSAlan Cox 				    vme->end - vme->start, OBJPC_SYNC);
33989f6b863SAttilio Rao 				VM_OBJECT_WUNLOCK(object);
340*b249ce48SMateusz Guzik 				VOP_UNLOCK(vp);
3413b582b4eSTor Egge 				vn_finished_write(mp);
34295fab37eSRobert Watson 				vm_object_deallocate(object);
34395fab37eSRobert Watson 				/*
34495fab37eSRobert Watson 				 * Why bother if there's no read permissions
34595fab37eSRobert Watson 				 * anymore?  For the rest, we need to leave
34695fab37eSRobert Watson 				 * the write permissions on for COW, or
34795fab37eSRobert Watson 				 * remove them entirely if configured to.
34895fab37eSRobert Watson 				 */
34995fab37eSRobert Watson 				if (!mac_mmap_revocation_via_cow) {
35095fab37eSRobert Watson 					vme->max_protection &= ~VM_PROT_WRITE;
35195fab37eSRobert Watson 					vme->protection &= ~VM_PROT_WRITE;
35295fab37eSRobert Watson 				} if ((revokeperms & VM_PROT_READ) == 0)
35395fab37eSRobert Watson 					vme->eflags |= MAP_ENTRY_COW |
35495fab37eSRobert Watson 					    MAP_ENTRY_NEEDS_COPY;
35595fab37eSRobert Watson 			}
35695fab37eSRobert Watson 			if (revokeperms & VM_PROT_EXECUTE) {
35795fab37eSRobert Watson 				vme->max_protection &= ~VM_PROT_EXECUTE;
35895fab37eSRobert Watson 				vme->protection &= ~VM_PROT_EXECUTE;
35995fab37eSRobert Watson 			}
36095fab37eSRobert Watson 			if (revokeperms & VM_PROT_READ) {
36195fab37eSRobert Watson 				vme->max_protection = 0;
36295fab37eSRobert Watson 				vme->protection = 0;
36395fab37eSRobert Watson 			}
36495fab37eSRobert Watson 			pmap_protect(map->pmap, vme->start, vme->end,
36595fab37eSRobert Watson 			    vme->protection & ~revokeperms);
36683704cc2SDoug Moore 			vm_map_try_merge_entries(map, prev, vme);
36795fab37eSRobert Watson 		}
36895fab37eSRobert Watson 	}
3691361cdc6SAlan Cox 	vm_map_unlock(map);
37095fab37eSRobert Watson }
37195fab37eSRobert Watson 
3722087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(proc_check_debug, "struct ucred *", "struct proc *");
3732087a58cSRobert Watson 
37495fab37eSRobert Watson int
mac_proc_check_debug(struct ucred * cred,struct proc * p)37530d239bcSRobert Watson mac_proc_check_debug(struct ucred *cred, struct proc *p)
37695fab37eSRobert Watson {
37795fab37eSRobert Watson 	int error;
37895fab37eSRobert Watson 
37926ae2b86SRobert Watson 	PROC_LOCK_ASSERT(p, MA_OWNED);
380b12baf55SRobert Watson 
381fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(proc_check_debug, cred, p);
3822087a58cSRobert Watson 	MAC_CHECK_PROBE2(proc_check_debug, error, cred, p);
38395fab37eSRobert Watson 
38495fab37eSRobert Watson 	return (error);
38595fab37eSRobert Watson }
38695fab37eSRobert Watson 
3872087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(proc_check_sched, "struct ucred *", "struct proc *");
3882087a58cSRobert Watson 
38995fab37eSRobert Watson int
mac_proc_check_sched(struct ucred * cred,struct proc * p)39030d239bcSRobert Watson mac_proc_check_sched(struct ucred *cred, struct proc *p)
39195fab37eSRobert Watson {
39295fab37eSRobert Watson 	int error;
39395fab37eSRobert Watson 
39426ae2b86SRobert Watson 	PROC_LOCK_ASSERT(p, MA_OWNED);
395b12baf55SRobert Watson 
396fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(proc_check_sched, cred, p);
3972087a58cSRobert Watson 	MAC_CHECK_PROBE2(proc_check_sched, error, cred, p);
39895fab37eSRobert Watson 
39995fab37eSRobert Watson 	return (error);
40095fab37eSRobert Watson }
40195fab37eSRobert Watson 
4022087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(proc_check_signal, "struct ucred *", "struct proc *",
4032087a58cSRobert Watson     "int");
4042087a58cSRobert Watson 
40595fab37eSRobert Watson int
mac_proc_check_signal(struct ucred * cred,struct proc * p,int signum)40630d239bcSRobert Watson mac_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
40795fab37eSRobert Watson {
40895fab37eSRobert Watson 	int error;
40995fab37eSRobert Watson 
41026ae2b86SRobert Watson 	PROC_LOCK_ASSERT(p, MA_OWNED);
411b12baf55SRobert Watson 
412fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(proc_check_signal, cred, p, signum);
4132087a58cSRobert Watson 	MAC_CHECK_PROBE3(proc_check_signal, error, cred, p, signum);
41495fab37eSRobert Watson 
41595fab37eSRobert Watson 	return (error);
41695fab37eSRobert Watson }
417030a28b3SRobert Watson 
4182087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(proc_check_wait, "struct ucred *", "struct proc *");
4192087a58cSRobert Watson 
420babe9a2bSRobert Watson int
mac_proc_check_wait(struct ucred * cred,struct proc * p)42130d239bcSRobert Watson mac_proc_check_wait(struct ucred *cred, struct proc *p)
422babe9a2bSRobert Watson {
423babe9a2bSRobert Watson 	int error;
424babe9a2bSRobert Watson 
42526ae2b86SRobert Watson 	PROC_LOCK_ASSERT(p, MA_OWNED);
426babe9a2bSRobert Watson 
427fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(proc_check_wait, cred, p);
4282087a58cSRobert Watson 	MAC_CHECK_PROBE2(proc_check_wait, error, cred, p);
429babe9a2bSRobert Watson 
430babe9a2bSRobert Watson 	return (error);
431babe9a2bSRobert Watson }
432