1175164Sjhb/*-
2175164Sjhb * Copyright (c) 2003-2006 SPARTA, Inc.
3225344Srwatson * Copyright (c) 2009-2011 Robert N. M. Watson
4175164Sjhb * All rights reserved.
5175164Sjhb *
6175164Sjhb * This software was developed for the FreeBSD Project in part by Network
7175164Sjhb * Associates Laboratories, the Security Research Division of Network
8175164Sjhb * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
9175164Sjhb * as part of the DARPA CHATS research program.
10175164Sjhb *
11175164Sjhb * This software was enhanced by SPARTA ISSO under SPAWAR contract
12189503Srwatson * N66001-04-C-6019 ("SEFOS"). *
13175164Sjhb *
14189503Srwatson * This software was developed at the University of Cambridge Computer
15189503Srwatson * Laboratory with support from a grant from Google, Inc.
16189503Srwatson *
17175164Sjhb * Redistribution and use in source and binary forms, with or without
18175164Sjhb * modification, are permitted provided that the following conditions
19175164Sjhb * are met:
20175164Sjhb * 1. Redistributions of source code must retain the above copyright
21175164Sjhb *    notice, this list of conditions and the following disclaimer.
22175164Sjhb * 2. Redistributions in binary form must reproduce the above copyright
23175164Sjhb *    notice, this list of conditions and the following disclaimer in the
24175164Sjhb *    documentation and/or other materials provided with the distribution.
25175164Sjhb *
26175164Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27175164Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28175164Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29175164Sjhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30175164Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31175164Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32175164Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33175164Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34175164Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35175164Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36175164Sjhb * SUCH DAMAGE.
37175164Sjhb */
38175164Sjhb
39175164Sjhb#include <sys/cdefs.h>
40175164Sjhb__FBSDID("$FreeBSD$");
41175164Sjhb
42175164Sjhb#include "opt_mac.h"
43175164Sjhb
44175164Sjhb#include <sys/param.h>
45175164Sjhb#include <sys/kernel.h>
46175164Sjhb#include <sys/mman.h>
47175164Sjhb#include <sys/malloc.h>
48175164Sjhb#include <sys/module.h>
49189503Srwatson#include <sys/sdt.h>
50175164Sjhb#include <sys/systm.h>
51175164Sjhb#include <sys/sysctl.h>
52175164Sjhb
53175164Sjhb#include <security/mac/mac_framework.h>
54175164Sjhb#include <security/mac/mac_internal.h>
55175164Sjhb#include <security/mac/mac_policy.h>
56175164Sjhb
57175164Sjhbstatic struct label *
58175164Sjhbmac_posixshm_label_alloc(void)
59175164Sjhb{
60175164Sjhb	struct label *label;
61175164Sjhb
62175164Sjhb	label = mac_labelzone_alloc(M_WAITOK);
63191731Srwatson	MAC_POLICY_PERFORM(posixshm_init_label, label);
64175164Sjhb	return (label);
65175164Sjhb}
66175164Sjhb
67175164Sjhbvoid
68175164Sjhbmac_posixshm_init(struct shmfd *shmfd)
69175164Sjhb{
70175164Sjhb
71182063Srwatson	if (mac_labeled & MPC_OBJECT_POSIXSHM)
72182063Srwatson		shmfd->shm_label = mac_posixshm_label_alloc();
73182063Srwatson	else
74182063Srwatson		shmfd->shm_label = NULL;
75175164Sjhb}
76175164Sjhb
77175164Sjhbstatic void
78175164Sjhbmac_posixshm_label_free(struct label *label)
79175164Sjhb{
80175164Sjhb
81191731Srwatson	MAC_POLICY_PERFORM_NOSLEEP(posixshm_destroy_label, label);
82175164Sjhb	mac_labelzone_free(label);
83175164Sjhb}
84175164Sjhb
85175164Sjhbvoid
86175164Sjhbmac_posixshm_destroy(struct shmfd *shmfd)
87175164Sjhb{
88175164Sjhb
89182063Srwatson	if (shmfd->shm_label != NULL) {
90182063Srwatson		mac_posixshm_label_free(shmfd->shm_label);
91182063Srwatson		shmfd->shm_label = NULL;
92182063Srwatson	}
93175164Sjhb}
94175164Sjhb
95175164Sjhbvoid
96175164Sjhbmac_posixshm_create(struct ucred *cred, struct shmfd *shmfd)
97175164Sjhb{
98175164Sjhb
99191731Srwatson	MAC_POLICY_PERFORM_NOSLEEP(posixshm_create, cred, shmfd,
100191731Srwatson	    shmfd->shm_label);
101175164Sjhb}
102175164Sjhb
103225344SrwatsonMAC_CHECK_PROBE_DEFINE2(posixshm_check_create, "struct ucred *",
104225344Srwatson    "const char *");
105225344Srwatson
106225344Srwatsonint
107225344Srwatsonmac_posixshm_check_create(struct ucred *cred, const char *path)
108225344Srwatson{
109225344Srwatson	int error;
110225344Srwatson
111225344Srwatson	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_create, cred, path);
112225344Srwatson	MAC_CHECK_PROBE2(posixshm_check_create, error, cred, path);
113225344Srwatson
114225344Srwatson	return (error);
115225344Srwatson}
116225344Srwatson
117189503SrwatsonMAC_CHECK_PROBE_DEFINE4(posixshm_check_mmap, "struct ucred *",
118189503Srwatson    "struct shmfd *", "int", "int");
119189503Srwatson
120175164Sjhbint
121175164Sjhbmac_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, int prot,
122175164Sjhb    int flags)
123175164Sjhb{
124175164Sjhb	int error;
125175164Sjhb
126191731Srwatson	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_mmap, cred, shmfd,
127191731Srwatson	    shmfd->shm_label, prot, flags);
128189503Srwatson	MAC_CHECK_PROBE4(posixshm_check_mmap, error, cred, shmfd, prot,
129189503Srwatson	    flags);
130175164Sjhb
131175164Sjhb	return (error);
132175164Sjhb}
133175164Sjhb
134225344SrwatsonMAC_CHECK_PROBE_DEFINE3(posixshm_check_open, "struct ucred *",
135255971Smarkj    "struct shmfd *", "accmode_t");
136189503Srwatson
137175164Sjhbint
138225344Srwatsonmac_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd,
139225344Srwatson    accmode_t accmode)
140175164Sjhb{
141175164Sjhb	int error;
142175164Sjhb
143191731Srwatson	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_open, cred, shmfd,
144225344Srwatson	    shmfd->shm_label, accmode);
145225344Srwatson	MAC_CHECK_PROBE3(posixshm_check_open, error, cred, shmfd, accmode);
146175164Sjhb
147175164Sjhb	return (error);
148175164Sjhb}
149175164Sjhb
150189503SrwatsonMAC_CHECK_PROBE_DEFINE3(posixshm_check_stat, "struct ucred *",
151189503Srwatson    "struct ucred *", "struct shmfd *");
152189503Srwatson
153175164Sjhbint
154175164Sjhbmac_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred,
155175164Sjhb    struct shmfd *shmfd)
156175164Sjhb{
157175164Sjhb	int error;
158175164Sjhb
159191731Srwatson	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_stat, active_cred, file_cred,
160191731Srwatson	    shmfd, shmfd->shm_label);
161189503Srwatson	MAC_CHECK_PROBE3(posixshm_check_stat, error, active_cred, file_cred,
162189503Srwatson	    shmfd);
163175164Sjhb
164175164Sjhb	return (error);
165175164Sjhb}
166175164Sjhb
167189503SrwatsonMAC_CHECK_PROBE_DEFINE3(posixshm_check_truncate, "struct ucred *",
168189503Srwatson    "struct ucred *", "struct shmfd *");
169189503Srwatson
170175164Sjhbint
171175164Sjhbmac_posixshm_check_truncate(struct ucred *active_cred, struct ucred *file_cred,
172175164Sjhb    struct shmfd *shmfd)
173175164Sjhb{
174175164Sjhb	int error;
175175164Sjhb
176191731Srwatson	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_truncate, active_cred,
177191731Srwatson	    file_cred, shmfd, shmfd->shm_label);
178189503Srwatson	MAC_CHECK_PROBE3(posixshm_check_truncate, error, active_cred,
179189503Srwatson	    file_cred, shmfd);
180175164Sjhb
181175164Sjhb	return (error);
182175164Sjhb}
183175164Sjhb
184189503SrwatsonMAC_CHECK_PROBE_DEFINE2(posixshm_check_unlink, "struct ucred *",
185189503Srwatson    "struct shmfd *");
186189503Srwatson
187175164Sjhbint
188175164Sjhbmac_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd)
189175164Sjhb{
190175164Sjhb	int error;
191175164Sjhb
192191731Srwatson	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_unlink, cred, shmfd,
193189797Srwatson	    shmfd->shm_label);
194189503Srwatson	MAC_CHECK_PROBE2(posixshm_check_unlink, error, cred, shmfd);
195175164Sjhb
196175164Sjhb	return (error);
197175164Sjhb}
198224914Skib
199224914SkibMAC_CHECK_PROBE_DEFINE3(posixshm_check_setmode, "struct ucred *",
200224914Skib    "struct shmfd *", "mode_t");
201224914Skib
202224914Skibint
203224914Skibmac_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, mode_t mode)
204224914Skib{
205224914Skib	int error;
206224914Skib
207224914Skib	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_setmode, cred, shmfd,
208224914Skib	    shmfd->shm_label, mode);
209224914Skib	MAC_CHECK_PROBE3(posixshm_check_setmode, error, cred, shmfd, mode);
210224914Skib
211224914Skib	return (error);
212224914Skib}
213224914Skib
214224914SkibMAC_CHECK_PROBE_DEFINE4(posixshm_check_setowner, "struct ucred *",
215224914Skib    "struct shmfd *", "uid_t", "gid_t");
216224914Skib
217224914Skibint
218224914Skibmac_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, uid_t uid,
219224914Skib    gid_t gid)
220224914Skib{
221224914Skib	int error;
222224914Skib
223224914Skib	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_setowner, cred, shmfd,
224224914Skib	    shmfd->shm_label, uid, gid);
225224914Skib	MAC_CHECK_PROBE4(posixshm_check_setowner, error, cred, shmfd,
226224914Skib	    uid, gid);
227224914Skib
228224914Skib	return (error);
229224914Skib}
230254603Skib
231254603SkibMAC_CHECK_PROBE_DEFINE3(posixshm_check_read, "struct ucred *",
232254603Skib    "struct ucred *", "struct shmfd *");
233254603Skib
234254603Skibint
235254603Skibmac_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred,
236254603Skib    struct shmfd *shmfd)
237254603Skib{
238254603Skib	int error;
239254603Skib
240254603Skib	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_read, active_cred,
241254603Skib	    file_cred, shmfd, shmfd->shm_label);
242254603Skib	MAC_CHECK_PROBE3(posixshm_check_read, error, active_cred,
243254603Skib	    file_cred, shmfd);
244254603Skib
245254603Skib	return (error);
246254603Skib}
247254603Skib
248254603SkibMAC_CHECK_PROBE_DEFINE3(posixshm_check_write, "struct ucred *",
249254603Skib    "struct ucred *", "struct shmfd *");
250254603Skib
251254603Skibint
252254603Skibmac_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred,
253254603Skib    struct shmfd *shmfd)
254254603Skib{
255254603Skib	int error;
256254603Skib
257254603Skib	MAC_POLICY_CHECK_NOSLEEP(posixshm_check_write, active_cred,
258254603Skib	    file_cred, shmfd, shmfd->shm_label);
259254603Skib	MAC_CHECK_PROBE3(posixshm_check_write, error, active_cred,
260254603Skib	    file_cred, shmfd);
261254603Skib
262254603Skib	return (error);
263254603Skib}
264