xref: /freebsd-src/sys/security/mac/mac_posix_sem.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
152648411SRobert Watson /*-
230d239bcSRobert Watson  * Copyright (c) 2003-2006 SPARTA, Inc.
32087a58cSRobert Watson  * Copyright (c) 2009 Robert N. M. Watson
452648411SRobert Watson  * All rights reserved.
552648411SRobert Watson  *
652648411SRobert Watson  * This software was developed for the FreeBSD Project in part by Network
752648411SRobert Watson  * Associates Laboratories, the Security Research Division of Network
852648411SRobert Watson  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
952648411SRobert Watson  * as part of the DARPA CHATS research program.
1052648411SRobert Watson  *
1130d239bcSRobert Watson  * This software was enhanced by SPARTA ISSO under SPAWAR contract
1230d239bcSRobert Watson  * N66001-04-C-6019 ("SEFOS").
1330d239bcSRobert Watson  *
142087a58cSRobert Watson  * This software was developed at the University of Cambridge Computer
152087a58cSRobert Watson  * Laboratory with support from a grant from Google, Inc.
162087a58cSRobert Watson  *
1752648411SRobert Watson  * Redistribution and use in source and binary forms, with or without
1852648411SRobert Watson  * modification, are permitted provided that the following conditions
1952648411SRobert Watson  * are met:
2052648411SRobert Watson  * 1. Redistributions of source code must retain the above copyright
2152648411SRobert Watson  *    notice, this list of conditions and the following disclaimer.
2252648411SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
2352648411SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
2452648411SRobert Watson  *    documentation and/or other materials provided with the distribution.
2552648411SRobert Watson  *
2652648411SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2752648411SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2852648411SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2952648411SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
3052648411SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3152648411SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3252648411SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3352648411SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3452648411SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3552648411SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3652648411SRobert Watson  * SUCH DAMAGE.
3752648411SRobert Watson  */
3852648411SRobert Watson 
3952648411SRobert Watson #include <sys/cdefs.h>
4052648411SRobert Watson #include "opt_mac.h"
4152648411SRobert Watson #include "opt_posix.h"
4252648411SRobert Watson 
4352648411SRobert Watson #include <sys/param.h>
4452648411SRobert Watson #include <sys/kernel.h>
456aeb05d7STom Rhodes #include <sys/ksem.h>
4652648411SRobert Watson #include <sys/malloc.h>
4752648411SRobert Watson #include <sys/module.h>
482087a58cSRobert Watson #include <sys/sdt.h>
4952648411SRobert Watson #include <sys/systm.h>
5052648411SRobert Watson #include <sys/sysctl.h>
5152648411SRobert Watson 
52aed55708SRobert Watson #include <security/mac/mac_framework.h>
5352648411SRobert Watson #include <security/mac/mac_internal.h>
540efd6615SRobert Watson #include <security/mac/mac_policy.h>
5552648411SRobert Watson 
5652648411SRobert Watson static struct label *
mac_posixsem_label_alloc(void)5730d239bcSRobert Watson mac_posixsem_label_alloc(void)
5852648411SRobert Watson {
5952648411SRobert Watson 	struct label *label;
6052648411SRobert Watson 
6152648411SRobert Watson 	label = mac_labelzone_alloc(M_WAITOK);
62fa765671SRobert Watson 	MAC_POLICY_PERFORM(posixsem_init_label, label);
6352648411SRobert Watson 	return (label);
6452648411SRobert Watson }
6552648411SRobert Watson 
6652648411SRobert Watson void
mac_posixsem_init(struct ksem * ks)6730d239bcSRobert Watson mac_posixsem_init(struct ksem *ks)
6852648411SRobert Watson {
6952648411SRobert Watson 
706356dba0SRobert Watson 	if (mac_labeled & MPC_OBJECT_POSIXSEM)
7130d239bcSRobert Watson 		ks->ks_label = mac_posixsem_label_alloc();
726356dba0SRobert Watson 	else
736356dba0SRobert Watson 		ks->ks_label = NULL;
7452648411SRobert Watson }
7552648411SRobert Watson 
7652648411SRobert Watson static void
mac_posixsem_label_free(struct label * label)7730d239bcSRobert Watson mac_posixsem_label_free(struct label *label)
7852648411SRobert Watson {
7952648411SRobert Watson 
80fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(posixsem_destroy_label, label);
81b5f992b9SRobert Watson 	mac_labelzone_free(label);
8252648411SRobert Watson }
8352648411SRobert Watson 
8452648411SRobert Watson void
mac_posixsem_destroy(struct ksem * ks)8530d239bcSRobert Watson mac_posixsem_destroy(struct ksem *ks)
8652648411SRobert Watson {
8752648411SRobert Watson 
886356dba0SRobert Watson 	if (ks->ks_label != NULL) {
8930d239bcSRobert Watson 		mac_posixsem_label_free(ks->ks_label);
90fe09513eSRobert Watson 		ks->ks_label = NULL;
9152648411SRobert Watson 	}
926356dba0SRobert Watson }
9352648411SRobert Watson 
9452648411SRobert Watson void
mac_posixsem_create(struct ucred * cred,struct ksem * ks)9530d239bcSRobert Watson mac_posixsem_create(struct ucred *cred, struct ksem *ks)
9652648411SRobert Watson {
9752648411SRobert Watson 
98fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(posixsem_create, cred, ks, ks->ks_label);
9952648411SRobert Watson }
10052648411SRobert Watson 
1012087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(posixsem_check_open, "struct ucred *",
1022087a58cSRobert Watson     "struct ksem *");
1032087a58cSRobert Watson 
10452648411SRobert Watson int
mac_posixsem_check_open(struct ucred * cred,struct ksem * ks)10530d239bcSRobert Watson mac_posixsem_check_open(struct ucred *cred, struct ksem *ks)
10652648411SRobert Watson {
10752648411SRobert Watson 	int error;
10852648411SRobert Watson 
109fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_open, cred, ks,
110fa765671SRobert Watson 	    ks->ks_label);
1112087a58cSRobert Watson 	MAC_CHECK_PROBE2(posixsem_check_open, error, cred, ks);
11252648411SRobert Watson 
11352648411SRobert Watson 	return (error);
11452648411SRobert Watson }
11552648411SRobert Watson 
1162087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(posixsem_check_getvalue, "struct ucred *",
1172087a58cSRobert Watson     "struct ucred *", "struct ksem *");
1182087a58cSRobert Watson 
11952648411SRobert Watson int
mac_posixsem_check_getvalue(struct ucred * active_cred,struct ucred * file_cred,struct ksem * ks)1206bc1e9cdSJohn Baldwin mac_posixsem_check_getvalue(struct ucred *active_cred, struct ucred *file_cred,
1216bc1e9cdSJohn Baldwin     struct ksem *ks)
12252648411SRobert Watson {
12352648411SRobert Watson 	int error;
12452648411SRobert Watson 
125fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_getvalue, active_cred,
126fa765671SRobert Watson 	    file_cred, ks, ks->ks_label);
1272087a58cSRobert Watson 	MAC_CHECK_PROBE3(posixsem_check_getvalue, error, active_cred,
1282087a58cSRobert Watson 	    file_cred, ks);
12952648411SRobert Watson 
13052648411SRobert Watson 	return (error);
13152648411SRobert Watson }
13252648411SRobert Watson 
1332087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(posixsem_check_post, "struct ucred *",
1342087a58cSRobert Watson     "struct ucred *", "struct ksem *");
1352087a58cSRobert Watson 
13652648411SRobert Watson int
mac_posixsem_check_post(struct ucred * active_cred,struct ucred * file_cred,struct ksem * ks)1376bc1e9cdSJohn Baldwin mac_posixsem_check_post(struct ucred *active_cred, struct ucred *file_cred,
1386bc1e9cdSJohn Baldwin     struct ksem *ks)
13952648411SRobert Watson {
14052648411SRobert Watson 	int error;
14152648411SRobert Watson 
142fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_post, active_cred, file_cred,
143fa765671SRobert Watson 	    ks, ks->ks_label);
1442087a58cSRobert Watson 	MAC_CHECK_PROBE3(posixsem_check_post, error, active_cred, file_cred,
1452087a58cSRobert Watson 	    ks);
1466bc1e9cdSJohn Baldwin 
1476bc1e9cdSJohn Baldwin 	return (error);
1486bc1e9cdSJohn Baldwin }
1496bc1e9cdSJohn Baldwin 
1502087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(posixsem_check_stat, "struct ucred *",
1512087a58cSRobert Watson     "struct ucred *", "struct ksem *");
1522087a58cSRobert Watson 
1536bc1e9cdSJohn Baldwin int
mac_posixsem_check_stat(struct ucred * active_cred,struct ucred * file_cred,struct ksem * ks)1546bc1e9cdSJohn Baldwin mac_posixsem_check_stat(struct ucred *active_cred, struct ucred *file_cred,
1556bc1e9cdSJohn Baldwin     struct ksem *ks)
1566bc1e9cdSJohn Baldwin {
1576bc1e9cdSJohn Baldwin 	int error;
1586bc1e9cdSJohn Baldwin 
159fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_stat, active_cred, file_cred,
160fa765671SRobert Watson 	    ks, ks->ks_label);
1612087a58cSRobert Watson 	MAC_CHECK_PROBE3(posixsem_check_stat, error, active_cred, file_cred,
1622087a58cSRobert Watson 	    ks);
16352648411SRobert Watson 
16452648411SRobert Watson 	return (error);
16552648411SRobert Watson }
16652648411SRobert Watson 
1672087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(posixsem_check_unlink, "struct ucred *",
1682087a58cSRobert Watson     "struct ksem *");
1692087a58cSRobert Watson 
17052648411SRobert Watson int
mac_posixsem_check_unlink(struct ucred * cred,struct ksem * ks)17130d239bcSRobert Watson mac_posixsem_check_unlink(struct ucred *cred, struct ksem *ks)
17252648411SRobert Watson {
17352648411SRobert Watson 	int error;
17452648411SRobert Watson 
175fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_unlink, cred, ks,
176fa765671SRobert Watson 	    ks->ks_label);
1772087a58cSRobert Watson 	MAC_CHECK_PROBE2(posixsem_check_unlink, error, cred, ks);
17852648411SRobert Watson 
17952648411SRobert Watson 	return (error);
18052648411SRobert Watson }
18152648411SRobert Watson 
1822087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(posixsem_check_wait, "struct ucred *",
1832087a58cSRobert Watson     "struct ucred *", "struct ksem *");
1842087a58cSRobert Watson 
18552648411SRobert Watson int
mac_posixsem_check_wait(struct ucred * active_cred,struct ucred * file_cred,struct ksem * ks)1866bc1e9cdSJohn Baldwin mac_posixsem_check_wait(struct ucred *active_cred, struct ucred *file_cred,
1876bc1e9cdSJohn Baldwin     struct ksem *ks)
18852648411SRobert Watson {
18952648411SRobert Watson 	int error;
19052648411SRobert Watson 
191fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_wait, active_cred, file_cred,
192fa765671SRobert Watson 	    ks, ks->ks_label);
1932087a58cSRobert Watson 	MAC_CHECK_PROBE3(posixsem_check_wait, error, active_cred, file_cred,
1942087a58cSRobert Watson 	    ks);
19552648411SRobert Watson 
19652648411SRobert Watson 	return (error);
19752648411SRobert Watson }
198*9c00bb91SKonstantin Belousov 
199*9c00bb91SKonstantin Belousov MAC_CHECK_PROBE_DEFINE3(posixsem_check_setmode, "struct ucred *",
200*9c00bb91SKonstantin Belousov     "struct ksem *", "mode_t");
201*9c00bb91SKonstantin Belousov 
202*9c00bb91SKonstantin Belousov int
mac_posixsem_check_setmode(struct ucred * cred,struct ksem * ks,mode_t mode)203*9c00bb91SKonstantin Belousov mac_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, mode_t mode)
204*9c00bb91SKonstantin Belousov {
205*9c00bb91SKonstantin Belousov 	int error;
206*9c00bb91SKonstantin Belousov 
207*9c00bb91SKonstantin Belousov 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_setmode, cred, ks,
208*9c00bb91SKonstantin Belousov 	    ks->ks_label, mode);
209*9c00bb91SKonstantin Belousov 	MAC_CHECK_PROBE3(posixsem_check_setmode, error, cred, ks, mode);
210*9c00bb91SKonstantin Belousov 
211*9c00bb91SKonstantin Belousov 	return (error);
212*9c00bb91SKonstantin Belousov }
213*9c00bb91SKonstantin Belousov 
214*9c00bb91SKonstantin Belousov MAC_CHECK_PROBE_DEFINE4(posixsem_check_setowner, "struct ucred *",
215*9c00bb91SKonstantin Belousov     "struct ks *", "uid_t", "gid_t");
216*9c00bb91SKonstantin Belousov 
217*9c00bb91SKonstantin Belousov int
mac_posixsem_check_setowner(struct ucred * cred,struct ksem * ks,uid_t uid,gid_t gid)218*9c00bb91SKonstantin Belousov mac_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, uid_t uid,
219*9c00bb91SKonstantin Belousov     gid_t gid)
220*9c00bb91SKonstantin Belousov {
221*9c00bb91SKonstantin Belousov 	int error;
222*9c00bb91SKonstantin Belousov 
223*9c00bb91SKonstantin Belousov 	MAC_POLICY_CHECK_NOSLEEP(posixsem_check_setowner, cred, ks,
224*9c00bb91SKonstantin Belousov 	    ks->ks_label, uid, gid);
225*9c00bb91SKonstantin Belousov 	MAC_CHECK_PROBE4(posixsem_check_setowner, error, cred, ks,
226*9c00bb91SKonstantin Belousov 	    uid, gid);
227*9c00bb91SKonstantin Belousov 
228*9c00bb91SKonstantin Belousov 	return (error);
229*9c00bb91SKonstantin Belousov }
230