1*a9643ea8Slogwang /*-
2*a9643ea8Slogwang * Copyright (c) 2003-2004 Networks Associates Technology, Inc.
3*a9643ea8Slogwang * Copyright (c) 2007 Robert N. M. Watson
4*a9643ea8Slogwang * All rights reserved.
5*a9643ea8Slogwang *
6*a9643ea8Slogwang * This software was developed for the FreeBSD Project in part by Network
7*a9643ea8Slogwang * Associates Laboratories, the Security Research Division of Network
8*a9643ea8Slogwang * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
9*a9643ea8Slogwang * as part of the DARPA CHATS research program.
10*a9643ea8Slogwang *
11*a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without
12*a9643ea8Slogwang * modification, are permitted provided that the following conditions
13*a9643ea8Slogwang * are met:
14*a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright
15*a9643ea8Slogwang * notice, this list of conditions and the following disclaimer.
16*a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright
17*a9643ea8Slogwang * notice, this list of conditions and the following disclaimer in the
18*a9643ea8Slogwang * documentation and/or other materials provided with the distribution.
19*a9643ea8Slogwang *
20*a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21*a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*a9643ea8Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*a9643ea8Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24*a9643ea8Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*a9643ea8Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*a9643ea8Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*a9643ea8Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*a9643ea8Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*a9643ea8Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*a9643ea8Slogwang * SUCH DAMAGE.
31*a9643ea8Slogwang */
32*a9643ea8Slogwang
33*a9643ea8Slogwang #include <sys/cdefs.h>
34*a9643ea8Slogwang __FBSDID("$FreeBSD$");
35*a9643ea8Slogwang
36*a9643ea8Slogwang #include "opt_mac.h"
37*a9643ea8Slogwang
38*a9643ea8Slogwang #include <sys/param.h>
39*a9643ea8Slogwang #include <sys/module.h>
40*a9643ea8Slogwang #include <sys/sysctl.h>
41*a9643ea8Slogwang #include <sys/systm.h>
42*a9643ea8Slogwang
43*a9643ea8Slogwang #include <vm/uma.h>
44*a9643ea8Slogwang
45*a9643ea8Slogwang #include <security/mac/mac_framework.h>
46*a9643ea8Slogwang #include <security/mac/mac_internal.h>
47*a9643ea8Slogwang #include <security/mac/mac_policy.h>
48*a9643ea8Slogwang
49*a9643ea8Slogwang /*
50*a9643ea8Slogwang * zone_label is the UMA zone from which most labels are allocated. Label
51*a9643ea8Slogwang * structures are initialized to zero bytes so that policies see a NULL/0
52*a9643ea8Slogwang * slot on first use, even if the policy is loaded after the label is
53*a9643ea8Slogwang * allocated for an object.
54*a9643ea8Slogwang */
55*a9643ea8Slogwang static uma_zone_t zone_label;
56*a9643ea8Slogwang
57*a9643ea8Slogwang static int mac_labelzone_ctor(void *mem, int size, void *arg, int flags);
58*a9643ea8Slogwang static void mac_labelzone_dtor(void *mem, int size, void *arg);
59*a9643ea8Slogwang
60*a9643ea8Slogwang void
mac_labelzone_init(void)61*a9643ea8Slogwang mac_labelzone_init(void)
62*a9643ea8Slogwang {
63*a9643ea8Slogwang
64*a9643ea8Slogwang zone_label = uma_zcreate("MAC labels", sizeof(struct label),
65*a9643ea8Slogwang mac_labelzone_ctor, mac_labelzone_dtor, NULL, NULL,
66*a9643ea8Slogwang UMA_ALIGN_PTR, 0);
67*a9643ea8Slogwang }
68*a9643ea8Slogwang
69*a9643ea8Slogwang /*
70*a9643ea8Slogwang * mac_init_label() and mac_destroy_label() are exported so that they can be
71*a9643ea8Slogwang * used in mbuf tag initialization, where labels are not slab allocated from
72*a9643ea8Slogwang * the zone_label zone.
73*a9643ea8Slogwang */
74*a9643ea8Slogwang void
mac_init_label(struct label * label)75*a9643ea8Slogwang mac_init_label(struct label *label)
76*a9643ea8Slogwang {
77*a9643ea8Slogwang
78*a9643ea8Slogwang bzero(label, sizeof(*label));
79*a9643ea8Slogwang label->l_flags = MAC_FLAG_INITIALIZED;
80*a9643ea8Slogwang }
81*a9643ea8Slogwang
82*a9643ea8Slogwang void
mac_destroy_label(struct label * label)83*a9643ea8Slogwang mac_destroy_label(struct label *label)
84*a9643ea8Slogwang {
85*a9643ea8Slogwang
86*a9643ea8Slogwang KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
87*a9643ea8Slogwang ("destroying uninitialized label"));
88*a9643ea8Slogwang
89*a9643ea8Slogwang #ifdef DIAGNOSTIC
90*a9643ea8Slogwang bzero(label, sizeof(*label));
91*a9643ea8Slogwang #else
92*a9643ea8Slogwang label->l_flags &= ~MAC_FLAG_INITIALIZED;
93*a9643ea8Slogwang #endif
94*a9643ea8Slogwang }
95*a9643ea8Slogwang
96*a9643ea8Slogwang static int
mac_labelzone_ctor(void * mem,int size,void * arg,int flags)97*a9643ea8Slogwang mac_labelzone_ctor(void *mem, int size, void *arg, int flags)
98*a9643ea8Slogwang {
99*a9643ea8Slogwang struct label *label;
100*a9643ea8Slogwang
101*a9643ea8Slogwang KASSERT(size == sizeof(*label), ("mac_labelzone_ctor: wrong size\n"));
102*a9643ea8Slogwang label = mem;
103*a9643ea8Slogwang mac_init_label(label);
104*a9643ea8Slogwang return (0);
105*a9643ea8Slogwang }
106*a9643ea8Slogwang
107*a9643ea8Slogwang static void
mac_labelzone_dtor(void * mem,int size,void * arg)108*a9643ea8Slogwang mac_labelzone_dtor(void *mem, int size, void *arg)
109*a9643ea8Slogwang {
110*a9643ea8Slogwang struct label *label;
111*a9643ea8Slogwang
112*a9643ea8Slogwang KASSERT(size == sizeof(*label), ("mac_labelzone_dtor: wrong size\n"));
113*a9643ea8Slogwang label = mem;
114*a9643ea8Slogwang mac_destroy_label(label);
115*a9643ea8Slogwang }
116*a9643ea8Slogwang
117*a9643ea8Slogwang struct label *
mac_labelzone_alloc(int flags)118*a9643ea8Slogwang mac_labelzone_alloc(int flags)
119*a9643ea8Slogwang {
120*a9643ea8Slogwang
121*a9643ea8Slogwang return (uma_zalloc(zone_label, flags));
122*a9643ea8Slogwang }
123*a9643ea8Slogwang
124*a9643ea8Slogwang void
mac_labelzone_free(struct label * label)125*a9643ea8Slogwang mac_labelzone_free(struct label *label)
126*a9643ea8Slogwang {
127*a9643ea8Slogwang
128*a9643ea8Slogwang uma_zfree(zone_label, label);
129*a9643ea8Slogwang }
130*a9643ea8Slogwang
131*a9643ea8Slogwang /*
132*a9643ea8Slogwang * Functions used by policy modules to get and set label values.
133*a9643ea8Slogwang */
134*a9643ea8Slogwang intptr_t
mac_label_get(struct label * l,int slot)135*a9643ea8Slogwang mac_label_get(struct label *l, int slot)
136*a9643ea8Slogwang {
137*a9643ea8Slogwang
138*a9643ea8Slogwang KASSERT(l != NULL, ("mac_label_get: NULL label"));
139*a9643ea8Slogwang
140*a9643ea8Slogwang return (l->l_perpolicy[slot]);
141*a9643ea8Slogwang }
142*a9643ea8Slogwang
143*a9643ea8Slogwang void
mac_label_set(struct label * l,int slot,intptr_t v)144*a9643ea8Slogwang mac_label_set(struct label *l, int slot, intptr_t v)
145*a9643ea8Slogwang {
146*a9643ea8Slogwang
147*a9643ea8Slogwang KASSERT(l != NULL, ("mac_label_set: NULL label"));
148*a9643ea8Slogwang
149*a9643ea8Slogwang l->l_perpolicy[slot] = v;
150*a9643ea8Slogwang }
151