Deleted Added
full compact
mac_syscalls.c (121372) mac_syscalls.c (121374)
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson and Ilmar Habibulin for the
8 * TrustedBSD Project.

--- 26 unchanged lines hidden (view full) ---

35 */
36
37/*
38 * Framework for extensible kernel access control. Kernel and userland
39 * interface to the framework, policy registration and composition.
40 */
41
42#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson and Ilmar Habibulin for the
8 * TrustedBSD Project.

--- 26 unchanged lines hidden (view full) ---

35 */
36
37/*
38 * Framework for extensible kernel access control. Kernel and userland
39 * interface to the framework, policy registration and composition.
40 */
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/sys/security/mac/mac_syscalls.c 121372 2003-10-22 20:47:41Z rwatson $");
43__FBSDID("$FreeBSD: head/sys/security/mac/mac_syscalls.c 121374 2003-10-22 20:59:31Z rwatson $");
44
45#include "opt_mac.h"
46#include "opt_devfs.h"
47
48#include <sys/param.h>
49#include <sys/condvar.h>
50#include <sys/extattr.h>
51#include <sys/imgact.h>

--- 28 unchanged lines hidden (view full) ---

80
81#include <net/bpfdesc.h>
82#include <net/if.h>
83#include <net/if_var.h>
84
85#include <netinet/in.h>
86#include <netinet/ip_var.h>
87
44
45#include "opt_mac.h"
46#include "opt_devfs.h"
47
48#include <sys/param.h>
49#include <sys/condvar.h>
50#include <sys/extattr.h>
51#include <sys/imgact.h>

--- 28 unchanged lines hidden (view full) ---

80
81#include <net/bpfdesc.h>
82#include <net/if.h>
83#include <net/if_var.h>
84
85#include <netinet/in.h>
86#include <netinet/ip_var.h>
87
88#include <security/mac/mac_internal.h>
89
88#ifdef MAC
89
90/*
91 * Declare that the kernel provides MAC support, version 1. This permits
92 * modules to refuse to be loaded if the necessary support isn't present,
93 * even if it's pre-boot.
94 */
95MODULE_VERSION(kernel_mac_support, 1);
96
90#ifdef MAC
91
92/*
93 * Declare that the kernel provides MAC support, version 1. This permits
94 * modules to refuse to be loaded if the necessary support isn't present,
95 * even if it's pre-boot.
96 */
97MODULE_VERSION(kernel_mac_support, 1);
98
97SYSCTL_DECL(_security);
98
99SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
100 "TrustedBSD MAC policy controls");
101
102#if MAC_MAX_SLOTS > 32
103#error "MAC_MAX_SLOTS too large"
104#endif
105
106static unsigned int mac_max_slots = MAC_MAX_SLOTS;

--- 18 unchanged lines hidden (view full) ---

125 * were already in flight when the policy was loaded. Since the policy
126 * already has to deal with uninitialized labels, this probably won't
127 * be a problem. Note: currently no locking. Will this be a problem?
128 */
129#ifndef MAC_ALWAYS_LABEL_MBUF
130int mac_labelmbufs = 0;
131#endif
132
99SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
100 "TrustedBSD MAC policy controls");
101
102#if MAC_MAX_SLOTS > 32
103#error "MAC_MAX_SLOTS too large"
104#endif
105
106static unsigned int mac_max_slots = MAC_MAX_SLOTS;

--- 18 unchanged lines hidden (view full) ---

