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