18b099b73SRobert Watson /*-
28b099b73SRobert Watson * Copyright (c) 2003-2004 Networks Associates Technology, Inc.
330d239bcSRobert Watson * Copyright (c) 2006 SPARTA, Inc.
42087a58cSRobert Watson * Copyright (c) 2009 Robert N. M. Watson
58b099b73SRobert Watson * All rights reserved.
68b099b73SRobert Watson *
78b099b73SRobert Watson * This software was developed for the FreeBSD Project in part by Network
88b099b73SRobert Watson * Associates Laboratories, the Security Research Division of Network
98b099b73SRobert Watson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
108b099b73SRobert Watson * as part of the DARPA CHATS research program.
118b099b73SRobert Watson *
1230d239bcSRobert Watson * This software was enhanced by SPARTA ISSO under SPAWAR contract
1330d239bcSRobert Watson * N66001-04-C-6019 ("SEFOS").
1430d239bcSRobert Watson *
152087a58cSRobert Watson * This software was developed at the University of Cambridge Computer
162087a58cSRobert Watson * Laboratory with support from a grant from Google, Inc.
172087a58cSRobert Watson *
188b099b73SRobert Watson * Redistribution and use in source and binary forms, with or without
198b099b73SRobert Watson * modification, are permitted provided that the following conditions
208b099b73SRobert Watson * are met:
218b099b73SRobert Watson * 1. Redistributions of source code must retain the above copyright
228b099b73SRobert Watson * notice, this list of conditions and the following disclaimer.
238b099b73SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright
248b099b73SRobert Watson * notice, this list of conditions and the following disclaimer in the
258b099b73SRobert Watson * documentation and/or other materials provided with the distribution.
268b099b73SRobert Watson *
278b099b73SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
288b099b73SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
298b099b73SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
308b099b73SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
318b099b73SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
328b099b73SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
338b099b73SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
348b099b73SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
358b099b73SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
368b099b73SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
378b099b73SRobert Watson * SUCH DAMAGE.
388b099b73SRobert Watson */
398b099b73SRobert Watson
408b099b73SRobert Watson #include <sys/cdefs.h>
418b099b73SRobert Watson #include "opt_mac.h"
428b099b73SRobert Watson
438b099b73SRobert Watson #include <sys/param.h>
448b099b73SRobert Watson #include <sys/kernel.h>
458b099b73SRobert Watson #include <sys/lock.h>
468b099b73SRobert Watson #include <sys/malloc.h>
478b099b73SRobert Watson #include <sys/mutex.h>
488b099b73SRobert Watson #include <sys/sbuf.h>
498b099b73SRobert Watson #include <sys/systm.h>
508b099b73SRobert Watson #include <sys/vnode.h>
518b099b73SRobert Watson #include <sys/mount.h>
528b099b73SRobert Watson #include <sys/file.h>
538b099b73SRobert Watson #include <sys/namei.h>
542087a58cSRobert Watson #include <sys/sdt.h>
558b099b73SRobert Watson #include <sys/sysctl.h>
568b099b73SRobert Watson #include <sys/sem.h>
578b099b73SRobert Watson
58aed55708SRobert Watson #include <security/mac/mac_framework.h>
598b099b73SRobert Watson #include <security/mac/mac_internal.h>
600efd6615SRobert Watson #include <security/mac/mac_policy.h>
618b099b73SRobert Watson
628b099b73SRobert Watson static struct label *
mac_sysv_sem_label_alloc(void)633831e7d7SRobert Watson mac_sysv_sem_label_alloc(void)
648b099b73SRobert Watson {
658b099b73SRobert Watson struct label *label;
668b099b73SRobert Watson
678b099b73SRobert Watson label = mac_labelzone_alloc(M_WAITOK);
68fa765671SRobert Watson MAC_POLICY_PERFORM(sysvsem_init_label, label);
698b099b73SRobert Watson return (label);
708b099b73SRobert Watson }
718b099b73SRobert Watson
728b099b73SRobert Watson void
mac_sysvsem_init(struct semid_kernel * semakptr)7330d239bcSRobert Watson mac_sysvsem_init(struct semid_kernel *semakptr)
748b099b73SRobert Watson {
758b099b73SRobert Watson
766356dba0SRobert Watson if (mac_labeled & MPC_OBJECT_SYSVSEM)
773831e7d7SRobert Watson semakptr->label = mac_sysv_sem_label_alloc();
786356dba0SRobert Watson else
796356dba0SRobert Watson semakptr->label = NULL;
808b099b73SRobert Watson }
818b099b73SRobert Watson
828b099b73SRobert Watson static void
mac_sysv_sem_label_free(struct label * label)833831e7d7SRobert Watson mac_sysv_sem_label_free(struct label *label)
848b099b73SRobert Watson {
858b099b73SRobert Watson
86fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(sysvsem_destroy_label, label);
878b099b73SRobert Watson mac_labelzone_free(label);
888b099b73SRobert Watson }
898b099b73SRobert Watson
908b099b73SRobert Watson void
mac_sysvsem_destroy(struct semid_kernel * semakptr)9130d239bcSRobert Watson mac_sysvsem_destroy(struct semid_kernel *semakptr)
928b099b73SRobert Watson {
938b099b73SRobert Watson
946356dba0SRobert Watson if (semakptr->label != NULL) {
953831e7d7SRobert Watson mac_sysv_sem_label_free(semakptr->label);
968b099b73SRobert Watson semakptr->label = NULL;
978b099b73SRobert Watson }
986356dba0SRobert Watson }
998b099b73SRobert Watson
1008b099b73SRobert Watson void
mac_sysvsem_create(struct ucred * cred,struct semid_kernel * semakptr)10130d239bcSRobert Watson mac_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr)
1028b099b73SRobert Watson {
1038b099b73SRobert Watson
104fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(sysvsem_create, cred, semakptr,
105fa765671SRobert Watson semakptr->label);
1068b099b73SRobert Watson }
1078b099b73SRobert Watson
1088b099b73SRobert Watson void
mac_sysvsem_cleanup(struct semid_kernel * semakptr)10930d239bcSRobert Watson mac_sysvsem_cleanup(struct semid_kernel *semakptr)
1108b099b73SRobert Watson {
1118b099b73SRobert Watson
112fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(sysvsem_cleanup, semakptr->label);
1138b099b73SRobert Watson }
1148b099b73SRobert Watson
1152087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(sysvsem_check_semctl, "struct ucred *",
1162087a58cSRobert Watson "struct semid_kernel *", "int");
1172087a58cSRobert Watson
1188b099b73SRobert Watson int
mac_sysvsem_check_semctl(struct ucred * cred,struct semid_kernel * semakptr,int cmd)11930d239bcSRobert Watson mac_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1208b099b73SRobert Watson int cmd)
1218b099b73SRobert Watson {
1228b099b73SRobert Watson int error;
1238b099b73SRobert Watson
124fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(sysvsem_check_semctl, cred, semakptr,
12540202729SRobert Watson semakptr->label, cmd);
1262087a58cSRobert Watson MAC_CHECK_PROBE3(sysvsem_check_semctl, error, cred, semakptr, cmd);
1278b099b73SRobert Watson
1288b099b73SRobert Watson return (error);
1298b099b73SRobert Watson }
1308b099b73SRobert Watson
1312087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(sysvsem_check_semget, "struct ucred *",
1322087a58cSRobert Watson "struct semid_kernel *");
1332087a58cSRobert Watson
1348b099b73SRobert Watson int
mac_sysvsem_check_semget(struct ucred * cred,struct semid_kernel * semakptr)13530d239bcSRobert Watson mac_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr)
1368b099b73SRobert Watson {
1378b099b73SRobert Watson int error;
1388b099b73SRobert Watson
139fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(sysvsem_check_semget, cred, semakptr,
14040202729SRobert Watson semakptr->label);
1418b099b73SRobert Watson
1428b099b73SRobert Watson return (error);
1438b099b73SRobert Watson }
1448b099b73SRobert Watson
1452087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(sysvsem_check_semop, "struct ucred *",
1462087a58cSRobert Watson "struct semid_kernel *", "size_t");
1472087a58cSRobert Watson
1488b099b73SRobert Watson int
mac_sysvsem_check_semop(struct ucred * cred,struct semid_kernel * semakptr,size_t accesstype)14930d239bcSRobert Watson mac_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
1508b099b73SRobert Watson size_t accesstype)
1518b099b73SRobert Watson {
1528b099b73SRobert Watson int error;
1538b099b73SRobert Watson
154fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(sysvsem_check_semop, cred, semakptr,
15540202729SRobert Watson semakptr->label, accesstype);
1562087a58cSRobert Watson MAC_CHECK_PROBE3(sysvsem_check_semop, error, cred, semakptr,
1572087a58cSRobert Watson accesstype);
1588b099b73SRobert Watson
1598b099b73SRobert Watson return (error);
1608b099b73SRobert Watson }
161