mac_vfs.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  1. /*-
  2. * Copyright (c) 1999-2002, 2009 Robert N. M. Watson
  3. * Copyright (c) 2001 Ilmar S. Habibulin
  4. * Copyright (c) 2001-2005 McAfee, Inc.
  5. * Copyright (c) 2005-2006 SPARTA, Inc.
  6. * Copyright (c) 2008 Apple Inc.
  7. * All rights reserved.
  8. *
  9. * This software was developed by Robert Watson and Ilmar Habibulin for the
  10. * TrustedBSD Project.
  11. *
  12. * This software was developed for the FreeBSD Project in part by McAfee
  13. * Research, the Security Research Division of McAfee, Inc. under
  14. * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
  15. * CHATS research program.
  16. *
  17. * This software was enhanced by SPARTA ISSO under SPAWAR contract
  18. * N66001-04-C-6019 ("SEFOS").
  19. *
  20. * This software was developed at the University of Cambridge Computer
  21. * Laboratory with support from a grant from Google, Inc.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the above copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  33. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  36. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  40. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  41. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  42. * SUCH DAMAGE.
  43. */
  44. #include <sys/cdefs.h>
  45. #include "opt_mac.h"
  46. #include <sys/param.h>
  47. #include <sys/condvar.h>
  48. #include <sys/extattr.h>
  49. #include <sys/imgact.h>
  50. #include <sys/kernel.h>
  51. #include <sys/lock.h>
  52. #include <sys/malloc.h>
  53. #include <sys/mutex.h>
  54. #include <sys/proc.h>
  55. #include <sys/sbuf.h>
  56. #include <sys/systm.h>
  57. #include <sys/vnode.h>
  58. #include <sys/mount.h>
  59. #include <sys/file.h>
  60. #include <sys/namei.h>
  61. #include <sys/sdt.h>
  62. #include <sys/sysctl.h>
  63. #include <vm/vm.h>
  64. #include <vm/pmap.h>
  65. #include <vm/vm_map.h>
  66. #include <vm/vm_object.h>
  67. #include <fs/devfs/devfs.h>
  68. #include <security/mac/mac_framework.h>
  69. #include <security/mac/mac_internal.h>
  70. #include <security/mac/mac_policy.h>
  71. /*
  72. * Warn about EA transactions only the first time they happen. No locking on
  73. * this variable.
  74. */
  75. static int ea_warn_once = 0;
  76. static int mac_vnode_setlabel_extattr(struct ucred *cred,
  77. struct vnode *vp, struct label *intlabel);
  78. static struct label *
  79. mac_devfs_label_alloc(void)
  80. {
  81. struct label *label;
  82. label = mac_labelzone_alloc(M_WAITOK);
  83. MAC_POLICY_PERFORM(devfs_init_label, label);
  84. return (label);
  85. }
  86. void
  87. mac_devfs_init(struct devfs_dirent *de)
  88. {
  89. if (mac_labeled & MPC_OBJECT_DEVFS)
  90. de->de_label = mac_devfs_label_alloc();
  91. else
  92. de->de_label = NULL;
  93. }
  94. static struct label *
  95. mac_mount_label_alloc(void)
  96. {
  97. struct label *label;
  98. label = mac_labelzone_alloc(M_WAITOK);
  99. MAC_POLICY_PERFORM(mount_init_label, label);
  100. return (label);
  101. }
  102. void
  103. mac_mount_init(struct mount *mp)
  104. {
  105. if (mac_labeled & MPC_OBJECT_MOUNT)
  106. mp->mnt_label = mac_mount_label_alloc();
  107. else
  108. mp->mnt_label = NULL;
  109. }
  110. struct label *
  111. mac_vnode_label_alloc(void)
  112. {
  113. struct label *label;
  114. label = mac_labelzone_alloc(M_WAITOK);
  115. MAC_POLICY_PERFORM(vnode_init_label, label);
  116. return (label);
  117. }
  118. void
  119. mac_vnode_init(struct vnode *vp)
  120. {
  121. if (mac_labeled & MPC_OBJECT_VNODE)
  122. vp->v_label = mac_vnode_label_alloc();
  123. else
  124. vp->v_label = NULL;
  125. }
  126. static void
  127. mac_devfs_label_free(struct label *label)
  128. {
  129. MAC_POLICY_PERFORM_NOSLEEP(devfs_destroy_label, label);
  130. mac_labelzone_free(label);
  131. }
  132. void
  133. mac_devfs_destroy(struct devfs_dirent *de)
  134. {
  135. if (de->de_label != NULL) {
  136. mac_devfs_label_free(de->de_label);
  137. de->de_label = NULL;
  138. }
  139. }
  140. static void
  141. mac_mount_label_free(struct label *label)
  142. {
  143. MAC_POLICY_PERFORM_NOSLEEP(mount_destroy_label, label);
  144. mac_labelzone_free(label);
  145. }
  146. void
  147. mac_mount_destroy(struct mount *mp)
  148. {
  149. if (mp->mnt_label != NULL) {
  150. mac_mount_label_free(mp->mnt_label);
  151. mp->mnt_label = NULL;
  152. }
  153. }
  154. void
  155. mac_vnode_label_free(struct label *label)
  156. {
  157. MAC_POLICY_PERFORM_NOSLEEP(vnode_destroy_label, label);
  158. mac_labelzone_free(label);
  159. }
  160. void
  161. mac_vnode_destroy(struct vnode *vp)
  162. {
  163. if (vp->v_label != NULL) {
  164. mac_vnode_label_free(vp->v_label);
  165. vp->v_label = NULL;
  166. }
  167. }
  168. void
  169. mac_vnode_copy_label(struct label *src, struct label *dest)
  170. {
  171. MAC_POLICY_PERFORM_NOSLEEP(vnode_copy_label, src, dest);
  172. }
  173. int
  174. mac_vnode_externalize_label(struct label *label, char *elements,
  175. char *outbuf, size_t outbuflen)
  176. {
  177. int error;
  178. MAC_POLICY_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
  179. return (error);
  180. }
  181. int
  182. mac_vnode_internalize_label(struct label *label, char *string)
  183. {
  184. int error;
  185. MAC_POLICY_INTERNALIZE(vnode, label, string);
  186. return (error);
  187. }
  188. void
  189. mac_devfs_update(struct mount *mp, struct devfs_dirent *de, struct vnode *vp)
  190. {
  191. MAC_POLICY_PERFORM_NOSLEEP(devfs_update, mp, de, de->de_label, vp,
  192. vp->v_label);
  193. }
  194. void
  195. mac_devfs_vnode_associate(struct mount *mp, struct devfs_dirent *de,
  196. struct vnode *vp)
  197. {
  198. MAC_POLICY_PERFORM_NOSLEEP(devfs_vnode_associate, mp, mp->mnt_label,
  199. de, de->de_label, vp, vp->v_label);
  200. }
  201. int
  202. mac_vnode_associate_extattr(struct mount *mp, struct vnode *vp)
  203. {
  204. int error;
  205. ASSERT_VOP_LOCKED(vp, "mac_vnode_associate_extattr");
  206. MAC_POLICY_CHECK(vnode_associate_extattr, mp, mp->mnt_label, vp,
  207. vp->v_label);
  208. return (error);
  209. }
  210. void
  211. mac_vnode_associate_singlelabel(struct mount *mp, struct vnode *vp)
  212. {
  213. MAC_POLICY_PERFORM_NOSLEEP(vnode_associate_singlelabel, mp,
  214. mp->mnt_label, vp, vp->v_label);
  215. }
  216. /*
  217. * Functions implementing extended-attribute backed labels for file systems
  218. * that support it.
  219. *
  220. * Where possible, we use EA transactions to make writes to multiple
  221. * attributes across difference policies mutually atomic. We allow work to
  222. * continue on file systems not supporting EA transactions, but generate a
  223. * printf warning.
  224. */
  225. int
  226. mac_vnode_create_extattr(struct ucred *cred, struct mount *mp,
  227. struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
  228. {
  229. int error;
  230. ASSERT_VOP_LOCKED(dvp, "mac_vnode_create_extattr");
  231. ASSERT_VOP_LOCKED(vp, "mac_vnode_create_extattr");
  232. error = VOP_OPENEXTATTR(vp, cred, curthread);
  233. if (error == EOPNOTSUPP) {
  234. if (ea_warn_once == 0) {
  235. printf("Warning: transactions not supported "
  236. "in EA write.\n");
  237. ea_warn_once = 1;
  238. }
  239. } else if (error)
  240. return (error);
  241. MAC_POLICY_CHECK(vnode_create_extattr, cred, mp, mp->mnt_label, dvp,
  242. dvp->v_label, vp, vp->v_label, cnp);
  243. if (error) {
  244. VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
  245. return (error);
  246. }
  247. error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
  248. if (error == EOPNOTSUPP)
  249. error = 0;
  250. return (error);
  251. }
  252. static int
  253. mac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
  254. struct label *intlabel)
  255. {
  256. int error;
  257. ASSERT_VOP_LOCKED(vp, "mac_vnode_setlabel_extattr");
  258. error = VOP_OPENEXTATTR(vp, cred, curthread);
  259. if (error == EOPNOTSUPP) {
  260. if (ea_warn_once == 0) {
  261. printf("Warning: transactions not supported "
  262. "in EA write.\n");
  263. ea_warn_once = 1;
  264. }
  265. } else if (error)
  266. return (error);
  267. MAC_POLICY_CHECK(vnode_setlabel_extattr, cred, vp, vp->v_label,
  268. intlabel);
  269. if (error) {
  270. VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
  271. return (error);
  272. }
  273. error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
  274. if (error == EOPNOTSUPP)
  275. error = 0;
  276. return (error);
  277. }
  278. void
  279. mac_vnode_execve_transition(struct ucred *old, struct ucred *new,
  280. struct vnode *vp, struct label *interpvplabel, struct image_params *imgp)
  281. {
  282. ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_transition");
  283. MAC_POLICY_PERFORM(vnode_execve_transition, old, new, vp,
  284. vp->v_label, interpvplabel, imgp, imgp->execlabel);
  285. }
  286. int
  287. mac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp,
  288. struct label *interpvplabel, struct image_params *imgp)
  289. {
  290. int result;
  291. ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_will_transition");
  292. result = 0;
  293. /* No sleeping since the process lock will be held by the caller. */
  294. MAC_POLICY_BOOLEAN_NOSLEEP(vnode_execve_will_transition, ||, old, vp,
  295. vp->v_label, interpvplabel, imgp, imgp->execlabel);
  296. return (result);
  297. }
  298. MAC_CHECK_PROBE_DEFINE3(vnode_check_access, "struct ucred *",
  299. "struct vnode *", "accmode_t");
  300. int
  301. mac_vnode_check_access_impl(struct ucred *cred, struct vnode *vp, accmode_t accmode)
  302. {
  303. int error;
  304. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_access");
  305. MAC_POLICY_CHECK(vnode_check_access, cred, vp, vp->v_label, accmode);
  306. MAC_CHECK_PROBE3(vnode_check_access, error, cred, vp, accmode);
  307. return (error);
  308. }
  309. MAC_CHECK_PROBE_DEFINE2(vnode_check_chdir, "struct ucred *",
  310. "struct vnode *");
  311. int
  312. mac_vnode_check_chdir(struct ucred *cred, struct vnode *dvp)
  313. {
  314. int error;
  315. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chdir");
  316. MAC_POLICY_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label);
  317. MAC_CHECK_PROBE2(vnode_check_chdir, error, cred, dvp);
  318. return (error);
  319. }
  320. MAC_CHECK_PROBE_DEFINE2(vnode_check_chroot, "struct ucred *",
  321. "struct vnode *");
  322. int
  323. mac_vnode_check_chroot(struct ucred *cred, struct vnode *dvp)
  324. {
  325. int error;
  326. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chroot");
  327. MAC_POLICY_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label);
  328. MAC_CHECK_PROBE2(vnode_check_chroot, error, cred, dvp);
  329. return (error);
  330. }
  331. MAC_CHECK_PROBE_DEFINE4(vnode_check_create, "struct ucred *",
  332. "struct vnode *", "struct componentname *", "struct vattr *");
  333. int
  334. mac_vnode_check_create(struct ucred *cred, struct vnode *dvp,
  335. struct componentname *cnp, struct vattr *vap)
  336. {
  337. int error;
  338. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_create");
  339. MAC_POLICY_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp,
  340. vap);
  341. MAC_CHECK_PROBE4(vnode_check_create, error, cred, dvp, cnp, vap);
  342. return (error);
  343. }
  344. MAC_CHECK_PROBE_DEFINE3(vnode_check_deleteacl, "struct ucred *",
  345. "struct vnode *", "acl_type_t");
  346. int
  347. mac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
  348. acl_type_t type)
  349. {
  350. int error;
  351. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteacl");
  352. MAC_POLICY_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
  353. MAC_CHECK_PROBE3(vnode_check_deleteacl, error, cred, vp, type);
  354. return (error);
  355. }
  356. MAC_CHECK_PROBE_DEFINE4(vnode_check_deleteextattr, "struct ucred *",
  357. "struct vnode *", "int", "const char *");
  358. int
  359. mac_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
  360. int attrnamespace, const char *name)
  361. {
  362. int error;
  363. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteextattr");
  364. MAC_POLICY_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label,
  365. attrnamespace, name);
  366. MAC_CHECK_PROBE4(vnode_check_deleteextattr, error, cred, vp,
  367. attrnamespace, name);
  368. return (error);
  369. }
  370. MAC_CHECK_PROBE_DEFINE3(vnode_check_exec, "struct ucred *", "struct vnode *",
  371. "struct image_params *");
  372. int
  373. mac_vnode_check_exec(struct ucred *cred, struct vnode *vp,
  374. struct image_params *imgp)
  375. {
  376. int error;
  377. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_exec");
  378. MAC_POLICY_CHECK(vnode_check_exec, cred, vp, vp->v_label, imgp,
  379. imgp->execlabel);
  380. MAC_CHECK_PROBE3(vnode_check_exec, error, cred, vp, imgp);
  381. return (error);
  382. }
  383. MAC_CHECK_PROBE_DEFINE3(vnode_check_getacl, "struct ucred *",
  384. "struct vnode *", "acl_type_t");
  385. int
  386. mac_vnode_check_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
  387. {
  388. int error;
  389. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getacl");
  390. MAC_POLICY_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
  391. MAC_CHECK_PROBE3(vnode_check_getacl, error, cred, vp, type);
  392. return (error);
  393. }
  394. MAC_CHECK_PROBE_DEFINE4(vnode_check_getextattr, "struct ucred *",
  395. "struct vnode *", "int", "const char *");
  396. int
  397. mac_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
  398. int attrnamespace, const char *name)
  399. {
  400. int error;
  401. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getextattr");
  402. MAC_POLICY_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
  403. attrnamespace, name);
  404. MAC_CHECK_PROBE4(vnode_check_getextattr, error, cred, vp,
  405. attrnamespace, name);
  406. return (error);
  407. }
  408. MAC_CHECK_PROBE_DEFINE4(vnode_check_link, "struct ucred *", "struct vnode *",
  409. "struct vnode *", "struct componentname *");
  410. int
  411. mac_vnode_check_link(struct ucred *cred, struct vnode *dvp,
  412. struct vnode *vp, struct componentname *cnp)
  413. {
  414. int error;
  415. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_link");
  416. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_link");
  417. MAC_POLICY_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
  418. vp->v_label, cnp);
  419. MAC_CHECK_PROBE4(vnode_check_link, error, cred, dvp, vp, cnp);
  420. return (error);
  421. }
  422. MAC_CHECK_PROBE_DEFINE3(vnode_check_listextattr, "struct ucred *",
  423. "struct vnode *", "int");
  424. int
  425. mac_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
  426. int attrnamespace)
  427. {
  428. int error;
  429. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_listextattr");
  430. MAC_POLICY_CHECK(vnode_check_listextattr, cred, vp, vp->v_label,
  431. attrnamespace);
  432. MAC_CHECK_PROBE3(vnode_check_listextattr, error, cred, vp,
  433. attrnamespace);
  434. return (error);
  435. }
  436. MAC_CHECK_PROBE_DEFINE3(vnode_check_lookup, "struct ucred *",
  437. "struct vnode *", "struct componentname *");
  438. int
  439. mac_vnode_check_lookup_impl(struct ucred *cred, struct vnode *dvp,
  440. struct componentname *cnp)
  441. {
  442. int error;
  443. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_lookup");
  444. if ((cnp->cn_flags & NOMACCHECK) != 0)
  445. return (0);
  446. MAC_POLICY_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp);
  447. MAC_CHECK_PROBE3(vnode_check_lookup, error, cred, dvp, cnp);
  448. return (error);
  449. }
  450. MAC_CHECK_PROBE_DEFINE4(vnode_check_mmap, "struct ucred *", "struct vnode *",
  451. "int", "int");
  452. int
  453. mac_vnode_check_mmap_impl(struct ucred *cred, struct vnode *vp, int prot,
  454. int flags)
  455. {
  456. int error;
  457. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap");
  458. MAC_POLICY_CHECK(vnode_check_mmap, cred, vp, vp->v_label, prot, flags);
  459. MAC_CHECK_PROBE4(vnode_check_mmap, error, cred, vp, prot, flags);
  460. return (error);
  461. }
  462. void
  463. mac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp,
  464. int *prot)
  465. {
  466. int result = *prot;
  467. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap_downgrade");
  468. MAC_POLICY_PERFORM(vnode_check_mmap_downgrade, cred, vp, vp->v_label,
  469. &result);
  470. *prot = result;
  471. }
  472. MAC_CHECK_PROBE_DEFINE3(vnode_check_mprotect, "struct ucred *",
  473. "struct vnode *", "int");
  474. int
  475. mac_vnode_check_mprotect(struct ucred *cred, struct vnode *vp, int prot)
  476. {
  477. int error;
  478. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mprotect");
  479. MAC_POLICY_CHECK(vnode_check_mprotect, cred, vp, vp->v_label, prot);
  480. MAC_CHECK_PROBE3(vnode_check_mprotect, error, cred, vp, prot);
  481. return (error);
  482. }
  483. MAC_CHECK_PROBE_DEFINE3(vnode_check_open, "struct ucred *", "struct vnode *",
  484. "accmode_t");
  485. int
  486. mac_vnode_check_open_impl(struct ucred *cred, struct vnode *vp, accmode_t accmode)
  487. {
  488. int error;
  489. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_open");
  490. MAC_POLICY_CHECK(vnode_check_open, cred, vp, vp->v_label, accmode);
  491. MAC_CHECK_PROBE3(vnode_check_open, error, cred, vp, accmode);
  492. return (error);
  493. }
  494. MAC_CHECK_PROBE_DEFINE3(vnode_check_poll, "struct ucred *", "struct ucred *",
  495. "struct vnode *");
  496. int
  497. mac_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
  498. struct vnode *vp)
  499. {
  500. int error;
  501. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_poll");
  502. MAC_POLICY_CHECK(vnode_check_poll, active_cred, file_cred, vp,
  503. vp->v_label);
  504. MAC_CHECK_PROBE3(vnode_check_poll, error, active_cred, file_cred,
  505. vp);
  506. return (error);
  507. }
  508. MAC_CHECK_PROBE_DEFINE3(vnode_check_read, "struct ucred *", "struct ucred *",
  509. "struct vnode *");
  510. int
  511. mac_vnode_check_read_impl(struct ucred *active_cred, struct ucred *file_cred,
  512. struct vnode *vp)
  513. {
  514. int error;
  515. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_read");
  516. MAC_POLICY_CHECK(vnode_check_read, active_cred, file_cred, vp,
  517. vp->v_label);
  518. MAC_CHECK_PROBE3(vnode_check_read, error, active_cred, file_cred,
  519. vp);
  520. return (error);
  521. }
  522. MAC_CHECK_PROBE_DEFINE2(vnode_check_readdir, "struct ucred *",
  523. "struct vnode *");
  524. int
  525. mac_vnode_check_readdir(struct ucred *cred, struct vnode *dvp)
  526. {
  527. int error;
  528. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_readdir");
  529. MAC_POLICY_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label);
  530. MAC_CHECK_PROBE2(vnode_check_readdir, error, cred, dvp);
  531. return (error);
  532. }
  533. MAC_CHECK_PROBE_DEFINE2(vnode_check_readlink, "struct ucred *",
  534. "struct vnode *");
  535. int
  536. mac_vnode_check_readlink_impl(struct ucred *cred, struct vnode *vp)
  537. {
  538. int error;
  539. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_readlink");
  540. MAC_POLICY_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
  541. MAC_CHECK_PROBE2(vnode_check_readlink, error, cred, vp);
  542. return (error);
  543. }
  544. MAC_CHECK_PROBE_DEFINE3(vnode_check_relabel, "struct ucred *",
  545. "struct vnode *", "struct label *");
  546. static int
  547. mac_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
  548. struct label *newlabel)
  549. {
  550. int error;
  551. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_relabel");
  552. MAC_POLICY_CHECK(vnode_check_relabel, cred, vp, vp->v_label, newlabel);
  553. MAC_CHECK_PROBE3(vnode_check_relabel, error, cred, vp, newlabel);
  554. return (error);
  555. }
  556. MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_from, "struct ucred *",
  557. "struct vnode *", "struct vnode *", "struct componentname *");
  558. int
  559. mac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
  560. struct vnode *vp, struct componentname *cnp)
  561. {
  562. int error;
  563. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_from");
  564. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_from");
  565. MAC_POLICY_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
  566. vp->v_label, cnp);
  567. MAC_CHECK_PROBE4(vnode_check_rename_from, error, cred, dvp, vp, cnp);
  568. return (error);
  569. }
  570. MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_to, "struct ucred *",
  571. "struct vnode *", "struct vnode *", "struct componentname *");
  572. int
  573. mac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
  574. struct vnode *vp, int samedir, struct componentname *cnp)
  575. {
  576. int error;
  577. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_to");
  578. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_to");
  579. MAC_POLICY_CHECK(vnode_check_rename_to, cred, dvp, dvp->v_label, vp,
  580. vp != NULL ? vp->v_label : NULL, samedir, cnp);
  581. MAC_CHECK_PROBE4(vnode_check_rename_to, error, cred, dvp, vp, cnp);
  582. return (error);
  583. }
  584. MAC_CHECK_PROBE_DEFINE2(vnode_check_revoke, "struct ucred *",
  585. "struct vnode *");
  586. int
  587. mac_vnode_check_revoke(struct ucred *cred, struct vnode *vp)
  588. {
  589. int error;
  590. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_revoke");
  591. MAC_POLICY_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
  592. MAC_CHECK_PROBE2(vnode_check_revoke, error, cred, vp);
  593. return (error);
  594. }
  595. MAC_CHECK_PROBE_DEFINE4(vnode_check_setacl, "struct ucred *",
  596. "struct vnode *", "acl_type_t", "struct acl *");
  597. int
  598. mac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
  599. struct acl *acl)
  600. {
  601. int error;
  602. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setacl");
  603. MAC_POLICY_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
  604. MAC_CHECK_PROBE4(vnode_check_setacl, error, cred, vp, type, acl);
  605. return (error);
  606. }
  607. MAC_CHECK_PROBE_DEFINE4(vnode_check_setextattr, "struct ucred *",
  608. "struct vnode *", "int", "const char *");
  609. int
  610. mac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
  611. int attrnamespace, const char *name)
  612. {
  613. int error;
  614. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setextattr");
  615. MAC_POLICY_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
  616. attrnamespace, name);
  617. MAC_CHECK_PROBE4(vnode_check_setextattr, error, cred, vp,
  618. attrnamespace, name);
  619. return (error);
  620. }
  621. MAC_CHECK_PROBE_DEFINE3(vnode_check_setflags, "struct ucred *",
  622. "struct vnode *", "u_long");
  623. int
  624. mac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
  625. {
  626. int error;
  627. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setflags");
  628. MAC_POLICY_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
  629. MAC_CHECK_PROBE3(vnode_check_setflags, error, cred, vp, flags);
  630. return (error);
  631. }
  632. MAC_CHECK_PROBE_DEFINE3(vnode_check_setmode, "struct ucred *",
  633. "struct vnode *", "mode_t");
  634. int
  635. mac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
  636. {
  637. int error;
  638. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setmode");
  639. MAC_POLICY_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
  640. MAC_CHECK_PROBE3(vnode_check_setmode, error, cred, vp, mode);
  641. return (error);
  642. }
  643. MAC_CHECK_PROBE_DEFINE4(vnode_check_setowner, "struct ucred *",
  644. "struct vnode *", "uid_t", "gid_t");
  645. int
  646. mac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
  647. gid_t gid)
  648. {
  649. int error;
  650. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setowner");
  651. MAC_POLICY_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
  652. MAC_CHECK_PROBE4(vnode_check_setowner, error, cred, vp, uid, gid);
  653. return (error);
  654. }
  655. MAC_CHECK_PROBE_DEFINE4(vnode_check_setutimes, "struct ucred *",
  656. "struct vnode *", "struct timespec *", "struct timespec *");
  657. int
  658. mac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
  659. struct timespec atime, struct timespec mtime)
  660. {
  661. int error;
  662. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setutimes");
  663. MAC_POLICY_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
  664. mtime);
  665. MAC_CHECK_PROBE4(vnode_check_setutimes, error, cred, vp, &atime,
  666. &mtime);
  667. return (error);
  668. }
  669. MAC_CHECK_PROBE_DEFINE3(vnode_check_stat, "struct ucred *", "struct ucred *",
  670. "struct vnode *");
  671. int
  672. mac_vnode_check_stat_impl(struct ucred *active_cred, struct ucred *file_cred,
  673. struct vnode *vp)
  674. {
  675. int error;
  676. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_stat");
  677. MAC_POLICY_CHECK(vnode_check_stat, active_cred, file_cred, vp,
  678. vp->v_label);
  679. MAC_CHECK_PROBE3(vnode_check_stat, error, active_cred, file_cred,
  680. vp);
  681. return (error);
  682. }
  683. MAC_CHECK_PROBE_DEFINE4(vnode_check_unlink, "struct ucred *",
  684. "struct vnode *", "struct vnode *", "struct componentname *");
  685. int
  686. mac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
  687. struct vnode *vp, struct componentname *cnp)
  688. {
  689. int error;
  690. ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_unlink");
  691. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_unlink");
  692. MAC_POLICY_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
  693. vp->v_label, cnp);
  694. MAC_CHECK_PROBE4(vnode_check_unlink, error, cred, dvp, vp, cnp);
  695. return (error);
  696. }
  697. MAC_CHECK_PROBE_DEFINE3(vnode_check_write, "struct ucred *",
  698. "struct ucred *", "struct vnode *");
  699. int
  700. mac_vnode_check_write_impl(struct ucred *active_cred, struct ucred *file_cred,
  701. struct vnode *vp)
  702. {
  703. int error;
  704. ASSERT_VOP_LOCKED(vp, "mac_vnode_check_write");
  705. MAC_POLICY_CHECK(vnode_check_write, active_cred, file_cred, vp,
  706. vp->v_label);
  707. MAC_CHECK_PROBE3(vnode_check_write, error, active_cred, file_cred,
  708. vp);
  709. return (error);
  710. }
  711. void
  712. mac_vnode_relabel(struct ucred *cred, struct vnode *vp,
  713. struct label *newlabel)
  714. {
  715. MAC_POLICY_PERFORM(vnode_relabel, cred, vp, vp->v_label, newlabel);
  716. }
  717. void
  718. mac_mount_create(struct ucred *cred, struct mount *mp)
  719. {
  720. MAC_POLICY_PERFORM(mount_create, cred, mp, mp->mnt_label);
  721. }
  722. MAC_CHECK_PROBE_DEFINE2(mount_check_stat, "struct ucred *",
  723. "struct mount *");
  724. int
  725. mac_mount_check_stat(struct ucred *cred, struct mount *mount)
  726. {
  727. int error;
  728. MAC_POLICY_CHECK_NOSLEEP(mount_check_stat, cred, mount, mount->mnt_label);
  729. MAC_CHECK_PROBE2(mount_check_stat, error, cred, mount);
  730. return (error);
  731. }
  732. void
  733. mac_devfs_create_device(struct ucred *cred, struct mount *mp,
  734. struct cdev *dev, struct devfs_dirent *de)
  735. {
  736. MAC_POLICY_PERFORM_NOSLEEP(devfs_create_device, cred, mp, dev, de,
  737. de->de_label);
  738. }
  739. void
  740. mac_devfs_create_symlink(struct ucred *cred, struct mount *mp,
  741. struct devfs_dirent *dd, struct devfs_dirent *de)
  742. {
  743. MAC_POLICY_PERFORM_NOSLEEP(devfs_create_symlink, cred, mp, dd,
  744. dd->de_label, de, de->de_label);
  745. }
  746. void
  747. mac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
  748. struct devfs_dirent *de)
  749. {
  750. MAC_POLICY_PERFORM_NOSLEEP(devfs_create_directory, mp, dirname,
  751. dirnamelen, de, de->de_label);
  752. }
  753. /*
  754. * Implementation of VOP_SETLABEL() that relies on extended attributes to
  755. * store label data. Can be referenced by filesystems supporting extended
  756. * attributes.
  757. */
  758. int
  759. vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
  760. {
  761. struct vnode *vp = ap->a_vp;
  762. struct label *intlabel = ap->a_label;
  763. int error;
  764. ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
  765. if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
  766. return (EOPNOTSUPP);
  767. error = mac_vnode_setlabel_extattr(ap->a_cred, vp, intlabel);
  768. if (error)
  769. return (error);
  770. /*
  771. * XXXRW: See the comment below in vn_setlabel() as to why this might
  772. * be the wrong place to call mac_vnode_relabel().
  773. */
  774. mac_vnode_relabel(ap->a_cred, vp, intlabel);
  775. return (0);
  776. }
  777. int
  778. vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
  779. {
  780. int error;
  781. if (vp->v_mount == NULL) {
  782. /* printf("vn_setlabel: null v_mount\n"); */
  783. if (vp->v_type != VNON)
  784. printf("vn_setlabel: null v_mount with non-VNON\n");
  785. return (EBADF);
  786. }
  787. if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
  788. return (EOPNOTSUPP);
  789. /*
  790. * Multi-phase commit. First check the policies to confirm the
  791. * change is OK. Then commit via the filesystem. Finally, update
  792. * the actual vnode label.
  793. */
  794. error = mac_vnode_check_relabel(cred, vp, intlabel);
  795. if (error)
  796. return (error);
  797. /*
  798. * VADMIN provides the opportunity for the filesystem to make
  799. * decisions about who is and is not able to modify labels and
  800. * protections on files. This might not be right. We can't assume
  801. * VOP_SETLABEL() will do it, because we might implement that as part
  802. * of vop_stdsetlabel_ea().
  803. */
  804. error = VOP_ACCESS(vp, VADMIN, cred, curthread);
  805. if (error)
  806. return (error);
  807. error = VOP_SETLABEL(vp, intlabel, cred, curthread);
  808. if (error)
  809. return (error);
  810. /*
  811. * It would be more symmetric if mac_vnode_relabel() was called here
  812. * rather than in VOP_SETLABEL(), but we don't for historical reasons.
  813. * We should think about moving it so that the filesystem is
  814. * responsible only for persistence in VOP_SETLABEL(), not the vnode
  815. * label update itself.
  816. */
  817. return (0);
  818. }
  819. #ifdef DEBUG_VFS_LOCKS
  820. void
  821. mac_vnode_assert_locked(struct vnode *vp, const char *func)
  822. {
  823. ASSERT_VOP_LOCKED(vp, func);
  824. }
  825. #endif