14074f67fSRobert Watson /*-
2a1b9471aSRobert Watson  * Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
34074f67fSRobert Watson  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
44074f67fSRobert Watson  * Copyright (c) 2005 Tom Rhodes
54074f67fSRobert Watson  * Copyright (c) 2006 SPARTA, Inc.
64074f67fSRobert Watson  * All rights reserved.
74074f67fSRobert Watson  *
84074f67fSRobert Watson  * This software was developed by Robert Watson for the TrustedBSD Project.
94074f67fSRobert Watson  * It was later enhanced by Tom Rhodes for the TrustedBSD Project.
104074f67fSRobert Watson  *
114074f67fSRobert Watson  * This software was developed for the FreeBSD Project in part by Network
124074f67fSRobert Watson  * Associates Laboratories, the Security Research Division of Network
134074f67fSRobert Watson  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
144074f67fSRobert Watson  * as part of the DARPA CHATS research program.
154074f67fSRobert Watson  *
164074f67fSRobert Watson  * This software was enhanced by SPARTA ISSO under SPAWAR contract
174074f67fSRobert Watson  * N66001-04-C-6019 ("SEFOS").
184074f67fSRobert Watson  *
194074f67fSRobert Watson  * Redistribution and use in source and binary forms, with or without
204074f67fSRobert Watson  * modification, are permitted provided that the following conditions
214074f67fSRobert Watson  * are met:
224074f67fSRobert Watson  * 1. Redistributions of source code must retain the above copyright
234074f67fSRobert Watson  *    notice, this list of conditions and the following disclaimer.
244074f67fSRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
254074f67fSRobert Watson  *    notice, this list of conditions and the following disclaimer in the
264074f67fSRobert Watson  *    documentation and/or other materials provided with the distribution.
274074f67fSRobert Watson  *
284074f67fSRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
294074f67fSRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
304074f67fSRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
314074f67fSRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
324074f67fSRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
334074f67fSRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
344074f67fSRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
354074f67fSRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
364074f67fSRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
374074f67fSRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
384074f67fSRobert Watson  * SUCH DAMAGE.
394074f67fSRobert Watson  */
404074f67fSRobert Watson 
414074f67fSRobert Watson #include <sys/param.h>
424074f67fSRobert Watson #include <sys/acl.h>
434074f67fSRobert Watson #include <sys/kernel.h>
444074f67fSRobert Watson #include <sys/jail.h>
454074f67fSRobert Watson #include <sys/lock.h>
464074f67fSRobert Watson #include <sys/malloc.h>
474074f67fSRobert Watson #include <sys/module.h>
484074f67fSRobert Watson #include <sys/mount.h>
494074f67fSRobert Watson #include <sys/mutex.h>
504074f67fSRobert Watson #include <sys/priv.h>
514074f67fSRobert Watson #include <sys/systm.h>
524074f67fSRobert Watson #include <sys/vnode.h>
534074f67fSRobert Watson #include <sys/sysctl.h>
544074f67fSRobert Watson #include <sys/syslog.h>
554074f67fSRobert Watson #include <sys/stat.h>
564074f67fSRobert Watson 
574074f67fSRobert Watson #include <security/mac/mac_policy.h>
584074f67fSRobert Watson #include <security/mac_bsdextended/mac_bsdextended.h>
5934f6230eSRobert Watson #include <security/mac_bsdextended/ugidfw_internal.h>
604074f67fSRobert Watson 
6134f6230eSRobert Watson int
ugidfw_vnode_check_access(struct ucred * cred,struct vnode * vp,struct label * vplabel,accmode_t accmode)624074f67fSRobert Watson ugidfw_vnode_check_access(struct ucred *cred, struct vnode *vp,
6315bc6b2bSEdward Tomasz Napierala     struct label *vplabel, accmode_t accmode)
644074f67fSRobert Watson {
654074f67fSRobert Watson 
66a1b9471aSRobert Watson 	return (ugidfw_check_vp(cred, vp, ugidfw_accmode2mbi(accmode)));
674074f67fSRobert Watson }
684074f67fSRobert Watson 
6934f6230eSRobert Watson int
ugidfw_vnode_check_chdir(struct ucred * cred,struct vnode * dvp,struct label * dvplabel)704074f67fSRobert Watson ugidfw_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
714074f67fSRobert Watson     struct label *dvplabel)
724074f67fSRobert Watson {
734074f67fSRobert Watson 
744074f67fSRobert Watson 	return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
754074f67fSRobert Watson }
764074f67fSRobert Watson 
7734f6230eSRobert Watson int
ugidfw_vnode_check_chroot(struct ucred * cred,struct vnode * dvp,struct label * dvplabel)784074f67fSRobert Watson ugidfw_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
794074f67fSRobert Watson     struct label *dvplabel)
804074f67fSRobert Watson {
814074f67fSRobert Watson 
824074f67fSRobert Watson 	return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
834074f67fSRobert Watson }
844074f67fSRobert Watson 
8534f6230eSRobert Watson int
ugidfw_check_create_vnode(struct ucred * cred,struct vnode * dvp,struct label * dvplabel,struct componentname * cnp,struct vattr * vap)864074f67fSRobert Watson ugidfw_check_create_vnode(struct ucred *cred, struct vnode *dvp,
874074f67fSRobert Watson     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
884074f67fSRobert Watson {
894074f67fSRobert Watson 
904074f67fSRobert Watson 	return (ugidfw_check_vp(cred, dvp, MBI_WRITE));
914074f67fSRobert Watson }
924074f67fSRobert Watson 
9334f6230eSRobert Watson int
ugidfw_vnode_check_deleteacl(struct ucred * cred,struct vnode * vp,struct label * vplabel,acl_type_t type)944074f67fSRobert Watson ugidfw_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
954074f67fSRobert Watson     struct label *vplabel, acl_type_t type)
964074f67fSRobert Watson {
974074f67fSRobert Watson 
984074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
994074f67fSRobert Watson }
1004074f67fSRobert Watson 
10134f6230eSRobert Watson int
ugidfw_vnode_check_deleteextattr(struct ucred * cred,struct vnode * vp,struct label * vplabel,int attrnamespace,const char * name)1024074f67fSRobert Watson ugidfw_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
1034074f67fSRobert Watson     struct label *vplabel, int attrnamespace, const char *name)
1044074f67fSRobert Watson {
1054074f67fSRobert Watson 
1064074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
1074074f67fSRobert Watson }
1084074f67fSRobert Watson 
10934f6230eSRobert Watson int
ugidfw_vnode_check_exec(struct ucred * cred,struct vnode * vp,struct label * vplabel,struct image_params * imgp,struct label * execlabel)1104074f67fSRobert Watson ugidfw_vnode_check_exec(struct ucred *cred, struct vnode *vp,
1114074f67fSRobert Watson     struct label *vplabel, struct image_params *imgp,
1124074f67fSRobert Watson     struct label *execlabel)
1134074f67fSRobert Watson {
1144074f67fSRobert Watson 
1154074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_READ|MBI_EXEC));
1164074f67fSRobert Watson }
1174074f67fSRobert Watson 
11834f6230eSRobert Watson int
ugidfw_vnode_check_getacl(struct ucred * cred,struct vnode * vp,struct label * vplabel,acl_type_t type)1194074f67fSRobert Watson ugidfw_vnode_check_getacl(struct ucred *cred, struct vnode *vp,
1204074f67fSRobert Watson     struct label *vplabel, acl_type_t type)
1214074f67fSRobert Watson {
1224074f67fSRobert Watson 
1234074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_STAT));
1244074f67fSRobert Watson }
1254074f67fSRobert Watson 
12634f6230eSRobert Watson int
ugidfw_vnode_check_getextattr(struct ucred * cred,struct vnode * vp,struct label * vplabel,int attrnamespace,const char * name)1274074f67fSRobert Watson ugidfw_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
128fefd0ac8SRobert Watson     struct label *vplabel, int attrnamespace, const char *name)
1294074f67fSRobert Watson {
1304074f67fSRobert Watson 
1314074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_READ));
1324074f67fSRobert Watson }
1334074f67fSRobert Watson 
13434f6230eSRobert Watson int
ugidfw_vnode_check_link(struct ucred * cred,struct vnode * dvp,struct label * dvplabel,struct vnode * vp,struct label * label,struct componentname * cnp)1354074f67fSRobert Watson ugidfw_vnode_check_link(struct ucred *cred, struct vnode *dvp,
1364074f67fSRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *label,
1374074f67fSRobert Watson     struct componentname *cnp)
1384074f67fSRobert Watson {
1394074f67fSRobert Watson 	int error;
1404074f67fSRobert Watson 
1414074f67fSRobert Watson 	error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
1424074f67fSRobert Watson 	if (error)
1434074f67fSRobert Watson 		return (error);
1444074f67fSRobert Watson 	error = ugidfw_check_vp(cred, vp, MBI_WRITE);
1454074f67fSRobert Watson 	if (error)
1464074f67fSRobert Watson 		return (error);
1474074f67fSRobert Watson 	return (0);
1484074f67fSRobert Watson }
1494074f67fSRobert Watson 
15034f6230eSRobert Watson int
ugidfw_vnode_check_listextattr(struct ucred * cred,struct vnode * vp,struct label * vplabel,int attrnamespace)1514074f67fSRobert Watson ugidfw_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
1524074f67fSRobert Watson     struct label *vplabel, int attrnamespace)
1534074f67fSRobert Watson {
1544074f67fSRobert Watson 
1554074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_READ));
1564074f67fSRobert Watson }
1574074f67fSRobert Watson 
15834f6230eSRobert Watson int
ugidfw_vnode_check_lookup(struct ucred * cred,struct vnode * dvp,struct label * dvplabel,struct componentname * cnp)1594074f67fSRobert Watson ugidfw_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
1604074f67fSRobert Watson     struct label *dvplabel, struct componentname *cnp)
1614074f67fSRobert Watson {
1624074f67fSRobert Watson 
1634074f67fSRobert Watson 	return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
1644074f67fSRobert Watson }
1654074f67fSRobert Watson 
16634f6230eSRobert Watson int
ugidfw_vnode_check_open(struct ucred * cred,struct vnode * vp,struct label * vplabel,accmode_t accmode)1674074f67fSRobert Watson ugidfw_vnode_check_open(struct ucred *cred, struct vnode *vp,
16815bc6b2bSEdward Tomasz Napierala     struct label *vplabel, accmode_t accmode)
1694074f67fSRobert Watson {
1704074f67fSRobert Watson 
171a1b9471aSRobert Watson 	return (ugidfw_check_vp(cred, vp, ugidfw_accmode2mbi(accmode)));
1724074f67fSRobert Watson }
1734074f67fSRobert Watson 
17434f6230eSRobert Watson int
ugidfw_vnode_check_readdir(struct ucred * cred,struct vnode * dvp,struct label * dvplabel)1754074f67fSRobert Watson ugidfw_vnode_check_readdir(struct ucred *cred, struct vnode *dvp,
1764074f67fSRobert Watson     struct label *dvplabel)
1774074f67fSRobert Watson {
1784074f67fSRobert Watson 
1794074f67fSRobert Watson 	return (ugidfw_check_vp(cred, dvp, MBI_READ));
1804074f67fSRobert Watson }
1814074f67fSRobert Watson 
18234f6230eSRobert Watson int
ugidfw_vnode_check_readdlink(struct ucred * cred,struct vnode * vp,struct label * vplabel)1834074f67fSRobert Watson ugidfw_vnode_check_readdlink(struct ucred *cred, struct vnode *vp,
1844074f67fSRobert Watson     struct label *vplabel)
1854074f67fSRobert Watson {
1864074f67fSRobert Watson 
1874074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_READ));
1884074f67fSRobert Watson }
1894074f67fSRobert Watson 
19034f6230eSRobert Watson int
ugidfw_vnode_check_rename_from(struct ucred * cred,struct vnode * dvp,struct label * dvplabel,struct vnode * vp,struct label * vplabel,struct componentname * cnp)1914074f67fSRobert Watson ugidfw_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
1924074f67fSRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
1934074f67fSRobert Watson     struct componentname *cnp)
1944074f67fSRobert Watson {
1954074f67fSRobert Watson 	int error;
1964074f67fSRobert Watson 
1974074f67fSRobert Watson 	error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
1984074f67fSRobert Watson 	if (error)
1994074f67fSRobert Watson 		return (error);
2004074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
2014074f67fSRobert Watson }
2024074f67fSRobert Watson 
20334f6230eSRobert Watson int
ugidfw_vnode_check_rename_to(struct ucred * cred,struct vnode * dvp,struct label * dvplabel,struct vnode * vp,struct label * vplabel,int samedir,struct componentname * cnp)2044074f67fSRobert Watson ugidfw_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
2054074f67fSRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2064074f67fSRobert Watson     int samedir, struct componentname *cnp)
2074074f67fSRobert Watson {
2084074f67fSRobert Watson 	int error;
2094074f67fSRobert Watson 
2104074f67fSRobert Watson 	error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
2114074f67fSRobert Watson 	if (error)
2124074f67fSRobert Watson 		return (error);
2134074f67fSRobert Watson 	if (vp != NULL)
2144074f67fSRobert Watson 		error = ugidfw_check_vp(cred, vp, MBI_WRITE);
2154074f67fSRobert Watson 	return (error);
2164074f67fSRobert Watson }
2174074f67fSRobert Watson 
21834f6230eSRobert Watson int
ugidfw_vnode_check_revoke(struct ucred * cred,struct vnode * vp,struct label * vplabel)2194074f67fSRobert Watson ugidfw_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
2204074f67fSRobert Watson     struct label *vplabel)
2214074f67fSRobert Watson {
2224074f67fSRobert Watson 
2234074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
2244074f67fSRobert Watson }
2254074f67fSRobert Watson 
22634f6230eSRobert Watson int
ugidfw_check_setacl_vnode(struct ucred * cred,struct vnode * vp,struct label * vplabel,acl_type_t type,struct acl * acl)2274074f67fSRobert Watson ugidfw_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
2284074f67fSRobert Watson     struct label *vplabel, acl_type_t type, struct acl *acl)
2294074f67fSRobert Watson {
2304074f67fSRobert Watson 
2314074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
2324074f67fSRobert Watson }
2334074f67fSRobert Watson 
23434f6230eSRobert Watson int
ugidfw_vnode_check_setextattr(struct ucred * cred,struct vnode * vp,struct label * vplabel,int attrnamespace,const char * name)2354074f67fSRobert Watson ugidfw_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
236fefd0ac8SRobert Watson     struct label *vplabel, int attrnamespace, const char *name)
2374074f67fSRobert Watson {
2384074f67fSRobert Watson 
2394074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
2404074f67fSRobert Watson }
2414074f67fSRobert Watson 
24234f6230eSRobert Watson int
ugidfw_vnode_check_setflags(struct ucred * cred,struct vnode * vp,struct label * vplabel,u_long flags)2434074f67fSRobert Watson ugidfw_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
2444074f67fSRobert Watson     struct label *vplabel, u_long flags)
2454074f67fSRobert Watson {
2464074f67fSRobert Watson 
2474074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
2484074f67fSRobert Watson }
2494074f67fSRobert Watson 
25034f6230eSRobert Watson int
ugidfw_vnode_check_setmode(struct ucred * cred,struct vnode * vp,struct label * vplabel,mode_t mode)2514074f67fSRobert Watson ugidfw_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
2524074f67fSRobert Watson     struct label *vplabel, mode_t mode)
2534074f67fSRobert Watson {
2544074f67fSRobert Watson 
2554074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
2564074f67fSRobert Watson }
2574074f67fSRobert Watson 
25834f6230eSRobert Watson int
ugidfw_vnode_check_setowner(struct ucred * cred,struct vnode * vp,struct label * vplabel,uid_t uid,gid_t gid)2594074f67fSRobert Watson ugidfw_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
2604074f67fSRobert Watson     struct label *vplabel, uid_t uid, gid_t gid)
2614074f67fSRobert Watson {
2624074f67fSRobert Watson 
2634074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
2644074f67fSRobert Watson }
2654074f67fSRobert Watson 
26634f6230eSRobert Watson int
ugidfw_vnode_check_setutimes(struct ucred * cred,struct vnode * vp,struct label * vplabel,struct timespec atime,struct timespec utime)2674074f67fSRobert Watson ugidfw_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
2684074f67fSRobert Watson     struct label *vplabel, struct timespec atime, struct timespec utime)
2694074f67fSRobert Watson {
2704074f67fSRobert Watson 
2714074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
2724074f67fSRobert Watson }
2734074f67fSRobert Watson 
27434f6230eSRobert Watson int
ugidfw_vnode_check_stat(struct ucred * active_cred,struct ucred * file_cred,struct vnode * vp,struct label * vplabel)2754074f67fSRobert Watson ugidfw_vnode_check_stat(struct ucred *active_cred,
2764074f67fSRobert Watson     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
2774074f67fSRobert Watson {
2784074f67fSRobert Watson 
2794074f67fSRobert Watson 	return (ugidfw_check_vp(active_cred, vp, MBI_STAT));
2804074f67fSRobert Watson }
2814074f67fSRobert Watson 
28234f6230eSRobert Watson int
ugidfw_vnode_check_unlink(struct ucred * cred,struct vnode * dvp,struct label * dvplabel,struct vnode * vp,struct label * vplabel,struct componentname * cnp)2834074f67fSRobert Watson ugidfw_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
2844074f67fSRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2854074f67fSRobert Watson     struct componentname *cnp)
2864074f67fSRobert Watson {
2874074f67fSRobert Watson 	int error;
2884074f67fSRobert Watson 
2894074f67fSRobert Watson 	error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
2904074f67fSRobert Watson 	if (error)
2914074f67fSRobert Watson 		return (error);
2924074f67fSRobert Watson 	return (ugidfw_check_vp(cred, vp, MBI_WRITE));
2934074f67fSRobert Watson }
294