1122524Srwatson/*-
2136773Srwatson * Copyright (c) 2003-2004 Networks Associates Technology, Inc.
3166533Srwatson * Copyright (c) 2007 Robert N. M. Watson
4122524Srwatson * All rights reserved.
5122524Srwatson *
6122524Srwatson * This software was developed for the FreeBSD Project in part by Network
7122524Srwatson * Associates Laboratories, the Security Research Division of Network
8122524Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
9122524Srwatson * as part of the DARPA CHATS research program.
10122524Srwatson *
11122524Srwatson * Redistribution and use in source and binary forms, with or without
12122524Srwatson * modification, are permitted provided that the following conditions
13122524Srwatson * are met:
14122524Srwatson * 1. Redistributions of source code must retain the above copyright
15122524Srwatson *    notice, this list of conditions and the following disclaimer.
16122524Srwatson * 2. Redistributions in binary form must reproduce the above copyright
17122524Srwatson *    notice, this list of conditions and the following disclaimer in the
18122524Srwatson *    documentation and/or other materials provided with the distribution.
19122524Srwatson *
20122524Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21122524Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22122524Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23122524Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24122524Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25122524Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26122524Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27122524Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28122524Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29122524Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30122524Srwatson * SUCH DAMAGE.
31122524Srwatson */
32122524Srwatson
33122524Srwatson#include <sys/cdefs.h>
34122524Srwatson__FBSDID("$FreeBSD$");
35122524Srwatson
36122524Srwatson#include "opt_mac.h"
37122524Srwatson
38122524Srwatson#include <sys/param.h>
39166533Srwatson#include <sys/module.h>
40122524Srwatson#include <sys/sysctl.h>
41122524Srwatson#include <sys/systm.h>
42122524Srwatson
43122524Srwatson#include <vm/uma.h>
44122524Srwatson
45163606Srwatson#include <security/mac/mac_framework.h>
46122524Srwatson#include <security/mac/mac_internal.h>
47166533Srwatson#include <security/mac/mac_policy.h>
48122524Srwatson
49165422Srwatson/*
50165593Srwatson * zone_label is the UMA zone from which most labels are allocated.  Label
51165422Srwatson * structures are initialized to zero bytes so that policies see a NULL/0
52165422Srwatson * slot on first use, even if the policy is loaded after the label is
53165422Srwatson * allocated for an object.
54165422Srwatson */
55165422Srwatsonstatic uma_zone_t	zone_label;
56122524Srwatson
57132987Sgreenstatic int	mac_labelzone_ctor(void *mem, int size, void *arg, int flags);
58122524Srwatsonstatic void	mac_labelzone_dtor(void *mem, int size, void *arg);
59122524Srwatson
60122524Srwatsonvoid
61122524Srwatsonmac_labelzone_init(void)
62122524Srwatson{
63122524Srwatson
64122524Srwatson	zone_label = uma_zcreate("MAC labels", sizeof(struct label),
65122524Srwatson	    mac_labelzone_ctor, mac_labelzone_dtor, NULL, NULL,
66122524Srwatson	    UMA_ALIGN_PTR, 0);
67122524Srwatson}
68122524Srwatson
69165593Srwatson/*
70165593Srwatson * mac_init_label() and mac_destroy_label() are exported so that they can be
71165593Srwatson * used in mbuf tag initialization, where labels are not slab allocated from
72165593Srwatson * the zone_label zone.
73165593Srwatson */
74165593Srwatsonvoid
75165593Srwatsonmac_init_label(struct label *label)
76165593Srwatson{
77165593Srwatson
78165593Srwatson	bzero(label, sizeof(*label));
79165593Srwatson	label->l_flags = MAC_FLAG_INITIALIZED;
80165593Srwatson}
81165593Srwatson
82165593Srwatsonvoid
83165593Srwatsonmac_destroy_label(struct label *label)
84165593Srwatson{
85165593Srwatson
86165593Srwatson	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
87165593Srwatson	    ("destroying uninitialized label"));
88165593Srwatson
89165593Srwatson#ifdef DIAGNOSTIC
90165593Srwatson	bzero(label, sizeof(*label));
91165593Srwatson#else
92165593Srwatson	label->l_flags &= ~MAC_FLAG_INITIALIZED;
93165593Srwatson#endif
94165593Srwatson}
95165593Srwatson
96165593Srwatson
97132987Sgreenstatic int
98132987Sgreenmac_labelzone_ctor(void *mem, int size, void *arg, int flags)
99122524Srwatson{
100122524Srwatson	struct label *label;
101122524Srwatson
102122524Srwatson	KASSERT(size == sizeof(*label), ("mac_labelzone_ctor: wrong size\n"));
103122524Srwatson	label = mem;
104165593Srwatson	mac_init_label(label);
105132987Sgreen	return (0);
106122524Srwatson}
107122524Srwatson
108122524Srwatsonstatic void
109122524Srwatsonmac_labelzone_dtor(void *mem, int size, void *arg)
110122524Srwatson{
111122524Srwatson	struct label *label;
112122524Srwatson
113122524Srwatson	KASSERT(size == sizeof(*label), ("mac_labelzone_dtor: wrong size\n"));
114122524Srwatson	label = mem;
115165593Srwatson	mac_destroy_label(label);
116122524Srwatson}
117122524Srwatson
118122524Srwatsonstruct label *
119122524Srwatsonmac_labelzone_alloc(int flags)
120122524Srwatson{
121122524Srwatson
122122524Srwatson	return (uma_zalloc(zone_label, flags));
123122524Srwatson}
124122524Srwatson
125122524Srwatsonvoid
126122524Srwatsonmac_labelzone_free(struct label *label)
127122524Srwatson{
128122524Srwatson
129122524Srwatson	uma_zfree(zone_label, label);
130122524Srwatson}
131166533Srwatson
132166533Srwatson/*
133166533Srwatson * Functions used by policy modules to get and set label values.
134166533Srwatson */
135166533Srwatsonintptr_t
136166533Srwatsonmac_label_get(struct label *l, int slot)
137166533Srwatson{
138166533Srwatson
139166533Srwatson	KASSERT(l != NULL, ("mac_label_get: NULL label"));
140166533Srwatson
141166533Srwatson	return (l->l_perpolicy[slot]);
142166533Srwatson}
143166533Srwatson
144166533Srwatsonvoid
145166533Srwatsonmac_label_set(struct label *l, int slot, intptr_t v)
146166533Srwatson{
147166533Srwatson
148166533Srwatson	KASSERT(l != NULL, ("mac_label_set: NULL label"));
149166533Srwatson
150166533Srwatson	l->l_perpolicy[slot] = v;
151166533Srwatson}
152