1*a9643ea8Slogwang /*-
2*a9643ea8Slogwang * Copyright (c) 2003-2004 Networks Associates Technology, Inc.
3*a9643ea8Slogwang * Copyright (c) 2006 SPARTA, Inc.
4*a9643ea8Slogwang * Copyright (c) 2008 Apple Inc.
5*a9643ea8Slogwang * Copyright (c) 2009 Robert N. M. Watson
6*a9643ea8Slogwang * All rights reserved.
7*a9643ea8Slogwang *
8*a9643ea8Slogwang * This software was developed for the FreeBSD Project in part by Network
9*a9643ea8Slogwang * Associates Laboratories, the Security Research Division of Network
10*a9643ea8Slogwang * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
11*a9643ea8Slogwang * as part of the DARPA CHATS research program.
12*a9643ea8Slogwang *
13*a9643ea8Slogwang * This software was enhanced by SPARTA ISSO under SPAWAR contract
14*a9643ea8Slogwang * N66001-04-C-6019 ("SEFOS").
15*a9643ea8Slogwang *
16*a9643ea8Slogwang * This software was developed at the University of Cambridge Computer
17*a9643ea8Slogwang * Laboratory with support from a grant from Google, Inc.
18*a9643ea8Slogwang *
19*a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without
20*a9643ea8Slogwang * modification, are permitted provided that the following conditions
21*a9643ea8Slogwang * are met:
22*a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright
23*a9643ea8Slogwang * notice, this list of conditions and the following disclaimer.
24*a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright
25*a9643ea8Slogwang * notice, this list of conditions and the following disclaimer in the
26*a9643ea8Slogwang * documentation and/or other materials provided with the distribution.
27*a9643ea8Slogwang *
28*a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
29*a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30*a9643ea8Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31*a9643ea8Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32*a9643ea8Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33*a9643ea8Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34*a9643ea8Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35*a9643ea8Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36*a9643ea8Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37*a9643ea8Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38*a9643ea8Slogwang * SUCH DAMAGE.
39*a9643ea8Slogwang */
40*a9643ea8Slogwang
41*a9643ea8Slogwang #include <sys/cdefs.h>
42*a9643ea8Slogwang __FBSDID("$FreeBSD$");
43*a9643ea8Slogwang
44*a9643ea8Slogwang #include "opt_mac.h"
45*a9643ea8Slogwang
46*a9643ea8Slogwang #include <sys/param.h>
47*a9643ea8Slogwang #include <sys/kernel.h>
48*a9643ea8Slogwang #include <sys/lock.h>
49*a9643ea8Slogwang #include <sys/malloc.h>
50*a9643ea8Slogwang #include <sys/mutex.h>
51*a9643ea8Slogwang #include <sys/sbuf.h>
52*a9643ea8Slogwang #include <sys/sdt.h>
53*a9643ea8Slogwang #include <sys/systm.h>
54*a9643ea8Slogwang #include <sys/vnode.h>
55*a9643ea8Slogwang #include <sys/mount.h>
56*a9643ea8Slogwang #include <sys/file.h>
57*a9643ea8Slogwang #include <sys/namei.h>
58*a9643ea8Slogwang #include <sys/sysctl.h>
59*a9643ea8Slogwang #include <sys/msg.h>
60*a9643ea8Slogwang
61*a9643ea8Slogwang #include <security/mac/mac_framework.h>
62*a9643ea8Slogwang #include <security/mac/mac_internal.h>
63*a9643ea8Slogwang #include <security/mac/mac_policy.h>
64*a9643ea8Slogwang
65*a9643ea8Slogwang static struct label *
mac_sysv_msgmsg_label_alloc(void)66*a9643ea8Slogwang mac_sysv_msgmsg_label_alloc(void)
67*a9643ea8Slogwang {
68*a9643ea8Slogwang struct label *label;
69*a9643ea8Slogwang
70*a9643ea8Slogwang label = mac_labelzone_alloc(M_WAITOK);
71*a9643ea8Slogwang MAC_POLICY_PERFORM(sysvmsg_init_label, label);
72*a9643ea8Slogwang return (label);
73*a9643ea8Slogwang }
74*a9643ea8Slogwang
75*a9643ea8Slogwang void
mac_sysvmsg_init(struct msg * msgptr)76*a9643ea8Slogwang mac_sysvmsg_init(struct msg *msgptr)
77*a9643ea8Slogwang {
78*a9643ea8Slogwang
79*a9643ea8Slogwang if (mac_labeled & MPC_OBJECT_SYSVMSG)
80*a9643ea8Slogwang msgptr->label = mac_sysv_msgmsg_label_alloc();
81*a9643ea8Slogwang else
82*a9643ea8Slogwang msgptr->label = NULL;
83*a9643ea8Slogwang }
84*a9643ea8Slogwang
85*a9643ea8Slogwang static struct label *
mac_sysv_msgqueue_label_alloc(void)86*a9643ea8Slogwang mac_sysv_msgqueue_label_alloc(void)
87*a9643ea8Slogwang {
88*a9643ea8Slogwang struct label *label;
89*a9643ea8Slogwang
90*a9643ea8Slogwang label = mac_labelzone_alloc(M_WAITOK);
91*a9643ea8Slogwang MAC_POLICY_PERFORM(sysvmsq_init_label, label);
92*a9643ea8Slogwang return (label);
93*a9643ea8Slogwang }
94*a9643ea8Slogwang
95*a9643ea8Slogwang void
mac_sysvmsq_init(struct msqid_kernel * msqkptr)96*a9643ea8Slogwang mac_sysvmsq_init(struct msqid_kernel *msqkptr)
97*a9643ea8Slogwang {
98*a9643ea8Slogwang
99*a9643ea8Slogwang if (mac_labeled & MPC_OBJECT_SYSVMSQ)
100*a9643ea8Slogwang msqkptr->label = mac_sysv_msgqueue_label_alloc();
101*a9643ea8Slogwang else
102*a9643ea8Slogwang msqkptr->label = NULL;
103*a9643ea8Slogwang }
104*a9643ea8Slogwang
105*a9643ea8Slogwang static void
mac_sysv_msgmsg_label_free(struct label * label)106*a9643ea8Slogwang mac_sysv_msgmsg_label_free(struct label *label)
107*a9643ea8Slogwang {
108*a9643ea8Slogwang
109*a9643ea8Slogwang MAC_POLICY_PERFORM_NOSLEEP(sysvmsg_destroy_label, label);
110*a9643ea8Slogwang mac_labelzone_free(label);
111*a9643ea8Slogwang }
112*a9643ea8Slogwang
113*a9643ea8Slogwang void
mac_sysvmsg_destroy(struct msg * msgptr)114*a9643ea8Slogwang mac_sysvmsg_destroy(struct msg *msgptr)
115*a9643ea8Slogwang {
116*a9643ea8Slogwang
117*a9643ea8Slogwang if (msgptr->label != NULL) {
118*a9643ea8Slogwang mac_sysv_msgmsg_label_free(msgptr->label);
119*a9643ea8Slogwang msgptr->label = NULL;
120*a9643ea8Slogwang }
121*a9643ea8Slogwang }
122*a9643ea8Slogwang
123*a9643ea8Slogwang static void
mac_sysv_msgqueue_label_free(struct label * label)124*a9643ea8Slogwang mac_sysv_msgqueue_label_free(struct label *label)
125*a9643ea8Slogwang {
126*a9643ea8Slogwang
127*a9643ea8Slogwang MAC_POLICY_PERFORM_NOSLEEP(sysvmsq_destroy_label, label);
128*a9643ea8Slogwang mac_labelzone_free(label);
129*a9643ea8Slogwang }
130*a9643ea8Slogwang
131*a9643ea8Slogwang void
mac_sysvmsq_destroy(struct msqid_kernel * msqkptr)132*a9643ea8Slogwang mac_sysvmsq_destroy(struct msqid_kernel *msqkptr)
133*a9643ea8Slogwang {
134*a9643ea8Slogwang
135*a9643ea8Slogwang if (msqkptr->label != NULL) {
136*a9643ea8Slogwang mac_sysv_msgqueue_label_free(msqkptr->label);
137*a9643ea8Slogwang msqkptr->label = NULL;
138*a9643ea8Slogwang }
139*a9643ea8Slogwang }
140*a9643ea8Slogwang
141*a9643ea8Slogwang void
mac_sysvmsg_create(struct ucred * cred,struct msqid_kernel * msqkptr,struct msg * msgptr)142*a9643ea8Slogwang mac_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
143*a9643ea8Slogwang struct msg *msgptr)
144*a9643ea8Slogwang {
145*a9643ea8Slogwang
146*a9643ea8Slogwang MAC_POLICY_PERFORM_NOSLEEP(sysvmsg_create, cred, msqkptr,
147*a9643ea8Slogwang msqkptr->label, msgptr, msgptr->label);
148*a9643ea8Slogwang }
149*a9643ea8Slogwang
150*a9643ea8Slogwang void
mac_sysvmsq_create(struct ucred * cred,struct msqid_kernel * msqkptr)151*a9643ea8Slogwang mac_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr)
152*a9643ea8Slogwang {
153*a9643ea8Slogwang
154*a9643ea8Slogwang MAC_POLICY_PERFORM_NOSLEEP(sysvmsq_create, cred, msqkptr,
155*a9643ea8Slogwang msqkptr->label);
156*a9643ea8Slogwang }
157*a9643ea8Slogwang
158*a9643ea8Slogwang void
mac_sysvmsg_cleanup(struct msg * msgptr)159*a9643ea8Slogwang mac_sysvmsg_cleanup(struct msg *msgptr)
160*a9643ea8Slogwang {
161*a9643ea8Slogwang
162*a9643ea8Slogwang MAC_POLICY_PERFORM_NOSLEEP(sysvmsg_cleanup, msgptr->label);
163*a9643ea8Slogwang }
164*a9643ea8Slogwang
165*a9643ea8Slogwang void
mac_sysvmsq_cleanup(struct msqid_kernel * msqkptr)166*a9643ea8Slogwang mac_sysvmsq_cleanup(struct msqid_kernel *msqkptr)
167*a9643ea8Slogwang {
168*a9643ea8Slogwang
169*a9643ea8Slogwang MAC_POLICY_PERFORM_NOSLEEP(sysvmsq_cleanup, msqkptr->label);
170*a9643ea8Slogwang }
171*a9643ea8Slogwang
172*a9643ea8Slogwang MAC_CHECK_PROBE_DEFINE3(sysvmsq_check_msgmsq, "struct ucred *",
173*a9643ea8Slogwang "struct msg *", "struct msqid_kernel *");
174*a9643ea8Slogwang
175*a9643ea8Slogwang int
mac_sysvmsq_check_msgmsq(struct ucred * cred,struct msg * msgptr,struct msqid_kernel * msqkptr)176*a9643ea8Slogwang mac_sysvmsq_check_msgmsq(struct ucred *cred, struct msg *msgptr,
177*a9643ea8Slogwang struct msqid_kernel *msqkptr)
178*a9643ea8Slogwang {
179*a9643ea8Slogwang int error;
180*a9643ea8Slogwang
181*a9643ea8Slogwang MAC_POLICY_CHECK_NOSLEEP(sysvmsq_check_msgmsq, cred, msgptr,
182*a9643ea8Slogwang msgptr->label, msqkptr, msqkptr->label);
183*a9643ea8Slogwang MAC_CHECK_PROBE3(sysvmsq_check_msgmsq, error, cred, msgptr, msqkptr);
184*a9643ea8Slogwang
185*a9643ea8Slogwang return (error);
186*a9643ea8Slogwang }
187*a9643ea8Slogwang
188*a9643ea8Slogwang MAC_CHECK_PROBE_DEFINE2(sysvmsq_check_msgrcv, "struct ucred *",
189*a9643ea8Slogwang "struct msg *");
190*a9643ea8Slogwang
191*a9643ea8Slogwang int
mac_sysvmsq_check_msgrcv(struct ucred * cred,struct msg * msgptr)192*a9643ea8Slogwang mac_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr)
193*a9643ea8Slogwang {
194*a9643ea8Slogwang int error;
195*a9643ea8Slogwang
196*a9643ea8Slogwang MAC_POLICY_CHECK_NOSLEEP(sysvmsq_check_msgrcv, cred, msgptr,
197*a9643ea8Slogwang msgptr->label);
198*a9643ea8Slogwang MAC_CHECK_PROBE2(sysvmsq_check_msgrcv, error, cred, msgptr);
199*a9643ea8Slogwang
200*a9643ea8Slogwang return (error);
201*a9643ea8Slogwang }
202*a9643ea8Slogwang
203*a9643ea8Slogwang MAC_CHECK_PROBE_DEFINE2(sysvmsq_check_msgrmid, "struct ucred *",
204*a9643ea8Slogwang "struct msg *");
205*a9643ea8Slogwang
206*a9643ea8Slogwang int
mac_sysvmsq_check_msgrmid(struct ucred * cred,struct msg * msgptr)207*a9643ea8Slogwang mac_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr)
208*a9643ea8Slogwang {
209*a9643ea8Slogwang int error;
210*a9643ea8Slogwang
211*a9643ea8Slogwang MAC_POLICY_CHECK_NOSLEEP(sysvmsq_check_msgrmid, cred, msgptr,
212*a9643ea8Slogwang msgptr->label);
213*a9643ea8Slogwang MAC_CHECK_PROBE2(sysvmsq_check_msgrmid, error, cred, msgptr);
214*a9643ea8Slogwang
215*a9643ea8Slogwang return (error);
216*a9643ea8Slogwang }
217*a9643ea8Slogwang
218*a9643ea8Slogwang MAC_CHECK_PROBE_DEFINE2(sysvmsq_check_msqget, "struct ucred *",
219*a9643ea8Slogwang "struct msqid_kernel *");
220*a9643ea8Slogwang
221*a9643ea8Slogwang int
mac_sysvmsq_check_msqget(struct ucred * cred,struct msqid_kernel * msqkptr)222*a9643ea8Slogwang mac_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr)
223*a9643ea8Slogwang {
224*a9643ea8Slogwang int error;
225*a9643ea8Slogwang
226*a9643ea8Slogwang MAC_POLICY_CHECK_NOSLEEP(sysvmsq_check_msqget, cred, msqkptr,
227*a9643ea8Slogwang msqkptr->label);
228*a9643ea8Slogwang MAC_CHECK_PROBE2(sysvmsq_check_msqget, error, cred, msqkptr);
229*a9643ea8Slogwang
230*a9643ea8Slogwang return (error);
231*a9643ea8Slogwang }
232*a9643ea8Slogwang
233*a9643ea8Slogwang MAC_CHECK_PROBE_DEFINE2(sysvmsq_check_msqsnd, "struct ucred *",
234*a9643ea8Slogwang "struct msqid_kernel *");
235*a9643ea8Slogwang
236*a9643ea8Slogwang int
mac_sysvmsq_check_msqsnd(struct ucred * cred,struct msqid_kernel * msqkptr)237*a9643ea8Slogwang mac_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr)
238*a9643ea8Slogwang {
239*a9643ea8Slogwang int error;
240*a9643ea8Slogwang
241*a9643ea8Slogwang MAC_POLICY_CHECK_NOSLEEP(sysvmsq_check_msqsnd, cred, msqkptr,
242*a9643ea8Slogwang msqkptr->label);
243*a9643ea8Slogwang MAC_CHECK_PROBE2(sysvmsq_check_msqsnd, error, cred, msqkptr);
244*a9643ea8Slogwang
245*a9643ea8Slogwang return (error);
246*a9643ea8Slogwang }
247*a9643ea8Slogwang
248*a9643ea8Slogwang MAC_CHECK_PROBE_DEFINE2(sysvmsq_check_msqrcv, "struct ucred *",
249*a9643ea8Slogwang "struct msqid_kernel *");
250*a9643ea8Slogwang
251*a9643ea8Slogwang int
mac_sysvmsq_check_msqrcv(struct ucred * cred,struct msqid_kernel * msqkptr)252*a9643ea8Slogwang mac_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr)
253*a9643ea8Slogwang {
254*a9643ea8Slogwang int error;
255*a9643ea8Slogwang
256*a9643ea8Slogwang MAC_POLICY_CHECK_NOSLEEP(sysvmsq_check_msqrcv, cred, msqkptr,
257*a9643ea8Slogwang msqkptr->label);
258*a9643ea8Slogwang MAC_CHECK_PROBE2(sysvmsq_check_msqrcv, error, cred, msqkptr);
259*a9643ea8Slogwang
260*a9643ea8Slogwang return (error);
261*a9643ea8Slogwang }
262*a9643ea8Slogwang
263*a9643ea8Slogwang MAC_CHECK_PROBE_DEFINE3(sysvmsq_check_msqctl, "struct ucred *",
264*a9643ea8Slogwang "struct msqid_kernel *", "int");
265*a9643ea8Slogwang
266*a9643ea8Slogwang int
mac_sysvmsq_check_msqctl(struct ucred * cred,struct msqid_kernel * msqkptr,int cmd)267*a9643ea8Slogwang mac_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
268*a9643ea8Slogwang int cmd)
269*a9643ea8Slogwang {
270*a9643ea8Slogwang int error;
271*a9643ea8Slogwang
272*a9643ea8Slogwang MAC_POLICY_CHECK_NOSLEEP(sysvmsq_check_msqctl, cred, msqkptr,
273*a9643ea8Slogwang msqkptr->label, cmd);
274*a9643ea8Slogwang MAC_CHECK_PROBE3(sysvmsq_check_msqctl, error, cred, msqkptr, cmd);
275*a9643ea8Slogwang
276*a9643ea8Slogwang return (error);
277*a9643ea8Slogwang }
278