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