125 * were already in flight when the policy was loaded. Since the policy
126 * already has to deal with uninitialized labels, this probably won't
127 * be a problem. Note: currently no locking. Will this be a problem?
128 */
129#ifndef MAC_ALWAYS_LABEL_MBUF
130int mac_labelmbufs = 0;
131#endif
132
133static int mac_enforce_fs = 1;
134SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
135 &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
136TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
137
138static int mac_enforce_kld = 1;
139SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
140 &mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
141TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
142
143static int mac_enforce_network = 1;
144SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
145 &mac_enforce_network, 0, "Enforce MAC policy on network packets");
146TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
147
148static int mac_enforce_pipe = 1;
149SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
150 &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
151TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe);
152
153static int mac_enforce_process = 1;
154SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
155 &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
156TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
157
158static int mac_enforce_socket = 1;
159SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
160 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
161TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
162
163static int mac_enforce_system = 1;
164SYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW,
165 &mac_enforce_system, 0, "Enforce MAC policy on system operations");
166TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system);
167
168static int mac_enforce_vm = 1;
169SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
170 &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
171TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
172
173static int mac_mmap_revocation = 1;
174SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
175 &mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
176 "relabel");
177static int mac_mmap_revocation_via_cow = 0;
178SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
179 &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
180 "copy-on-write semantics, or by removing all write access");
181
182#ifdef MAC_DEBUG
183SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
184 "TrustedBSD MAC debug info");
133#ifdef MAC_DEBUG
134SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
135 "TrustedBSD MAC debug info");
185
186static int mac_debug_label_fallback = 0;
187SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
188 &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
189 "when label is corrupted.");
190TUNABLE_INT("security.mac.debug_label_fallback",
191 &mac_debug_label_fallback);
192
193SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
194 "TrustedBSD MAC object counters");
195
136SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
137 "TrustedBSD MAC object counters");
138
196static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
197 nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
198 nmacipqs, nmacpipes, nmacprocs;
199
200#define MAC_DEBUG_COUNTER_INC(x) atomic_add_int(x, 1);
201#define MAC_DEBUG_COUNTER_DEC(x) atomic_subtract_int(x, 1);
202
203SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
204 &nmacmbufs, 0, "number of mbufs in use");
205SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD,
206 &nmaccreds, 0, "number of ucreds in use");
207SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
208 &nmacifnets, 0, "number of ifnets in use");
209SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
210 &nmacipqs, 0, "number of ipqs in use");
211SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
212 &nmacbpfdescs, 0, "number of bpfdescs in use");
213SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
214 &nmacsockets, 0, "number of sockets in use");
215SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD,
216 &nmacpipes, 0, "number of pipes in use");
217SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD,
218 &nmacprocs, 0, "number of procs in use");
219SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD,
220 &nmacmounts, 0, "number of mounts in use");
139static unsigned int nmactemp;
221SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
222 &nmactemp, 0, "number of temporary labels in use");
140SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
141 &nmactemp, 0, "number of temporary labels in use");
223SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD,
224 &nmacvnodes, 0, "number of vnodes in use");
225SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
226 &nmacdevfsdirents, 0, "number of devfs dirents inuse");
227#else
228#define MAC_DEBUG_COUNTER_INC(x)
229#define MAC_DEBUG_COUNTER_DEC(x)
230#endif
231
232static int mac_policy_register(struct mac_policy_conf *mpc);
233static int mac_policy_unregister(struct mac_policy_conf *mpc);
234
142#endif
143
144static int mac_policy_register(struct mac_policy_conf *mpc);
145static int mac_policy_unregister(struct mac_policy_conf *mpc);
146
235static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
236 struct vnode *vp, int *prot);
237static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
238 struct ucred *cred, struct vm_map *map);
239
240static void mac_destroy_socket_label(struct label *label);
241
242static int mac_setlabel_vnode_extattr(struct ucred *cred,
243 struct vnode *vp, struct label *intlabel);
244
245MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
246MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
247
248/*
249 * mac_static_policy_list holds a list of policy modules that are not
250 * loaded while the system is "live", and cannot be unloaded. These
251 * policies can be invoked without holding the busy count.
252 *
253 * mac_policy_list stores the list of dynamic policies. A busy count is

--- 82 unchanged lines hidden (view full) ---

336 mac_policy_count--;
337 KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK"));
338 if (mac_policy_count == 0)
339 cv_signal(&mac_policy_cv);
340 mtx_unlock(&mac_policy_mtx);
341}
342
343/*
147MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
148
149/*
150 * mac_static_policy_list holds a list of policy modules that are not
151 * loaded while the system is "live", and cannot be unloaded. These
152 * policies can be invoked without holding the busy count.
153 *
154 * mac_policy_list stores the list of dynamic policies. A busy count is

--- 82 unchanged lines hidden (view full) ---

237 mac_policy_count--;
238 KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK"));
239 if (mac_policy_count == 0)
240 cv_signal(&mac_policy_cv);
241 mtx_unlock(&mac_policy_mtx);
242}
243
244/*
344 * MAC_CHECK performs the designated check by walking the policy
345 * module list and checking with each as to how it feels about the
346 * request. Note that it returns its value via 'error' in the scope
347 * of the caller.
348 */
349#define MAC_CHECK(check, args...) do { \
350 struct mac_policy_conf *mpc; \
351 int entrycount; \
352 \
353 error = 0; \
354 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \
355 if (mpc->mpc_ops->mpo_ ## check != NULL) \
356 error = mac_error_select( \
357 mpc->mpc_ops->mpo_ ## check (args), \
358 error); \
359 } \
360 if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \
361 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \
362 if (mpc->mpc_ops->mpo_ ## check != NULL) \
363 error = mac_error_select( \
364 mpc->mpc_ops->mpo_ ## check (args), \
365 error); \
366 } \
367 mac_policy_list_unbusy(); \
368 } \
369} while (0)
370
371/*
372 * MAC_BOOLEAN performs the designated boolean composition by walking
373 * the module list, invoking each instance of the operation, and
374 * combining the results using the passed C operator. Note that it
375 * returns its value via 'result' in the scope of the caller, which
376 * should be initialized by the caller in a meaningful way to get
377 * a meaningful result.
378 */
379#define MAC_BOOLEAN(operation, composition, args...) do { \
380 struct mac_policy_conf *mpc; \
381 int entrycount; \
382 \
383 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \
384 if (mpc->mpc_ops->mpo_ ## operation != NULL) \
385 result = result composition \
386 mpc->mpc_ops->mpo_ ## operation (args); \
387 } \
388 if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \
389 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \
390 if (mpc->mpc_ops->mpo_ ## operation != NULL) \
391 result = result composition \
392 mpc->mpc_ops->mpo_ ## operation \
393 (args); \
394 } \
395 mac_policy_list_unbusy(); \
396 } \
397} while (0)
398
399#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \
400 outbuflen) do { \
401 int claimed, first, ignorenotfound, savedlen; \
402 char *element_name, *element_temp; \
403 struct sbuf sb; \
404 \
405 error = 0; \
406 first = 1; \
407 sbuf_new(&sb, outbuf, outbuflen, SBUF_FIXEDLEN); \
408 element_temp = elementlist; \
409 while ((element_name = strsep(&element_temp, ",")) != NULL) { \
410 if (element_name[0] == '?') { \
411 element_name++; \
412 ignorenotfound = 1; \
413 } else \
414 ignorenotfound = 0; \
415 savedlen = sbuf_len(&sb); \
416 if (first) { \
417 error = sbuf_printf(&sb, "%s/", element_name); \
418 first = 0; \
419 } else \
420 error = sbuf_printf(&sb, ",%s/", element_name); \
421 if (error == -1) { \
422 error = EINVAL; /* XXX: E2BIG? */ \
423 break; \
424 } \
425 claimed = 0; \
426 MAC_CHECK(externalize_ ## type, label, element_name, \
427 &sb, &claimed); \
428 if (error) \
429 break; \
430 if (claimed == 0 && ignorenotfound) { \
431 /* Revert last label name. */ \
432 sbuf_setpos(&sb, savedlen); \
433 } else if (claimed != 1) { \
434 error = EINVAL; /* XXX: ENOLABEL? */ \
435 break; \
436 } \
437 } \
438 sbuf_finish(&sb); \
439} while (0)
440
441#define MAC_INTERNALIZE(type, label, instring) do { \
442 char *element, *element_name, *element_data; \
443 int claimed; \
444 \
445 error = 0; \
446 element = instring; \
447 while ((element_name = strsep(&element, ",")) != NULL) { \
448 element_data = element_name; \
449 element_name = strsep(&element_data, "/"); \
450 if (element_data == NULL) { \
451 error = EINVAL; \
452 break; \
453 } \
454 claimed = 0; \
455 MAC_CHECK(internalize_ ## type, label, element_name, \
456 element_data, &claimed); \
457 if (error) \
458 break; \
459 if (claimed != 1) { \
460 /* XXXMAC: Another error here? */ \
461 error = EINVAL; \
462 break; \
463 } \
464 } \
465} while (0)
466
467/*
468 * MAC_PERFORM performs the designated operation by walking the policy
469 * module list and invoking that operation for each policy.
470 */
471#define MAC_PERFORM(operation, args...) do { \
472 struct mac_policy_conf *mpc; \
473 int entrycount; \
474 \
475 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \
476 if (mpc->mpc_ops->mpo_ ## operation != NULL) \
477 mpc->mpc_ops->mpo_ ## operation (args); \
478 } \
479 if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \
480 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \
481 if (mpc->mpc_ops->mpo_ ## operation != NULL) \
482 mpc->mpc_ops->mpo_ ## operation (args); \
483 } \
484 mac_policy_list_unbusy(); \
485 } \
486} while (0)
487
488/*
489 * Initialize the MAC subsystem, including appropriate SMP locks.
490 */
491static void
492mac_init(void)
493{
494
495 LIST_INIT(&mac_static_policy_list);
496 LIST_INIT(&mac_policy_list);

--- 233 unchanged lines hidden (view full) ---

730 return (EPERM);
731
732 /* Precedence goes to error over success; otherwise, arbitrary. */
733 if (error1 != 0)
734 return (error1);
735 return (error2);
736}
737
245 * Initialize the MAC subsystem, including appropriate SMP locks.
246 */
247static void
248mac_init(void)
249{
250
251 LIST_INIT(&mac_static_policy_list);
252 LIST_INIT(&mac_policy_list);

--- 233 unchanged lines hidden (view full) ---

486 return (EPERM);
487
488 /* Precedence goes to error over success; otherwise, arbitrary. */
489 if (error1 != 0)
490 return (error1);
491 return (error2);
492}
493
738static struct label *
739mbuf_to_label(struct mbuf *mbuf)
740{
741 struct m_tag *tag;
742 struct label *label;
743
744 tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
745 label = (struct label *)(tag+1);
746
747 return (label);
748}
749
750static void
494void
751mac_init_label(struct label *label)
752{
753
754 bzero(label, sizeof(*label));
755 label->l_flags = MAC_FLAG_INITIALIZED;
756}
757
495mac_init_label(struct label *label)
496{
497
498 bzero(label, sizeof(*label));
499 label->l_flags = MAC_FLAG_INITIALIZED;
500}
501
758static void
502void
759mac_destroy_label(struct label *label)
760{
761
762 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
763 ("destroying uninitialized label"));
764
765 bzero(label, sizeof(*label));
766 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
767}
768
503mac_destroy_label(struct label *label)
504{
505
506 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
507 ("destroying uninitialized label"));
508
509 bzero(label, sizeof(*label));
510 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
511}
512
769void
770mac_init_bpfdesc(struct bpf_d *bpf_d)
771{
772
773 mac_init_label(&bpf_d->bd_label);
774 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
775 MAC_DEBUG_COUNTER_INC(&nmacbpfdescs);
776}
777
778static void
779mac_init_cred_label(struct label *label)
780{
781
782 mac_init_label(label);
783 MAC_PERFORM(init_cred_label, label);
784 MAC_DEBUG_COUNTER_INC(&nmaccreds);
785}
786
787void
788mac_init_cred(struct ucred *cred)
789{
790
791 mac_init_cred_label(&cred->cr_label);
792}
793
794void
795mac_init_devfsdirent(struct devfs_dirent *de)
796{
797
798 mac_init_label(&de->de_label);
799 MAC_PERFORM(init_devfsdirent_label, &de->de_label);
800 MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents);
801}
802
803static void
804mac_init_ifnet_label(struct label *label)
805{
806
807 mac_init_label(label);
808 MAC_PERFORM(init_ifnet_label, label);
809 MAC_DEBUG_COUNTER_INC(&nmacifnets);
810}
811
812void
813mac_init_ifnet(struct ifnet *ifp)
814{
815
816 mac_init_ifnet_label(&ifp->if_label);
817}
818
819int
513int
820mac_init_ipq(struct ipq *ipq, int flag)
821{
822 int error;
823
824 mac_init_label(&ipq->ipq_label);
825
826 MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag);
827 if (error) {
828 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
829 mac_destroy_label(&ipq->ipq_label);
830 } else {
831 MAC_DEBUG_COUNTER_INC(&nmacipqs);
832 }
833 return (error);
834}
835
836int
837mac_init_mbuf_tag(struct m_tag *tag, int flag)
838{
839 struct label *label;
840 int error;
841
842 label = (struct label *) (tag + 1);
843 mac_init_label(label);
844
845 MAC_CHECK(init_mbuf_label, label, flag);
846 if (error) {
847 MAC_PERFORM(destroy_mbuf_label, label);
848 mac_destroy_label(label);
849 } else {
850 MAC_DEBUG_COUNTER_INC(&nmacmbufs);
851 }
852 return (error);
853}
854
855int
856mac_init_mbuf(struct mbuf *m, int flag)
857{
858 struct m_tag *tag;
859 int error;
860
861 M_ASSERTPKTHDR(m);
862
863#ifndef MAC_ALWAYS_LABEL_MBUF
864 /*
865 * If conditionally allocating mbuf labels, don't allocate unless
866 * they are required.
867 */
868 if (!mac_labelmbufs)
869 return (0);
870#endif
871 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
872 flag);
873 if (tag == NULL)
874 return (ENOMEM);
875 error = mac_init_mbuf_tag(tag, flag);
876 if (error) {
877 m_tag_free(tag);
878 return (error);
879 }
880 m_tag_prepend(m, tag);
881 return (0);
882}
883
884void
885mac_init_mount(struct mount *mp)
886{
887
888 mac_init_label(&mp->mnt_mntlabel);
889 mac_init_label(&mp->mnt_fslabel);
890 MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel);
891 MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel);
892 MAC_DEBUG_COUNTER_INC(&nmacmounts);
893}
894
895static void
896mac_init_pipe_label(struct label *label)
897{
898
899 mac_init_label(label);
900 MAC_PERFORM(init_pipe_label, label);
901 MAC_DEBUG_COUNTER_INC(&nmacpipes);
902}
903
904void
905mac_init_pipe(struct pipe *pipe)
906{
907 struct label *label;
908
909 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
910 pipe->pipe_label = label;
911 pipe->pipe_peer->pipe_label = label;
912 mac_init_pipe_label(label);
913}
914
915void
916mac_init_proc(struct proc *p)
917{
918
919 mac_init_label(&p->p_label);
920 MAC_PERFORM(init_proc_label, &p->p_label);
921 MAC_DEBUG_COUNTER_INC(&nmacprocs);
922}
923
924static int
925mac_init_socket_label(struct label *label, int flag)
926{
927 int error;
928
929 mac_init_label(label);
930
931 MAC_CHECK(init_socket_label, label, flag);
932 if (error) {
933 MAC_PERFORM(destroy_socket_label, label);
934 mac_destroy_label(label);
935 } else {
936 MAC_DEBUG_COUNTER_INC(&nmacsockets);
937 }
938
939 return (error);
940}
941
942static int
943mac_init_socket_peer_label(struct label *label, int flag)
944{
945 int error;
946
947 mac_init_label(label);
948
949 MAC_CHECK(init_socket_peer_label, label, flag);
950 if (error) {
951 MAC_PERFORM(destroy_socket_label, label);
952 mac_destroy_label(label);
953 }
954
955 return (error);
956}
957
958int
959mac_init_socket(struct socket *socket, int flag)
960{
961 int error;
962
963 error = mac_init_socket_label(&socket->so_label, flag);
964 if (error)
965 return (error);
966
967 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
968 if (error)
969 mac_destroy_socket_label(&socket->so_label);
970
971 return (error);
972}
973
974void
975mac_init_vnode_label(struct label *label)
976{
977
978 mac_init_label(label);
979 MAC_PERFORM(init_vnode_label, label);
980 MAC_DEBUG_COUNTER_INC(&nmacvnodes);
981}
982
983void
984mac_init_vnode(struct vnode *vp)
985{
986
987 mac_init_vnode_label(&vp->v_label);
988}
989
990void
991mac_destroy_bpfdesc(struct bpf_d *bpf_d)
992{
993
994 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
995 mac_destroy_label(&bpf_d->bd_label);
996 MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs);
997}
998
999static void
1000mac_destroy_cred_label(struct label *label)
1001{
1002
1003 MAC_PERFORM(destroy_cred_label, label);
1004 mac_destroy_label(label);
1005 MAC_DEBUG_COUNTER_DEC(&nmaccreds);
1006}
1007
1008void
1009mac_destroy_cred(struct ucred *cred)
1010{
1011
1012 mac_destroy_cred_label(&cred->cr_label);
1013}
1014
1015void
1016mac_destroy_devfsdirent(struct devfs_dirent *de)
1017{
1018
1019 MAC_PERFORM(destroy_devfsdirent_label, &de->de_label);
1020 mac_destroy_label(&de->de_label);
1021 MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents);
1022}
1023
1024static void
1025mac_destroy_ifnet_label(struct label *label)
1026{
1027
1028 MAC_PERFORM(destroy_ifnet_label, label);
1029 mac_destroy_label(label);
1030 MAC_DEBUG_COUNTER_DEC(&nmacifnets);
1031}
1032
1033void
1034mac_destroy_ifnet(struct ifnet *ifp)
1035{
1036
1037 mac_destroy_ifnet_label(&ifp->if_label);
1038}
1039
1040void
1041mac_destroy_ipq(struct ipq *ipq)
1042{
1043
1044 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
1045 mac_destroy_label(&ipq->ipq_label);
1046 MAC_DEBUG_COUNTER_DEC(&nmacipqs);
1047}
1048
1049void
1050mac_destroy_mbuf_tag(struct m_tag *tag)
1051{
1052 struct label *label;
1053
1054 label = (struct label *)(tag+1);
1055
1056 MAC_PERFORM(destroy_mbuf_label, label);
1057 mac_destroy_label(label);
1058 MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
1059}
1060
1061void
1062mac_destroy_mount(struct mount *mp)
1063{
1064
1065 MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel);
1066 MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel);
1067 mac_destroy_label(&mp->mnt_fslabel);
1068 mac_destroy_label(&mp->mnt_mntlabel);
1069 MAC_DEBUG_COUNTER_DEC(&nmacmounts);
1070}
1071
1072static void
1073mac_destroy_pipe_label(struct label *label)
1074{
1075
1076 MAC_PERFORM(destroy_pipe_label, label);
1077 mac_destroy_label(label);
1078 MAC_DEBUG_COUNTER_DEC(&nmacpipes);
1079}
1080
1081void
1082mac_destroy_pipe(struct pipe *pipe)
1083{
1084
1085 mac_destroy_pipe_label(pipe->pipe_label);
1086 free(pipe->pipe_label, M_MACPIPELABEL);
1087}
1088
1089void
1090mac_destroy_proc(struct proc *p)
1091{
1092
1093 MAC_PERFORM(destroy_proc_label, &p->p_label);
1094 mac_destroy_label(&p->p_label);
1095 MAC_DEBUG_COUNTER_DEC(&nmacprocs);
1096}
1097
1098static void
1099mac_destroy_socket_label(struct label *label)
1100{
1101
1102 MAC_PERFORM(destroy_socket_label, label);
1103 mac_destroy_label(label);
1104 MAC_DEBUG_COUNTER_DEC(&nmacsockets);
1105}
1106
1107static void
1108mac_destroy_socket_peer_label(struct label *label)
1109{
1110
1111 MAC_PERFORM(destroy_socket_peer_label, label);
1112 mac_destroy_label(label);
1113}
1114
1115void
1116mac_destroy_socket(struct socket *socket)
1117{
1118
1119 mac_destroy_socket_label(&socket->so_label);
1120 mac_destroy_socket_peer_label(&socket->so_peerlabel);
1121}
1122
1123void
1124mac_destroy_vnode_label(struct label *label)
1125{
1126
1127 MAC_PERFORM(destroy_vnode_label, label);
1128 mac_destroy_label(label);
1129 MAC_DEBUG_COUNTER_DEC(&nmacvnodes);
1130}
1131
1132void
1133mac_destroy_vnode(struct vnode *vp)
1134{
1135
1136 mac_destroy_vnode_label(&vp->v_label);
1137}
1138
1139void
1140mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
1141{
1142 struct label *src_label, *dest_label;
1143
1144 src_label = (struct label *)(src+1);
1145 dest_label = (struct label *)(dest+1);
1146
1147 /*
1148 * mac_init_mbuf_tag() is called on the target tag in
1149 * m_tag_copy(), so we don't need to call it here.
1150 */
1151 MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
1152}
1153
1154static void
1155mac_copy_pipe_label(struct label *src, struct label *dest)
1156{
1157
1158 MAC_PERFORM(copy_pipe_label, src, dest);
1159}
1160
1161void
1162mac_copy_vnode_label(struct label *src, struct label *dest)
1163{
1164
1165 MAC_PERFORM(copy_vnode_label, src, dest);
1166}
1167
1168static int
1169mac_check_structmac_consistent(struct mac *mac)
1170{
1171
1172 if (mac->m_buflen < 0 ||
1173 mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
1174 return (EINVAL);
1175
1176 return (0);
1177}
1178
514mac_check_structmac_consistent(struct mac *mac)
515{
516
517 if (mac->m_buflen < 0 ||
518 mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
519 return (EINVAL);
520
521 return (0);
522}
523
1179static int
1180mac_externalize_cred_label(struct label *label, char *elements,
1181 char *outbuf, size_t outbuflen, int flags)
1182{
1183 int error;
1184
1185 MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen);
1186
1187 return (error);
1188}
1189
1190static int
1191mac_externalize_ifnet_label(struct label *label, char *elements,
1192 char *outbuf, size_t outbuflen, int flags)
1193{
1194 int error;
1195
1196 MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen);
1197
1198 return (error);
1199}
1200
1201static int
1202mac_externalize_pipe_label(struct label *label, char *elements,
1203 char *outbuf, size_t outbuflen, int flags)
1204{
1205 int error;
1206
1207 MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen);
1208
1209 return (error);
1210}
1211
1212static int
1213mac_externalize_socket_label(struct label *label, char *elements,
1214 char *outbuf, size_t outbuflen, int flags)
1215{
1216 int error;
1217
1218 MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen);
1219
1220 return (error);
1221}
1222
1223static int
1224mac_externalize_socket_peer_label(struct label *label, char *elements,
1225 char *outbuf, size_t outbuflen, int flags)
1226{
1227 int error;
1228
1229 MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen);
1230
1231 return (error);
1232}
1233
1234static int
1235mac_externalize_vnode_label(struct label *label, char *elements,
1236 char *outbuf, size_t outbuflen, int flags)
1237{
1238 int error;
1239
1240 MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen);
1241
1242 return (error);
1243}
1244
1245static int
1246mac_internalize_cred_label(struct label *label, char *string)
1247{
1248 int error;
1249
1250 MAC_INTERNALIZE(cred_label, label, string);
1251
1252 return (error);
1253}
1254
1255static int
1256mac_internalize_ifnet_label(struct label *label, char *string)
1257{
1258 int error;
1259
1260 MAC_INTERNALIZE(ifnet_label, label, string);
1261
1262 return (error);
1263}
1264
1265static int
1266mac_internalize_pipe_label(struct label *label, char *string)
1267{
1268 int error;
1269
1270 MAC_INTERNALIZE(pipe_label, label, string);
1271
1272 return (error);
1273}
1274
1275static int
1276mac_internalize_socket_label(struct label *label, char *string)
1277{
1278 int error;
1279
1280 MAC_INTERNALIZE(socket_label, label, string);
1281
1282 return (error);
1283}
1284
1285static int
1286mac_internalize_vnode_label(struct label *label, char *string)
1287{
1288 int error;
1289
1290 MAC_INTERNALIZE(vnode_label, label, string);
1291
1292 return (error);
1293}
1294
1295/*
1296 * Initialize MAC label for the first kernel process, from which other
1297 * kernel processes and threads are spawned.
1298 */
1299void
1300mac_create_proc0(struct ucred *cred)
1301{
1302
1303 MAC_PERFORM(create_proc0, cred);
1304}
1305
1306/*
1307 * Initialize MAC label for the first userland process, from which other
1308 * userland processes and threads are spawned.
1309 */
1310void
1311mac_create_proc1(struct ucred *cred)
1312{
1313
1314 MAC_PERFORM(create_proc1, cred);
1315}
1316
1317void
1318mac_thread_userret(struct thread *td)
1319{
1320
1321 MAC_PERFORM(thread_userret, td);
1322}
1323
1324/*
1325 * When a new process is created, its label must be initialized. Generally,
1326 * this involves inheritence from the parent process, modulo possible
1327 * deltas. This function allows that processing to take place.
1328 */
1329void
1330mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
1331{
1332
1333 MAC_PERFORM(create_cred, parent_cred, child_cred);
1334}
1335
1336void
1337mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de,
1338 struct vnode *vp)
1339{
1340
1341 MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp,
1342 &vp->v_label);
1343}
1344
1345void
1346mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
1347 struct vnode *vp)
1348{
1349
1350 MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
1351 &de->de_label, vp, &vp->v_label);
1352}
1353
1354int
524int
1355mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
1356{
1357 int error;
1358
1359 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
1360
1361 MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
1362 &vp->v_label);
1363
1364 return (error);
1365}
1366
1367void
1368mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
1369{
1370
1371 MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
1372 &vp->v_label);
1373}
1374
1375int
1376mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1377 struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
1378{
1379 int error;
1380
1381 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
1382 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
1383
1384 error = VOP_OPENEXTATTR(vp, cred, curthread);
1385 if (error == EOPNOTSUPP) {
1386 /* XXX: Optionally abort if transactions not supported. */
1387 if (ea_warn_once == 0) {
1388 printf("Warning: transactions not supported "
1389 "in EA write.\n");
1390 ea_warn_once = 1;
1391 }
1392 } else if (error)
1393 return (error);
1394
1395 MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
1396 dvp, &dvp->v_label, vp, &vp->v_label, cnp);
1397
1398 if (error) {
1399 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
1400 return (error);
1401 }
1402
1403 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1404
1405 if (error == EOPNOTSUPP)
1406 error = 0; /* XXX */
1407
1408 return (error);
1409}
1410
1411static int
1412mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1413 struct label *intlabel)
1414{
1415 int error;
1416
1417 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
1418
1419 error = VOP_OPENEXTATTR(vp, cred, curthread);
1420 if (error == EOPNOTSUPP) {
1421 /* XXX: Optionally abort if transactions not supported. */
1422 if (ea_warn_once == 0) {
1423 printf("Warning: transactions not supported "
1424 "in EA write.\n");
1425 ea_warn_once = 1;
1426 }
1427 } else if (error)
1428 return (error);
1429
1430 MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
1431
1432 if (error) {
1433 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
1434 return (error);
1435 }
1436
1437 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1438
1439 if (error == EOPNOTSUPP)
1440 error = 0; /* XXX */
1441
1442 return (error);
1443}
1444
1445int
1446mac_execve_enter(struct image_params *imgp, struct mac *mac_p,
1447 struct label *execlabelstorage)
1448{
1449 struct mac mac;
1450 char *buffer;
1451 int error;
1452
1453 if (mac_p == NULL)
1454 return (0);
1455
1456 error = copyin(mac_p, &mac, sizeof(mac));
1457 if (error)
1458 return (error);
1459
1460 error = mac_check_structmac_consistent(&mac);
1461 if (error)
1462 return (error);
1463
1464 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
1465 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
1466 if (error) {
1467 free(buffer, M_MACTEMP);
1468 return (error);
1469 }
1470
1471 mac_init_cred_label(execlabelstorage);
1472 error = mac_internalize_cred_label(execlabelstorage, buffer);
1473 free(buffer, M_MACTEMP);
1474 if (error) {
1475 mac_destroy_cred_label(execlabelstorage);
1476 return (error);
1477 }
1478 imgp->execlabel = execlabelstorage;
1479 return (0);
1480}
1481
1482void
1483mac_execve_exit(struct image_params *imgp)
1484{
1485 if (imgp->execlabel != NULL)
1486 mac_destroy_cred_label(imgp->execlabel);
1487}
1488
1489void
1490mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp,
1491 struct label *interpvnodelabel, struct image_params *imgp)
1492{
1493
1494 ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
1495
1496 if (!mac_enforce_process && !mac_enforce_fs)
1497 return;
1498
1499 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label,
1500 interpvnodelabel, imgp, imgp->execlabel);
1501}
1502
1503int
1504mac_execve_will_transition(struct ucred *old, struct vnode *vp,
1505 struct label *interpvnodelabel, struct image_params *imgp)
1506{
1507 int result;
1508
1509 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition");
1510
1511 if (!mac_enforce_process && !mac_enforce_fs)
1512 return (0);
1513
1514 result = 0;
1515 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label,
1516 interpvnodelabel, imgp, imgp->execlabel);
1517
1518 return (result);
1519}
1520
1521int
1522mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode)
1523{
1524 int error;
1525
1526 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
1527
1528 if (!mac_enforce_fs)
1529 return (0);
1530
1531 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode);
1532 return (error);
1533}
1534
1535int
1536mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
1537{
1538 int error;
1539
1540 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
1541
1542 if (!mac_enforce_fs)
1543 return (0);
1544
1545 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
1546 return (error);
1547}
1548
1549int
1550mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
1551{
1552 int error;
1553
1554 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
1555
1556 if (!mac_enforce_fs)
1557 return (0);
1558
1559 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
1560 return (error);
1561}
1562
1563int
1564mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1565 struct componentname *cnp, struct vattr *vap)
1566{
1567 int error;
1568
1569 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
1570
1571 if (!mac_enforce_fs)
1572 return (0);
1573
1574 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
1575 return (error);
1576}
1577
1578int
1579mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
1580 struct componentname *cnp)
1581{
1582 int error;
1583
1584 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
1585 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
1586
1587 if (!mac_enforce_fs)
1588 return (0);
1589
1590 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
1591 &vp->v_label, cnp);
1592 return (error);
1593}
1594
1595int
1596mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1597 acl_type_t type)
1598{
1599 int error;
1600
1601 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
1602
1603 if (!mac_enforce_fs)
1604 return (0);
1605
1606 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
1607 return (error);
1608}
1609
1610int
1611mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
1612 int attrnamespace, const char *name)
1613{
1614 int error;
1615
1616 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr");
1617
1618 if (!mac_enforce_fs)
1619 return (0);
1620
1621 MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label,
1622 attrnamespace, name);
1623 return (error);
1624}
1625
1626int
1627mac_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1628 struct image_params *imgp)
1629{
1630 int error;
1631
1632 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
1633
1634 if (!mac_enforce_process && !mac_enforce_fs)
1635 return (0);
1636
1637 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp,
1638 imgp->execlabel);
1639
1640 return (error);
1641}
1642
1643int
1644mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
1645{
1646 int error;
1647
1648 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
1649
1650 if (!mac_enforce_fs)
1651 return (0);
1652
1653 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
1654 return (error);
1655}
1656
1657int
1658mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1659 int attrnamespace, const char *name, struct uio *uio)
1660{
1661 int error;
1662
1663 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
1664
1665 if (!mac_enforce_fs)
1666 return (0);
1667
1668 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
1669 attrnamespace, name, uio);
1670 return (error);
1671}
1672
1673int
1674mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1675 struct vnode *vp, struct componentname *cnp)
1676{
1677 int error;
1678
1679 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
1680 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
1681
1682 if (!mac_enforce_fs)
1683 return (0);
1684
1685 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
1686 &vp->v_label, cnp);
1687 return (error);
1688}
1689
1690int
1691mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
1692 int attrnamespace)
1693{
1694 int error;
1695
1696 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr");
1697
1698 if (!mac_enforce_fs)
1699 return (0);
1700
1701 MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label,
1702 attrnamespace);
1703 return (error);
1704}
1705
1706int
1707mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1708 struct componentname *cnp)
1709{
1710 int error;
1711
1712 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
1713
1714 if (!mac_enforce_fs)
1715 return (0);
1716
1717 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
1718 return (error);
1719}
1720
1721int
1722mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
1723{
1724 int error;
1725
1726 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
1727
1728 if (!mac_enforce_fs || !mac_enforce_vm)
1729 return (0);
1730
1731 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
1732 return (error);
1733}
1734
1735void
1736mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
1737{
1738 int result = *prot;
1739
1740 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
1741
1742 if (!mac_enforce_fs || !mac_enforce_vm)
1743 return;
1744
1745 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label,
1746 &result);
1747
1748 *prot = result;
1749}
1750
1751int
1752mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
1753{
1754 int error;
1755
1756 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
1757
1758 if (!mac_enforce_fs || !mac_enforce_vm)
1759 return (0);
1760
1761 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
1762 return (error);
1763}
1764
1765int
1766mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode)
1767{
1768 int error;
1769
1770 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
1771
1772 if (!mac_enforce_fs)
1773 return (0);
1774
1775 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
1776 return (error);
1777}
1778
1779int
1780mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1781 struct vnode *vp)
1782{
1783 int error;
1784
1785 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
1786
1787 if (!mac_enforce_fs)
1788 return (0);
1789
1790 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
1791 &vp->v_label);
1792
1793 return (error);
1794}
1795
1796int
1797mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1798 struct vnode *vp)
1799{
1800 int error;
1801
1802 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
1803
1804 if (!mac_enforce_fs)
1805 return (0);
1806
1807 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
1808 &vp->v_label);
1809
1810 return (error);
1811}
1812
1813int
1814mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
1815{
1816 int error;
1817
1818 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
1819
1820 if (!mac_enforce_fs)
1821 return (0);
1822
1823 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
1824 return (error);
1825}
1826
1827int
1828mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
1829{
1830 int error;
1831
1832 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
1833
1834 if (!mac_enforce_fs)
1835 return (0);
1836
1837 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
1838 return (error);
1839}
1840
1841static int
1842mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1843 struct label *newlabel)
1844{
1845 int error;
1846
1847 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
1848
1849 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
1850
1851 return (error);
1852}
1853
1854int
1855mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1856 struct vnode *vp, struct componentname *cnp)
1857{
1858 int error;
1859
1860 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
1861 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
1862
1863 if (!mac_enforce_fs)
1864 return (0);
1865
1866 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
1867 &vp->v_label, cnp);
1868 return (error);
1869}
1870
1871int
1872mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1873 struct vnode *vp, int samedir, struct componentname *cnp)
1874{
1875 int error;
1876
1877 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
1878 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
1879
1880 if (!mac_enforce_fs)
1881 return (0);
1882
1883 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
1884 vp != NULL ? &vp->v_label : NULL, samedir, cnp);
1885 return (error);
1886}
1887
1888int
1889mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
1890{
1891 int error;
1892
1893 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
1894
1895 if (!mac_enforce_fs)
1896 return (0);
1897
1898 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
1899 return (error);
1900}
1901
1902int
1903mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
1904 struct acl *acl)
1905{
1906 int error;
1907
1908 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
1909
1910 if (!mac_enforce_fs)
1911 return (0);
1912
1913 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
1914 return (error);
1915}
1916
1917int
1918mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
1919 int attrnamespace, const char *name, struct uio *uio)
1920{
1921 int error;
1922
1923 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
1924
1925 if (!mac_enforce_fs)
1926 return (0);
1927
1928 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
1929 attrnamespace, name, uio);
1930 return (error);
1931}
1932
1933int
1934mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
1935{
1936 int error;
1937
1938 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
1939
1940 if (!mac_enforce_fs)
1941 return (0);
1942
1943 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
1944 return (error);
1945}
1946
1947int
1948mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
1949{
1950 int error;
1951
1952 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
1953
1954 if (!mac_enforce_fs)
1955 return (0);
1956
1957 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
1958 return (error);
1959}
1960
1961int
1962mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
1963 gid_t gid)
1964{
1965 int error;
1966
1967 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
1968
1969 if (!mac_enforce_fs)
1970 return (0);
1971
1972 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
1973 return (error);
1974}
1975
1976int
1977mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
1978 struct timespec atime, struct timespec mtime)
1979{
1980 int error;
1981
1982 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
1983
1984 if (!mac_enforce_fs)
1985 return (0);
1986
1987 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
1988 mtime);
1989 return (error);
1990}
1991
1992int
1993mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
1994 struct vnode *vp)
1995{
1996 int error;
1997
1998 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
1999
2000 if (!mac_enforce_fs)
2001 return (0);
2002
2003 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
2004 &vp->v_label);
2005 return (error);
2006}
2007
2008int
2009mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2010 struct vnode *vp)
2011{
2012 int error;
2013
2014 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
2015
2016 if (!mac_enforce_fs)
2017 return (0);
2018
2019 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
2020 &vp->v_label);
2021
2022 return (error);
2023}
2024
2025/*
2026 * When relabeling a process, call out to the policies for the maximum
2027 * permission allowed for each object type we know about in its
2028 * memory space, and revoke access (in the least surprising ways we
2029 * know) when necessary. The process lock is not held here.
2030 */
2031void
2032mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
2033{
2034
2035 /* XXX freeze all other threads */
2036 mac_cred_mmapped_drop_perms_recurse(td, cred,
2037 &td->td_proc->p_vmspace->vm_map);
2038 /* XXX allow other threads to continue */
2039}
2040
2041static __inline const char *
2042prot2str(vm_prot_t prot)
2043{
2044
2045 switch (prot & VM_PROT_ALL) {
2046 case VM_PROT_READ:
2047 return ("r--");
2048 case VM_PROT_READ | VM_PROT_WRITE:
2049 return ("rw-");
2050 case VM_PROT_READ | VM_PROT_EXECUTE:
2051 return ("r-x");
2052 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2053 return ("rwx");
2054 case VM_PROT_WRITE:
2055 return ("-w-");
2056 case VM_PROT_EXECUTE:
2057 return ("--x");
2058 case VM_PROT_WRITE | VM_PROT_EXECUTE:
2059 return ("-wx");
2060 default:
2061 return ("---");
2062 }
2063}
2064
2065static void
2066mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
2067 struct vm_map *map)
2068{
2069 struct vm_map_entry *vme;
2070 int result;
2071 vm_prot_t revokeperms;
2072 vm_object_t object;
2073 vm_ooffset_t offset;
2074 struct vnode *vp;
2075
2076 if (!mac_mmap_revocation)
2077 return;
2078
2079 vm_map_lock_read(map);
2080 for (vme = map->header.next; vme != &map->header; vme = vme->next) {
2081 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2082 mac_cred_mmapped_drop_perms_recurse(td, cred,
2083 vme->object.sub_map);
2084 continue;
2085 }
2086 /*
2087 * Skip over entries that obviously are not shared.
2088 */
2089 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
2090 !vme->max_protection)
2091 continue;
2092 /*
2093 * Drill down to the deepest backing object.
2094 */
2095 offset = vme->offset;
2096 object = vme->object.vm_object;
2097 if (object == NULL)
2098 continue;
2099 while (object->backing_object != NULL) {
2100 object = object->backing_object;
2101 offset += object->backing_object_offset;
2102 }
2103 /*
2104 * At the moment, vm_maps and objects aren't considered
2105 * by the MAC system, so only things with backing by a
2106 * normal object (read: vnodes) are checked.
2107 */
2108 if (object->type != OBJT_VNODE)
2109 continue;
2110 vp = (struct vnode *)object->handle;
2111 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2112 result = vme->max_protection;
2113 mac_check_vnode_mmap_downgrade(cred, vp, &result);
2114 VOP_UNLOCK(vp, 0, td);
2115 /*
2116 * Find out what maximum protection we may be allowing
2117 * now but a policy needs to get removed.
2118 */
2119 revokeperms = vme->max_protection & ~result;
2120 if (!revokeperms)
2121 continue;
2122 printf("pid %ld: revoking %s perms from %#lx:%ld "
2123 "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
2124 prot2str(revokeperms), (u_long)vme->start,
2125 (long)(vme->end - vme->start),
2126 prot2str(vme->max_protection), prot2str(vme->protection));
2127 vm_map_lock_upgrade(map);
2128 /*
2129 * This is the really simple case: if a map has more
2130 * max_protection than is allowed, but it's not being
2131 * actually used (that is, the current protection is
2132 * still allowed), we can just wipe it out and do
2133 * nothing more.
2134 */
2135 if ((vme->protection & revokeperms) == 0) {
2136 vme->max_protection -= revokeperms;
2137 } else {
2138 if (revokeperms & VM_PROT_WRITE) {
2139 /*
2140 * In the more complicated case, flush out all
2141 * pending changes to the object then turn it
2142 * copy-on-write.
2143 */
2144 vm_object_reference(object);
2145 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2146 VM_OBJECT_LOCK(object);
2147 vm_object_page_clean(object,
2148 OFF_TO_IDX(offset),
2149 OFF_TO_IDX(offset + vme->end - vme->start +
2150 PAGE_MASK),
2151 OBJPC_SYNC);
2152 VM_OBJECT_UNLOCK(object);
2153 VOP_UNLOCK(vp, 0, td);
2154 vm_object_deallocate(object);
2155 /*
2156 * Why bother if there's no read permissions
2157 * anymore? For the rest, we need to leave
2158 * the write permissions on for COW, or
2159 * remove them entirely if configured to.
2160 */
2161 if (!mac_mmap_revocation_via_cow) {
2162 vme->max_protection &= ~VM_PROT_WRITE;
2163 vme->protection &= ~VM_PROT_WRITE;
2164 } if ((revokeperms & VM_PROT_READ) == 0)
2165 vme->eflags |= MAP_ENTRY_COW |
2166 MAP_ENTRY_NEEDS_COPY;
2167 }
2168 if (revokeperms & VM_PROT_EXECUTE) {
2169 vme->max_protection &= ~VM_PROT_EXECUTE;
2170 vme->protection &= ~VM_PROT_EXECUTE;
2171 }
2172 if (revokeperms & VM_PROT_READ) {
2173 vme->max_protection = 0;
2174 vme->protection = 0;
2175 }
2176 pmap_protect(map->pmap, vme->start, vme->end,
2177 vme->protection & ~revokeperms);
2178 vm_map_simplify_entry(map, vme);
2179 }
2180 vm_map_lock_downgrade(map);
2181 }
2182 vm_map_unlock_read(map);
2183}
2184
2185/*
2186 * When the subject's label changes, it may require revocation of privilege
2187 * to mapped objects. This can't be done on-the-fly later with a unified
2188 * buffer cache.
2189 */
2190static void
2191mac_relabel_cred(struct ucred *cred, struct label *newlabel)
2192{
2193
2194 MAC_PERFORM(relabel_cred, cred, newlabel);
2195}
2196
2197void
2198mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
2199{
2200
2201 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
2202}
2203
2204void
2205mac_create_ifnet(struct ifnet *ifnet)
2206{
2207
2208 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
2209}
2210
2211void
2212mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
2213{
2214
2215 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
2216}
2217
2218void
2219mac_create_socket(struct ucred *cred, struct socket *socket)
2220{
2221
2222 MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
2223}
2224
2225void
2226mac_create_pipe(struct ucred *cred, struct pipe *pipe)
2227{
2228
2229 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
2230}
2231
2232void
2233mac_create_socket_from_socket(struct socket *oldsocket,
2234 struct socket *newsocket)
2235{
2236
2237 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
2238 newsocket, &newsocket->so_label);
2239}
2240
2241static void
2242mac_relabel_socket(struct ucred *cred, struct socket *socket,
2243 struct label *newlabel)
2244{
2245
2246 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
2247}
2248
2249static void
2250mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
2251{
2252
2253 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
2254}
2255
2256void
2257mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
2258{
2259 struct label *label;
2260
2261 label = mbuf_to_label(mbuf);
2262
2263 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
2264 &socket->so_peerlabel);
2265}
2266
2267void
2268mac_set_socket_peer_from_socket(struct socket *oldsocket,
2269 struct socket *newsocket)
2270{
2271
2272 MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
2273 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
2274}
2275
2276void
2277mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2278{
2279 struct label *label;
2280
2281 label = mbuf_to_label(datagram);
2282
2283 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2284 datagram, label);
2285}
2286
2287void
2288mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2289{
2290 struct label *datagramlabel, *fragmentlabel;
2291
2292 datagramlabel = mbuf_to_label(datagram);
2293 fragmentlabel = mbuf_to_label(fragment);
2294
2295 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
2296 fragmentlabel);
2297}
2298
2299void
2300mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2301{
2302 struct label *label;
2303
2304 label = mbuf_to_label(fragment);
2305
2306 MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
2307}
2308
2309void
2310mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2311{
2312 struct label *oldmbuflabel, *newmbuflabel;
2313
2314 oldmbuflabel = mbuf_to_label(oldmbuf);
2315 newmbuflabel = mbuf_to_label(newmbuf);
2316
2317 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
2318 newmbuflabel);
2319}
2320
2321void
2322mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2323{
2324 struct label *label;
2325
2326 label = mbuf_to_label(mbuf);
2327
2328 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2329 label);
2330}
2331
2332void
2333mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2334{
2335 struct label *label;
2336
2337 label = mbuf_to_label(mbuf);
2338
2339 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2340 label);
2341}
2342
2343void
2344mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2345{
2346 struct label *label;
2347
2348 label = mbuf_to_label(mbuf);
2349
2350 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2351 label);
2352}
2353
2354void
2355mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2356 struct mbuf *newmbuf)
2357{
2358 struct label *oldmbuflabel, *newmbuflabel;
2359
2360 oldmbuflabel = mbuf_to_label(oldmbuf);
2361 newmbuflabel = mbuf_to_label(newmbuf);
2362
2363 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
2364 ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
2365}
2366
2367void
2368mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2369{
2370 struct label *oldmbuflabel, *newmbuflabel;
2371
2372 oldmbuflabel = mbuf_to_label(oldmbuf);
2373 newmbuflabel = mbuf_to_label(newmbuf);
2374
2375 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
2376 newmbuflabel);
2377}
2378
2379int
2380mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2381{
2382 struct label *label;
2383 int result;
2384
2385 label = mbuf_to_label(fragment);
2386
2387 result = 1;
2388 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
2389 &ipq->ipq_label);
2390
2391 return (result);
2392}
2393
2394void
2395mac_reflect_mbuf_icmp(struct mbuf *m)
2396{
2397 struct label *label;
2398
2399 label = mbuf_to_label(m);
2400
2401 MAC_PERFORM(reflect_mbuf_icmp, m, label);
2402}
2403void
2404mac_reflect_mbuf_tcp(struct mbuf *m)
2405{
2406 struct label *label;
2407
2408 label = mbuf_to_label(m);
2409
2410 MAC_PERFORM(reflect_mbuf_tcp, m, label);
2411}
2412
2413void
2414mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2415{
2416 struct label *label;
2417
2418 label = mbuf_to_label(fragment);
2419
2420 MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
2421}
2422
2423void
2424mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2425{
2426 struct label *label;
2427
2428 label = mbuf_to_label(mbuf);
2429
2430 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2431 label);
2432}
2433
2434void
2435mac_create_mount(struct ucred *cred, struct mount *mp)
2436{
2437
2438 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2439 &mp->mnt_fslabel);
2440}
2441
2442void
2443mac_create_root_mount(struct ucred *cred, struct mount *mp)
2444{
2445
2446 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2447 &mp->mnt_fslabel);
2448}
2449
2450int
2451mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2452{
2453 int error;
2454
2455 if (!mac_enforce_network)
2456 return (0);
2457
2458 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
2459 &ifnet->if_label);
2460
2461 return (error);
2462}
2463
2464static int
2465mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
2466{
2467 int error;
2468
2469 MAC_CHECK(check_cred_relabel, cred, newlabel);
2470
2471 return (error);
2472}
2473
2474int
2475mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
2476{
2477 int error;
2478
2479 if (!mac_enforce_process)
2480 return (0);
2481
2482 MAC_CHECK(check_cred_visible, u1, u2);
2483
2484 return (error);
2485}
2486
2487int
2488mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
2489{
2490 struct label *label;
2491 int error;
2492
2493 M_ASSERTPKTHDR(mbuf);
2494
2495 if (!mac_enforce_network)
2496 return (0);
2497
2498 label = mbuf_to_label(mbuf);
2499
2500 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
2501 label);
2502
2503 return (error);
2504}
2505
2506int
2507mac_check_kenv_dump(struct ucred *cred)
2508{
2509 int error;
2510
2511 if (!mac_enforce_system)
2512 return (0);
2513
2514 MAC_CHECK(check_kenv_dump, cred);
2515
2516 return (error);
2517}
2518
2519int
2520mac_check_kenv_get(struct ucred *cred, char *name)
2521{
2522 int error;
2523
2524 if (!mac_enforce_system)
2525 return (0);
2526
2527 MAC_CHECK(check_kenv_get, cred, name);
2528
2529 return (error);
2530}
2531
2532int
2533mac_check_kenv_set(struct ucred *cred, char *name, char *value)
2534{
2535 int error;
2536
2537 if (!mac_enforce_system)
2538 return (0);
2539
2540 MAC_CHECK(check_kenv_set, cred, name, value);
2541
2542 return (error);
2543}
2544
2545int
2546mac_check_kenv_unset(struct ucred *cred, char *name)
2547{
2548 int error;
2549
2550 if (!mac_enforce_system)
2551 return (0);
2552
2553 MAC_CHECK(check_kenv_unset, cred, name);
2554
2555 return (error);
2556}
2557
2558int
2559mac_check_kld_load(struct ucred *cred, struct vnode *vp)
2560{
2561 int error;
2562
2563 ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
2564
2565 if (!mac_enforce_kld)
2566 return (0);
2567
2568 MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
2569
2570 return (error);
2571}
2572
2573int
2574mac_check_kld_stat(struct ucred *cred)
2575{
2576 int error;
2577
2578 if (!mac_enforce_kld)
2579 return (0);
2580
2581 MAC_CHECK(check_kld_stat, cred);
2582
2583 return (error);
2584}
2585
2586int
2587mac_check_kld_unload(struct ucred *cred)
2588{
2589 int error;
2590
2591 if (!mac_enforce_kld)
2592 return (0);
2593
2594 MAC_CHECK(check_kld_unload, cred);
2595
2596 return (error);
2597}
2598
2599int
2600mac_check_mount_stat(struct ucred *cred, struct mount *mount)
2601{
2602 int error;
2603
2604 if (!mac_enforce_fs)
2605 return (0);
2606
2607 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
2608
2609 return (error);
2610}
2611
2612int
2613mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
2614 void *data)
2615{
2616 int error;
2617
2618 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2619
2620 if (!mac_enforce_pipe)
2621 return (0);
2622
2623 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
2624
2625 return (error);
2626}
2627
2628int
2629mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
2630{
2631 int error;
2632
2633 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2634
2635 if (!mac_enforce_pipe)
2636 return (0);
2637
2638 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2639
2640 return (error);
2641}
2642
2643int
2644mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2645{
2646 int error;
2647
2648 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2649
2650 if (!mac_enforce_pipe)
2651 return (0);
2652
2653 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
2654
2655 return (error);
2656}
2657
2658static int
2659mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
2660 struct label *newlabel)
2661{
2662 int error;
2663
2664 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2665
2666 if (!mac_enforce_pipe)
2667 return (0);
2668
2669 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
2670
2671 return (error);
2672}
2673
2674int
2675mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2676{
2677 int error;
2678
2679 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2680
2681 if (!mac_enforce_pipe)
2682 return (0);
2683
2684 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2685
2686 return (error);
2687}
2688
2689int
2690mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2691{
2692 int error;
2693
2694 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2695
2696 if (!mac_enforce_pipe)
2697 return (0);
2698
2699 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2700
2701 return (error);
2702}
2703
2704int
2705mac_check_proc_debug(struct ucred *cred, struct proc *proc)
2706{
2707 int error;
2708
2709 PROC_LOCK_ASSERT(proc, MA_OWNED);
2710
2711 if (!mac_enforce_process)
2712 return (0);
2713
2714 MAC_CHECK(check_proc_debug, cred, proc);
2715
2716 return (error);
2717}
2718
2719int
2720mac_check_proc_sched(struct ucred *cred, struct proc *proc)
2721{
2722 int error;
2723
2724 PROC_LOCK_ASSERT(proc, MA_OWNED);
2725
2726 if (!mac_enforce_process)
2727 return (0);
2728
2729 MAC_CHECK(check_proc_sched, cred, proc);
2730
2731 return (error);
2732}
2733
2734int
2735mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2736{
2737 int error;
2738
2739 PROC_LOCK_ASSERT(proc, MA_OWNED);
2740
2741 if (!mac_enforce_process)
2742 return (0);
2743
2744 MAC_CHECK(check_proc_signal, cred, proc, signum);
2745
2746 return (error);
2747}
2748
2749int
2750mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
2751 struct sockaddr *sockaddr)
2752{
2753 int error;
2754
2755 if (!mac_enforce_socket)
2756 return (0);
2757
2758 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
2759 sockaddr);
2760
2761 return (error);
2762}
2763
2764int
2765mac_check_socket_connect(struct ucred *cred, struct socket *socket,
2766 struct sockaddr *sockaddr)
2767{
2768 int error;
2769
2770 if (!mac_enforce_socket)
2771 return (0);
2772
2773 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
2774 sockaddr);
2775
2776 return (error);
2777}
2778
2779int
2780mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2781{
2782 struct label *label;
2783 int error;
2784
2785 if (!mac_enforce_socket)
2786 return (0);
2787
2788 label = mbuf_to_label(mbuf);
2789
2790 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
2791 label);
2792
2793 return (error);
2794}
2795
2796int
2797mac_check_socket_listen(struct ucred *cred, struct socket *socket)
2798{
2799 int error;
2800
2801 if (!mac_enforce_socket)
2802 return (0);
2803
2804 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
2805 return (error);
2806}
2807
2808int
2809mac_check_socket_receive(struct ucred *cred, struct socket *so)
2810{
2811 int error;
2812
2813 if (!mac_enforce_socket)
2814 return (0);
2815
2816 MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
2817
2818 return (error);
2819}
2820
2821static int
2822mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
2823 struct label *newlabel)
2824{
2825 int error;
2826
2827 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
2828 newlabel);
2829
2830 return (error);
2831}
2832
2833int
2834mac_check_socket_send(struct ucred *cred, struct socket *so)
2835{
2836 int error;
2837
2838 if (!mac_enforce_socket)
2839 return (0);
2840
2841 MAC_CHECK(check_socket_send, cred, so, &so->so_label);
2842
2843 return (error);
2844}
2845
2846int
2847mac_check_socket_visible(struct ucred *cred, struct socket *socket)
2848{
2849 int error;
2850
2851 if (!mac_enforce_socket)
2852 return (0);
2853
2854 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
2855
2856 return (error);
2857}
2858
2859int
2860mac_check_sysarch_ioperm(struct ucred *cred)
2861{
2862 int error;
2863
2864 if (!mac_enforce_system)
2865 return (0);
2866
2867 MAC_CHECK(check_sysarch_ioperm, cred);
2868 return (error);
2869}
2870
2871int
2872mac_check_system_acct(struct ucred *cred, struct vnode *vp)
2873{
2874 int error;
2875
2876 if (vp != NULL) {
2877 ASSERT_VOP_LOCKED(vp, "mac_check_system_acct");
2878 }
2879
2880 if (!mac_enforce_system)
2881 return (0);
2882
2883 MAC_CHECK(check_system_acct, cred, vp,
2884 vp != NULL ? &vp->v_label : NULL);
2885
2886 return (error);
2887}
2888
2889int
2890mac_check_system_nfsd(struct ucred *cred)
2891{
2892 int error;
2893
2894 if (!mac_enforce_system)
2895 return (0);
2896
2897 MAC_CHECK(check_system_nfsd, cred);
2898
2899 return (error);
2900}
2901
2902int
2903mac_check_system_reboot(struct ucred *cred, int howto)
2904{
2905 int error;
2906
2907 if (!mac_enforce_system)
2908 return (0);
2909
2910 MAC_CHECK(check_system_reboot, cred, howto);
2911
2912 return (error);
2913}
2914
2915int
2916mac_check_system_settime(struct ucred *cred)
2917{
2918 int error;
2919
2920 if (!mac_enforce_system)
2921 return (0);
2922
2923 MAC_CHECK(check_system_settime, cred);
2924
2925 return (error);
2926}
2927
2928int
2929mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
2930{
2931 int error;
2932
2933 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon");
2934
2935 if (!mac_enforce_system)
2936 return (0);
2937
2938 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label);
2939 return (error);
2940}
2941
2942int
2943mac_check_system_swapoff(struct ucred *cred, struct vnode *vp)
2944{
2945 int error;
2946
2947 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff");
2948
2949 if (!mac_enforce_system)
2950 return (0);
2951
2952 MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label);
2953 return (error);
2954}
2955
2956int
2957mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
2958 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
2959{
2960 int error;
2961
2962 /*
2963 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
2964 * but since it's not exported from kern_sysctl.c, we can't.
2965 */
2966 if (!mac_enforce_system)
2967 return (0);
2968
2969 MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
2970 inkernel, new, newlen);
2971
2972 return (error);
2973}
2974
2975int
2976mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
2977 struct ifnet *ifnet)
2978{
2979 char *elements, *buffer;
2980 struct mac mac;
2981 int error;
2982
2983 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
2984 if (error)
2985 return (error);
2986
2987 error = mac_check_structmac_consistent(&mac);
2988 if (error)
2989 return (error);
2990
2991 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2992 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
2993 if (error) {
2994 free(elements, M_MACTEMP);
2995 return (error);
2996 }
2997
2998 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2999 error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
3000 buffer, mac.m_buflen, M_WAITOK);
3001 if (error == 0)
3002 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3003
3004 free(buffer, M_MACTEMP);
3005 free(elements, M_MACTEMP);
3006
3007 return (error);
3008}
3009
3010int
3011mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
3012 struct ifnet *ifnet)
3013{
3014 struct label intlabel;
3015 struct mac mac;
3016 char *buffer;
3017 int error;
3018
3019 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
3020 if (error)
3021 return (error);
3022
3023 error = mac_check_structmac_consistent(&mac);
3024 if (error)
3025 return (error);
3026
3027 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3028 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3029 if (error) {
3030 free(buffer, M_MACTEMP);
3031 return (error);
3032 }
3033
3034 mac_init_ifnet_label(&intlabel);
3035 error = mac_internalize_ifnet_label(&intlabel, buffer);
3036 free(buffer, M_MACTEMP);
3037 if (error) {
3038 mac_destroy_ifnet_label(&intlabel);
3039 return (error);
3040 }
3041
3042 /*
3043 * XXX: Note that this is a redundant privilege check, since
3044 * policies impose this check themselves if required by the
3045 * policy. Eventually, this should go away.
3046 */
3047 error = suser_cred(cred, 0);
3048 if (error) {
3049 mac_destroy_ifnet_label(&intlabel);
3050 return (error);
3051 }
3052
3053 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
3054 &intlabel);
3055 if (error) {
3056 mac_destroy_ifnet_label(&intlabel);
3057 return (error);
3058 }
3059
3060 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
3061
3062 mac_destroy_ifnet_label(&intlabel);
3063 return (0);
3064}
3065
3066void
3067mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de)
3068{
3069
3070 MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label);
3071}
3072
3073void
3074mac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
3075 struct devfs_dirent *dd, struct devfs_dirent *de)
3076{
3077
3078 MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de,
3079 &de->de_label);
3080}
3081
3082void
3083mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen,
3084 struct devfs_dirent *de)
3085{
3086
3087 MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de,
3088 &de->de_label);
3089}
3090
3091int
3092mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
3093 struct mac *mac)
3094{
3095 struct label intlabel;
3096 char *buffer;
3097 int error;
3098
3099 error = mac_check_structmac_consistent(mac);
3100 if (error)
3101 return (error);
3102
3103 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3104 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
3105 if (error) {
3106 free(buffer, M_MACTEMP);
3107 return (error);
3108 }
3109
3110 mac_init_socket_label(&intlabel, M_WAITOK);
3111 error = mac_internalize_socket_label(&intlabel, buffer);
3112 free(buffer, M_MACTEMP);
3113 if (error) {
3114 mac_destroy_socket_label(&intlabel);
3115 return (error);
3116 }
3117
3118 mac_check_socket_relabel(cred, so, &intlabel);
3119 if (error) {
3120 mac_destroy_socket_label(&intlabel);
3121 return (error);
3122 }
3123
3124 mac_relabel_socket(cred, so, &intlabel);
3125
3126 mac_destroy_socket_label(&intlabel);
3127 return (0);
3128}
3129
3130int
3131mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
3132{
3133 int error;
3134
3135 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3136
3137 error = mac_check_pipe_relabel(cred, pipe, label);
3138 if (error)
3139 return (error);
3140
3141 mac_relabel_pipe(cred, pipe, label);
3142
3143 return (0);
3144}
3145
3146int
3147mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
3148 struct mac *mac)
3149{
3150 char *buffer, *elements;
3151 int error;
3152
3153 error = mac_check_structmac_consistent(mac);
3154 if (error)
3155 return (error);
3156
3157 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3158 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3159 if (error) {
3160 free(elements, M_MACTEMP);
3161 return (error);
3162 }
3163
3164 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3165 error = mac_externalize_socket_label(&so->so_label, elements,
3166 buffer, mac->m_buflen, M_WAITOK);
3167 if (error == 0)
3168 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3169
3170 free(buffer, M_MACTEMP);
3171 free(elements, M_MACTEMP);
3172
3173 return (error);
3174}
3175
3176int
3177mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
3178 struct mac *mac)
3179{
3180 char *elements, *buffer;
3181 int error;
3182
3183 error = mac_check_structmac_consistent(mac);
3184 if (error)
3185 return (error);
3186
3187 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3188 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3189 if (error) {
3190 free(elements, M_MACTEMP);
3191 return (error);
3192 }
3193
3194 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3195 error = mac_externalize_socket_peer_label(&so->so_peerlabel,
3196 elements, buffer, mac->m_buflen, M_WAITOK);
3197 if (error == 0)
3198 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3199
3200 free(buffer, M_MACTEMP);
3201 free(elements, M_MACTEMP);
3202
3203 return (error);
3204}
3205
3206/*
3207 * Implementation of VOP_SETLABEL() that relies on extended attributes
3208 * to store label data. Can be referenced by filesystems supporting
3209 * extended attributes.
3210 */
3211int
3212vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
3213{
3214 struct vnode *vp = ap->a_vp;
3215 struct label *intlabel = ap->a_label;
3216 int error;
3217
3218 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
3219
3220 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3221 return (EOPNOTSUPP);
3222
3223 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
3224 if (error)
3225 return (error);
3226
3227 mac_relabel_vnode(ap->a_cred, vp, intlabel);
3228
3229 return (0);
3230}
3231
3232static int
3233vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
3234{
3235 int error;
3236
3237 if (vp->v_mount == NULL) {
3238 /* printf("vn_setlabel: null v_mount\n"); */
3239 if (vp->v_type != VNON)
3240 printf("vn_setlabel: null v_mount with non-VNON\n");
3241 return (EBADF);
3242 }
3243
3244 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3245 return (EOPNOTSUPP);
3246
3247 /*
3248 * Multi-phase commit. First check the policies to confirm the
3249 * change is OK. Then commit via the filesystem. Finally,
3250 * update the actual vnode label. Question: maybe the filesystem
3251 * should update the vnode at the end as part of VOP_SETLABEL()?
3252 */
3253 error = mac_check_vnode_relabel(cred, vp, intlabel);
3254 if (error)
3255 return (error);
3256
3257 /*
3258 * VADMIN provides the opportunity for the filesystem to make
3259 * decisions about who is and is not able to modify labels
3260 * and protections on files. This might not be right. We can't
3261 * assume VOP_SETLABEL() will do it, because we might implement
3262 * that as part of vop_stdsetlabel_ea().
3263 */
3264 error = VOP_ACCESS(vp, VADMIN, cred, curthread);
3265 if (error)
3266 return (error);
3267
3268 error = VOP_SETLABEL(vp, intlabel, cred, curthread);
3269 if (error)
3270 return (error);
3271
3272 return (0);
3273}
3274
3275int
3276__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
3277{
3278 char *elements, *buffer;
3279 struct mac mac;
3280 struct proc *tproc;
3281 struct ucred *tcred;
3282 int error;
3283

--- 668 unchanged lines hidden ---
525__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
526{
527 char *elements, *buffer;
528 struct mac mac;
529 struct proc *tproc;
530 struct ucred *tcred;
531 int error;
532

--- 668 unchanged lines hidden ---