1100894Srwatson/*-
2189797Srwatson * Copyright (c) 1999-2002, 2006, 2009 Robert N. M. Watson
3100894Srwatson * Copyright (c) 2001 Ilmar S. Habibulin
4145160Srwatson * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
5163606Srwatson * Copyright (c) 2005-2006 SPARTA, Inc.
6182063Srwatson * Copyright (c) 2008 Apple Inc.
7100894Srwatson * All rights reserved.
8100894Srwatson *
9100894Srwatson * This software was developed by Robert Watson and Ilmar Habibulin for the
10100894Srwatson * TrustedBSD Project.
11100894Srwatson *
12106392Srwatson * This software was developed for the FreeBSD Project in part by Network
13106392Srwatson * Associates Laboratories, the Security Research Division of Network
14106392Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
15106392Srwatson * as part of the DARPA CHATS research program.
16100894Srwatson *
17147983Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract
18147983Srwatson * N66001-04-C-6019 ("SEFOS").
19147983Srwatson *
20189797Srwatson * This software was developed at the University of Cambridge Computer
21189797Srwatson * Laboratory with support from a grant from Google, Inc.
22189797Srwatson *
23100894Srwatson * Redistribution and use in source and binary forms, with or without
24100894Srwatson * modification, are permitted provided that the following conditions
25100894Srwatson * are met:
26100894Srwatson * 1. Redistributions of source code must retain the above copyright
27100894Srwatson *    notice, this list of conditions and the following disclaimer.
28100894Srwatson * 2. Redistributions in binary form must reproduce the above copyright
29100894Srwatson *    notice, this list of conditions and the following disclaimer in the
30100894Srwatson *    documentation and/or other materials provided with the distribution.
31100894Srwatson *
32100894Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
33100894Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34100894Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35100894Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
36100894Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37100894Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38100894Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39100894Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40100894Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41100894Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42100894Srwatson * SUCH DAMAGE.
43100894Srwatson */
44116182Sobrien
45116182Sobrien#include <sys/cdefs.h>
46116182Sobrien__FBSDID("$FreeBSD$");
47116182Sobrien
48100894Srwatson#include "opt_mac.h"
49101173Srwatson
50100894Srwatson#include <sys/param.h>
51224778Srwatson#include <sys/capability.h>
52177785Skib#include <sys/fcntl.h>
53100979Srwatson#include <sys/kernel.h>
54100979Srwatson#include <sys/lock.h>
55102949Sbde#include <sys/malloc.h>
56100979Srwatson#include <sys/mutex.h>
57100979Srwatson#include <sys/mac.h>
58100979Srwatson#include <sys/proc.h>
59100979Srwatson#include <sys/systm.h>
60219028Snetchild#include <sys/sysctl.h>
61100894Srwatson#include <sys/sysproto.h>
62100894Srwatson#include <sys/sysent.h>
63100979Srwatson#include <sys/vnode.h>
64100979Srwatson#include <sys/mount.h>
65100979Srwatson#include <sys/file.h>
66100979Srwatson#include <sys/namei.h>
67100979Srwatson#include <sys/socket.h>
68100979Srwatson#include <sys/pipe.h>
69100979Srwatson#include <sys/socketvar.h>
70100894Srwatson
71163606Srwatson#include <security/mac/mac_framework.h>
72121374Srwatson#include <security/mac/mac_internal.h>
73165469Srwatson#include <security/mac/mac_policy.h>
74121374Srwatson
75100979Srwatson#ifdef MAC
76100979Srwatson
77219258SnetchildFEATURE(security_mac, "Mandatory Access Control Framework support");
78219028Snetchild
79105988Srwatsonint
80225617Skmacysys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
81105694Srwatson{
82105694Srwatson	char *elements, *buffer;
83105694Srwatson	struct mac mac;
84105694Srwatson	struct proc *tproc;
85105694Srwatson	struct ucred *tcred;
86105694Srwatson	int error;
87105694Srwatson
88107849Salfred	error = copyin(uap->mac_p, &mac, sizeof(mac));
89105694Srwatson	if (error)
90105694Srwatson		return (error);
91105694Srwatson
92105694Srwatson	error = mac_check_structmac_consistent(&mac);
93105694Srwatson	if (error)
94105694Srwatson		return (error);
95105694Srwatson
96105694Srwatson	tproc = pfind(uap->pid);
97105694Srwatson	if (tproc == NULL)
98105694Srwatson		return (ESRCH);
99105694Srwatson
100105694Srwatson	tcred = NULL;				/* Satisfy gcc. */
101105694Srwatson	error = p_cansee(td, tproc);
102105694Srwatson	if (error == 0)
103105694Srwatson		tcred = crhold(tproc->p_ucred);
104105694Srwatson	PROC_UNLOCK(tproc);
105105694Srwatson	if (error)
106105694Srwatson		return (error);
107105694Srwatson
108111119Simp	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
109105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
110105694Srwatson	if (error) {
111105694Srwatson		free(elements, M_MACTEMP);
112105694Srwatson		crfree(tcred);
113105694Srwatson		return (error);
114105694Srwatson	}
115105694Srwatson
116111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
117172930Srwatson	error = mac_cred_externalize_label(tcred->cr_label, elements,
118122159Srwatson	    buffer, mac.m_buflen);
119105694Srwatson	if (error == 0)
120105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
121105694Srwatson
122105694Srwatson	free(buffer, M_MACTEMP);
123105694Srwatson	free(elements, M_MACTEMP);
124105694Srwatson	crfree(tcred);
125105694Srwatson	return (error);
126105694Srwatson}
127105694Srwatson
128100979Srwatsonint
129225617Skmacysys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
130100894Srwatson{
131105694Srwatson	char *elements, *buffer;
132105694Srwatson	struct mac mac;
133100979Srwatson	int error;
134100894Srwatson
135105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
136105694Srwatson	if (error)
137105694Srwatson		return (error);
138105694Srwatson
139105694Srwatson	error = mac_check_structmac_consistent(&mac);
140105694Srwatson	if (error)
141105694Srwatson		return (error);
142105694Srwatson
143111119Simp	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
144105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
145105694Srwatson	if (error) {
146105694Srwatson		free(elements, M_MACTEMP);
147105694Srwatson		return (error);
148105694Srwatson	}
149105694Srwatson
150111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
151172930Srwatson	error = mac_cred_externalize_label(td->td_ucred->cr_label,
152122159Srwatson	    elements, buffer, mac.m_buflen);
153100979Srwatson	if (error == 0)
154105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
155100979Srwatson
156105694Srwatson	free(buffer, M_MACTEMP);
157105694Srwatson	free(elements, M_MACTEMP);
158100979Srwatson	return (error);
159100979Srwatson}
160100979Srwatson
161100979Srwatsonint
162225617Skmacysys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
163100979Srwatson{
164100979Srwatson	struct ucred *newcred, *oldcred;
165122524Srwatson	struct label *intlabel;
166100979Srwatson	struct proc *p;
167105694Srwatson	struct mac mac;
168105694Srwatson	char *buffer;
169100979Srwatson	int error;
170100979Srwatson
171182063Srwatson	if (!(mac_labeled & MPC_OBJECT_CRED))
172182063Srwatson		return (EINVAL);
173182063Srwatson
174105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
175100979Srwatson	if (error)
176100979Srwatson		return (error);
177100979Srwatson
178105694Srwatson	error = mac_check_structmac_consistent(&mac);
179100979Srwatson	if (error)
180100979Srwatson		return (error);
181100979Srwatson
182111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
183105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
184105694Srwatson	if (error) {
185105694Srwatson		free(buffer, M_MACTEMP);
186105694Srwatson		return (error);
187105694Srwatson	}
188105694Srwatson
189122524Srwatson	intlabel = mac_cred_label_alloc();
190172930Srwatson	error = mac_cred_internalize_label(intlabel, buffer);
191105694Srwatson	free(buffer, M_MACTEMP);
192122524Srwatson	if (error)
193122524Srwatson		goto out;
194105694Srwatson
195100979Srwatson	newcred = crget();
196100979Srwatson
197100979Srwatson	p = td->td_proc;
198100979Srwatson	PROC_LOCK(p);
199100979Srwatson	oldcred = p->p_ucred;
200100979Srwatson
201172930Srwatson	error = mac_cred_check_relabel(oldcred, intlabel);
202100979Srwatson	if (error) {
203100979Srwatson		PROC_UNLOCK(p);
204100979Srwatson		crfree(newcred);
205105694Srwatson		goto out;
206100979Srwatson	}
207100979Srwatson
208100979Srwatson	setsugid(p);
209100979Srwatson	crcopy(newcred, oldcred);
210172930Srwatson	mac_cred_relabel(newcred, intlabel);
211102136Srwatson	p->p_ucred = newcred;
212100979Srwatson
213100979Srwatson	PROC_UNLOCK(p);
214100979Srwatson	crfree(oldcred);
215184412Srwatson	mac_proc_vm_revoke(td);
216105694Srwatson
217105694Srwatsonout:
218122524Srwatson	mac_cred_label_free(intlabel);
219105694Srwatson	return (error);
220100979Srwatson}
221100979Srwatson
222100979Srwatsonint
223225617Skmacysys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
224100979Srwatson{
225105694Srwatson	char *elements, *buffer;
226122524Srwatson	struct label *intlabel;
227100979Srwatson	struct file *fp;
228105694Srwatson	struct mac mac;
229100979Srwatson	struct vnode *vp;
230100979Srwatson	struct pipe *pipe;
231122820Srwatson	struct socket *so;
232255219Spjd	cap_rights_t rights;
233105694Srwatson	short label_type;
234241896Skib	int error;
235100979Srwatson
236105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
237105694Srwatson	if (error)
238105694Srwatson		return (error);
239100979Srwatson
240105694Srwatson	error = mac_check_structmac_consistent(&mac);
241105694Srwatson	if (error)
242105694Srwatson		return (error);
243105694Srwatson
244111119Simp	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
245105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
246105694Srwatson	if (error) {
247105694Srwatson		free(elements, M_MACTEMP);
248105694Srwatson		return (error);
249105694Srwatson	}
250105694Srwatson
251111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
252255219Spjd	error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_GET), &fp);
253100979Srwatson	if (error)
254100979Srwatson		goto out;
255100979Srwatson
256105694Srwatson	label_type = fp->f_type;
257100979Srwatson	switch (fp->f_type) {
258100979Srwatson	case DTYPE_FIFO:
259100979Srwatson	case DTYPE_VNODE:
260234032Srwatson		if (!(mac_labeled & MPC_OBJECT_VNODE)) {
261234032Srwatson			error = EINVAL;
262234032Srwatson			goto out_fdrop;
263234032Srwatson		}
264116678Sphk		vp = fp->f_vnode;
265122524Srwatson		intlabel = mac_vnode_label_alloc();
266175202Sattilio		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
267172930Srwatson		mac_vnode_copy_label(vp->v_label, intlabel);
268175294Sattilio		VOP_UNLOCK(vp, 0);
269172930Srwatson		error = mac_vnode_externalize_label(intlabel, elements,
270122584Srwatson		    buffer, mac.m_buflen);
271122584Srwatson		mac_vnode_label_free(intlabel);
272122584Srwatson		break;
273105694Srwatson
274100979Srwatson	case DTYPE_PIPE:
275234032Srwatson		if (!(mac_labeled & MPC_OBJECT_PIPE)) {
276234032Srwatson			error = EINVAL;
277234032Srwatson			goto out_fdrop;
278234032Srwatson		}
279109153Sdillon		pipe = fp->f_data;
280122524Srwatson		intlabel = mac_pipe_label_alloc();
281105694Srwatson		PIPE_LOCK(pipe);
282172930Srwatson		mac_pipe_copy_label(pipe->pipe_pair->pp_label, intlabel);
283105694Srwatson		PIPE_UNLOCK(pipe);
284172930Srwatson		error = mac_pipe_externalize_label(intlabel, elements,
285122159Srwatson		    buffer, mac.m_buflen);
286122524Srwatson		mac_pipe_label_free(intlabel);
287105694Srwatson		break;
288122584Srwatson
289122820Srwatson	case DTYPE_SOCKET:
290234032Srwatson		if (!(mac_labeled & MPC_OBJECT_SOCKET)) {
291234032Srwatson			error = EINVAL;
292234032Srwatson			goto out_fdrop;
293234032Srwatson		}
294122820Srwatson		so = fp->f_data;
295122820Srwatson		intlabel = mac_socket_label_alloc(M_WAITOK);
296145160Srwatson		SOCK_LOCK(so);
297172930Srwatson		mac_socket_copy_label(so->so_label, intlabel);
298145160Srwatson		SOCK_UNLOCK(so);
299172930Srwatson		error = mac_socket_externalize_label(intlabel, elements,
300122820Srwatson		    buffer, mac.m_buflen);
301122820Srwatson		mac_socket_label_free(intlabel);
302122820Srwatson		break;
303122820Srwatson
304105694Srwatson	default:
305122584Srwatson		error = EINVAL;
306105694Srwatson	}
307100979Srwatson	if (error == 0)
308105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
309234032Srwatsonout_fdrop:
310234032Srwatson	fdrop(fp, td);
311105694Srwatsonout:
312105694Srwatson	free(buffer, M_MACTEMP);
313105694Srwatson	free(elements, M_MACTEMP);
314100979Srwatson	return (error);
315100979Srwatson}
316100979Srwatson
317100979Srwatsonint
318225617Skmacysys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
319100979Srwatson{
320105694Srwatson	char *elements, *buffer;
321100979Srwatson	struct nameidata nd;
322122524Srwatson	struct label *intlabel;
323105694Srwatson	struct mac mac;
324241896Skib	int error;
325100979Srwatson
326182063Srwatson	if (!(mac_labeled & MPC_OBJECT_VNODE))
327182063Srwatson		return (EINVAL);
328182063Srwatson
329105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
330105694Srwatson	if (error)
331105694Srwatson		return (error);
332105694Srwatson
333105694Srwatson	error = mac_check_structmac_consistent(&mac);
334105694Srwatson	if (error)
335105694Srwatson		return (error);
336105694Srwatson
337111119Simp	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
338105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
339105694Srwatson	if (error) {
340105694Srwatson		free(elements, M_MACTEMP);
341105694Srwatson		return (error);
342105694Srwatson	}
343105694Srwatson
344111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
345241896Skib	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
346150914Scsjp	    uap->path_p, td);
347100979Srwatson	error = namei(&nd);
348100979Srwatson	if (error)
349100979Srwatson		goto out;
350100979Srwatson
351122524Srwatson	intlabel = mac_vnode_label_alloc();
352172930Srwatson	mac_vnode_copy_label(nd.ni_vp->v_label, intlabel);
353172930Srwatson	error = mac_vnode_externalize_label(intlabel, elements, buffer,
354122159Srwatson	    mac.m_buflen);
355105694Srwatson
356100979Srwatson	NDFREE(&nd, 0);
357122524Srwatson	mac_vnode_label_free(intlabel);
358105694Srwatson	if (error == 0)
359105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
360105694Srwatson
361105694Srwatsonout:
362105694Srwatson	free(buffer, M_MACTEMP);
363105694Srwatson	free(elements, M_MACTEMP);
364105694Srwatson
365105694Srwatson	return (error);
366105694Srwatson}
367105694Srwatson
368105694Srwatsonint
369225617Skmacysys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
370105694Srwatson{
371105694Srwatson	char *elements, *buffer;
372105694Srwatson	struct nameidata nd;
373122524Srwatson	struct label *intlabel;
374105694Srwatson	struct mac mac;
375241896Skib	int error;
376105694Srwatson
377182063Srwatson	if (!(mac_labeled & MPC_OBJECT_VNODE))
378182063Srwatson		return (EINVAL);
379182063Srwatson
380105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
381100979Srwatson	if (error)
382105694Srwatson		return (error);
383105694Srwatson
384105694Srwatson	error = mac_check_structmac_consistent(&mac);
385105694Srwatson	if (error)
386105694Srwatson		return (error);
387105694Srwatson
388111119Simp	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
389105694Srwatson	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
390105694Srwatson	if (error) {
391105694Srwatson		free(elements, M_MACTEMP);
392105694Srwatson		return (error);
393105694Srwatson	}
394105694Srwatson
395111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
396241896Skib	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE,
397150914Scsjp	    uap->path_p, td);
398105694Srwatson	error = namei(&nd);
399105694Srwatson	if (error)
400100979Srwatson		goto out;
401100979Srwatson
402122524Srwatson	intlabel = mac_vnode_label_alloc();
403172930Srwatson	mac_vnode_copy_label(nd.ni_vp->v_label, intlabel);
404172930Srwatson	error = mac_vnode_externalize_label(intlabel, elements, buffer,
405122159Srwatson	    mac.m_buflen);
406105694Srwatson	NDFREE(&nd, 0);
407122524Srwatson	mac_vnode_label_free(intlabel);
408100979Srwatson
409105694Srwatson	if (error == 0)
410105694Srwatson		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
411105694Srwatson
412100979Srwatsonout:
413105694Srwatson	free(buffer, M_MACTEMP);
414105694Srwatson	free(elements, M_MACTEMP);
415105694Srwatson
416100979Srwatson	return (error);
417100979Srwatson}
418100979Srwatson
419100979Srwatsonint
420225617Skmacysys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
421100979Srwatson{
422122524Srwatson	struct label *intlabel;
423105694Srwatson	struct pipe *pipe;
424122820Srwatson	struct socket *so;
425100979Srwatson	struct file *fp;
426100979Srwatson	struct mount *mp;
427100979Srwatson	struct vnode *vp;
428105694Srwatson	struct mac mac;
429255219Spjd	cap_rights_t rights;
430105694Srwatson	char *buffer;
431241896Skib	int error;
432100979Srwatson
433105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
434100979Srwatson	if (error)
435105694Srwatson		return (error);
436100979Srwatson
437105694Srwatson	error = mac_check_structmac_consistent(&mac);
438100979Srwatson	if (error)
439105694Srwatson		return (error);
440100979Srwatson
441111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
442105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
443105694Srwatson	if (error) {
444105694Srwatson		free(buffer, M_MACTEMP);
445105694Srwatson		return (error);
446105694Srwatson	}
447105694Srwatson
448255219Spjd	error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_SET), &fp);
449100979Srwatson	if (error)
450105694Srwatson		goto out;
451100979Srwatson
452100979Srwatson	switch (fp->f_type) {
453100979Srwatson	case DTYPE_FIFO:
454100979Srwatson	case DTYPE_VNODE:
455234032Srwatson		if (!(mac_labeled & MPC_OBJECT_VNODE)) {
456234032Srwatson			error = EINVAL;
457234032Srwatson			goto out_fdrop;
458234032Srwatson		}
459122524Srwatson		intlabel = mac_vnode_label_alloc();
460172930Srwatson		error = mac_vnode_internalize_label(intlabel, buffer);
461105694Srwatson		if (error) {
462122524Srwatson			mac_vnode_label_free(intlabel);
463105694Srwatson			break;
464105694Srwatson		}
465116678Sphk		vp = fp->f_vnode;
466100979Srwatson		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
467105694Srwatson		if (error != 0) {
468122524Srwatson			mac_vnode_label_free(intlabel);
469100979Srwatson			break;
470105694Srwatson		}
471175202Sattilio		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
472122524Srwatson		error = vn_setlabel(vp, intlabel, td->td_ucred);
473175294Sattilio		VOP_UNLOCK(vp, 0);
474100979Srwatson		vn_finished_write(mp);
475122524Srwatson		mac_vnode_label_free(intlabel);
476100979Srwatson		break;
477105694Srwatson
478100979Srwatson	case DTYPE_PIPE:
479234032Srwatson		if (!(mac_labeled & MPC_OBJECT_PIPE)) {
480234032Srwatson			error = EINVAL;
481234032Srwatson			goto out_fdrop;
482234032Srwatson		}
483122524Srwatson		intlabel = mac_pipe_label_alloc();
484172930Srwatson		error = mac_pipe_internalize_label(intlabel, buffer);
485105694Srwatson		if (error == 0) {
486109153Sdillon			pipe = fp->f_data;
487105694Srwatson			PIPE_LOCK(pipe);
488125293Srwatson			error = mac_pipe_label_set(td->td_ucred,
489125293Srwatson			    pipe->pipe_pair, intlabel);
490105694Srwatson			PIPE_UNLOCK(pipe);
491105694Srwatson		}
492122524Srwatson		mac_pipe_label_free(intlabel);
493100979Srwatson		break;
494105694Srwatson
495122820Srwatson	case DTYPE_SOCKET:
496234032Srwatson		if (!(mac_labeled & MPC_OBJECT_SOCKET)) {
497234032Srwatson			error = EINVAL;
498234032Srwatson			goto out_fdrop;
499234032Srwatson		}
500122820Srwatson		intlabel = mac_socket_label_alloc(M_WAITOK);
501172930Srwatson		error = mac_socket_internalize_label(intlabel, buffer);
502122820Srwatson		if (error == 0) {
503122820Srwatson			so = fp->f_data;
504122820Srwatson			error = mac_socket_label_set(td->td_ucred, so,
505122820Srwatson			    intlabel);
506122820Srwatson		}
507122820Srwatson		mac_socket_label_free(intlabel);
508122820Srwatson		break;
509122820Srwatson
510100979Srwatson	default:
511100979Srwatson		error = EINVAL;
512100979Srwatson	}
513234032Srwatsonout_fdrop:
514100979Srwatson	fdrop(fp, td);
515105694Srwatsonout:
516105694Srwatson	free(buffer, M_MACTEMP);
517100979Srwatson	return (error);
518100979Srwatson}
519100979Srwatson
520100979Srwatsonint
521225617Skmacysys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
522100979Srwatson{
523122524Srwatson	struct label *intlabel;
524100979Srwatson	struct nameidata nd;
525100979Srwatson	struct mount *mp;
526105694Srwatson	struct mac mac;
527105694Srwatson	char *buffer;
528241896Skib	int error;
529100979Srwatson
530182063Srwatson	if (!(mac_labeled & MPC_OBJECT_VNODE))
531182063Srwatson		return (EINVAL);
532182063Srwatson
533105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
534100979Srwatson	if (error)
535105694Srwatson		return (error);
536100979Srwatson
537105694Srwatson	error = mac_check_structmac_consistent(&mac);
538100979Srwatson	if (error)
539105694Srwatson		return (error);
540100979Srwatson
541111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
542105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
543105694Srwatson	if (error) {
544105694Srwatson		free(buffer, M_MACTEMP);
545105694Srwatson		return (error);
546105694Srwatson	}
547105694Srwatson
548122524Srwatson	intlabel = mac_vnode_label_alloc();
549172930Srwatson	error = mac_vnode_internalize_label(intlabel, buffer);
550105694Srwatson	free(buffer, M_MACTEMP);
551122524Srwatson	if (error)
552122524Srwatson		goto out;
553105694Srwatson
554241896Skib	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
555150914Scsjp	    uap->path_p, td);
556100979Srwatson	error = namei(&nd);
557105694Srwatson	if (error == 0) {
558105694Srwatson		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
559156893Stegge		if (error == 0) {
560122524Srwatson			error = vn_setlabel(nd.ni_vp, intlabel,
561105694Srwatson			    td->td_ucred);
562156893Stegge			vn_finished_write(mp);
563156893Stegge		}
564105694Srwatson	}
565105694Srwatson
566105694Srwatson	NDFREE(&nd, 0);
567122524Srwatsonout:
568122524Srwatson	mac_vnode_label_free(intlabel);
569105694Srwatson	return (error);
570105694Srwatson}
571105694Srwatson
572105694Srwatsonint
573225617Skmacysys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
574105694Srwatson{
575122524Srwatson	struct label *intlabel;
576105694Srwatson	struct nameidata nd;
577105694Srwatson	struct mount *mp;
578105694Srwatson	struct mac mac;
579105694Srwatson	char *buffer;
580241896Skib	int error;
581105694Srwatson
582182063Srwatson	if (!(mac_labeled & MPC_OBJECT_VNODE))
583182063Srwatson		return (EINVAL);
584182063Srwatson
585105694Srwatson	error = copyin(uap->mac_p, &mac, sizeof(mac));
586100979Srwatson	if (error)
587105694Srwatson		return (error);
588105694Srwatson
589105694Srwatson	error = mac_check_structmac_consistent(&mac);
590100979Srwatson	if (error)
591105694Srwatson		return (error);
592100979Srwatson
593111119Simp	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
594105694Srwatson	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
595105694Srwatson	if (error) {
596105694Srwatson		free(buffer, M_MACTEMP);
597105694Srwatson		return (error);
598105694Srwatson	}
599105694Srwatson
600122524Srwatson	intlabel = mac_vnode_label_alloc();
601172930Srwatson	error = mac_vnode_internalize_label(intlabel, buffer);
602105694Srwatson	free(buffer, M_MACTEMP);
603122524Srwatson	if (error)
604122524Srwatson		goto out;
605105694Srwatson
606241896Skib	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE,
607150914Scsjp	    uap->path_p, td);
608105694Srwatson	error = namei(&nd);
609105694Srwatson	if (error == 0) {
610105694Srwatson		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
611156893Stegge		if (error == 0) {
612122524Srwatson			error = vn_setlabel(nd.ni_vp, intlabel,
613105694Srwatson			    td->td_ucred);
614156893Stegge			vn_finished_write(mp);
615156893Stegge		}
616105694Srwatson	}
617105694Srwatson
618100979Srwatson	NDFREE(&nd, 0);
619122524Srwatsonout:
620122524Srwatson	mac_vnode_label_free(intlabel);
621100979Srwatson	return (error);
622100979Srwatson}
623100979Srwatson
624102123Srwatsonint
625225617Skmacysys_mac_syscall(struct thread *td, struct mac_syscall_args *uap)
626102123Srwatson{
627102123Srwatson	struct mac_policy_conf *mpc;
628102123Srwatson	char target[MAC_MAX_POLICY_NAME];
629189797Srwatson	int error;
630102123Srwatson
631107849Salfred	error = copyinstr(uap->policy, target, sizeof(target), NULL);
632102123Srwatson	if (error)
633102123Srwatson		return (error);
634102123Srwatson
635102123Srwatson	error = ENOSYS;
636119494Srwatson	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
637102123Srwatson		if (strcmp(mpc->mpc_name, target) == 0 &&
638102123Srwatson		    mpc->mpc_ops->mpo_syscall != NULL) {
639102123Srwatson			error = mpc->mpc_ops->mpo_syscall(td,
640107849Salfred			    uap->call, uap->arg);
641102123Srwatson			goto out;
642102123Srwatson		}
643102123Srwatson	}
644102123Srwatson
645189797Srwatson	if (!LIST_EMPTY(&mac_policy_list)) {
646189797Srwatson		mac_policy_slock_sleep();
647114806Srwatson		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
648114806Srwatson			if (strcmp(mpc->mpc_name, target) == 0 &&
649114806Srwatson			    mpc->mpc_ops->mpo_syscall != NULL) {
650114806Srwatson				error = mpc->mpc_ops->mpo_syscall(td,
651114806Srwatson				    uap->call, uap->arg);
652114806Srwatson				break;
653114806Srwatson			}
654114806Srwatson		}
655189797Srwatson		mac_policy_sunlock_sleep();
656114806Srwatson	}
657102123Srwatsonout:
658102123Srwatson	return (error);
659102123Srwatson}
660102123Srwatson
661100979Srwatson#else /* !MAC */
662100979Srwatson
663100979Srwatsonint
664225617Skmacysys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
665105694Srwatson{
666105694Srwatson
667105694Srwatson	return (ENOSYS);
668105694Srwatson}
669105694Srwatson
670105694Srwatsonint
671225617Skmacysys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
672100979Srwatson{
673100979Srwatson
674100894Srwatson	return (ENOSYS);
675100894Srwatson}
676100894Srwatson
677100894Srwatsonint
678225617Skmacysys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
679100894Srwatson{
680100894Srwatson
681100894Srwatson	return (ENOSYS);
682100894Srwatson}
683100894Srwatson
684100894Srwatsonint
685225617Skmacysys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
686100894Srwatson{
687100894Srwatson
688100894Srwatson	return (ENOSYS);
689100894Srwatson}
690100894Srwatson
691100894Srwatsonint
692225617Skmacysys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
693100894Srwatson{
694100894Srwatson
695100894Srwatson	return (ENOSYS);
696100894Srwatson}
697100894Srwatson
698100894Srwatsonint
699225617Skmacysys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
700105694Srwatson{
701105694Srwatson
702105694Srwatson	return (ENOSYS);
703105694Srwatson}
704105694Srwatson
705105694Srwatsonint
706225617Skmacysys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
707100894Srwatson{
708100894Srwatson
709100894Srwatson	return (ENOSYS);
710100894Srwatson}
711100894Srwatson
712100894Srwatsonint
713225617Skmacysys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
714100894Srwatson{
715100894Srwatson
716100894Srwatson	return (ENOSYS);
717100894Srwatson}
718100979Srwatson
719102123Srwatsonint
720225617Skmacysys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
721105694Srwatson{
722105694Srwatson
723105694Srwatson	return (ENOSYS);
724105694Srwatson}
725105694Srwatson
726105694Srwatsonint
727225617Skmacysys_mac_syscall(struct thread *td, struct mac_syscall_args *uap)
728102123Srwatson{
729102123Srwatson
730102123Srwatson	return (ENOSYS);
731102123Srwatson}
732102123Srwatson
733128901Srwatson#endif /* !MAC */
734