714{ 715 716 /* Certain decision-making errors take top priority. */ 717 if (error1 == EDEADLK || error2 == EDEADLK) 718 return (EDEADLK); 719 720 /* Invalid arguments should be reported where possible. */ 721 if (error1 == EINVAL || error2 == EINVAL) 722 return (EINVAL); 723 724 /* Precedence goes to "visibility", with both process and file. */ 725 if (error1 == ESRCH || error2 == ESRCH) 726 return (ESRCH); 727 728 if (error1 == ENOENT || error2 == ENOENT) 729 return (ENOENT); 730 731 /* Precedence goes to DAC/MAC protections. */ 732 if (error1 == EACCES || error2 == EACCES) 733 return (EACCES); 734 735 /* Precedence goes to privilege. */ 736 if (error1 == EPERM || error2 == EPERM) 737 return (EPERM); 738 739 /* Precedence goes to error over success; otherwise, arbitrary. */ 740 if (error1 != 0) 741 return (error1); 742 return (error2); 743} 744 745static struct label * 746mbuf_to_label(struct mbuf *mbuf) 747{ 748 struct m_tag *tag; 749 struct label *label; 750 751 tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 752 label = (struct label *)(tag+1); 753 754 return (label); 755} 756 757static void 758mac_init_label(struct label *label) 759{ 760 761 bzero(label, sizeof(*label)); 762 label->l_flags = MAC_FLAG_INITIALIZED; 763} 764 765static void 766mac_destroy_label(struct label *label) 767{ 768 769 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 770 ("destroying uninitialized label")); 771 772 bzero(label, sizeof(*label)); 773 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 774} 775 776void 777mac_init_bpfdesc(struct bpf_d *bpf_d) 778{ 779 780 mac_init_label(&bpf_d->bd_label); 781 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 782 MAC_DEBUG_COUNTER_INC(&nmacbpfdescs); 783} 784 785static void 786mac_init_cred_label(struct label *label) 787{ 788 789 mac_init_label(label); 790 MAC_PERFORM(init_cred_label, label); 791 MAC_DEBUG_COUNTER_INC(&nmaccreds); 792} 793 794void 795mac_init_cred(struct ucred *cred) 796{ 797 798 mac_init_cred_label(&cred->cr_label); 799} 800 801void 802mac_init_devfsdirent(struct devfs_dirent *de) 803{ 804 805 mac_init_label(&de->de_label); 806 MAC_PERFORM(init_devfsdirent_label, &de->de_label); 807 MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents); 808} 809 810static void 811mac_init_ifnet_label(struct label *label) 812{ 813 814 mac_init_label(label); 815 MAC_PERFORM(init_ifnet_label, label); 816 MAC_DEBUG_COUNTER_INC(&nmacifnets); 817} 818 819void 820mac_init_ifnet(struct ifnet *ifp) 821{ 822 823 mac_init_ifnet_label(&ifp->if_label); 824} 825 826int 827mac_init_ipq(struct ipq *ipq, int flag) 828{ 829 int error; 830 831 mac_init_label(&ipq->ipq_label); 832 833 MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag); 834 if (error) { 835 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 836 mac_destroy_label(&ipq->ipq_label); 837 } else { 838 MAC_DEBUG_COUNTER_INC(&nmacipqs); 839 } 840 return (error); 841} 842 843int 844mac_init_mbuf_tag(struct m_tag *tag, int flag) 845{ 846 struct label *label; 847 int error; 848 849 label = (struct label *) (tag + 1); 850 mac_init_label(label); 851 852 MAC_CHECK(init_mbuf_label, label, flag); 853 if (error) { 854 MAC_PERFORM(destroy_mbuf_label, label); 855 mac_destroy_label(label); 856 } else { 857 MAC_DEBUG_COUNTER_INC(&nmacmbufs); 858 } 859 return (error); 860} 861 862int 863mac_init_mbuf(struct mbuf *m, int flag) 864{ 865 struct m_tag *tag; 866 int error; 867 868 M_ASSERTPKTHDR(m); 869 870#ifndef MAC_ALWAYS_LABEL_MBUF 871 /* 872 * If conditionally allocating mbuf labels, don't allocate unless 873 * they are required. 874 */ 875 if (!mac_labelmbufs) 876 return (0); 877#endif 878 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 879 flag); 880 if (tag == NULL) 881 return (ENOMEM); 882 error = mac_init_mbuf_tag(tag, flag); 883 if (error) { 884 m_tag_free(tag); 885 return (error); 886 } 887 m_tag_prepend(m, tag); 888 return (0); 889} 890 891void 892mac_init_mount(struct mount *mp) 893{ 894 895 mac_init_label(&mp->mnt_mntlabel); 896 mac_init_label(&mp->mnt_fslabel); 897 MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 898 MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 899 MAC_DEBUG_COUNTER_INC(&nmacmounts); 900} 901 902static void 903mac_init_pipe_label(struct label *label) 904{ 905 906 mac_init_label(label); 907 MAC_PERFORM(init_pipe_label, label); 908 MAC_DEBUG_COUNTER_INC(&nmacpipes); 909} 910 911void 912mac_init_pipe(struct pipe *pipe) 913{ 914 struct label *label; 915 916 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 917 pipe->pipe_label = label; 918 pipe->pipe_peer->pipe_label = label; 919 mac_init_pipe_label(label); 920} 921 922void 923mac_init_proc(struct proc *p) 924{ 925 926 mac_init_label(&p->p_label); 927 MAC_PERFORM(init_proc_label, &p->p_label); 928 MAC_DEBUG_COUNTER_INC(&nmacprocs); 929} 930 931static int 932mac_init_socket_label(struct label *label, int flag) 933{ 934 int error; 935 936 mac_init_label(label); 937 938 MAC_CHECK(init_socket_label, label, flag); 939 if (error) { 940 MAC_PERFORM(destroy_socket_label, label); 941 mac_destroy_label(label); 942 } else { 943 MAC_DEBUG_COUNTER_INC(&nmacsockets); 944 } 945 946 return (error); 947} 948 949static int 950mac_init_socket_peer_label(struct label *label, int flag) 951{ 952 int error; 953 954 mac_init_label(label); 955 956 MAC_CHECK(init_socket_peer_label, label, flag); 957 if (error) { 958 MAC_PERFORM(destroy_socket_label, label); 959 mac_destroy_label(label); 960 } 961 962 return (error); 963} 964 965int 966mac_init_socket(struct socket *socket, int flag) 967{ 968 int error; 969 970 error = mac_init_socket_label(&socket->so_label, flag); 971 if (error) 972 return (error); 973 974 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 975 if (error) 976 mac_destroy_socket_label(&socket->so_label); 977 978 return (error); 979} 980 981void 982mac_init_vnode_label(struct label *label) 983{ 984 985 mac_init_label(label); 986 MAC_PERFORM(init_vnode_label, label); 987 MAC_DEBUG_COUNTER_INC(&nmacvnodes); 988} 989 990void 991mac_init_vnode(struct vnode *vp) 992{ 993 994 mac_init_vnode_label(&vp->v_label); 995} 996 997void 998mac_destroy_bpfdesc(struct bpf_d *bpf_d) 999{ 1000 1001 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1002 mac_destroy_label(&bpf_d->bd_label); 1003 MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs); 1004} 1005 1006static void 1007mac_destroy_cred_label(struct label *label) 1008{ 1009 1010 MAC_PERFORM(destroy_cred_label, label); 1011 mac_destroy_label(label); 1012 MAC_DEBUG_COUNTER_DEC(&nmaccreds); 1013} 1014 1015void 1016mac_destroy_cred(struct ucred *cred) 1017{ 1018 1019 mac_destroy_cred_label(&cred->cr_label); 1020} 1021 1022void 1023mac_destroy_devfsdirent(struct devfs_dirent *de) 1024{ 1025 1026 MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1027 mac_destroy_label(&de->de_label); 1028 MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents); 1029} 1030 1031static void 1032mac_destroy_ifnet_label(struct label *label) 1033{ 1034 1035 MAC_PERFORM(destroy_ifnet_label, label); 1036 mac_destroy_label(label); 1037 MAC_DEBUG_COUNTER_DEC(&nmacifnets); 1038} 1039 1040void 1041mac_destroy_ifnet(struct ifnet *ifp) 1042{ 1043 1044 mac_destroy_ifnet_label(&ifp->if_label); 1045} 1046 1047void 1048mac_destroy_ipq(struct ipq *ipq) 1049{ 1050 1051 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1052 mac_destroy_label(&ipq->ipq_label); 1053 MAC_DEBUG_COUNTER_DEC(&nmacipqs); 1054} 1055 1056void 1057mac_destroy_mbuf_tag(struct m_tag *tag) 1058{ 1059 struct label *label; 1060 1061 label = (struct label *)(tag+1); 1062 1063 MAC_PERFORM(destroy_mbuf_label, label); 1064 mac_destroy_label(label); 1065 MAC_DEBUG_COUNTER_DEC(&nmacmbufs); 1066} 1067 1068void 1069mac_destroy_mount(struct mount *mp) 1070{ 1071 1072 MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1073 MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1074 mac_destroy_label(&mp->mnt_fslabel); 1075 mac_destroy_label(&mp->mnt_mntlabel); 1076 MAC_DEBUG_COUNTER_DEC(&nmacmounts); 1077} 1078 1079static void 1080mac_destroy_pipe_label(struct label *label) 1081{ 1082 1083 MAC_PERFORM(destroy_pipe_label, label); 1084 mac_destroy_label(label); 1085 MAC_DEBUG_COUNTER_DEC(&nmacpipes); 1086} 1087 1088void 1089mac_destroy_pipe(struct pipe *pipe) 1090{ 1091 1092 mac_destroy_pipe_label(pipe->pipe_label); 1093 free(pipe->pipe_label, M_MACPIPELABEL); 1094} 1095 1096void 1097mac_destroy_proc(struct proc *p) 1098{ 1099 1100 MAC_PERFORM(destroy_proc_label, &p->p_label); 1101 mac_destroy_label(&p->p_label); 1102 MAC_DEBUG_COUNTER_DEC(&nmacprocs); 1103} 1104 1105static void 1106mac_destroy_socket_label(struct label *label) 1107{ 1108 1109 MAC_PERFORM(destroy_socket_label, label); 1110 mac_destroy_label(label); 1111 MAC_DEBUG_COUNTER_DEC(&nmacsockets); 1112} 1113 1114static void 1115mac_destroy_socket_peer_label(struct label *label) 1116{ 1117 1118 MAC_PERFORM(destroy_socket_peer_label, label); 1119 mac_destroy_label(label); 1120} 1121 1122void 1123mac_destroy_socket(struct socket *socket) 1124{ 1125 1126 mac_destroy_socket_label(&socket->so_label); 1127 mac_destroy_socket_peer_label(&socket->so_peerlabel); 1128} 1129 1130void 1131mac_destroy_vnode_label(struct label *label) 1132{ 1133 1134 MAC_PERFORM(destroy_vnode_label, label); 1135 mac_destroy_label(label); 1136 MAC_DEBUG_COUNTER_DEC(&nmacvnodes); 1137} 1138 1139void 1140mac_destroy_vnode(struct vnode *vp) 1141{ 1142 1143 mac_destroy_vnode_label(&vp->v_label); 1144} 1145 1146void 1147mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 1148{ 1149 struct label *src_label, *dest_label; 1150 1151 src_label = (struct label *)(src+1); 1152 dest_label = (struct label *)(dest+1); 1153 1154 /* 1155 * mac_init_mbuf_tag() is called on the target tag in 1156 * m_tag_copy(), so we don't need to call it here. 1157 */ 1158 MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 1159} 1160 1161static void 1162mac_copy_pipe_label(struct label *src, struct label *dest) 1163{ 1164 1165 MAC_PERFORM(copy_pipe_label, src, dest); 1166} 1167 1168void 1169mac_copy_vnode_label(struct label *src, struct label *dest) 1170{ 1171 1172 MAC_PERFORM(copy_vnode_label, src, dest); 1173} 1174 1175static int 1176mac_check_structmac_consistent(struct mac *mac) 1177{ 1178 1179 if (mac->m_buflen < 0 || 1180 mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1181 return (EINVAL); 1182 1183 return (0); 1184} 1185 1186static int 1187mac_externalize_cred_label(struct label *label, char *elements, 1188 char *outbuf, size_t outbuflen, int flags) 1189{ 1190 int error; 1191 1192 MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1193 1194 return (error); 1195} 1196 1197static int 1198mac_externalize_ifnet_label(struct label *label, char *elements, 1199 char *outbuf, size_t outbuflen, int flags) 1200{ 1201 int error; 1202 1203 MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1204 1205 return (error); 1206} 1207 1208static int 1209mac_externalize_pipe_label(struct label *label, char *elements, 1210 char *outbuf, size_t outbuflen, int flags) 1211{ 1212 int error; 1213 1214 MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1215 1216 return (error); 1217} 1218 1219static int 1220mac_externalize_socket_label(struct label *label, char *elements, 1221 char *outbuf, size_t outbuflen, int flags) 1222{ 1223 int error; 1224 1225 MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1226 1227 return (error); 1228} 1229 1230static int 1231mac_externalize_socket_peer_label(struct label *label, char *elements, 1232 char *outbuf, size_t outbuflen, int flags) 1233{ 1234 int error; 1235 1236 MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1237 1238 return (error); 1239} 1240 1241static int 1242mac_externalize_vnode_label(struct label *label, char *elements, 1243 char *outbuf, size_t outbuflen, int flags) 1244{ 1245 int error; 1246 1247 MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1248 1249 return (error); 1250} 1251 1252static int 1253mac_internalize_cred_label(struct label *label, char *string) 1254{ 1255 int error; 1256 1257 MAC_INTERNALIZE(cred_label, label, string); 1258 1259 return (error); 1260} 1261 1262static int 1263mac_internalize_ifnet_label(struct label *label, char *string) 1264{ 1265 int error; 1266 1267 MAC_INTERNALIZE(ifnet_label, label, string); 1268 1269 return (error); 1270} 1271 1272static int 1273mac_internalize_pipe_label(struct label *label, char *string) 1274{ 1275 int error; 1276 1277 MAC_INTERNALIZE(pipe_label, label, string); 1278 1279 return (error); 1280} 1281 1282static int 1283mac_internalize_socket_label(struct label *label, char *string) 1284{ 1285 int error; 1286 1287 MAC_INTERNALIZE(socket_label, label, string); 1288 1289 return (error); 1290} 1291 1292static int 1293mac_internalize_vnode_label(struct label *label, char *string) 1294{ 1295 int error; 1296 1297 MAC_INTERNALIZE(vnode_label, label, string); 1298 1299 return (error); 1300} 1301 1302/* 1303 * Initialize MAC label for the first kernel process, from which other 1304 * kernel processes and threads are spawned. 1305 */ 1306void 1307mac_create_proc0(struct ucred *cred) 1308{ 1309 1310 MAC_PERFORM(create_proc0, cred); 1311} 1312 1313/* 1314 * Initialize MAC label for the first userland process, from which other 1315 * userland processes and threads are spawned. 1316 */ 1317void 1318mac_create_proc1(struct ucred *cred) 1319{ 1320 1321 MAC_PERFORM(create_proc1, cred); 1322} 1323 1324void 1325mac_thread_userret(struct thread *td) 1326{ 1327 1328 MAC_PERFORM(thread_userret, td); 1329} 1330 1331/* 1332 * When a new process is created, its label must be initialized. Generally, 1333 * this involves inheritence from the parent process, modulo possible 1334 * deltas. This function allows that processing to take place. 1335 */ 1336void 1337mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1338{ 1339 1340 MAC_PERFORM(create_cred, parent_cred, child_cred); 1341} 1342 1343void 1344mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1345 struct vnode *vp) 1346{ 1347 1348 MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1349 &vp->v_label); 1350} 1351 1352void 1353mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1354 struct vnode *vp) 1355{ 1356 1357 MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1358 &de->de_label, vp, &vp->v_label); 1359} 1360 1361int 1362mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1363{ 1364 int error; 1365 1366 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1367 1368 MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1369 &vp->v_label); 1370 1371 return (error); 1372} 1373 1374void 1375mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1376{ 1377 1378 MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1379 &vp->v_label); 1380} 1381 1382int 1383mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1384 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1385{ 1386 int error; 1387 1388 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1389 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1390 1391 error = VOP_OPENEXTATTR(vp, cred, curthread); 1392 if (error == EOPNOTSUPP) { 1393 /* XXX: Optionally abort if transactions not supported. */ 1394 if (ea_warn_once == 0) { 1395 printf("Warning: transactions not supported " 1396 "in EA write.\n"); 1397 ea_warn_once = 1; 1398 } 1399 } else if (error) 1400 return (error); 1401 1402 MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1403 dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1404 1405 if (error) { 1406 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1407 return (error); 1408 } 1409 1410 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1411 1412 if (error == EOPNOTSUPP) 1413 error = 0; /* XXX */ 1414 1415 return (error); 1416} 1417 1418static int 1419mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1420 struct label *intlabel) 1421{ 1422 int error; 1423 1424 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1425 1426 error = VOP_OPENEXTATTR(vp, cred, curthread); 1427 if (error == EOPNOTSUPP) { 1428 /* XXX: Optionally abort if transactions not supported. */ 1429 if (ea_warn_once == 0) { 1430 printf("Warning: transactions not supported " 1431 "in EA write.\n"); 1432 ea_warn_once = 1; 1433 } 1434 } else if (error) 1435 return (error); 1436 1437 MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1438 1439 if (error) { 1440 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1441 return (error); 1442 } 1443 1444 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1445 1446 if (error == EOPNOTSUPP) 1447 error = 0; /* XXX */ 1448 1449 return (error); 1450} 1451 1452int 1453mac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1454 struct label *execlabelstorage) 1455{ 1456 struct mac mac; 1457 char *buffer; 1458 int error; 1459 1460 if (mac_p == NULL) 1461 return (0); 1462 1463 error = copyin(mac_p, &mac, sizeof(mac)); 1464 if (error) 1465 return (error); 1466 1467 error = mac_check_structmac_consistent(&mac); 1468 if (error) 1469 return (error); 1470 1471 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1472 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1473 if (error) { 1474 free(buffer, M_MACTEMP); 1475 return (error); 1476 } 1477 1478 mac_init_cred_label(execlabelstorage); 1479 error = mac_internalize_cred_label(execlabelstorage, buffer); 1480 free(buffer, M_MACTEMP); 1481 if (error) { 1482 mac_destroy_cred_label(execlabelstorage); 1483 return (error); 1484 } 1485 imgp->execlabel = execlabelstorage; 1486 return (0); 1487} 1488 1489void 1490mac_execve_exit(struct image_params *imgp) 1491{ 1492 if (imgp->execlabel != NULL) 1493 mac_destroy_cred_label(imgp->execlabel); 1494} 1495 1496void 1497mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1498 struct label *interpvnodelabel, struct image_params *imgp) 1499{ 1500 1501 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1502 1503 if (!mac_enforce_process && !mac_enforce_fs) 1504 return; 1505 1506 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1507 interpvnodelabel, imgp, imgp->execlabel); 1508} 1509 1510int 1511mac_execve_will_transition(struct ucred *old, struct vnode *vp, 1512 struct label *interpvnodelabel, struct image_params *imgp) 1513{ 1514 int result; 1515 1516 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1517 1518 if (!mac_enforce_process && !mac_enforce_fs) 1519 return (0); 1520 1521 result = 0; 1522 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1523 interpvnodelabel, imgp, imgp->execlabel); 1524 1525 return (result); 1526} 1527 1528int 1529mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1530{ 1531 int error; 1532 1533 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1534 1535 if (!mac_enforce_fs) 1536 return (0); 1537 1538 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1539 return (error); 1540} 1541 1542int 1543mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1544{ 1545 int error; 1546 1547 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1548 1549 if (!mac_enforce_fs) 1550 return (0); 1551 1552 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1553 return (error); 1554} 1555 1556int 1557mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1558{ 1559 int error; 1560 1561 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1562 1563 if (!mac_enforce_fs) 1564 return (0); 1565 1566 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1567 return (error); 1568} 1569 1570int 1571mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1572 struct componentname *cnp, struct vattr *vap) 1573{ 1574 int error; 1575 1576 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1577 1578 if (!mac_enforce_fs) 1579 return (0); 1580 1581 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1582 return (error); 1583} 1584 1585int 1586mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1587 struct componentname *cnp) 1588{ 1589 int error; 1590 1591 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1592 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1593 1594 if (!mac_enforce_fs) 1595 return (0); 1596 1597 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1598 &vp->v_label, cnp); 1599 return (error); 1600} 1601 1602int 1603mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1604 acl_type_t type) 1605{ 1606 int error; 1607 1608 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1609 1610 if (!mac_enforce_fs) 1611 return (0); 1612 1613 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1614 return (error); 1615} 1616 1617int 1618mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 1619 int attrnamespace, const char *name) 1620{ 1621 int error; 1622 1623 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr"); 1624 1625 if (!mac_enforce_fs) 1626 return (0); 1627 1628 MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label, 1629 attrnamespace, name); 1630 return (error); 1631} 1632 1633int 1634mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1635 struct image_params *imgp) 1636{ 1637 int error; 1638 1639 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1640 1641 if (!mac_enforce_process && !mac_enforce_fs) 1642 return (0); 1643 1644 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1645 imgp->execlabel); 1646 1647 return (error); 1648} 1649 1650int 1651mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1652{ 1653 int error; 1654 1655 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1656 1657 if (!mac_enforce_fs) 1658 return (0); 1659 1660 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1661 return (error); 1662} 1663 1664int 1665mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1666 int attrnamespace, const char *name, struct uio *uio) 1667{ 1668 int error; 1669 1670 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1671 1672 if (!mac_enforce_fs) 1673 return (0); 1674 1675 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1676 attrnamespace, name, uio); 1677 return (error); 1678} 1679 1680int 1681mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1682 struct vnode *vp, struct componentname *cnp) 1683{ 1684 int error; 1685 1686 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1687 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1688 1689 if (!mac_enforce_fs) 1690 return (0); 1691 1692 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1693 &vp->v_label, cnp); 1694 return (error); 1695} 1696 1697int 1698mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 1699 int attrnamespace) 1700{ 1701 int error; 1702 1703 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr"); 1704 1705 if (!mac_enforce_fs) 1706 return (0); 1707 1708 MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label, 1709 attrnamespace); 1710 return (error); 1711} 1712 1713int 1714mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1715 struct componentname *cnp) 1716{ 1717 int error; 1718 1719 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1720 1721 if (!mac_enforce_fs) 1722 return (0); 1723 1724 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1725 return (error); 1726} 1727 1728int 1729mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1730{ 1731 int error; 1732 1733 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1734 1735 if (!mac_enforce_fs || !mac_enforce_vm) 1736 return (0); 1737 1738 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1739 return (error); 1740} 1741 1742void 1743mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1744{ 1745 int result = *prot; 1746 1747 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1748 1749 if (!mac_enforce_fs || !mac_enforce_vm) 1750 return; 1751 1752 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1753 &result); 1754 1755 *prot = result; 1756} 1757 1758int 1759mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1760{ 1761 int error; 1762 1763 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1764 1765 if (!mac_enforce_fs || !mac_enforce_vm) 1766 return (0); 1767 1768 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1769 return (error); 1770} 1771 1772int 1773mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1774{ 1775 int error; 1776 1777 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1778 1779 if (!mac_enforce_fs) 1780 return (0); 1781 1782 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1783 return (error); 1784} 1785 1786int 1787mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1788 struct vnode *vp) 1789{ 1790 int error; 1791 1792 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1793 1794 if (!mac_enforce_fs) 1795 return (0); 1796 1797 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1798 &vp->v_label); 1799 1800 return (error); 1801} 1802 1803int 1804mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1805 struct vnode *vp) 1806{ 1807 int error; 1808 1809 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1810 1811 if (!mac_enforce_fs) 1812 return (0); 1813 1814 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1815 &vp->v_label); 1816 1817 return (error); 1818} 1819 1820int 1821mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1822{ 1823 int error; 1824 1825 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1826 1827 if (!mac_enforce_fs) 1828 return (0); 1829 1830 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1831 return (error); 1832} 1833 1834int 1835mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1836{ 1837 int error; 1838 1839 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1840 1841 if (!mac_enforce_fs) 1842 return (0); 1843 1844 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1845 return (error); 1846} 1847 1848static int 1849mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1850 struct label *newlabel) 1851{ 1852 int error; 1853 1854 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1855 1856 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1857 1858 return (error); 1859} 1860 1861int 1862mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1863 struct vnode *vp, struct componentname *cnp) 1864{ 1865 int error; 1866 1867 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1868 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1869 1870 if (!mac_enforce_fs) 1871 return (0); 1872 1873 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1874 &vp->v_label, cnp); 1875 return (error); 1876} 1877 1878int 1879mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1880 struct vnode *vp, int samedir, struct componentname *cnp) 1881{ 1882 int error; 1883 1884 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1885 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1886 1887 if (!mac_enforce_fs) 1888 return (0); 1889 1890 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1891 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1892 return (error); 1893} 1894 1895int 1896mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1897{ 1898 int error; 1899 1900 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1901 1902 if (!mac_enforce_fs) 1903 return (0); 1904 1905 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1906 return (error); 1907} 1908 1909int 1910mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1911 struct acl *acl) 1912{ 1913 int error; 1914 1915 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1916 1917 if (!mac_enforce_fs) 1918 return (0); 1919 1920 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1921 return (error); 1922} 1923 1924int 1925mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1926 int attrnamespace, const char *name, struct uio *uio) 1927{ 1928 int error; 1929 1930 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1931 1932 if (!mac_enforce_fs) 1933 return (0); 1934 1935 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1936 attrnamespace, name, uio); 1937 return (error); 1938} 1939 1940int 1941mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1942{ 1943 int error; 1944 1945 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1946 1947 if (!mac_enforce_fs) 1948 return (0); 1949 1950 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1951 return (error); 1952} 1953 1954int 1955mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1956{ 1957 int error; 1958 1959 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1960 1961 if (!mac_enforce_fs) 1962 return (0); 1963 1964 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1965 return (error); 1966} 1967 1968int 1969mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1970 gid_t gid) 1971{ 1972 int error; 1973 1974 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1975 1976 if (!mac_enforce_fs) 1977 return (0); 1978 1979 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1980 return (error); 1981} 1982 1983int 1984mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1985 struct timespec atime, struct timespec mtime) 1986{ 1987 int error; 1988 1989 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1990 1991 if (!mac_enforce_fs) 1992 return (0); 1993 1994 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1995 mtime); 1996 return (error); 1997} 1998 1999int 2000mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2001 struct vnode *vp) 2002{ 2003 int error; 2004 2005 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2006 2007 if (!mac_enforce_fs) 2008 return (0); 2009 2010 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2011 &vp->v_label); 2012 return (error); 2013} 2014 2015int 2016mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2017 struct vnode *vp) 2018{ 2019 int error; 2020 2021 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2022 2023 if (!mac_enforce_fs) 2024 return (0); 2025 2026 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2027 &vp->v_label); 2028 2029 return (error); 2030} 2031 2032/* 2033 * When relabeling a process, call out to the policies for the maximum 2034 * permission allowed for each object type we know about in its 2035 * memory space, and revoke access (in the least surprising ways we 2036 * know) when necessary. The process lock is not held here. 2037 */ 2038void 2039mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2040{ 2041 2042 /* XXX freeze all other threads */ 2043 mac_cred_mmapped_drop_perms_recurse(td, cred, 2044 &td->td_proc->p_vmspace->vm_map); 2045 /* XXX allow other threads to continue */ 2046} 2047 2048static __inline const char * 2049prot2str(vm_prot_t prot) 2050{ 2051 2052 switch (prot & VM_PROT_ALL) { 2053 case VM_PROT_READ: 2054 return ("r--"); 2055 case VM_PROT_READ | VM_PROT_WRITE: 2056 return ("rw-"); 2057 case VM_PROT_READ | VM_PROT_EXECUTE: 2058 return ("r-x"); 2059 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2060 return ("rwx"); 2061 case VM_PROT_WRITE: 2062 return ("-w-"); 2063 case VM_PROT_EXECUTE: 2064 return ("--x"); 2065 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2066 return ("-wx"); 2067 default: 2068 return ("---"); 2069 } 2070} 2071 2072static void 2073mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2074 struct vm_map *map) 2075{ 2076 struct vm_map_entry *vme; 2077 int result; 2078 vm_prot_t revokeperms; 2079 vm_object_t object; 2080 vm_ooffset_t offset; 2081 struct vnode *vp; 2082 2083 if (!mac_mmap_revocation) 2084 return; 2085 2086 vm_map_lock_read(map); 2087 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2088 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2089 mac_cred_mmapped_drop_perms_recurse(td, cred, 2090 vme->object.sub_map); 2091 continue; 2092 } 2093 /* 2094 * Skip over entries that obviously are not shared. 2095 */ 2096 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2097 !vme->max_protection) 2098 continue; 2099 /* 2100 * Drill down to the deepest backing object. 2101 */ 2102 offset = vme->offset; 2103 object = vme->object.vm_object; 2104 if (object == NULL) 2105 continue; 2106 while (object->backing_object != NULL) { 2107 object = object->backing_object; 2108 offset += object->backing_object_offset; 2109 } 2110 /* 2111 * At the moment, vm_maps and objects aren't considered 2112 * by the MAC system, so only things with backing by a 2113 * normal object (read: vnodes) are checked. 2114 */ 2115 if (object->type != OBJT_VNODE) 2116 continue; 2117 vp = (struct vnode *)object->handle; 2118 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2119 result = vme->max_protection; 2120 mac_check_vnode_mmap_downgrade(cred, vp, &result); 2121 VOP_UNLOCK(vp, 0, td); 2122 /* 2123 * Find out what maximum protection we may be allowing 2124 * now but a policy needs to get removed. 2125 */ 2126 revokeperms = vme->max_protection & ~result; 2127 if (!revokeperms) 2128 continue; 2129 printf("pid %ld: revoking %s perms from %#lx:%ld " 2130 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2131 prot2str(revokeperms), (u_long)vme->start, 2132 (long)(vme->end - vme->start), 2133 prot2str(vme->max_protection), prot2str(vme->protection)); 2134 vm_map_lock_upgrade(map); 2135 /* 2136 * This is the really simple case: if a map has more 2137 * max_protection than is allowed, but it's not being 2138 * actually used (that is, the current protection is 2139 * still allowed), we can just wipe it out and do 2140 * nothing more. 2141 */ 2142 if ((vme->protection & revokeperms) == 0) { 2143 vme->max_protection -= revokeperms; 2144 } else { 2145 if (revokeperms & VM_PROT_WRITE) { 2146 /* 2147 * In the more complicated case, flush out all 2148 * pending changes to the object then turn it 2149 * copy-on-write. 2150 */ 2151 vm_object_reference(object); 2152 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2153 VM_OBJECT_LOCK(object); 2154 vm_object_page_clean(object, 2155 OFF_TO_IDX(offset), 2156 OFF_TO_IDX(offset + vme->end - vme->start + 2157 PAGE_MASK), 2158 OBJPC_SYNC); 2159 VM_OBJECT_UNLOCK(object); 2160 VOP_UNLOCK(vp, 0, td); 2161 vm_object_deallocate(object); 2162 /* 2163 * Why bother if there's no read permissions 2164 * anymore? For the rest, we need to leave 2165 * the write permissions on for COW, or 2166 * remove them entirely if configured to. 2167 */ 2168 if (!mac_mmap_revocation_via_cow) { 2169 vme->max_protection &= ~VM_PROT_WRITE; 2170 vme->protection &= ~VM_PROT_WRITE; 2171 } if ((revokeperms & VM_PROT_READ) == 0) 2172 vme->eflags |= MAP_ENTRY_COW | 2173 MAP_ENTRY_NEEDS_COPY; 2174 } 2175 if (revokeperms & VM_PROT_EXECUTE) { 2176 vme->max_protection &= ~VM_PROT_EXECUTE; 2177 vme->protection &= ~VM_PROT_EXECUTE; 2178 } 2179 if (revokeperms & VM_PROT_READ) { 2180 vme->max_protection = 0; 2181 vme->protection = 0; 2182 } 2183 pmap_protect(map->pmap, vme->start, vme->end, 2184 vme->protection & ~revokeperms); 2185 vm_map_simplify_entry(map, vme); 2186 } 2187 vm_map_lock_downgrade(map); 2188 } 2189 vm_map_unlock_read(map); 2190} 2191 2192/* 2193 * When the subject's label changes, it may require revocation of privilege 2194 * to mapped objects. This can't be done on-the-fly later with a unified 2195 * buffer cache. 2196 */ 2197static void 2198mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2199{ 2200 2201 MAC_PERFORM(relabel_cred, cred, newlabel); 2202} 2203 2204void 2205mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2206{ 2207 2208 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2209} 2210 2211void 2212mac_create_ifnet(struct ifnet *ifnet) 2213{ 2214 2215 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2216} 2217 2218void 2219mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2220{ 2221 2222 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2223} 2224 2225void 2226mac_create_socket(struct ucred *cred, struct socket *socket) 2227{ 2228 2229 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2230} 2231 2232void 2233mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2234{ 2235 2236 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2237} 2238 2239void 2240mac_create_socket_from_socket(struct socket *oldsocket, 2241 struct socket *newsocket) 2242{ 2243 2244 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2245 newsocket, &newsocket->so_label); 2246} 2247 2248static void 2249mac_relabel_socket(struct ucred *cred, struct socket *socket, 2250 struct label *newlabel) 2251{ 2252 2253 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2254} 2255 2256static void 2257mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2258{ 2259 2260 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2261} 2262 2263void 2264mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2265{ 2266 struct label *label; 2267 2268 label = mbuf_to_label(mbuf); 2269 2270 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2271 &socket->so_peerlabel); 2272} 2273 2274void 2275mac_set_socket_peer_from_socket(struct socket *oldsocket, 2276 struct socket *newsocket) 2277{ 2278 2279 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2280 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2281} 2282 2283void 2284mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2285{ 2286 struct label *label; 2287 2288 label = mbuf_to_label(datagram); 2289 2290 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2291 datagram, label); 2292} 2293 2294void 2295mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2296{ 2297 struct label *datagramlabel, *fragmentlabel; 2298 2299 datagramlabel = mbuf_to_label(datagram); 2300 fragmentlabel = mbuf_to_label(fragment); 2301 2302 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2303 fragmentlabel); 2304} 2305 2306void 2307mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2308{ 2309 struct label *label; 2310 2311 label = mbuf_to_label(fragment); 2312 2313 MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2314} 2315 2316void 2317mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2318{ 2319 struct label *oldmbuflabel, *newmbuflabel; 2320 2321 oldmbuflabel = mbuf_to_label(oldmbuf); 2322 newmbuflabel = mbuf_to_label(newmbuf); 2323 2324 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2325 newmbuflabel); 2326} 2327 2328void 2329mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2330{ 2331 struct label *label; 2332 2333 label = mbuf_to_label(mbuf); 2334 2335 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2336 label); 2337} 2338 2339void 2340mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2341{ 2342 struct label *label; 2343 2344 label = mbuf_to_label(mbuf); 2345 2346 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2347 label); 2348} 2349 2350void 2351mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2352{ 2353 struct label *label; 2354 2355 label = mbuf_to_label(mbuf); 2356 2357 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2358 label); 2359} 2360 2361void 2362mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2363 struct mbuf *newmbuf) 2364{ 2365 struct label *oldmbuflabel, *newmbuflabel; 2366 2367 oldmbuflabel = mbuf_to_label(oldmbuf); 2368 newmbuflabel = mbuf_to_label(newmbuf); 2369 2370 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2371 ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2372} 2373 2374void 2375mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2376{ 2377 struct label *oldmbuflabel, *newmbuflabel; 2378 2379 oldmbuflabel = mbuf_to_label(oldmbuf); 2380 newmbuflabel = mbuf_to_label(newmbuf); 2381 2382 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2383 newmbuflabel); 2384} 2385 2386int 2387mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2388{ 2389 struct label *label; 2390 int result; 2391 2392 label = mbuf_to_label(fragment); 2393 2394 result = 1; 2395 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2396 &ipq->ipq_label); 2397 2398 return (result); 2399} 2400 2401void 2402mac_reflect_mbuf_icmp(struct mbuf *m) 2403{ 2404 struct label *label; 2405 2406 label = mbuf_to_label(m); 2407 2408 MAC_PERFORM(reflect_mbuf_icmp, m, label); 2409} 2410void 2411mac_reflect_mbuf_tcp(struct mbuf *m) 2412{ 2413 struct label *label; 2414 2415 label = mbuf_to_label(m); 2416 2417 MAC_PERFORM(reflect_mbuf_tcp, m, label); 2418} 2419 2420void 2421mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2422{ 2423 struct label *label; 2424 2425 label = mbuf_to_label(fragment); 2426 2427 MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2428} 2429 2430void 2431mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2432{ 2433 struct label *label; 2434 2435 label = mbuf_to_label(mbuf); 2436 2437 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2438 label); 2439} 2440 2441void 2442mac_create_mount(struct ucred *cred, struct mount *mp) 2443{ 2444 2445 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2446 &mp->mnt_fslabel); 2447} 2448 2449void 2450mac_create_root_mount(struct ucred *cred, struct mount *mp) 2451{ 2452 2453 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2454 &mp->mnt_fslabel); 2455} 2456 2457int 2458mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2459{ 2460 int error; 2461 2462 if (!mac_enforce_network) 2463 return (0); 2464 2465 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2466 &ifnet->if_label); 2467 2468 return (error); 2469} 2470 2471static int 2472mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2473{ 2474 int error; 2475 2476 MAC_CHECK(check_cred_relabel, cred, newlabel); 2477 2478 return (error); 2479} 2480 2481int 2482mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2483{ 2484 int error; 2485 2486 if (!mac_enforce_process) 2487 return (0); 2488 2489 MAC_CHECK(check_cred_visible, u1, u2); 2490 2491 return (error); 2492} 2493 2494int 2495mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2496{ 2497 struct label *label; 2498 int error; 2499 2500 M_ASSERTPKTHDR(mbuf); 2501 2502 if (!mac_enforce_network) 2503 return (0); 2504 2505 label = mbuf_to_label(mbuf); 2506 2507 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2508 label); 2509 2510 return (error); 2511} 2512 2513int 2514mac_check_kenv_dump(struct ucred *cred) 2515{ 2516 int error; 2517 2518 if (!mac_enforce_system) 2519 return (0); 2520 2521 MAC_CHECK(check_kenv_dump, cred); 2522 2523 return (error); 2524} 2525 2526int 2527mac_check_kenv_get(struct ucred *cred, char *name) 2528{ 2529 int error; 2530 2531 if (!mac_enforce_system) 2532 return (0); 2533 2534 MAC_CHECK(check_kenv_get, cred, name); 2535 2536 return (error); 2537} 2538 2539int 2540mac_check_kenv_set(struct ucred *cred, char *name, char *value) 2541{ 2542 int error; 2543 2544 if (!mac_enforce_system) 2545 return (0); 2546 2547 MAC_CHECK(check_kenv_set, cred, name, value); 2548 2549 return (error); 2550} 2551 2552int 2553mac_check_kenv_unset(struct ucred *cred, char *name) 2554{ 2555 int error; 2556 2557 if (!mac_enforce_system) 2558 return (0); 2559 2560 MAC_CHECK(check_kenv_unset, cred, name); 2561 2562 return (error); 2563} 2564 2565int 2566mac_check_kld_load(struct ucred *cred, struct vnode *vp) 2567{ 2568 int error; 2569 2570 ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2571 2572 if (!mac_enforce_kld) 2573 return (0); 2574 2575 MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2576 2577 return (error); 2578} 2579 2580int 2581mac_check_kld_stat(struct ucred *cred) 2582{ 2583 int error; 2584 2585 if (!mac_enforce_kld) 2586 return (0); 2587 2588 MAC_CHECK(check_kld_stat, cred); 2589 2590 return (error); 2591} 2592 2593int 2594mac_check_kld_unload(struct ucred *cred) 2595{ 2596 int error; 2597 2598 if (!mac_enforce_kld) 2599 return (0); 2600 2601 MAC_CHECK(check_kld_unload, cred); 2602 2603 return (error); 2604} 2605 2606int 2607mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2608{ 2609 int error; 2610 2611 if (!mac_enforce_fs) 2612 return (0); 2613 2614 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2615 2616 return (error); 2617} 2618 2619int 2620mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2621 void *data) 2622{ 2623 int error; 2624 2625 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2626 2627 if (!mac_enforce_pipe) 2628 return (0); 2629 2630 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2631 2632 return (error); 2633} 2634 2635int 2636mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2637{ 2638 int error; 2639 2640 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2641 2642 if (!mac_enforce_pipe) 2643 return (0); 2644 2645 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2646 2647 return (error); 2648} 2649 2650int 2651mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2652{ 2653 int error; 2654 2655 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2656 2657 if (!mac_enforce_pipe) 2658 return (0); 2659 2660 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2661 2662 return (error); 2663} 2664 2665static int 2666mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2667 struct label *newlabel) 2668{ 2669 int error; 2670 2671 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2672 2673 if (!mac_enforce_pipe) 2674 return (0); 2675 2676 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2677 2678 return (error); 2679} 2680 2681int 2682mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2683{ 2684 int error; 2685 2686 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2687 2688 if (!mac_enforce_pipe) 2689 return (0); 2690 2691 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2692 2693 return (error); 2694} 2695 2696int 2697mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2698{ 2699 int error; 2700 2701 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2702 2703 if (!mac_enforce_pipe) 2704 return (0); 2705 2706 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2707 2708 return (error); 2709} 2710 2711int 2712mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2713{ 2714 int error; 2715 2716 PROC_LOCK_ASSERT(proc, MA_OWNED); 2717 2718 if (!mac_enforce_process) 2719 return (0); 2720 2721 MAC_CHECK(check_proc_debug, cred, proc); 2722 2723 return (error); 2724} 2725 2726int 2727mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2728{ 2729 int error; 2730 2731 PROC_LOCK_ASSERT(proc, MA_OWNED); 2732 2733 if (!mac_enforce_process) 2734 return (0); 2735 2736 MAC_CHECK(check_proc_sched, cred, proc); 2737 2738 return (error); 2739} 2740 2741int 2742mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2743{ 2744 int error; 2745 2746 PROC_LOCK_ASSERT(proc, MA_OWNED); 2747 2748 if (!mac_enforce_process) 2749 return (0); 2750 2751 MAC_CHECK(check_proc_signal, cred, proc, signum); 2752 2753 return (error); 2754} 2755 2756int 2757mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2758 struct sockaddr *sockaddr) 2759{ 2760 int error; 2761 2762 if (!mac_enforce_socket) 2763 return (0); 2764 2765 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2766 sockaddr); 2767 2768 return (error); 2769} 2770 2771int 2772mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2773 struct sockaddr *sockaddr) 2774{ 2775 int error; 2776 2777 if (!mac_enforce_socket) 2778 return (0); 2779 2780 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2781 sockaddr); 2782 2783 return (error); 2784} 2785 2786int 2787mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2788{ 2789 struct label *label; 2790 int error; 2791 2792 if (!mac_enforce_socket) 2793 return (0); 2794 2795 label = mbuf_to_label(mbuf); 2796 2797 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2798 label); 2799 2800 return (error); 2801} 2802 2803int 2804mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2805{ 2806 int error; 2807 2808 if (!mac_enforce_socket) 2809 return (0); 2810 2811 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2812 return (error); 2813} 2814 2815int 2816mac_check_socket_receive(struct ucred *cred, struct socket *so) 2817{ 2818 int error; 2819 2820 if (!mac_enforce_socket) 2821 return (0); 2822 2823 MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2824 2825 return (error); 2826} 2827 2828static int 2829mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2830 struct label *newlabel) 2831{ 2832 int error; 2833 2834 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2835 newlabel); 2836 2837 return (error); 2838} 2839 2840int 2841mac_check_socket_send(struct ucred *cred, struct socket *so) 2842{ 2843 int error; 2844 2845 if (!mac_enforce_socket) 2846 return (0); 2847 2848 MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2849 2850 return (error); 2851} 2852 2853int 2854mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2855{ 2856 int error; 2857 2858 if (!mac_enforce_socket) 2859 return (0); 2860 2861 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2862 2863 return (error); 2864} 2865 2866int 2867mac_check_sysarch_ioperm(struct ucred *cred) 2868{ 2869 int error; 2870 2871 if (!mac_enforce_system) 2872 return (0); 2873 2874 MAC_CHECK(check_sysarch_ioperm, cred); 2875 return (error); 2876} 2877 2878int 2879mac_check_system_acct(struct ucred *cred, struct vnode *vp) 2880{ 2881 int error; 2882 2883 if (vp != NULL) { 2884 ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2885 } 2886 2887 if (!mac_enforce_system) 2888 return (0); 2889 2890 MAC_CHECK(check_system_acct, cred, vp, 2891 vp != NULL ? &vp->v_label : NULL); 2892 2893 return (error); 2894} 2895 2896int 2897mac_check_system_nfsd(struct ucred *cred) 2898{ 2899 int error; 2900 2901 if (!mac_enforce_system) 2902 return (0); 2903 2904 MAC_CHECK(check_system_nfsd, cred); 2905 2906 return (error); 2907} 2908 2909int 2910mac_check_system_reboot(struct ucred *cred, int howto) 2911{ 2912 int error; 2913 2914 if (!mac_enforce_system) 2915 return (0); 2916 2917 MAC_CHECK(check_system_reboot, cred, howto); 2918 2919 return (error); 2920} 2921 2922int 2923mac_check_system_settime(struct ucred *cred) 2924{ 2925 int error; 2926 2927 if (!mac_enforce_system) 2928 return (0); 2929 2930 MAC_CHECK(check_system_settime, cred); 2931 2932 return (error); 2933} 2934 2935int 2936mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2937{ 2938 int error; 2939 2940 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2941 2942 if (!mac_enforce_system) 2943 return (0); 2944 2945 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2946 return (error); 2947} 2948 2949int 2950mac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2951{ 2952 int error; 2953 2954 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2955 2956 if (!mac_enforce_system) 2957 return (0); 2958 2959 MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2960 return (error); 2961} 2962 2963int 2964mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2965 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2966{ 2967 int error; 2968 2969 /* 2970 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2971 * but since it's not exported from kern_sysctl.c, we can't. 2972 */ 2973 if (!mac_enforce_system) 2974 return (0); 2975 2976 MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2977 inkernel, new, newlen); 2978 2979 return (error); 2980} 2981 2982int 2983mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2984 struct ifnet *ifnet) 2985{ 2986 char *elements, *buffer; 2987 struct mac mac; 2988 int error; 2989 2990 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2991 if (error) 2992 return (error); 2993 2994 error = mac_check_structmac_consistent(&mac); 2995 if (error) 2996 return (error); 2997 2998 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2999 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3000 if (error) { 3001 free(elements, M_MACTEMP); 3002 return (error); 3003 } 3004 3005 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3006 error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3007 buffer, mac.m_buflen, M_WAITOK); 3008 if (error == 0) 3009 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3010 3011 free(buffer, M_MACTEMP); 3012 free(elements, M_MACTEMP); 3013 3014 return (error); 3015} 3016 3017int 3018mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3019 struct ifnet *ifnet) 3020{ 3021 struct label intlabel; 3022 struct mac mac; 3023 char *buffer; 3024 int error; 3025 3026 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3027 if (error) 3028 return (error); 3029 3030 error = mac_check_structmac_consistent(&mac); 3031 if (error) 3032 return (error); 3033 3034 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3035 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3036 if (error) { 3037 free(buffer, M_MACTEMP); 3038 return (error); 3039 } 3040 3041 mac_init_ifnet_label(&intlabel); 3042 error = mac_internalize_ifnet_label(&intlabel, buffer); 3043 free(buffer, M_MACTEMP); 3044 if (error) { 3045 mac_destroy_ifnet_label(&intlabel); 3046 return (error); 3047 } 3048 3049 /* 3050 * XXX: Note that this is a redundant privilege check, since 3051 * policies impose this check themselves if required by the 3052 * policy. Eventually, this should go away. 3053 */ 3054 error = suser_cred(cred, 0); 3055 if (error) { 3056 mac_destroy_ifnet_label(&intlabel); 3057 return (error); 3058 } 3059 3060 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3061 &intlabel); 3062 if (error) { 3063 mac_destroy_ifnet_label(&intlabel); 3064 return (error); 3065 } 3066 3067 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3068 3069 mac_destroy_ifnet_label(&intlabel); 3070 return (0); 3071} 3072 3073void 3074mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 3075{ 3076 3077 MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3078} 3079 3080void 3081mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3082 struct devfs_dirent *dd, struct devfs_dirent *de) 3083{ 3084 3085 MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3086 &de->de_label); 3087} 3088 3089void 3090mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3091 struct devfs_dirent *de) 3092{ 3093 3094 MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3095 &de->de_label); 3096} 3097 3098int 3099mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3100 struct mac *mac) 3101{ 3102 struct label intlabel; 3103 char *buffer; 3104 int error; 3105 3106 error = mac_check_structmac_consistent(mac); 3107 if (error) 3108 return (error); 3109 3110 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3111 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3112 if (error) { 3113 free(buffer, M_MACTEMP); 3114 return (error); 3115 } 3116 3117 mac_init_socket_label(&intlabel, M_WAITOK); 3118 error = mac_internalize_socket_label(&intlabel, buffer); 3119 free(buffer, M_MACTEMP); 3120 if (error) { 3121 mac_destroy_socket_label(&intlabel); 3122 return (error); 3123 } 3124 3125 mac_check_socket_relabel(cred, so, &intlabel); 3126 if (error) { 3127 mac_destroy_socket_label(&intlabel); 3128 return (error); 3129 } 3130 3131 mac_relabel_socket(cred, so, &intlabel); 3132 3133 mac_destroy_socket_label(&intlabel); 3134 return (0); 3135} 3136 3137int 3138mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3139{ 3140 int error; 3141 3142 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3143 3144 error = mac_check_pipe_relabel(cred, pipe, label); 3145 if (error) 3146 return (error); 3147 3148 mac_relabel_pipe(cred, pipe, label); 3149 3150 return (0); 3151} 3152 3153int 3154mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3155 struct mac *mac) 3156{ 3157 char *buffer, *elements; 3158 int error; 3159 3160 error = mac_check_structmac_consistent(mac); 3161 if (error) 3162 return (error); 3163 3164 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3165 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3166 if (error) { 3167 free(elements, M_MACTEMP); 3168 return (error); 3169 } 3170 3171 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3172 error = mac_externalize_socket_label(&so->so_label, elements, 3173 buffer, mac->m_buflen, M_WAITOK); 3174 if (error == 0) 3175 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3176 3177 free(buffer, M_MACTEMP); 3178 free(elements, M_MACTEMP); 3179 3180 return (error); 3181} 3182 3183int 3184mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3185 struct mac *mac) 3186{ 3187 char *elements, *buffer; 3188 int error; 3189 3190 error = mac_check_structmac_consistent(mac); 3191 if (error) 3192 return (error); 3193 3194 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3195 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3196 if (error) { 3197 free(elements, M_MACTEMP); 3198 return (error); 3199 } 3200 3201 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3202 error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3203 elements, buffer, mac->m_buflen, M_WAITOK); 3204 if (error == 0) 3205 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3206 3207 free(buffer, M_MACTEMP); 3208 free(elements, M_MACTEMP); 3209 3210 return (error); 3211} 3212 3213/* 3214 * Implementation of VOP_SETLABEL() that relies on extended attributes 3215 * to store label data. Can be referenced by filesystems supporting 3216 * extended attributes. 3217 */ 3218int 3219vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3220{ 3221 struct vnode *vp = ap->a_vp; 3222 struct label *intlabel = ap->a_label; 3223 int error; 3224 3225 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3226 3227 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3228 return (EOPNOTSUPP); 3229 3230 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3231 if (error) 3232 return (error); 3233 3234 mac_relabel_vnode(ap->a_cred, vp, intlabel); 3235 3236 return (0); 3237} 3238 3239static int 3240vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3241{ 3242 int error; 3243 3244 if (vp->v_mount == NULL) { 3245 /* printf("vn_setlabel: null v_mount\n"); */ 3246 if (vp->v_type != VNON) 3247 printf("vn_setlabel: null v_mount with non-VNON\n"); 3248 return (EBADF); 3249 } 3250 3251 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3252 return (EOPNOTSUPP); 3253 3254 /* 3255 * Multi-phase commit. First check the policies to confirm the 3256 * change is OK. Then commit via the filesystem. Finally, 3257 * update the actual vnode label. Question: maybe the filesystem 3258 * should update the vnode at the end as part of VOP_SETLABEL()? 3259 */ 3260 error = mac_check_vnode_relabel(cred, vp, intlabel); 3261 if (error) 3262 return (error); 3263 3264 /* 3265 * VADMIN provides the opportunity for the filesystem to make 3266 * decisions about who is and is not able to modify labels 3267 * and protections on files. This might not be right. We can't 3268 * assume VOP_SETLABEL() will do it, because we might implement 3269 * that as part of vop_stdsetlabel_ea(). 3270 */ 3271 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3272 if (error) 3273 return (error); 3274 3275 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3276 if (error) 3277 return (error); 3278 3279 return (0); 3280} 3281 3282int 3283__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3284{ 3285 char *elements, *buffer; 3286 struct mac mac; 3287 struct proc *tproc; 3288 struct ucred *tcred; 3289 int error; 3290 3291 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3292 if (error) 3293 return (error); 3294 3295 error = mac_check_structmac_consistent(&mac); 3296 if (error) 3297 return (error); 3298 3299 tproc = pfind(uap->pid); 3300 if (tproc == NULL) 3301 return (ESRCH); 3302 3303 tcred = NULL; /* Satisfy gcc. */ 3304 error = p_cansee(td, tproc); 3305 if (error == 0) 3306 tcred = crhold(tproc->p_ucred); 3307 PROC_UNLOCK(tproc); 3308 if (error) 3309 return (error); 3310 3311 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3312 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3313 if (error) { 3314 free(elements, M_MACTEMP); 3315 crfree(tcred); 3316 return (error); 3317 } 3318 3319 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3320 error = mac_externalize_cred_label(&tcred->cr_label, elements, 3321 buffer, mac.m_buflen, M_WAITOK); 3322 if (error == 0) 3323 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3324 3325 free(buffer, M_MACTEMP); 3326 free(elements, M_MACTEMP); 3327 crfree(tcred); 3328 return (error); 3329} 3330 3331/* 3332 * MPSAFE 3333 */ 3334int 3335__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3336{ 3337 char *elements, *buffer; 3338 struct mac mac; 3339 int error; 3340 3341 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3342 if (error) 3343 return (error); 3344 3345 error = mac_check_structmac_consistent(&mac); 3346 if (error) 3347 return (error); 3348 3349 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3350 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3351 if (error) { 3352 free(elements, M_MACTEMP); 3353 return (error); 3354 } 3355 3356 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3357 error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3358 elements, buffer, mac.m_buflen, M_WAITOK); 3359 if (error == 0) 3360 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3361 3362 free(buffer, M_MACTEMP); 3363 free(elements, M_MACTEMP); 3364 return (error); 3365} 3366 3367/* 3368 * MPSAFE 3369 */ 3370int 3371__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3372{ 3373 struct ucred *newcred, *oldcred; 3374 struct label intlabel; 3375 struct proc *p; 3376 struct mac mac; 3377 char *buffer; 3378 int error; 3379 3380 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3381 if (error) 3382 return (error); 3383 3384 error = mac_check_structmac_consistent(&mac); 3385 if (error) 3386 return (error); 3387 3388 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3389 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3390 if (error) { 3391 free(buffer, M_MACTEMP); 3392 return (error); 3393 } 3394 3395 mac_init_cred_label(&intlabel); 3396 error = mac_internalize_cred_label(&intlabel, buffer); 3397 free(buffer, M_MACTEMP); 3398 if (error) { 3399 mac_destroy_cred_label(&intlabel); 3400 return (error); 3401 } 3402 3403 newcred = crget(); 3404 3405 p = td->td_proc; 3406 PROC_LOCK(p); 3407 oldcred = p->p_ucred; 3408 3409 error = mac_check_cred_relabel(oldcred, &intlabel); 3410 if (error) { 3411 PROC_UNLOCK(p); 3412 crfree(newcred); 3413 goto out; 3414 } 3415 3416 setsugid(p); 3417 crcopy(newcred, oldcred); 3418 mac_relabel_cred(newcred, &intlabel); 3419 p->p_ucred = newcred; 3420 3421 /* 3422 * Grab additional reference for use while revoking mmaps, prior 3423 * to releasing the proc lock and sharing the cred. 3424 */ 3425 crhold(newcred); 3426 PROC_UNLOCK(p); 3427 3428 if (mac_enforce_vm) { 3429 mtx_lock(&Giant); 3430 mac_cred_mmapped_drop_perms(td, newcred); 3431 mtx_unlock(&Giant); 3432 } 3433 3434 crfree(newcred); /* Free revocation reference. */ 3435 crfree(oldcred); 3436 3437out: 3438 mac_destroy_cred_label(&intlabel); 3439 return (error); 3440} 3441 3442/* 3443 * MPSAFE 3444 */ 3445int 3446__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3447{ 3448 char *elements, *buffer; 3449 struct label intlabel; 3450 struct file *fp; 3451 struct mac mac; 3452 struct vnode *vp; 3453 struct pipe *pipe; 3454 short label_type; 3455 int error; 3456 3457 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3458 if (error) 3459 return (error); 3460 3461 error = mac_check_structmac_consistent(&mac); 3462 if (error) 3463 return (error); 3464 3465 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3466 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3467 if (error) { 3468 free(elements, M_MACTEMP); 3469 return (error); 3470 } 3471 3472 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3473 mtx_lock(&Giant); /* VFS */ 3474 error = fget(td, uap->fd, &fp); 3475 if (error) 3476 goto out; 3477 3478 label_type = fp->f_type; 3479 switch (fp->f_type) { 3480 case DTYPE_FIFO: 3481 case DTYPE_VNODE: 3482 vp = fp->f_vnode; 3483 3484 mac_init_vnode_label(&intlabel); 3485 3486 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3487 mac_copy_vnode_label(&vp->v_label, &intlabel); 3488 VOP_UNLOCK(vp, 0, td); 3489 3490 break; 3491 case DTYPE_PIPE: 3492 pipe = fp->f_data; 3493 3494 mac_init_pipe_label(&intlabel); 3495 3496 PIPE_LOCK(pipe); 3497 mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3498 PIPE_UNLOCK(pipe); 3499 break; 3500 default: 3501 error = EINVAL; 3502 fdrop(fp, td); 3503 goto out; 3504 } 3505 fdrop(fp, td); 3506 3507 switch (label_type) { 3508 case DTYPE_FIFO: 3509 case DTYPE_VNODE: 3510 if (error == 0) 3511 error = mac_externalize_vnode_label(&intlabel, 3512 elements, buffer, mac.m_buflen, M_WAITOK); 3513 mac_destroy_vnode_label(&intlabel); 3514 break; 3515 case DTYPE_PIPE: 3516 error = mac_externalize_pipe_label(&intlabel, elements, 3517 buffer, mac.m_buflen, M_WAITOK); 3518 mac_destroy_pipe_label(&intlabel); 3519 break; 3520 default: 3521 panic("__mac_get_fd: corrupted label_type"); 3522 } 3523 3524 if (error == 0) 3525 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3526 3527out: 3528 mtx_unlock(&Giant); /* VFS */ 3529 free(buffer, M_MACTEMP); 3530 free(elements, M_MACTEMP); 3531 3532 return (error); 3533} 3534 3535/* 3536 * MPSAFE 3537 */ 3538int 3539__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3540{ 3541 char *elements, *buffer; 3542 struct nameidata nd; 3543 struct label intlabel; 3544 struct mac mac; 3545 int error; 3546 3547 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3548 if (error) 3549 return (error); 3550 3551 error = mac_check_structmac_consistent(&mac); 3552 if (error) 3553 return (error); 3554 3555 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3556 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3557 if (error) { 3558 free(elements, M_MACTEMP); 3559 return (error); 3560 } 3561 3562 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3563 mtx_lock(&Giant); /* VFS */ 3564 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3565 td); 3566 error = namei(&nd); 3567 if (error) 3568 goto out; 3569 3570 mac_init_vnode_label(&intlabel); 3571 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3572 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3573 mac.m_buflen, M_WAITOK); 3574 3575 NDFREE(&nd, 0); 3576 mac_destroy_vnode_label(&intlabel); 3577 3578 if (error == 0) 3579 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3580 3581out: 3582 mtx_unlock(&Giant); /* VFS */ 3583 3584 free(buffer, M_MACTEMP); 3585 free(elements, M_MACTEMP); 3586 3587 return (error); 3588} 3589 3590/* 3591 * MPSAFE 3592 */ 3593int 3594__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3595{ 3596 char *elements, *buffer; 3597 struct nameidata nd; 3598 struct label intlabel; 3599 struct mac mac; 3600 int error; 3601 3602 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3603 if (error) 3604 return (error); 3605 3606 error = mac_check_structmac_consistent(&mac); 3607 if (error) 3608 return (error); 3609 3610 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3611 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3612 if (error) { 3613 free(elements, M_MACTEMP); 3614 return (error); 3615 } 3616 3617 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3618 mtx_lock(&Giant); /* VFS */ 3619 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3620 td); 3621 error = namei(&nd); 3622 if (error) 3623 goto out; 3624 3625 mac_init_vnode_label(&intlabel); 3626 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3627 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3628 mac.m_buflen, M_WAITOK); 3629 NDFREE(&nd, 0); 3630 mac_destroy_vnode_label(&intlabel); 3631 3632 if (error == 0) 3633 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3634 3635out: 3636 mtx_unlock(&Giant); /* VFS */ 3637 3638 free(buffer, M_MACTEMP); 3639 free(elements, M_MACTEMP); 3640 3641 return (error); 3642} 3643 3644/* 3645 * MPSAFE 3646 */ 3647int 3648__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3649{ 3650 struct label intlabel; 3651 struct pipe *pipe; 3652 struct file *fp; 3653 struct mount *mp; 3654 struct vnode *vp; 3655 struct mac mac; 3656 char *buffer; 3657 int error; 3658 3659 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3660 if (error) 3661 return (error); 3662 3663 error = mac_check_structmac_consistent(&mac); 3664 if (error) 3665 return (error); 3666 3667 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3668 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3669 if (error) { 3670 free(buffer, M_MACTEMP); 3671 return (error); 3672 } 3673 3674 mtx_lock(&Giant); /* VFS */ 3675 3676 error = fget(td, uap->fd, &fp); 3677 if (error) 3678 goto out; 3679 3680 switch (fp->f_type) { 3681 case DTYPE_FIFO: 3682 case DTYPE_VNODE: 3683 mac_init_vnode_label(&intlabel); 3684 error = mac_internalize_vnode_label(&intlabel, buffer); 3685 if (error) { 3686 mac_destroy_vnode_label(&intlabel); 3687 break; 3688 } 3689 3690 vp = fp->f_vnode; 3691 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3692 if (error != 0) { 3693 mac_destroy_vnode_label(&intlabel); 3694 break; 3695 } 3696 3697 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3698 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3699 VOP_UNLOCK(vp, 0, td); 3700 vn_finished_write(mp); 3701 3702 mac_destroy_vnode_label(&intlabel); 3703 break; 3704 3705 case DTYPE_PIPE: 3706 mac_init_pipe_label(&intlabel); 3707 error = mac_internalize_pipe_label(&intlabel, buffer); 3708 if (error == 0) { 3709 pipe = fp->f_data; 3710 PIPE_LOCK(pipe); 3711 error = mac_pipe_label_set(td->td_ucred, pipe, 3712 &intlabel); 3713 PIPE_UNLOCK(pipe); 3714 } 3715 3716 mac_destroy_pipe_label(&intlabel); 3717 break; 3718 3719 default: 3720 error = EINVAL; 3721 } 3722 3723 fdrop(fp, td); 3724out: 3725 mtx_unlock(&Giant); /* VFS */ 3726 3727 free(buffer, M_MACTEMP); 3728 3729 return (error); 3730} 3731 3732/* 3733 * MPSAFE 3734 */ 3735int 3736__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3737{ 3738 struct label intlabel; 3739 struct nameidata nd; 3740 struct mount *mp; 3741 struct mac mac; 3742 char *buffer; 3743 int error; 3744 3745 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3746 if (error) 3747 return (error); 3748 3749 error = mac_check_structmac_consistent(&mac); 3750 if (error) 3751 return (error); 3752 3753 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3754 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3755 if (error) { 3756 free(buffer, M_MACTEMP); 3757 return (error); 3758 } 3759 3760 mac_init_vnode_label(&intlabel); 3761 error = mac_internalize_vnode_label(&intlabel, buffer); 3762 free(buffer, M_MACTEMP); 3763 if (error) { 3764 mac_destroy_vnode_label(&intlabel); 3765 return (error); 3766 } 3767 3768 mtx_lock(&Giant); /* VFS */ 3769 3770 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3771 td); 3772 error = namei(&nd); 3773 if (error == 0) { 3774 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3775 if (error == 0) 3776 error = vn_setlabel(nd.ni_vp, &intlabel, 3777 td->td_ucred); 3778 vn_finished_write(mp); 3779 } 3780 3781 NDFREE(&nd, 0); 3782 mtx_unlock(&Giant); /* VFS */ 3783 mac_destroy_vnode_label(&intlabel); 3784 3785 return (error); 3786} 3787 3788/* 3789 * MPSAFE 3790 */ 3791int 3792__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3793{ 3794 struct label intlabel; 3795 struct nameidata nd; 3796 struct mount *mp; 3797 struct mac mac; 3798 char *buffer; 3799 int error; 3800 3801 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3802 if (error) 3803 return (error); 3804 3805 error = mac_check_structmac_consistent(&mac); 3806 if (error) 3807 return (error); 3808 3809 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3810 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3811 if (error) { 3812 free(buffer, M_MACTEMP); 3813 return (error); 3814 } 3815 3816 mac_init_vnode_label(&intlabel); 3817 error = mac_internalize_vnode_label(&intlabel, buffer); 3818 free(buffer, M_MACTEMP); 3819 if (error) { 3820 mac_destroy_vnode_label(&intlabel); 3821 return (error); 3822 } 3823 3824 mtx_lock(&Giant); /* VFS */ 3825 3826 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3827 td); 3828 error = namei(&nd); 3829 if (error == 0) { 3830 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3831 if (error == 0) 3832 error = vn_setlabel(nd.ni_vp, &intlabel, 3833 td->td_ucred); 3834 vn_finished_write(mp); 3835 } 3836 3837 NDFREE(&nd, 0); 3838 mtx_unlock(&Giant); /* VFS */ 3839 mac_destroy_vnode_label(&intlabel); 3840 3841 return (error); 3842} 3843 3844/* 3845 * MPSAFE 3846 */ 3847int 3848mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3849{ 3850 struct mac_policy_conf *mpc; 3851 char target[MAC_MAX_POLICY_NAME]; 3852 int entrycount, error; 3853 3854 error = copyinstr(uap->policy, target, sizeof(target), NULL); 3855 if (error) 3856 return (error); 3857 3858 error = ENOSYS; 3859 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { 3860 if (strcmp(mpc->mpc_name, target) == 0 && 3861 mpc->mpc_ops->mpo_syscall != NULL) { 3862 error = mpc->mpc_ops->mpo_syscall(td, 3863 uap->call, uap->arg); 3864 goto out; 3865 } 3866 } 3867 3868 if ((entrycount = mac_policy_list_conditional_busy()) != 0) { 3869 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3870 if (strcmp(mpc->mpc_name, target) == 0 && 3871 mpc->mpc_ops->mpo_syscall != NULL) { 3872 error = mpc->mpc_ops->mpo_syscall(td, 3873 uap->call, uap->arg); 3874 break; 3875 } 3876 } 3877 mac_policy_list_unbusy(); 3878 } 3879out: 3880 return (error); 3881} 3882 3883SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3884SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3885 3886#else /* !MAC */ 3887 3888int 3889__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3890{ 3891 3892 return (ENOSYS); 3893} 3894 3895int 3896__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3897{ 3898 3899 return (ENOSYS); 3900} 3901 3902int 3903__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3904{ 3905 3906 return (ENOSYS); 3907} 3908 3909int 3910__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3911{ 3912 3913 return (ENOSYS); 3914} 3915 3916int 3917__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3918{ 3919 3920 return (ENOSYS); 3921} 3922 3923int 3924__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3925{ 3926 3927 return (ENOSYS); 3928} 3929 3930int 3931__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3932{ 3933 3934 return (ENOSYS); 3935} 3936 3937int 3938__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3939{ 3940 3941 return (ENOSYS); 3942} 3943 3944int 3945__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3946{ 3947 3948 return (ENOSYS); 3949} 3950 3951int 3952mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3953{ 3954 3955 return (ENOSYS); 3956} 3957 3958#endif
| 713{ 714 715 /* Certain decision-making errors take top priority. */ 716 if (error1 == EDEADLK || error2 == EDEADLK) 717 return (EDEADLK); 718 719 /* Invalid arguments should be reported where possible. */ 720 if (error1 == EINVAL || error2 == EINVAL) 721 return (EINVAL); 722 723 /* Precedence goes to "visibility", with both process and file. */ 724 if (error1 == ESRCH || error2 == ESRCH) 725 return (ESRCH); 726 727 if (error1 == ENOENT || error2 == ENOENT) 728 return (ENOENT); 729 730 /* Precedence goes to DAC/MAC protections. */ 731 if (error1 == EACCES || error2 == EACCES) 732 return (EACCES); 733 734 /* Precedence goes to privilege. */ 735 if (error1 == EPERM || error2 == EPERM) 736 return (EPERM); 737 738 /* Precedence goes to error over success; otherwise, arbitrary. */ 739 if (error1 != 0) 740 return (error1); 741 return (error2); 742} 743 744static struct label * 745mbuf_to_label(struct mbuf *mbuf) 746{ 747 struct m_tag *tag; 748 struct label *label; 749 750 tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 751 label = (struct label *)(tag+1); 752 753 return (label); 754} 755 756static void 757mac_init_label(struct label *label) 758{ 759 760 bzero(label, sizeof(*label)); 761 label->l_flags = MAC_FLAG_INITIALIZED; 762} 763 764static void 765mac_destroy_label(struct label *label) 766{ 767 768 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 769 ("destroying uninitialized label")); 770 771 bzero(label, sizeof(*label)); 772 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 773} 774 775void 776mac_init_bpfdesc(struct bpf_d *bpf_d) 777{ 778 779 mac_init_label(&bpf_d->bd_label); 780 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 781 MAC_DEBUG_COUNTER_INC(&nmacbpfdescs); 782} 783 784static void 785mac_init_cred_label(struct label *label) 786{ 787 788 mac_init_label(label); 789 MAC_PERFORM(init_cred_label, label); 790 MAC_DEBUG_COUNTER_INC(&nmaccreds); 791} 792 793void 794mac_init_cred(struct ucred *cred) 795{ 796 797 mac_init_cred_label(&cred->cr_label); 798} 799 800void 801mac_init_devfsdirent(struct devfs_dirent *de) 802{ 803 804 mac_init_label(&de->de_label); 805 MAC_PERFORM(init_devfsdirent_label, &de->de_label); 806 MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents); 807} 808 809static void 810mac_init_ifnet_label(struct label *label) 811{ 812 813 mac_init_label(label); 814 MAC_PERFORM(init_ifnet_label, label); 815 MAC_DEBUG_COUNTER_INC(&nmacifnets); 816} 817 818void 819mac_init_ifnet(struct ifnet *ifp) 820{ 821 822 mac_init_ifnet_label(&ifp->if_label); 823} 824 825int 826mac_init_ipq(struct ipq *ipq, int flag) 827{ 828 int error; 829 830 mac_init_label(&ipq->ipq_label); 831 832 MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag); 833 if (error) { 834 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 835 mac_destroy_label(&ipq->ipq_label); 836 } else { 837 MAC_DEBUG_COUNTER_INC(&nmacipqs); 838 } 839 return (error); 840} 841 842int 843mac_init_mbuf_tag(struct m_tag *tag, int flag) 844{ 845 struct label *label; 846 int error; 847 848 label = (struct label *) (tag + 1); 849 mac_init_label(label); 850 851 MAC_CHECK(init_mbuf_label, label, flag); 852 if (error) { 853 MAC_PERFORM(destroy_mbuf_label, label); 854 mac_destroy_label(label); 855 } else { 856 MAC_DEBUG_COUNTER_INC(&nmacmbufs); 857 } 858 return (error); 859} 860 861int 862mac_init_mbuf(struct mbuf *m, int flag) 863{ 864 struct m_tag *tag; 865 int error; 866 867 M_ASSERTPKTHDR(m); 868 869#ifndef MAC_ALWAYS_LABEL_MBUF 870 /* 871 * If conditionally allocating mbuf labels, don't allocate unless 872 * they are required. 873 */ 874 if (!mac_labelmbufs) 875 return (0); 876#endif 877 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 878 flag); 879 if (tag == NULL) 880 return (ENOMEM); 881 error = mac_init_mbuf_tag(tag, flag); 882 if (error) { 883 m_tag_free(tag); 884 return (error); 885 } 886 m_tag_prepend(m, tag); 887 return (0); 888} 889 890void 891mac_init_mount(struct mount *mp) 892{ 893 894 mac_init_label(&mp->mnt_mntlabel); 895 mac_init_label(&mp->mnt_fslabel); 896 MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 897 MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 898 MAC_DEBUG_COUNTER_INC(&nmacmounts); 899} 900 901static void 902mac_init_pipe_label(struct label *label) 903{ 904 905 mac_init_label(label); 906 MAC_PERFORM(init_pipe_label, label); 907 MAC_DEBUG_COUNTER_INC(&nmacpipes); 908} 909 910void 911mac_init_pipe(struct pipe *pipe) 912{ 913 struct label *label; 914 915 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 916 pipe->pipe_label = label; 917 pipe->pipe_peer->pipe_label = label; 918 mac_init_pipe_label(label); 919} 920 921void 922mac_init_proc(struct proc *p) 923{ 924 925 mac_init_label(&p->p_label); 926 MAC_PERFORM(init_proc_label, &p->p_label); 927 MAC_DEBUG_COUNTER_INC(&nmacprocs); 928} 929 930static int 931mac_init_socket_label(struct label *label, int flag) 932{ 933 int error; 934 935 mac_init_label(label); 936 937 MAC_CHECK(init_socket_label, label, flag); 938 if (error) { 939 MAC_PERFORM(destroy_socket_label, label); 940 mac_destroy_label(label); 941 } else { 942 MAC_DEBUG_COUNTER_INC(&nmacsockets); 943 } 944 945 return (error); 946} 947 948static int 949mac_init_socket_peer_label(struct label *label, int flag) 950{ 951 int error; 952 953 mac_init_label(label); 954 955 MAC_CHECK(init_socket_peer_label, label, flag); 956 if (error) { 957 MAC_PERFORM(destroy_socket_label, label); 958 mac_destroy_label(label); 959 } 960 961 return (error); 962} 963 964int 965mac_init_socket(struct socket *socket, int flag) 966{ 967 int error; 968 969 error = mac_init_socket_label(&socket->so_label, flag); 970 if (error) 971 return (error); 972 973 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 974 if (error) 975 mac_destroy_socket_label(&socket->so_label); 976 977 return (error); 978} 979 980void 981mac_init_vnode_label(struct label *label) 982{ 983 984 mac_init_label(label); 985 MAC_PERFORM(init_vnode_label, label); 986 MAC_DEBUG_COUNTER_INC(&nmacvnodes); 987} 988 989void 990mac_init_vnode(struct vnode *vp) 991{ 992 993 mac_init_vnode_label(&vp->v_label); 994} 995 996void 997mac_destroy_bpfdesc(struct bpf_d *bpf_d) 998{ 999 1000 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1001 mac_destroy_label(&bpf_d->bd_label); 1002 MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs); 1003} 1004 1005static void 1006mac_destroy_cred_label(struct label *label) 1007{ 1008 1009 MAC_PERFORM(destroy_cred_label, label); 1010 mac_destroy_label(label); 1011 MAC_DEBUG_COUNTER_DEC(&nmaccreds); 1012} 1013 1014void 1015mac_destroy_cred(struct ucred *cred) 1016{ 1017 1018 mac_destroy_cred_label(&cred->cr_label); 1019} 1020 1021void 1022mac_destroy_devfsdirent(struct devfs_dirent *de) 1023{ 1024 1025 MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1026 mac_destroy_label(&de->de_label); 1027 MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents); 1028} 1029 1030static void 1031mac_destroy_ifnet_label(struct label *label) 1032{ 1033 1034 MAC_PERFORM(destroy_ifnet_label, label); 1035 mac_destroy_label(label); 1036 MAC_DEBUG_COUNTER_DEC(&nmacifnets); 1037} 1038 1039void 1040mac_destroy_ifnet(struct ifnet *ifp) 1041{ 1042 1043 mac_destroy_ifnet_label(&ifp->if_label); 1044} 1045 1046void 1047mac_destroy_ipq(struct ipq *ipq) 1048{ 1049 1050 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1051 mac_destroy_label(&ipq->ipq_label); 1052 MAC_DEBUG_COUNTER_DEC(&nmacipqs); 1053} 1054 1055void 1056mac_destroy_mbuf_tag(struct m_tag *tag) 1057{ 1058 struct label *label; 1059 1060 label = (struct label *)(tag+1); 1061 1062 MAC_PERFORM(destroy_mbuf_label, label); 1063 mac_destroy_label(label); 1064 MAC_DEBUG_COUNTER_DEC(&nmacmbufs); 1065} 1066 1067void 1068mac_destroy_mount(struct mount *mp) 1069{ 1070 1071 MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1072 MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1073 mac_destroy_label(&mp->mnt_fslabel); 1074 mac_destroy_label(&mp->mnt_mntlabel); 1075 MAC_DEBUG_COUNTER_DEC(&nmacmounts); 1076} 1077 1078static void 1079mac_destroy_pipe_label(struct label *label) 1080{ 1081 1082 MAC_PERFORM(destroy_pipe_label, label); 1083 mac_destroy_label(label); 1084 MAC_DEBUG_COUNTER_DEC(&nmacpipes); 1085} 1086 1087void 1088mac_destroy_pipe(struct pipe *pipe) 1089{ 1090 1091 mac_destroy_pipe_label(pipe->pipe_label); 1092 free(pipe->pipe_label, M_MACPIPELABEL); 1093} 1094 1095void 1096mac_destroy_proc(struct proc *p) 1097{ 1098 1099 MAC_PERFORM(destroy_proc_label, &p->p_label); 1100 mac_destroy_label(&p->p_label); 1101 MAC_DEBUG_COUNTER_DEC(&nmacprocs); 1102} 1103 1104static void 1105mac_destroy_socket_label(struct label *label) 1106{ 1107 1108 MAC_PERFORM(destroy_socket_label, label); 1109 mac_destroy_label(label); 1110 MAC_DEBUG_COUNTER_DEC(&nmacsockets); 1111} 1112 1113static void 1114mac_destroy_socket_peer_label(struct label *label) 1115{ 1116 1117 MAC_PERFORM(destroy_socket_peer_label, label); 1118 mac_destroy_label(label); 1119} 1120 1121void 1122mac_destroy_socket(struct socket *socket) 1123{ 1124 1125 mac_destroy_socket_label(&socket->so_label); 1126 mac_destroy_socket_peer_label(&socket->so_peerlabel); 1127} 1128 1129void 1130mac_destroy_vnode_label(struct label *label) 1131{ 1132 1133 MAC_PERFORM(destroy_vnode_label, label); 1134 mac_destroy_label(label); 1135 MAC_DEBUG_COUNTER_DEC(&nmacvnodes); 1136} 1137 1138void 1139mac_destroy_vnode(struct vnode *vp) 1140{ 1141 1142 mac_destroy_vnode_label(&vp->v_label); 1143} 1144 1145void 1146mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 1147{ 1148 struct label *src_label, *dest_label; 1149 1150 src_label = (struct label *)(src+1); 1151 dest_label = (struct label *)(dest+1); 1152 1153 /* 1154 * mac_init_mbuf_tag() is called on the target tag in 1155 * m_tag_copy(), so we don't need to call it here. 1156 */ 1157 MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 1158} 1159 1160static void 1161mac_copy_pipe_label(struct label *src, struct label *dest) 1162{ 1163 1164 MAC_PERFORM(copy_pipe_label, src, dest); 1165} 1166 1167void 1168mac_copy_vnode_label(struct label *src, struct label *dest) 1169{ 1170 1171 MAC_PERFORM(copy_vnode_label, src, dest); 1172} 1173 1174static int 1175mac_check_structmac_consistent(struct mac *mac) 1176{ 1177 1178 if (mac->m_buflen < 0 || 1179 mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1180 return (EINVAL); 1181 1182 return (0); 1183} 1184 1185static int 1186mac_externalize_cred_label(struct label *label, char *elements, 1187 char *outbuf, size_t outbuflen, int flags) 1188{ 1189 int error; 1190 1191 MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1192 1193 return (error); 1194} 1195 1196static int 1197mac_externalize_ifnet_label(struct label *label, char *elements, 1198 char *outbuf, size_t outbuflen, int flags) 1199{ 1200 int error; 1201 1202 MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1203 1204 return (error); 1205} 1206 1207static int 1208mac_externalize_pipe_label(struct label *label, char *elements, 1209 char *outbuf, size_t outbuflen, int flags) 1210{ 1211 int error; 1212 1213 MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1214 1215 return (error); 1216} 1217 1218static int 1219mac_externalize_socket_label(struct label *label, char *elements, 1220 char *outbuf, size_t outbuflen, int flags) 1221{ 1222 int error; 1223 1224 MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1225 1226 return (error); 1227} 1228 1229static int 1230mac_externalize_socket_peer_label(struct label *label, char *elements, 1231 char *outbuf, size_t outbuflen, int flags) 1232{ 1233 int error; 1234 1235 MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1236 1237 return (error); 1238} 1239 1240static int 1241mac_externalize_vnode_label(struct label *label, char *elements, 1242 char *outbuf, size_t outbuflen, int flags) 1243{ 1244 int error; 1245 1246 MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1247 1248 return (error); 1249} 1250 1251static int 1252mac_internalize_cred_label(struct label *label, char *string) 1253{ 1254 int error; 1255 1256 MAC_INTERNALIZE(cred_label, label, string); 1257 1258 return (error); 1259} 1260 1261static int 1262mac_internalize_ifnet_label(struct label *label, char *string) 1263{ 1264 int error; 1265 1266 MAC_INTERNALIZE(ifnet_label, label, string); 1267 1268 return (error); 1269} 1270 1271static int 1272mac_internalize_pipe_label(struct label *label, char *string) 1273{ 1274 int error; 1275 1276 MAC_INTERNALIZE(pipe_label, label, string); 1277 1278 return (error); 1279} 1280 1281static int 1282mac_internalize_socket_label(struct label *label, char *string) 1283{ 1284 int error; 1285 1286 MAC_INTERNALIZE(socket_label, label, string); 1287 1288 return (error); 1289} 1290 1291static int 1292mac_internalize_vnode_label(struct label *label, char *string) 1293{ 1294 int error; 1295 1296 MAC_INTERNALIZE(vnode_label, label, string); 1297 1298 return (error); 1299} 1300 1301/* 1302 * Initialize MAC label for the first kernel process, from which other 1303 * kernel processes and threads are spawned. 1304 */ 1305void 1306mac_create_proc0(struct ucred *cred) 1307{ 1308 1309 MAC_PERFORM(create_proc0, cred); 1310} 1311 1312/* 1313 * Initialize MAC label for the first userland process, from which other 1314 * userland processes and threads are spawned. 1315 */ 1316void 1317mac_create_proc1(struct ucred *cred) 1318{ 1319 1320 MAC_PERFORM(create_proc1, cred); 1321} 1322 1323void 1324mac_thread_userret(struct thread *td) 1325{ 1326 1327 MAC_PERFORM(thread_userret, td); 1328} 1329 1330/* 1331 * When a new process is created, its label must be initialized. Generally, 1332 * this involves inheritence from the parent process, modulo possible 1333 * deltas. This function allows that processing to take place. 1334 */ 1335void 1336mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1337{ 1338 1339 MAC_PERFORM(create_cred, parent_cred, child_cred); 1340} 1341 1342void 1343mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1344 struct vnode *vp) 1345{ 1346 1347 MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1348 &vp->v_label); 1349} 1350 1351void 1352mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1353 struct vnode *vp) 1354{ 1355 1356 MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1357 &de->de_label, vp, &vp->v_label); 1358} 1359 1360int 1361mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1362{ 1363 int error; 1364 1365 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1366 1367 MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1368 &vp->v_label); 1369 1370 return (error); 1371} 1372 1373void 1374mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1375{ 1376 1377 MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1378 &vp->v_label); 1379} 1380 1381int 1382mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1383 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1384{ 1385 int error; 1386 1387 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1388 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1389 1390 error = VOP_OPENEXTATTR(vp, cred, curthread); 1391 if (error == EOPNOTSUPP) { 1392 /* XXX: Optionally abort if transactions not supported. */ 1393 if (ea_warn_once == 0) { 1394 printf("Warning: transactions not supported " 1395 "in EA write.\n"); 1396 ea_warn_once = 1; 1397 } 1398 } else if (error) 1399 return (error); 1400 1401 MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1402 dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1403 1404 if (error) { 1405 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1406 return (error); 1407 } 1408 1409 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1410 1411 if (error == EOPNOTSUPP) 1412 error = 0; /* XXX */ 1413 1414 return (error); 1415} 1416 1417static int 1418mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1419 struct label *intlabel) 1420{ 1421 int error; 1422 1423 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1424 1425 error = VOP_OPENEXTATTR(vp, cred, curthread); 1426 if (error == EOPNOTSUPP) { 1427 /* XXX: Optionally abort if transactions not supported. */ 1428 if (ea_warn_once == 0) { 1429 printf("Warning: transactions not supported " 1430 "in EA write.\n"); 1431 ea_warn_once = 1; 1432 } 1433 } else if (error) 1434 return (error); 1435 1436 MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1437 1438 if (error) { 1439 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1440 return (error); 1441 } 1442 1443 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1444 1445 if (error == EOPNOTSUPP) 1446 error = 0; /* XXX */ 1447 1448 return (error); 1449} 1450 1451int 1452mac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1453 struct label *execlabelstorage) 1454{ 1455 struct mac mac; 1456 char *buffer; 1457 int error; 1458 1459 if (mac_p == NULL) 1460 return (0); 1461 1462 error = copyin(mac_p, &mac, sizeof(mac)); 1463 if (error) 1464 return (error); 1465 1466 error = mac_check_structmac_consistent(&mac); 1467 if (error) 1468 return (error); 1469 1470 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1471 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1472 if (error) { 1473 free(buffer, M_MACTEMP); 1474 return (error); 1475 } 1476 1477 mac_init_cred_label(execlabelstorage); 1478 error = mac_internalize_cred_label(execlabelstorage, buffer); 1479 free(buffer, M_MACTEMP); 1480 if (error) { 1481 mac_destroy_cred_label(execlabelstorage); 1482 return (error); 1483 } 1484 imgp->execlabel = execlabelstorage; 1485 return (0); 1486} 1487 1488void 1489mac_execve_exit(struct image_params *imgp) 1490{ 1491 if (imgp->execlabel != NULL) 1492 mac_destroy_cred_label(imgp->execlabel); 1493} 1494 1495void 1496mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1497 struct label *interpvnodelabel, struct image_params *imgp) 1498{ 1499 1500 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1501 1502 if (!mac_enforce_process && !mac_enforce_fs) 1503 return; 1504 1505 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1506 interpvnodelabel, imgp, imgp->execlabel); 1507} 1508 1509int 1510mac_execve_will_transition(struct ucred *old, struct vnode *vp, 1511 struct label *interpvnodelabel, struct image_params *imgp) 1512{ 1513 int result; 1514 1515 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1516 1517 if (!mac_enforce_process && !mac_enforce_fs) 1518 return (0); 1519 1520 result = 0; 1521 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1522 interpvnodelabel, imgp, imgp->execlabel); 1523 1524 return (result); 1525} 1526 1527int 1528mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1529{ 1530 int error; 1531 1532 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1533 1534 if (!mac_enforce_fs) 1535 return (0); 1536 1537 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1538 return (error); 1539} 1540 1541int 1542mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1543{ 1544 int error; 1545 1546 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1547 1548 if (!mac_enforce_fs) 1549 return (0); 1550 1551 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1552 return (error); 1553} 1554 1555int 1556mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1557{ 1558 int error; 1559 1560 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1561 1562 if (!mac_enforce_fs) 1563 return (0); 1564 1565 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1566 return (error); 1567} 1568 1569int 1570mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1571 struct componentname *cnp, struct vattr *vap) 1572{ 1573 int error; 1574 1575 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1576 1577 if (!mac_enforce_fs) 1578 return (0); 1579 1580 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1581 return (error); 1582} 1583 1584int 1585mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1586 struct componentname *cnp) 1587{ 1588 int error; 1589 1590 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1591 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1592 1593 if (!mac_enforce_fs) 1594 return (0); 1595 1596 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1597 &vp->v_label, cnp); 1598 return (error); 1599} 1600 1601int 1602mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1603 acl_type_t type) 1604{ 1605 int error; 1606 1607 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1608 1609 if (!mac_enforce_fs) 1610 return (0); 1611 1612 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1613 return (error); 1614} 1615 1616int 1617mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 1618 int attrnamespace, const char *name) 1619{ 1620 int error; 1621 1622 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr"); 1623 1624 if (!mac_enforce_fs) 1625 return (0); 1626 1627 MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label, 1628 attrnamespace, name); 1629 return (error); 1630} 1631 1632int 1633mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1634 struct image_params *imgp) 1635{ 1636 int error; 1637 1638 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1639 1640 if (!mac_enforce_process && !mac_enforce_fs) 1641 return (0); 1642 1643 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1644 imgp->execlabel); 1645 1646 return (error); 1647} 1648 1649int 1650mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1651{ 1652 int error; 1653 1654 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1655 1656 if (!mac_enforce_fs) 1657 return (0); 1658 1659 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1660 return (error); 1661} 1662 1663int 1664mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1665 int attrnamespace, const char *name, struct uio *uio) 1666{ 1667 int error; 1668 1669 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1670 1671 if (!mac_enforce_fs) 1672 return (0); 1673 1674 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1675 attrnamespace, name, uio); 1676 return (error); 1677} 1678 1679int 1680mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1681 struct vnode *vp, struct componentname *cnp) 1682{ 1683 int error; 1684 1685 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1686 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1687 1688 if (!mac_enforce_fs) 1689 return (0); 1690 1691 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1692 &vp->v_label, cnp); 1693 return (error); 1694} 1695 1696int 1697mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 1698 int attrnamespace) 1699{ 1700 int error; 1701 1702 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr"); 1703 1704 if (!mac_enforce_fs) 1705 return (0); 1706 1707 MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label, 1708 attrnamespace); 1709 return (error); 1710} 1711 1712int 1713mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1714 struct componentname *cnp) 1715{ 1716 int error; 1717 1718 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1719 1720 if (!mac_enforce_fs) 1721 return (0); 1722 1723 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1724 return (error); 1725} 1726 1727int 1728mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1729{ 1730 int error; 1731 1732 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1733 1734 if (!mac_enforce_fs || !mac_enforce_vm) 1735 return (0); 1736 1737 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1738 return (error); 1739} 1740 1741void 1742mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1743{ 1744 int result = *prot; 1745 1746 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1747 1748 if (!mac_enforce_fs || !mac_enforce_vm) 1749 return; 1750 1751 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1752 &result); 1753 1754 *prot = result; 1755} 1756 1757int 1758mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1759{ 1760 int error; 1761 1762 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1763 1764 if (!mac_enforce_fs || !mac_enforce_vm) 1765 return (0); 1766 1767 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1768 return (error); 1769} 1770 1771int 1772mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1773{ 1774 int error; 1775 1776 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1777 1778 if (!mac_enforce_fs) 1779 return (0); 1780 1781 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1782 return (error); 1783} 1784 1785int 1786mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1787 struct vnode *vp) 1788{ 1789 int error; 1790 1791 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1792 1793 if (!mac_enforce_fs) 1794 return (0); 1795 1796 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1797 &vp->v_label); 1798 1799 return (error); 1800} 1801 1802int 1803mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1804 struct vnode *vp) 1805{ 1806 int error; 1807 1808 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1809 1810 if (!mac_enforce_fs) 1811 return (0); 1812 1813 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1814 &vp->v_label); 1815 1816 return (error); 1817} 1818 1819int 1820mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1821{ 1822 int error; 1823 1824 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1825 1826 if (!mac_enforce_fs) 1827 return (0); 1828 1829 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1830 return (error); 1831} 1832 1833int 1834mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1835{ 1836 int error; 1837 1838 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1839 1840 if (!mac_enforce_fs) 1841 return (0); 1842 1843 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1844 return (error); 1845} 1846 1847static int 1848mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1849 struct label *newlabel) 1850{ 1851 int error; 1852 1853 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1854 1855 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1856 1857 return (error); 1858} 1859 1860int 1861mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1862 struct vnode *vp, struct componentname *cnp) 1863{ 1864 int error; 1865 1866 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1867 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1868 1869 if (!mac_enforce_fs) 1870 return (0); 1871 1872 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1873 &vp->v_label, cnp); 1874 return (error); 1875} 1876 1877int 1878mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1879 struct vnode *vp, int samedir, struct componentname *cnp) 1880{ 1881 int error; 1882 1883 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1884 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1885 1886 if (!mac_enforce_fs) 1887 return (0); 1888 1889 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1890 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1891 return (error); 1892} 1893 1894int 1895mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1896{ 1897 int error; 1898 1899 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1900 1901 if (!mac_enforce_fs) 1902 return (0); 1903 1904 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1905 return (error); 1906} 1907 1908int 1909mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1910 struct acl *acl) 1911{ 1912 int error; 1913 1914 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1915 1916 if (!mac_enforce_fs) 1917 return (0); 1918 1919 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1920 return (error); 1921} 1922 1923int 1924mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1925 int attrnamespace, const char *name, struct uio *uio) 1926{ 1927 int error; 1928 1929 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1930 1931 if (!mac_enforce_fs) 1932 return (0); 1933 1934 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1935 attrnamespace, name, uio); 1936 return (error); 1937} 1938 1939int 1940mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1941{ 1942 int error; 1943 1944 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1945 1946 if (!mac_enforce_fs) 1947 return (0); 1948 1949 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1950 return (error); 1951} 1952 1953int 1954mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1955{ 1956 int error; 1957 1958 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1959 1960 if (!mac_enforce_fs) 1961 return (0); 1962 1963 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1964 return (error); 1965} 1966 1967int 1968mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1969 gid_t gid) 1970{ 1971 int error; 1972 1973 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1974 1975 if (!mac_enforce_fs) 1976 return (0); 1977 1978 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1979 return (error); 1980} 1981 1982int 1983mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1984 struct timespec atime, struct timespec mtime) 1985{ 1986 int error; 1987 1988 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1989 1990 if (!mac_enforce_fs) 1991 return (0); 1992 1993 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1994 mtime); 1995 return (error); 1996} 1997 1998int 1999mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2000 struct vnode *vp) 2001{ 2002 int error; 2003 2004 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2005 2006 if (!mac_enforce_fs) 2007 return (0); 2008 2009 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2010 &vp->v_label); 2011 return (error); 2012} 2013 2014int 2015mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2016 struct vnode *vp) 2017{ 2018 int error; 2019 2020 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2021 2022 if (!mac_enforce_fs) 2023 return (0); 2024 2025 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2026 &vp->v_label); 2027 2028 return (error); 2029} 2030 2031/* 2032 * When relabeling a process, call out to the policies for the maximum 2033 * permission allowed for each object type we know about in its 2034 * memory space, and revoke access (in the least surprising ways we 2035 * know) when necessary. The process lock is not held here. 2036 */ 2037void 2038mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2039{ 2040 2041 /* XXX freeze all other threads */ 2042 mac_cred_mmapped_drop_perms_recurse(td, cred, 2043 &td->td_proc->p_vmspace->vm_map); 2044 /* XXX allow other threads to continue */ 2045} 2046 2047static __inline const char * 2048prot2str(vm_prot_t prot) 2049{ 2050 2051 switch (prot & VM_PROT_ALL) { 2052 case VM_PROT_READ: 2053 return ("r--"); 2054 case VM_PROT_READ | VM_PROT_WRITE: 2055 return ("rw-"); 2056 case VM_PROT_READ | VM_PROT_EXECUTE: 2057 return ("r-x"); 2058 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2059 return ("rwx"); 2060 case VM_PROT_WRITE: 2061 return ("-w-"); 2062 case VM_PROT_EXECUTE: 2063 return ("--x"); 2064 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2065 return ("-wx"); 2066 default: 2067 return ("---"); 2068 } 2069} 2070 2071static void 2072mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2073 struct vm_map *map) 2074{ 2075 struct vm_map_entry *vme; 2076 int result; 2077 vm_prot_t revokeperms; 2078 vm_object_t object; 2079 vm_ooffset_t offset; 2080 struct vnode *vp; 2081 2082 if (!mac_mmap_revocation) 2083 return; 2084 2085 vm_map_lock_read(map); 2086 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2087 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2088 mac_cred_mmapped_drop_perms_recurse(td, cred, 2089 vme->object.sub_map); 2090 continue; 2091 } 2092 /* 2093 * Skip over entries that obviously are not shared. 2094 */ 2095 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2096 !vme->max_protection) 2097 continue; 2098 /* 2099 * Drill down to the deepest backing object. 2100 */ 2101 offset = vme->offset; 2102 object = vme->object.vm_object; 2103 if (object == NULL) 2104 continue; 2105 while (object->backing_object != NULL) { 2106 object = object->backing_object; 2107 offset += object->backing_object_offset; 2108 } 2109 /* 2110 * At the moment, vm_maps and objects aren't considered 2111 * by the MAC system, so only things with backing by a 2112 * normal object (read: vnodes) are checked. 2113 */ 2114 if (object->type != OBJT_VNODE) 2115 continue; 2116 vp = (struct vnode *)object->handle; 2117 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2118 result = vme->max_protection; 2119 mac_check_vnode_mmap_downgrade(cred, vp, &result); 2120 VOP_UNLOCK(vp, 0, td); 2121 /* 2122 * Find out what maximum protection we may be allowing 2123 * now but a policy needs to get removed. 2124 */ 2125 revokeperms = vme->max_protection & ~result; 2126 if (!revokeperms) 2127 continue; 2128 printf("pid %ld: revoking %s perms from %#lx:%ld " 2129 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2130 prot2str(revokeperms), (u_long)vme->start, 2131 (long)(vme->end - vme->start), 2132 prot2str(vme->max_protection), prot2str(vme->protection)); 2133 vm_map_lock_upgrade(map); 2134 /* 2135 * This is the really simple case: if a map has more 2136 * max_protection than is allowed, but it's not being 2137 * actually used (that is, the current protection is 2138 * still allowed), we can just wipe it out and do 2139 * nothing more. 2140 */ 2141 if ((vme->protection & revokeperms) == 0) { 2142 vme->max_protection -= revokeperms; 2143 } else { 2144 if (revokeperms & VM_PROT_WRITE) { 2145 /* 2146 * In the more complicated case, flush out all 2147 * pending changes to the object then turn it 2148 * copy-on-write. 2149 */ 2150 vm_object_reference(object); 2151 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2152 VM_OBJECT_LOCK(object); 2153 vm_object_page_clean(object, 2154 OFF_TO_IDX(offset), 2155 OFF_TO_IDX(offset + vme->end - vme->start + 2156 PAGE_MASK), 2157 OBJPC_SYNC); 2158 VM_OBJECT_UNLOCK(object); 2159 VOP_UNLOCK(vp, 0, td); 2160 vm_object_deallocate(object); 2161 /* 2162 * Why bother if there's no read permissions 2163 * anymore? For the rest, we need to leave 2164 * the write permissions on for COW, or 2165 * remove them entirely if configured to. 2166 */ 2167 if (!mac_mmap_revocation_via_cow) { 2168 vme->max_protection &= ~VM_PROT_WRITE; 2169 vme->protection &= ~VM_PROT_WRITE; 2170 } if ((revokeperms & VM_PROT_READ) == 0) 2171 vme->eflags |= MAP_ENTRY_COW | 2172 MAP_ENTRY_NEEDS_COPY; 2173 } 2174 if (revokeperms & VM_PROT_EXECUTE) { 2175 vme->max_protection &= ~VM_PROT_EXECUTE; 2176 vme->protection &= ~VM_PROT_EXECUTE; 2177 } 2178 if (revokeperms & VM_PROT_READ) { 2179 vme->max_protection = 0; 2180 vme->protection = 0; 2181 } 2182 pmap_protect(map->pmap, vme->start, vme->end, 2183 vme->protection & ~revokeperms); 2184 vm_map_simplify_entry(map, vme); 2185 } 2186 vm_map_lock_downgrade(map); 2187 } 2188 vm_map_unlock_read(map); 2189} 2190 2191/* 2192 * When the subject's label changes, it may require revocation of privilege 2193 * to mapped objects. This can't be done on-the-fly later with a unified 2194 * buffer cache. 2195 */ 2196static void 2197mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2198{ 2199 2200 MAC_PERFORM(relabel_cred, cred, newlabel); 2201} 2202 2203void 2204mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2205{ 2206 2207 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2208} 2209 2210void 2211mac_create_ifnet(struct ifnet *ifnet) 2212{ 2213 2214 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2215} 2216 2217void 2218mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2219{ 2220 2221 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2222} 2223 2224void 2225mac_create_socket(struct ucred *cred, struct socket *socket) 2226{ 2227 2228 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2229} 2230 2231void 2232mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2233{ 2234 2235 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2236} 2237 2238void 2239mac_create_socket_from_socket(struct socket *oldsocket, 2240 struct socket *newsocket) 2241{ 2242 2243 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2244 newsocket, &newsocket->so_label); 2245} 2246 2247static void 2248mac_relabel_socket(struct ucred *cred, struct socket *socket, 2249 struct label *newlabel) 2250{ 2251 2252 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2253} 2254 2255static void 2256mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2257{ 2258 2259 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2260} 2261 2262void 2263mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2264{ 2265 struct label *label; 2266 2267 label = mbuf_to_label(mbuf); 2268 2269 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2270 &socket->so_peerlabel); 2271} 2272 2273void 2274mac_set_socket_peer_from_socket(struct socket *oldsocket, 2275 struct socket *newsocket) 2276{ 2277 2278 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2279 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2280} 2281 2282void 2283mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2284{ 2285 struct label *label; 2286 2287 label = mbuf_to_label(datagram); 2288 2289 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2290 datagram, label); 2291} 2292 2293void 2294mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2295{ 2296 struct label *datagramlabel, *fragmentlabel; 2297 2298 datagramlabel = mbuf_to_label(datagram); 2299 fragmentlabel = mbuf_to_label(fragment); 2300 2301 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2302 fragmentlabel); 2303} 2304 2305void 2306mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2307{ 2308 struct label *label; 2309 2310 label = mbuf_to_label(fragment); 2311 2312 MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2313} 2314 2315void 2316mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2317{ 2318 struct label *oldmbuflabel, *newmbuflabel; 2319 2320 oldmbuflabel = mbuf_to_label(oldmbuf); 2321 newmbuflabel = mbuf_to_label(newmbuf); 2322 2323 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2324 newmbuflabel); 2325} 2326 2327void 2328mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2329{ 2330 struct label *label; 2331 2332 label = mbuf_to_label(mbuf); 2333 2334 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2335 label); 2336} 2337 2338void 2339mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2340{ 2341 struct label *label; 2342 2343 label = mbuf_to_label(mbuf); 2344 2345 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2346 label); 2347} 2348 2349void 2350mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2351{ 2352 struct label *label; 2353 2354 label = mbuf_to_label(mbuf); 2355 2356 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2357 label); 2358} 2359 2360void 2361mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2362 struct mbuf *newmbuf) 2363{ 2364 struct label *oldmbuflabel, *newmbuflabel; 2365 2366 oldmbuflabel = mbuf_to_label(oldmbuf); 2367 newmbuflabel = mbuf_to_label(newmbuf); 2368 2369 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2370 ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2371} 2372 2373void 2374mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2375{ 2376 struct label *oldmbuflabel, *newmbuflabel; 2377 2378 oldmbuflabel = mbuf_to_label(oldmbuf); 2379 newmbuflabel = mbuf_to_label(newmbuf); 2380 2381 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2382 newmbuflabel); 2383} 2384 2385int 2386mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2387{ 2388 struct label *label; 2389 int result; 2390 2391 label = mbuf_to_label(fragment); 2392 2393 result = 1; 2394 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2395 &ipq->ipq_label); 2396 2397 return (result); 2398} 2399 2400void 2401mac_reflect_mbuf_icmp(struct mbuf *m) 2402{ 2403 struct label *label; 2404 2405 label = mbuf_to_label(m); 2406 2407 MAC_PERFORM(reflect_mbuf_icmp, m, label); 2408} 2409void 2410mac_reflect_mbuf_tcp(struct mbuf *m) 2411{ 2412 struct label *label; 2413 2414 label = mbuf_to_label(m); 2415 2416 MAC_PERFORM(reflect_mbuf_tcp, m, label); 2417} 2418 2419void 2420mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2421{ 2422 struct label *label; 2423 2424 label = mbuf_to_label(fragment); 2425 2426 MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2427} 2428 2429void 2430mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2431{ 2432 struct label *label; 2433 2434 label = mbuf_to_label(mbuf); 2435 2436 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2437 label); 2438} 2439 2440void 2441mac_create_mount(struct ucred *cred, struct mount *mp) 2442{ 2443 2444 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2445 &mp->mnt_fslabel); 2446} 2447 2448void 2449mac_create_root_mount(struct ucred *cred, struct mount *mp) 2450{ 2451 2452 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2453 &mp->mnt_fslabel); 2454} 2455 2456int 2457mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2458{ 2459 int error; 2460 2461 if (!mac_enforce_network) 2462 return (0); 2463 2464 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2465 &ifnet->if_label); 2466 2467 return (error); 2468} 2469 2470static int 2471mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2472{ 2473 int error; 2474 2475 MAC_CHECK(check_cred_relabel, cred, newlabel); 2476 2477 return (error); 2478} 2479 2480int 2481mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2482{ 2483 int error; 2484 2485 if (!mac_enforce_process) 2486 return (0); 2487 2488 MAC_CHECK(check_cred_visible, u1, u2); 2489 2490 return (error); 2491} 2492 2493int 2494mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2495{ 2496 struct label *label; 2497 int error; 2498 2499 M_ASSERTPKTHDR(mbuf); 2500 2501 if (!mac_enforce_network) 2502 return (0); 2503 2504 label = mbuf_to_label(mbuf); 2505 2506 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2507 label); 2508 2509 return (error); 2510} 2511 2512int 2513mac_check_kenv_dump(struct ucred *cred) 2514{ 2515 int error; 2516 2517 if (!mac_enforce_system) 2518 return (0); 2519 2520 MAC_CHECK(check_kenv_dump, cred); 2521 2522 return (error); 2523} 2524 2525int 2526mac_check_kenv_get(struct ucred *cred, char *name) 2527{ 2528 int error; 2529 2530 if (!mac_enforce_system) 2531 return (0); 2532 2533 MAC_CHECK(check_kenv_get, cred, name); 2534 2535 return (error); 2536} 2537 2538int 2539mac_check_kenv_set(struct ucred *cred, char *name, char *value) 2540{ 2541 int error; 2542 2543 if (!mac_enforce_system) 2544 return (0); 2545 2546 MAC_CHECK(check_kenv_set, cred, name, value); 2547 2548 return (error); 2549} 2550 2551int 2552mac_check_kenv_unset(struct ucred *cred, char *name) 2553{ 2554 int error; 2555 2556 if (!mac_enforce_system) 2557 return (0); 2558 2559 MAC_CHECK(check_kenv_unset, cred, name); 2560 2561 return (error); 2562} 2563 2564int 2565mac_check_kld_load(struct ucred *cred, struct vnode *vp) 2566{ 2567 int error; 2568 2569 ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2570 2571 if (!mac_enforce_kld) 2572 return (0); 2573 2574 MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2575 2576 return (error); 2577} 2578 2579int 2580mac_check_kld_stat(struct ucred *cred) 2581{ 2582 int error; 2583 2584 if (!mac_enforce_kld) 2585 return (0); 2586 2587 MAC_CHECK(check_kld_stat, cred); 2588 2589 return (error); 2590} 2591 2592int 2593mac_check_kld_unload(struct ucred *cred) 2594{ 2595 int error; 2596 2597 if (!mac_enforce_kld) 2598 return (0); 2599 2600 MAC_CHECK(check_kld_unload, cred); 2601 2602 return (error); 2603} 2604 2605int 2606mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2607{ 2608 int error; 2609 2610 if (!mac_enforce_fs) 2611 return (0); 2612 2613 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2614 2615 return (error); 2616} 2617 2618int 2619mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2620 void *data) 2621{ 2622 int error; 2623 2624 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2625 2626 if (!mac_enforce_pipe) 2627 return (0); 2628 2629 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2630 2631 return (error); 2632} 2633 2634int 2635mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2636{ 2637 int error; 2638 2639 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2640 2641 if (!mac_enforce_pipe) 2642 return (0); 2643 2644 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2645 2646 return (error); 2647} 2648 2649int 2650mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2651{ 2652 int error; 2653 2654 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2655 2656 if (!mac_enforce_pipe) 2657 return (0); 2658 2659 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2660 2661 return (error); 2662} 2663 2664static int 2665mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2666 struct label *newlabel) 2667{ 2668 int error; 2669 2670 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2671 2672 if (!mac_enforce_pipe) 2673 return (0); 2674 2675 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2676 2677 return (error); 2678} 2679 2680int 2681mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2682{ 2683 int error; 2684 2685 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2686 2687 if (!mac_enforce_pipe) 2688 return (0); 2689 2690 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2691 2692 return (error); 2693} 2694 2695int 2696mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2697{ 2698 int error; 2699 2700 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2701 2702 if (!mac_enforce_pipe) 2703 return (0); 2704 2705 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2706 2707 return (error); 2708} 2709 2710int 2711mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2712{ 2713 int error; 2714 2715 PROC_LOCK_ASSERT(proc, MA_OWNED); 2716 2717 if (!mac_enforce_process) 2718 return (0); 2719 2720 MAC_CHECK(check_proc_debug, cred, proc); 2721 2722 return (error); 2723} 2724 2725int 2726mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2727{ 2728 int error; 2729 2730 PROC_LOCK_ASSERT(proc, MA_OWNED); 2731 2732 if (!mac_enforce_process) 2733 return (0); 2734 2735 MAC_CHECK(check_proc_sched, cred, proc); 2736 2737 return (error); 2738} 2739 2740int 2741mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2742{ 2743 int error; 2744 2745 PROC_LOCK_ASSERT(proc, MA_OWNED); 2746 2747 if (!mac_enforce_process) 2748 return (0); 2749 2750 MAC_CHECK(check_proc_signal, cred, proc, signum); 2751 2752 return (error); 2753} 2754 2755int 2756mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2757 struct sockaddr *sockaddr) 2758{ 2759 int error; 2760 2761 if (!mac_enforce_socket) 2762 return (0); 2763 2764 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2765 sockaddr); 2766 2767 return (error); 2768} 2769 2770int 2771mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2772 struct sockaddr *sockaddr) 2773{ 2774 int error; 2775 2776 if (!mac_enforce_socket) 2777 return (0); 2778 2779 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2780 sockaddr); 2781 2782 return (error); 2783} 2784 2785int 2786mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2787{ 2788 struct label *label; 2789 int error; 2790 2791 if (!mac_enforce_socket) 2792 return (0); 2793 2794 label = mbuf_to_label(mbuf); 2795 2796 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2797 label); 2798 2799 return (error); 2800} 2801 2802int 2803mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2804{ 2805 int error; 2806 2807 if (!mac_enforce_socket) 2808 return (0); 2809 2810 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2811 return (error); 2812} 2813 2814int 2815mac_check_socket_receive(struct ucred *cred, struct socket *so) 2816{ 2817 int error; 2818 2819 if (!mac_enforce_socket) 2820 return (0); 2821 2822 MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2823 2824 return (error); 2825} 2826 2827static int 2828mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2829 struct label *newlabel) 2830{ 2831 int error; 2832 2833 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2834 newlabel); 2835 2836 return (error); 2837} 2838 2839int 2840mac_check_socket_send(struct ucred *cred, struct socket *so) 2841{ 2842 int error; 2843 2844 if (!mac_enforce_socket) 2845 return (0); 2846 2847 MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2848 2849 return (error); 2850} 2851 2852int 2853mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2854{ 2855 int error; 2856 2857 if (!mac_enforce_socket) 2858 return (0); 2859 2860 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2861 2862 return (error); 2863} 2864 2865int 2866mac_check_sysarch_ioperm(struct ucred *cred) 2867{ 2868 int error; 2869 2870 if (!mac_enforce_system) 2871 return (0); 2872 2873 MAC_CHECK(check_sysarch_ioperm, cred); 2874 return (error); 2875} 2876 2877int 2878mac_check_system_acct(struct ucred *cred, struct vnode *vp) 2879{ 2880 int error; 2881 2882 if (vp != NULL) { 2883 ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2884 } 2885 2886 if (!mac_enforce_system) 2887 return (0); 2888 2889 MAC_CHECK(check_system_acct, cred, vp, 2890 vp != NULL ? &vp->v_label : NULL); 2891 2892 return (error); 2893} 2894 2895int 2896mac_check_system_nfsd(struct ucred *cred) 2897{ 2898 int error; 2899 2900 if (!mac_enforce_system) 2901 return (0); 2902 2903 MAC_CHECK(check_system_nfsd, cred); 2904 2905 return (error); 2906} 2907 2908int 2909mac_check_system_reboot(struct ucred *cred, int howto) 2910{ 2911 int error; 2912 2913 if (!mac_enforce_system) 2914 return (0); 2915 2916 MAC_CHECK(check_system_reboot, cred, howto); 2917 2918 return (error); 2919} 2920 2921int 2922mac_check_system_settime(struct ucred *cred) 2923{ 2924 int error; 2925 2926 if (!mac_enforce_system) 2927 return (0); 2928 2929 MAC_CHECK(check_system_settime, cred); 2930 2931 return (error); 2932} 2933 2934int 2935mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2936{ 2937 int error; 2938 2939 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2940 2941 if (!mac_enforce_system) 2942 return (0); 2943 2944 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2945 return (error); 2946} 2947 2948int 2949mac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2950{ 2951 int error; 2952 2953 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2954 2955 if (!mac_enforce_system) 2956 return (0); 2957 2958 MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2959 return (error); 2960} 2961 2962int 2963mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2964 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2965{ 2966 int error; 2967 2968 /* 2969 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2970 * but since it's not exported from kern_sysctl.c, we can't. 2971 */ 2972 if (!mac_enforce_system) 2973 return (0); 2974 2975 MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2976 inkernel, new, newlen); 2977 2978 return (error); 2979} 2980 2981int 2982mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2983 struct ifnet *ifnet) 2984{ 2985 char *elements, *buffer; 2986 struct mac mac; 2987 int error; 2988 2989 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2990 if (error) 2991 return (error); 2992 2993 error = mac_check_structmac_consistent(&mac); 2994 if (error) 2995 return (error); 2996 2997 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2998 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2999 if (error) { 3000 free(elements, M_MACTEMP); 3001 return (error); 3002 } 3003 3004 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3005 error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3006 buffer, mac.m_buflen, M_WAITOK); 3007 if (error == 0) 3008 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3009 3010 free(buffer, M_MACTEMP); 3011 free(elements, M_MACTEMP); 3012 3013 return (error); 3014} 3015 3016int 3017mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3018 struct ifnet *ifnet) 3019{ 3020 struct label intlabel; 3021 struct mac mac; 3022 char *buffer; 3023 int error; 3024 3025 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3026 if (error) 3027 return (error); 3028 3029 error = mac_check_structmac_consistent(&mac); 3030 if (error) 3031 return (error); 3032 3033 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3034 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3035 if (error) { 3036 free(buffer, M_MACTEMP); 3037 return (error); 3038 } 3039 3040 mac_init_ifnet_label(&intlabel); 3041 error = mac_internalize_ifnet_label(&intlabel, buffer); 3042 free(buffer, M_MACTEMP); 3043 if (error) { 3044 mac_destroy_ifnet_label(&intlabel); 3045 return (error); 3046 } 3047 3048 /* 3049 * XXX: Note that this is a redundant privilege check, since 3050 * policies impose this check themselves if required by the 3051 * policy. Eventually, this should go away. 3052 */ 3053 error = suser_cred(cred, 0); 3054 if (error) { 3055 mac_destroy_ifnet_label(&intlabel); 3056 return (error); 3057 } 3058 3059 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3060 &intlabel); 3061 if (error) { 3062 mac_destroy_ifnet_label(&intlabel); 3063 return (error); 3064 } 3065 3066 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3067 3068 mac_destroy_ifnet_label(&intlabel); 3069 return (0); 3070} 3071 3072void 3073mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 3074{ 3075 3076 MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3077} 3078 3079void 3080mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3081 struct devfs_dirent *dd, struct devfs_dirent *de) 3082{ 3083 3084 MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3085 &de->de_label); 3086} 3087 3088void 3089mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3090 struct devfs_dirent *de) 3091{ 3092 3093 MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3094 &de->de_label); 3095} 3096 3097int 3098mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3099 struct mac *mac) 3100{ 3101 struct label intlabel; 3102 char *buffer; 3103 int error; 3104 3105 error = mac_check_structmac_consistent(mac); 3106 if (error) 3107 return (error); 3108 3109 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3110 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3111 if (error) { 3112 free(buffer, M_MACTEMP); 3113 return (error); 3114 } 3115 3116 mac_init_socket_label(&intlabel, M_WAITOK); 3117 error = mac_internalize_socket_label(&intlabel, buffer); 3118 free(buffer, M_MACTEMP); 3119 if (error) { 3120 mac_destroy_socket_label(&intlabel); 3121 return (error); 3122 } 3123 3124 mac_check_socket_relabel(cred, so, &intlabel); 3125 if (error) { 3126 mac_destroy_socket_label(&intlabel); 3127 return (error); 3128 } 3129 3130 mac_relabel_socket(cred, so, &intlabel); 3131 3132 mac_destroy_socket_label(&intlabel); 3133 return (0); 3134} 3135 3136int 3137mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3138{ 3139 int error; 3140 3141 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3142 3143 error = mac_check_pipe_relabel(cred, pipe, label); 3144 if (error) 3145 return (error); 3146 3147 mac_relabel_pipe(cred, pipe, label); 3148 3149 return (0); 3150} 3151 3152int 3153mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3154 struct mac *mac) 3155{ 3156 char *buffer, *elements; 3157 int error; 3158 3159 error = mac_check_structmac_consistent(mac); 3160 if (error) 3161 return (error); 3162 3163 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3164 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3165 if (error) { 3166 free(elements, M_MACTEMP); 3167 return (error); 3168 } 3169 3170 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3171 error = mac_externalize_socket_label(&so->so_label, elements, 3172 buffer, mac->m_buflen, M_WAITOK); 3173 if (error == 0) 3174 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3175 3176 free(buffer, M_MACTEMP); 3177 free(elements, M_MACTEMP); 3178 3179 return (error); 3180} 3181 3182int 3183mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3184 struct mac *mac) 3185{ 3186 char *elements, *buffer; 3187 int error; 3188 3189 error = mac_check_structmac_consistent(mac); 3190 if (error) 3191 return (error); 3192 3193 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3194 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3195 if (error) { 3196 free(elements, M_MACTEMP); 3197 return (error); 3198 } 3199 3200 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3201 error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3202 elements, buffer, mac->m_buflen, M_WAITOK); 3203 if (error == 0) 3204 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3205 3206 free(buffer, M_MACTEMP); 3207 free(elements, M_MACTEMP); 3208 3209 return (error); 3210} 3211 3212/* 3213 * Implementation of VOP_SETLABEL() that relies on extended attributes 3214 * to store label data. Can be referenced by filesystems supporting 3215 * extended attributes. 3216 */ 3217int 3218vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3219{ 3220 struct vnode *vp = ap->a_vp; 3221 struct label *intlabel = ap->a_label; 3222 int error; 3223 3224 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3225 3226 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3227 return (EOPNOTSUPP); 3228 3229 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3230 if (error) 3231 return (error); 3232 3233 mac_relabel_vnode(ap->a_cred, vp, intlabel); 3234 3235 return (0); 3236} 3237 3238static int 3239vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3240{ 3241 int error; 3242 3243 if (vp->v_mount == NULL) { 3244 /* printf("vn_setlabel: null v_mount\n"); */ 3245 if (vp->v_type != VNON) 3246 printf("vn_setlabel: null v_mount with non-VNON\n"); 3247 return (EBADF); 3248 } 3249 3250 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3251 return (EOPNOTSUPP); 3252 3253 /* 3254 * Multi-phase commit. First check the policies to confirm the 3255 * change is OK. Then commit via the filesystem. Finally, 3256 * update the actual vnode label. Question: maybe the filesystem 3257 * should update the vnode at the end as part of VOP_SETLABEL()? 3258 */ 3259 error = mac_check_vnode_relabel(cred, vp, intlabel); 3260 if (error) 3261 return (error); 3262 3263 /* 3264 * VADMIN provides the opportunity for the filesystem to make 3265 * decisions about who is and is not able to modify labels 3266 * and protections on files. This might not be right. We can't 3267 * assume VOP_SETLABEL() will do it, because we might implement 3268 * that as part of vop_stdsetlabel_ea(). 3269 */ 3270 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3271 if (error) 3272 return (error); 3273 3274 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3275 if (error) 3276 return (error); 3277 3278 return (0); 3279} 3280 3281int 3282__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3283{ 3284 char *elements, *buffer; 3285 struct mac mac; 3286 struct proc *tproc; 3287 struct ucred *tcred; 3288 int error; 3289 3290 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3291 if (error) 3292 return (error); 3293 3294 error = mac_check_structmac_consistent(&mac); 3295 if (error) 3296 return (error); 3297 3298 tproc = pfind(uap->pid); 3299 if (tproc == NULL) 3300 return (ESRCH); 3301 3302 tcred = NULL; /* Satisfy gcc. */ 3303 error = p_cansee(td, tproc); 3304 if (error == 0) 3305 tcred = crhold(tproc->p_ucred); 3306 PROC_UNLOCK(tproc); 3307 if (error) 3308 return (error); 3309 3310 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3311 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3312 if (error) { 3313 free(elements, M_MACTEMP); 3314 crfree(tcred); 3315 return (error); 3316 } 3317 3318 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3319 error = mac_externalize_cred_label(&tcred->cr_label, elements, 3320 buffer, mac.m_buflen, M_WAITOK); 3321 if (error == 0) 3322 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3323 3324 free(buffer, M_MACTEMP); 3325 free(elements, M_MACTEMP); 3326 crfree(tcred); 3327 return (error); 3328} 3329 3330/* 3331 * MPSAFE 3332 */ 3333int 3334__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3335{ 3336 char *elements, *buffer; 3337 struct mac mac; 3338 int error; 3339 3340 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3341 if (error) 3342 return (error); 3343 3344 error = mac_check_structmac_consistent(&mac); 3345 if (error) 3346 return (error); 3347 3348 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3349 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3350 if (error) { 3351 free(elements, M_MACTEMP); 3352 return (error); 3353 } 3354 3355 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3356 error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3357 elements, buffer, mac.m_buflen, M_WAITOK); 3358 if (error == 0) 3359 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3360 3361 free(buffer, M_MACTEMP); 3362 free(elements, M_MACTEMP); 3363 return (error); 3364} 3365 3366/* 3367 * MPSAFE 3368 */ 3369int 3370__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3371{ 3372 struct ucred *newcred, *oldcred; 3373 struct label intlabel; 3374 struct proc *p; 3375 struct mac mac; 3376 char *buffer; 3377 int error; 3378 3379 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3380 if (error) 3381 return (error); 3382 3383 error = mac_check_structmac_consistent(&mac); 3384 if (error) 3385 return (error); 3386 3387 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3388 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3389 if (error) { 3390 free(buffer, M_MACTEMP); 3391 return (error); 3392 } 3393 3394 mac_init_cred_label(&intlabel); 3395 error = mac_internalize_cred_label(&intlabel, buffer); 3396 free(buffer, M_MACTEMP); 3397 if (error) { 3398 mac_destroy_cred_label(&intlabel); 3399 return (error); 3400 } 3401 3402 newcred = crget(); 3403 3404 p = td->td_proc; 3405 PROC_LOCK(p); 3406 oldcred = p->p_ucred; 3407 3408 error = mac_check_cred_relabel(oldcred, &intlabel); 3409 if (error) { 3410 PROC_UNLOCK(p); 3411 crfree(newcred); 3412 goto out; 3413 } 3414 3415 setsugid(p); 3416 crcopy(newcred, oldcred); 3417 mac_relabel_cred(newcred, &intlabel); 3418 p->p_ucred = newcred; 3419 3420 /* 3421 * Grab additional reference for use while revoking mmaps, prior 3422 * to releasing the proc lock and sharing the cred. 3423 */ 3424 crhold(newcred); 3425 PROC_UNLOCK(p); 3426 3427 if (mac_enforce_vm) { 3428 mtx_lock(&Giant); 3429 mac_cred_mmapped_drop_perms(td, newcred); 3430 mtx_unlock(&Giant); 3431 } 3432 3433 crfree(newcred); /* Free revocation reference. */ 3434 crfree(oldcred); 3435 3436out: 3437 mac_destroy_cred_label(&intlabel); 3438 return (error); 3439} 3440 3441/* 3442 * MPSAFE 3443 */ 3444int 3445__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3446{ 3447 char *elements, *buffer; 3448 struct label intlabel; 3449 struct file *fp; 3450 struct mac mac; 3451 struct vnode *vp; 3452 struct pipe *pipe; 3453 short label_type; 3454 int error; 3455 3456 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3457 if (error) 3458 return (error); 3459 3460 error = mac_check_structmac_consistent(&mac); 3461 if (error) 3462 return (error); 3463 3464 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3465 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3466 if (error) { 3467 free(elements, M_MACTEMP); 3468 return (error); 3469 } 3470 3471 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3472 mtx_lock(&Giant); /* VFS */ 3473 error = fget(td, uap->fd, &fp); 3474 if (error) 3475 goto out; 3476 3477 label_type = fp->f_type; 3478 switch (fp->f_type) { 3479 case DTYPE_FIFO: 3480 case DTYPE_VNODE: 3481 vp = fp->f_vnode; 3482 3483 mac_init_vnode_label(&intlabel); 3484 3485 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3486 mac_copy_vnode_label(&vp->v_label, &intlabel); 3487 VOP_UNLOCK(vp, 0, td); 3488 3489 break; 3490 case DTYPE_PIPE: 3491 pipe = fp->f_data; 3492 3493 mac_init_pipe_label(&intlabel); 3494 3495 PIPE_LOCK(pipe); 3496 mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3497 PIPE_UNLOCK(pipe); 3498 break; 3499 default: 3500 error = EINVAL; 3501 fdrop(fp, td); 3502 goto out; 3503 } 3504 fdrop(fp, td); 3505 3506 switch (label_type) { 3507 case DTYPE_FIFO: 3508 case DTYPE_VNODE: 3509 if (error == 0) 3510 error = mac_externalize_vnode_label(&intlabel, 3511 elements, buffer, mac.m_buflen, M_WAITOK); 3512 mac_destroy_vnode_label(&intlabel); 3513 break; 3514 case DTYPE_PIPE: 3515 error = mac_externalize_pipe_label(&intlabel, elements, 3516 buffer, mac.m_buflen, M_WAITOK); 3517 mac_destroy_pipe_label(&intlabel); 3518 break; 3519 default: 3520 panic("__mac_get_fd: corrupted label_type"); 3521 } 3522 3523 if (error == 0) 3524 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3525 3526out: 3527 mtx_unlock(&Giant); /* VFS */ 3528 free(buffer, M_MACTEMP); 3529 free(elements, M_MACTEMP); 3530 3531 return (error); 3532} 3533 3534/* 3535 * MPSAFE 3536 */ 3537int 3538__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3539{ 3540 char *elements, *buffer; 3541 struct nameidata nd; 3542 struct label intlabel; 3543 struct mac mac; 3544 int error; 3545 3546 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3547 if (error) 3548 return (error); 3549 3550 error = mac_check_structmac_consistent(&mac); 3551 if (error) 3552 return (error); 3553 3554 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3555 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3556 if (error) { 3557 free(elements, M_MACTEMP); 3558 return (error); 3559 } 3560 3561 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3562 mtx_lock(&Giant); /* VFS */ 3563 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3564 td); 3565 error = namei(&nd); 3566 if (error) 3567 goto out; 3568 3569 mac_init_vnode_label(&intlabel); 3570 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3571 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3572 mac.m_buflen, M_WAITOK); 3573 3574 NDFREE(&nd, 0); 3575 mac_destroy_vnode_label(&intlabel); 3576 3577 if (error == 0) 3578 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3579 3580out: 3581 mtx_unlock(&Giant); /* VFS */ 3582 3583 free(buffer, M_MACTEMP); 3584 free(elements, M_MACTEMP); 3585 3586 return (error); 3587} 3588 3589/* 3590 * MPSAFE 3591 */ 3592int 3593__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3594{ 3595 char *elements, *buffer; 3596 struct nameidata nd; 3597 struct label intlabel; 3598 struct mac mac; 3599 int error; 3600 3601 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3602 if (error) 3603 return (error); 3604 3605 error = mac_check_structmac_consistent(&mac); 3606 if (error) 3607 return (error); 3608 3609 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3610 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3611 if (error) { 3612 free(elements, M_MACTEMP); 3613 return (error); 3614 } 3615 3616 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3617 mtx_lock(&Giant); /* VFS */ 3618 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3619 td); 3620 error = namei(&nd); 3621 if (error) 3622 goto out; 3623 3624 mac_init_vnode_label(&intlabel); 3625 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3626 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3627 mac.m_buflen, M_WAITOK); 3628 NDFREE(&nd, 0); 3629 mac_destroy_vnode_label(&intlabel); 3630 3631 if (error == 0) 3632 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3633 3634out: 3635 mtx_unlock(&Giant); /* VFS */ 3636 3637 free(buffer, M_MACTEMP); 3638 free(elements, M_MACTEMP); 3639 3640 return (error); 3641} 3642 3643/* 3644 * MPSAFE 3645 */ 3646int 3647__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3648{ 3649 struct label intlabel; 3650 struct pipe *pipe; 3651 struct file *fp; 3652 struct mount *mp; 3653 struct vnode *vp; 3654 struct mac mac; 3655 char *buffer; 3656 int error; 3657 3658 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3659 if (error) 3660 return (error); 3661 3662 error = mac_check_structmac_consistent(&mac); 3663 if (error) 3664 return (error); 3665 3666 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3667 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3668 if (error) { 3669 free(buffer, M_MACTEMP); 3670 return (error); 3671 } 3672 3673 mtx_lock(&Giant); /* VFS */ 3674 3675 error = fget(td, uap->fd, &fp); 3676 if (error) 3677 goto out; 3678 3679 switch (fp->f_type) { 3680 case DTYPE_FIFO: 3681 case DTYPE_VNODE: 3682 mac_init_vnode_label(&intlabel); 3683 error = mac_internalize_vnode_label(&intlabel, buffer); 3684 if (error) { 3685 mac_destroy_vnode_label(&intlabel); 3686 break; 3687 } 3688 3689 vp = fp->f_vnode; 3690 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3691 if (error != 0) { 3692 mac_destroy_vnode_label(&intlabel); 3693 break; 3694 } 3695 3696 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3697 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3698 VOP_UNLOCK(vp, 0, td); 3699 vn_finished_write(mp); 3700 3701 mac_destroy_vnode_label(&intlabel); 3702 break; 3703 3704 case DTYPE_PIPE: 3705 mac_init_pipe_label(&intlabel); 3706 error = mac_internalize_pipe_label(&intlabel, buffer); 3707 if (error == 0) { 3708 pipe = fp->f_data; 3709 PIPE_LOCK(pipe); 3710 error = mac_pipe_label_set(td->td_ucred, pipe, 3711 &intlabel); 3712 PIPE_UNLOCK(pipe); 3713 } 3714 3715 mac_destroy_pipe_label(&intlabel); 3716 break; 3717 3718 default: 3719 error = EINVAL; 3720 } 3721 3722 fdrop(fp, td); 3723out: 3724 mtx_unlock(&Giant); /* VFS */ 3725 3726 free(buffer, M_MACTEMP); 3727 3728 return (error); 3729} 3730 3731/* 3732 * MPSAFE 3733 */ 3734int 3735__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3736{ 3737 struct label intlabel; 3738 struct nameidata nd; 3739 struct mount *mp; 3740 struct mac mac; 3741 char *buffer; 3742 int error; 3743 3744 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3745 if (error) 3746 return (error); 3747 3748 error = mac_check_structmac_consistent(&mac); 3749 if (error) 3750 return (error); 3751 3752 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3753 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3754 if (error) { 3755 free(buffer, M_MACTEMP); 3756 return (error); 3757 } 3758 3759 mac_init_vnode_label(&intlabel); 3760 error = mac_internalize_vnode_label(&intlabel, buffer); 3761 free(buffer, M_MACTEMP); 3762 if (error) { 3763 mac_destroy_vnode_label(&intlabel); 3764 return (error); 3765 } 3766 3767 mtx_lock(&Giant); /* VFS */ 3768 3769 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3770 td); 3771 error = namei(&nd); 3772 if (error == 0) { 3773 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3774 if (error == 0) 3775 error = vn_setlabel(nd.ni_vp, &intlabel, 3776 td->td_ucred); 3777 vn_finished_write(mp); 3778 } 3779 3780 NDFREE(&nd, 0); 3781 mtx_unlock(&Giant); /* VFS */ 3782 mac_destroy_vnode_label(&intlabel); 3783 3784 return (error); 3785} 3786 3787/* 3788 * MPSAFE 3789 */ 3790int 3791__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3792{ 3793 struct label intlabel; 3794 struct nameidata nd; 3795 struct mount *mp; 3796 struct mac mac; 3797 char *buffer; 3798 int error; 3799 3800 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3801 if (error) 3802 return (error); 3803 3804 error = mac_check_structmac_consistent(&mac); 3805 if (error) 3806 return (error); 3807 3808 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3809 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3810 if (error) { 3811 free(buffer, M_MACTEMP); 3812 return (error); 3813 } 3814 3815 mac_init_vnode_label(&intlabel); 3816 error = mac_internalize_vnode_label(&intlabel, buffer); 3817 free(buffer, M_MACTEMP); 3818 if (error) { 3819 mac_destroy_vnode_label(&intlabel); 3820 return (error); 3821 } 3822 3823 mtx_lock(&Giant); /* VFS */ 3824 3825 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3826 td); 3827 error = namei(&nd); 3828 if (error == 0) { 3829 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3830 if (error == 0) 3831 error = vn_setlabel(nd.ni_vp, &intlabel, 3832 td->td_ucred); 3833 vn_finished_write(mp); 3834 } 3835 3836 NDFREE(&nd, 0); 3837 mtx_unlock(&Giant); /* VFS */ 3838 mac_destroy_vnode_label(&intlabel); 3839 3840 return (error); 3841} 3842 3843/* 3844 * MPSAFE 3845 */ 3846int 3847mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3848{ 3849 struct mac_policy_conf *mpc; 3850 char target[MAC_MAX_POLICY_NAME]; 3851 int entrycount, error; 3852 3853 error = copyinstr(uap->policy, target, sizeof(target), NULL); 3854 if (error) 3855 return (error); 3856 3857 error = ENOSYS; 3858 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { 3859 if (strcmp(mpc->mpc_name, target) == 0 && 3860 mpc->mpc_ops->mpo_syscall != NULL) { 3861 error = mpc->mpc_ops->mpo_syscall(td, 3862 uap->call, uap->arg); 3863 goto out; 3864 } 3865 } 3866 3867 if ((entrycount = mac_policy_list_conditional_busy()) != 0) { 3868 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3869 if (strcmp(mpc->mpc_name, target) == 0 && 3870 mpc->mpc_ops->mpo_syscall != NULL) { 3871 error = mpc->mpc_ops->mpo_syscall(td, 3872 uap->call, uap->arg); 3873 break; 3874 } 3875 } 3876 mac_policy_list_unbusy(); 3877 } 3878out: 3879 return (error); 3880} 3881 3882SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3883SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3884 3885#else /* !MAC */ 3886 3887int 3888__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3889{ 3890 3891 return (ENOSYS); 3892} 3893 3894int 3895__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3896{ 3897 3898 return (ENOSYS); 3899} 3900 3901int 3902__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3903{ 3904 3905 return (ENOSYS); 3906} 3907 3908int 3909__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3910{ 3911 3912 return (ENOSYS); 3913} 3914 3915int 3916__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3917{ 3918 3919 return (ENOSYS); 3920} 3921 3922int 3923__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3924{ 3925 3926 return (ENOSYS); 3927} 3928 3929int 3930__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3931{ 3932 3933 return (ENOSYS); 3934} 3935 3936int 3937__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3938{ 3939 3940 return (ENOSYS); 3941} 3942 3943int 3944__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3945{ 3946 3947 return (ENOSYS); 3948} 3949 3950int 3951mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3952{ 3953 3954 return (ENOSYS); 3955} 3956 3957#endif
|