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