1355mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
1356{
1357 int error;
1358
1359 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
1360
1361 MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
1362 &vp->v_label);
1363
1364 return (error);
1365}
1366
1367void
1368mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
1369{
1370
1371 MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
1372 &vp->v_label);
1373}
1374
1375int
1376mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1377 struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
1378{
1379 int error;
1380
1381 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
1382 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
1383
1384 error = VOP_OPENEXTATTR(vp, cred, curthread);
1385 if (error == EOPNOTSUPP) {
1386 /* XXX: Optionally abort if transactions not supported. */
1387 if (ea_warn_once == 0) {
1388 printf("Warning: transactions not supported "
1389 "in EA write.\n");
1390 ea_warn_once = 1;
1391 }
1392 } else if (error)
1393 return (error);
1394
1395 MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
1396 dvp, &dvp->v_label, vp, &vp->v_label, cnp);
1397
1398 if (error) {
1399 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
1400 return (error);
1401 }
1402
1403 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1404
1405 if (error == EOPNOTSUPP)
1406 error = 0; /* XXX */
1407
1408 return (error);
1409}
1410
1411static int
1412mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1413 struct label *intlabel)
1414{
1415 int error;
1416
1417 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
1418
1419 error = VOP_OPENEXTATTR(vp, cred, curthread);
1420 if (error == EOPNOTSUPP) {
1421 /* XXX: Optionally abort if transactions not supported. */
1422 if (ea_warn_once == 0) {
1423 printf("Warning: transactions not supported "
1424 "in EA write.\n");
1425 ea_warn_once = 1;
1426 }
1427 } else if (error)
1428 return (error);
1429
1430 MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
1431
1432 if (error) {
1433 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
1434 return (error);
1435 }
1436
1437 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
1438
1439 if (error == EOPNOTSUPP)
1440 error = 0; /* XXX */
1441
1442 return (error);
1443}
1444
1445int
1446mac_execve_enter(struct image_params *imgp, struct mac *mac_p,
1447 struct label *execlabelstorage)
1448{
1449 struct mac mac;
1450 char *buffer;
1451 int error;
1452
1453 if (mac_p == NULL)
1454 return (0);
1455
1456 error = copyin(mac_p, &mac, sizeof(mac));
1457 if (error)
1458 return (error);
1459
1460 error = mac_check_structmac_consistent(&mac);
1461 if (error)
1462 return (error);
1463
1464 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
1465 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
1466 if (error) {
1467 free(buffer, M_MACTEMP);
1468 return (error);
1469 }
1470
1471 mac_init_cred_label(execlabelstorage);
1472 error = mac_internalize_cred_label(execlabelstorage, buffer);
1473 free(buffer, M_MACTEMP);
1474 if (error) {
1475 mac_destroy_cred_label(execlabelstorage);
1476 return (error);
1477 }
1478 imgp->execlabel = execlabelstorage;
1479 return (0);
1480}
1481
1482void
1483mac_execve_exit(struct image_params *imgp)
1484{
1485 if (imgp->execlabel != NULL)
1486 mac_destroy_cred_label(imgp->execlabel);
1487}
1488
1489void
1490mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp,
1491 struct label *interpvnodelabel, struct image_params *imgp)
1492{
1493
1494 ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
1495
1496 if (!mac_enforce_process && !mac_enforce_fs)
1497 return;
1498
1499 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label,
1500 interpvnodelabel, imgp, imgp->execlabel);
1501}
1502
1503int
1504mac_execve_will_transition(struct ucred *old, struct vnode *vp,
1505 struct label *interpvnodelabel, struct image_params *imgp)
1506{
1507 int result;
1508
1509 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition");
1510
1511 if (!mac_enforce_process && !mac_enforce_fs)
1512 return (0);
1513
1514 result = 0;
1515 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label,
1516 interpvnodelabel, imgp, imgp->execlabel);
1517
1518 return (result);
1519}
1520
1521int
1522mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode)
1523{
1524 int error;
1525
1526 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
1527
1528 if (!mac_enforce_fs)
1529 return (0);
1530
1531 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode);
1532 return (error);
1533}
1534
1535int
1536mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
1537{
1538 int error;
1539
1540 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
1541
1542 if (!mac_enforce_fs)
1543 return (0);
1544
1545 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
1546 return (error);
1547}
1548
1549int
1550mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
1551{
1552 int error;
1553
1554 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
1555
1556 if (!mac_enforce_fs)
1557 return (0);
1558
1559 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
1560 return (error);
1561}
1562
1563int
1564mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1565 struct componentname *cnp, struct vattr *vap)
1566{
1567 int error;
1568
1569 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
1570
1571 if (!mac_enforce_fs)
1572 return (0);
1573
1574 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
1575 return (error);
1576}
1577
1578int
1579mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
1580 struct componentname *cnp)
1581{
1582 int error;
1583
1584 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
1585 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
1586
1587 if (!mac_enforce_fs)
1588 return (0);
1589
1590 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
1591 &vp->v_label, cnp);
1592 return (error);
1593}
1594
1595int
1596mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1597 acl_type_t type)
1598{
1599 int error;
1600
1601 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
1602
1603 if (!mac_enforce_fs)
1604 return (0);
1605
1606 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
1607 return (error);
1608}
1609
1610int
1611mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
1612 int attrnamespace, const char *name)
1613{
1614 int error;
1615
1616 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr");
1617
1618 if (!mac_enforce_fs)
1619 return (0);
1620
1621 MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label,
1622 attrnamespace, name);
1623 return (error);
1624}
1625
1626int
1627mac_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1628 struct image_params *imgp)
1629{
1630 int error;
1631
1632 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
1633
1634 if (!mac_enforce_process && !mac_enforce_fs)
1635 return (0);
1636
1637 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp,
1638 imgp->execlabel);
1639
1640 return (error);
1641}
1642
1643int
1644mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
1645{
1646 int error;
1647
1648 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
1649
1650 if (!mac_enforce_fs)
1651 return (0);
1652
1653 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
1654 return (error);
1655}
1656
1657int
1658mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1659 int attrnamespace, const char *name, struct uio *uio)
1660{
1661 int error;
1662
1663 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
1664
1665 if (!mac_enforce_fs)
1666 return (0);
1667
1668 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
1669 attrnamespace, name, uio);
1670 return (error);
1671}
1672
1673int
1674mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1675 struct vnode *vp, struct componentname *cnp)
1676{
1677 int error;
1678
1679 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
1680 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
1681
1682 if (!mac_enforce_fs)
1683 return (0);
1684
1685 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
1686 &vp->v_label, cnp);
1687 return (error);
1688}
1689
1690int
1691mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
1692 int attrnamespace)
1693{
1694 int error;
1695
1696 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr");
1697
1698 if (!mac_enforce_fs)
1699 return (0);
1700
1701 MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label,
1702 attrnamespace);
1703 return (error);
1704}
1705
1706int
1707mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1708 struct componentname *cnp)
1709{
1710 int error;
1711
1712 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
1713
1714 if (!mac_enforce_fs)
1715 return (0);
1716
1717 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
1718 return (error);
1719}
1720
1721int
1722mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
1723{
1724 int error;
1725
1726 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
1727
1728 if (!mac_enforce_fs || !mac_enforce_vm)
1729 return (0);
1730
1731 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
1732 return (error);
1733}
1734
1735void
1736mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
1737{
1738 int result = *prot;
1739
1740 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
1741
1742 if (!mac_enforce_fs || !mac_enforce_vm)
1743 return;
1744
1745 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label,
1746 &result);
1747
1748 *prot = result;
1749}
1750
1751int
1752mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
1753{
1754 int error;
1755
1756 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
1757
1758 if (!mac_enforce_fs || !mac_enforce_vm)
1759 return (0);
1760
1761 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
1762 return (error);
1763}
1764
1765int
1766mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode)
1767{
1768 int error;
1769
1770 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
1771
1772 if (!mac_enforce_fs)
1773 return (0);
1774
1775 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
1776 return (error);
1777}
1778
1779int
1780mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1781 struct vnode *vp)
1782{
1783 int error;
1784
1785 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
1786
1787 if (!mac_enforce_fs)
1788 return (0);
1789
1790 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
1791 &vp->v_label);
1792
1793 return (error);
1794}
1795
1796int
1797mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1798 struct vnode *vp)
1799{
1800 int error;
1801
1802 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
1803
1804 if (!mac_enforce_fs)
1805 return (0);
1806
1807 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
1808 &vp->v_label);
1809
1810 return (error);
1811}
1812
1813int
1814mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
1815{
1816 int error;
1817
1818 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
1819
1820 if (!mac_enforce_fs)
1821 return (0);
1822
1823 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
1824 return (error);
1825}
1826
1827int
1828mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
1829{
1830 int error;
1831
1832 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
1833
1834 if (!mac_enforce_fs)
1835 return (0);
1836
1837 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
1838 return (error);
1839}
1840
1841static int
1842mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1843 struct label *newlabel)
1844{
1845 int error;
1846
1847 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
1848
1849 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
1850
1851 return (error);
1852}
1853
1854int
1855mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1856 struct vnode *vp, struct componentname *cnp)
1857{
1858 int error;
1859
1860 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
1861 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
1862
1863 if (!mac_enforce_fs)
1864 return (0);
1865
1866 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
1867 &vp->v_label, cnp);
1868 return (error);
1869}
1870
1871int
1872mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1873 struct vnode *vp, int samedir, struct componentname *cnp)
1874{
1875 int error;
1876
1877 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
1878 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
1879
1880 if (!mac_enforce_fs)
1881 return (0);
1882
1883 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
1884 vp != NULL ? &vp->v_label : NULL, samedir, cnp);
1885 return (error);
1886}
1887
1888int
1889mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
1890{
1891 int error;
1892
1893 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
1894
1895 if (!mac_enforce_fs)
1896 return (0);
1897
1898 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
1899 return (error);
1900}
1901
1902int
1903mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
1904 struct acl *acl)
1905{
1906 int error;
1907
1908 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
1909
1910 if (!mac_enforce_fs)
1911 return (0);
1912
1913 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
1914 return (error);
1915}
1916
1917int
1918mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
1919 int attrnamespace, const char *name, struct uio *uio)
1920{
1921 int error;
1922
1923 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
1924
1925 if (!mac_enforce_fs)
1926 return (0);
1927
1928 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
1929 attrnamespace, name, uio);
1930 return (error);
1931}
1932
1933int
1934mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
1935{
1936 int error;
1937
1938 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
1939
1940 if (!mac_enforce_fs)
1941 return (0);
1942
1943 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
1944 return (error);
1945}
1946
1947int
1948mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
1949{
1950 int error;
1951
1952 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
1953
1954 if (!mac_enforce_fs)
1955 return (0);
1956
1957 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
1958 return (error);
1959}
1960
1961int
1962mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
1963 gid_t gid)
1964{
1965 int error;
1966
1967 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
1968
1969 if (!mac_enforce_fs)
1970 return (0);
1971
1972 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
1973 return (error);
1974}
1975
1976int
1977mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
1978 struct timespec atime, struct timespec mtime)
1979{
1980 int error;
1981
1982 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
1983
1984 if (!mac_enforce_fs)
1985 return (0);
1986
1987 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
1988 mtime);
1989 return (error);
1990}
1991
1992int
1993mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
1994 struct vnode *vp)
1995{
1996 int error;
1997
1998 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
1999
2000 if (!mac_enforce_fs)
2001 return (0);
2002
2003 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
2004 &vp->v_label);
2005 return (error);
2006}
2007
2008int
2009mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2010 struct vnode *vp)
2011{
2012 int error;
2013
2014 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
2015
2016 if (!mac_enforce_fs)
2017 return (0);
2018
2019 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
2020 &vp->v_label);
2021
2022 return (error);
2023}
2024
2025/*
2026 * When relabeling a process, call out to the policies for the maximum
2027 * permission allowed for each object type we know about in its
2028 * memory space, and revoke access (in the least surprising ways we
2029 * know) when necessary. The process lock is not held here.
2030 */
2031void
2032mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
2033{
2034
2035 /* XXX freeze all other threads */
2036 mac_cred_mmapped_drop_perms_recurse(td, cred,
2037 &td->td_proc->p_vmspace->vm_map);
2038 /* XXX allow other threads to continue */
2039}
2040
2041static __inline const char *
2042prot2str(vm_prot_t prot)
2043{
2044
2045 switch (prot & VM_PROT_ALL) {
2046 case VM_PROT_READ:
2047 return ("r--");
2048 case VM_PROT_READ | VM_PROT_WRITE:
2049 return ("rw-");
2050 case VM_PROT_READ | VM_PROT_EXECUTE:
2051 return ("r-x");
2052 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2053 return ("rwx");
2054 case VM_PROT_WRITE:
2055 return ("-w-");
2056 case VM_PROT_EXECUTE:
2057 return ("--x");
2058 case VM_PROT_WRITE | VM_PROT_EXECUTE:
2059 return ("-wx");
2060 default:
2061 return ("---");
2062 }
2063}
2064
2065static void
2066mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
2067 struct vm_map *map)
2068{
2069 struct vm_map_entry *vme;
2070 int result;
2071 vm_prot_t revokeperms;
2072 vm_object_t object;
2073 vm_ooffset_t offset;
2074 struct vnode *vp;
2075
2076 if (!mac_mmap_revocation)
2077 return;
2078
2079 vm_map_lock_read(map);
2080 for (vme = map->header.next; vme != &map->header; vme = vme->next) {
2081 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2082 mac_cred_mmapped_drop_perms_recurse(td, cred,
2083 vme->object.sub_map);
2084 continue;
2085 }
2086 /*
2087 * Skip over entries that obviously are not shared.
2088 */
2089 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
2090 !vme->max_protection)
2091 continue;
2092 /*
2093 * Drill down to the deepest backing object.
2094 */
2095 offset = vme->offset;
2096 object = vme->object.vm_object;
2097 if (object == NULL)
2098 continue;
2099 while (object->backing_object != NULL) {
2100 object = object->backing_object;
2101 offset += object->backing_object_offset;
2102 }
2103 /*
2104 * At the moment, vm_maps and objects aren't considered
2105 * by the MAC system, so only things with backing by a
2106 * normal object (read: vnodes) are checked.
2107 */
2108 if (object->type != OBJT_VNODE)
2109 continue;
2110 vp = (struct vnode *)object->handle;
2111 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2112 result = vme->max_protection;
2113 mac_check_vnode_mmap_downgrade(cred, vp, &result);
2114 VOP_UNLOCK(vp, 0, td);
2115 /*
2116 * Find out what maximum protection we may be allowing
2117 * now but a policy needs to get removed.
2118 */
2119 revokeperms = vme->max_protection & ~result;
2120 if (!revokeperms)
2121 continue;
2122 printf("pid %ld: revoking %s perms from %#lx:%ld "
2123 "(max %s/cur %s)\n", (long)td->td_proc->p_pid,
2124 prot2str(revokeperms), (u_long)vme->start,
2125 (long)(vme->end - vme->start),
2126 prot2str(vme->max_protection), prot2str(vme->protection));
2127 vm_map_lock_upgrade(map);
2128 /*
2129 * This is the really simple case: if a map has more
2130 * max_protection than is allowed, but it's not being
2131 * actually used (that is, the current protection is
2132 * still allowed), we can just wipe it out and do
2133 * nothing more.
2134 */
2135 if ((vme->protection & revokeperms) == 0) {
2136 vme->max_protection -= revokeperms;
2137 } else {
2138 if (revokeperms & VM_PROT_WRITE) {
2139 /*
2140 * In the more complicated case, flush out all
2141 * pending changes to the object then turn it
2142 * copy-on-write.
2143 */
2144 vm_object_reference(object);
2145 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2146 VM_OBJECT_LOCK(object);
2147 vm_object_page_clean(object,
2148 OFF_TO_IDX(offset),
2149 OFF_TO_IDX(offset + vme->end - vme->start +
2150 PAGE_MASK),
2151 OBJPC_SYNC);
2152 VM_OBJECT_UNLOCK(object);
2153 VOP_UNLOCK(vp, 0, td);
2154 vm_object_deallocate(object);
2155 /*
2156 * Why bother if there's no read permissions
2157 * anymore? For the rest, we need to leave
2158 * the write permissions on for COW, or
2159 * remove them entirely if configured to.
2160 */
2161 if (!mac_mmap_revocation_via_cow) {
2162 vme->max_protection &= ~VM_PROT_WRITE;
2163 vme->protection &= ~VM_PROT_WRITE;
2164 } if ((revokeperms & VM_PROT_READ) == 0)
2165 vme->eflags |= MAP_ENTRY_COW |
2166 MAP_ENTRY_NEEDS_COPY;
2167 }
2168 if (revokeperms & VM_PROT_EXECUTE) {
2169 vme->max_protection &= ~VM_PROT_EXECUTE;
2170 vme->protection &= ~VM_PROT_EXECUTE;
2171 }
2172 if (revokeperms & VM_PROT_READ) {
2173 vme->max_protection = 0;
2174 vme->protection = 0;
2175 }
2176 pmap_protect(map->pmap, vme->start, vme->end,
2177 vme->protection & ~revokeperms);
2178 vm_map_simplify_entry(map, vme);
2179 }
2180 vm_map_lock_downgrade(map);
2181 }
2182 vm_map_unlock_read(map);
2183}
2184
2185/*
2186 * When the subject's label changes, it may require revocation of privilege
2187 * to mapped objects. This can't be done on-the-fly later with a unified
2188 * buffer cache.
2189 */
2190static void
2191mac_relabel_cred(struct ucred *cred, struct label *newlabel)
2192{
2193
2194 MAC_PERFORM(relabel_cred, cred, newlabel);
2195}
2196
2197void
2198mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
2199{
2200
2201 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
2202}
2203
2204void
2205mac_create_ifnet(struct ifnet *ifnet)
2206{
2207
2208 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
2209}
2210
2211void
2212mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
2213{
2214
2215 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
2216}
2217
2218void
2219mac_create_socket(struct ucred *cred, struct socket *socket)
2220{
2221
2222 MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
2223}
2224
2225void
2226mac_create_pipe(struct ucred *cred, struct pipe *pipe)
2227{
2228
2229 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
2230}
2231
2232void
2233mac_create_socket_from_socket(struct socket *oldsocket,
2234 struct socket *newsocket)
2235{
2236
2237 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
2238 newsocket, &newsocket->so_label);
2239}
2240
2241static void
2242mac_relabel_socket(struct ucred *cred, struct socket *socket,
2243 struct label *newlabel)
2244{
2245
2246 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
2247}
2248
2249static void
2250mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
2251{
2252
2253 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
2254}
2255
2256void
2257mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
2258{
2259 struct label *label;
2260
2261 label = mbuf_to_label(mbuf);
2262
2263 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
2264 &socket->so_peerlabel);
2265}
2266
2267void
2268mac_set_socket_peer_from_socket(struct socket *oldsocket,
2269 struct socket *newsocket)
2270{
2271
2272 MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
2273 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
2274}
2275
2276void
2277mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2278{
2279 struct label *label;
2280
2281 label = mbuf_to_label(datagram);
2282
2283 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2284 datagram, label);
2285}
2286
2287void
2288mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2289{
2290 struct label *datagramlabel, *fragmentlabel;
2291
2292 datagramlabel = mbuf_to_label(datagram);
2293 fragmentlabel = mbuf_to_label(fragment);
2294
2295 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
2296 fragmentlabel);
2297}
2298
2299void
2300mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2301{
2302 struct label *label;
2303
2304 label = mbuf_to_label(fragment);
2305
2306 MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
2307}
2308
2309void
2310mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2311{
2312 struct label *oldmbuflabel, *newmbuflabel;
2313
2314 oldmbuflabel = mbuf_to_label(oldmbuf);
2315 newmbuflabel = mbuf_to_label(newmbuf);
2316
2317 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
2318 newmbuflabel);
2319}
2320
2321void
2322mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2323{
2324 struct label *label;
2325
2326 label = mbuf_to_label(mbuf);
2327
2328 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2329 label);
2330}
2331
2332void
2333mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2334{
2335 struct label *label;
2336
2337 label = mbuf_to_label(mbuf);
2338
2339 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2340 label);
2341}
2342
2343void
2344mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2345{
2346 struct label *label;
2347
2348 label = mbuf_to_label(mbuf);
2349
2350 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2351 label);
2352}
2353
2354void
2355mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2356 struct mbuf *newmbuf)
2357{
2358 struct label *oldmbuflabel, *newmbuflabel;
2359
2360 oldmbuflabel = mbuf_to_label(oldmbuf);
2361 newmbuflabel = mbuf_to_label(newmbuf);
2362
2363 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
2364 ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
2365}
2366
2367void
2368mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2369{
2370 struct label *oldmbuflabel, *newmbuflabel;
2371
2372 oldmbuflabel = mbuf_to_label(oldmbuf);
2373 newmbuflabel = mbuf_to_label(newmbuf);
2374
2375 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
2376 newmbuflabel);
2377}
2378
2379int
2380mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2381{
2382 struct label *label;
2383 int result;
2384
2385 label = mbuf_to_label(fragment);
2386
2387 result = 1;
2388 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
2389 &ipq->ipq_label);
2390
2391 return (result);
2392}
2393
2394void
2395mac_reflect_mbuf_icmp(struct mbuf *m)
2396{
2397 struct label *label;
2398
2399 label = mbuf_to_label(m);
2400
2401 MAC_PERFORM(reflect_mbuf_icmp, m, label);
2402}
2403void
2404mac_reflect_mbuf_tcp(struct mbuf *m)
2405{
2406 struct label *label;
2407
2408 label = mbuf_to_label(m);
2409
2410 MAC_PERFORM(reflect_mbuf_tcp, m, label);
2411}
2412
2413void
2414mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2415{
2416 struct label *label;
2417
2418 label = mbuf_to_label(fragment);
2419
2420 MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
2421}
2422
2423void
2424mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2425{
2426 struct label *label;
2427
2428 label = mbuf_to_label(mbuf);
2429
2430 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2431 label);
2432}
2433
2434void
2435mac_create_mount(struct ucred *cred, struct mount *mp)
2436{
2437
2438 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2439 &mp->mnt_fslabel);
2440}
2441
2442void
2443mac_create_root_mount(struct ucred *cred, struct mount *mp)
2444{
2445
2446 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2447 &mp->mnt_fslabel);
2448}
2449
2450int
2451mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2452{
2453 int error;
2454
2455 if (!mac_enforce_network)
2456 return (0);
2457
2458 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
2459 &ifnet->if_label);
2460
2461 return (error);
2462}
2463
2464static int
2465mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
2466{
2467 int error;
2468
2469 MAC_CHECK(check_cred_relabel, cred, newlabel);
2470
2471 return (error);
2472}
2473
2474int
2475mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
2476{
2477 int error;
2478
2479 if (!mac_enforce_process)
2480 return (0);
2481
2482 MAC_CHECK(check_cred_visible, u1, u2);
2483
2484 return (error);
2485}
2486
2487int
2488mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
2489{
2490 struct label *label;
2491 int error;
2492
2493 M_ASSERTPKTHDR(mbuf);
2494
2495 if (!mac_enforce_network)
2496 return (0);
2497
2498 label = mbuf_to_label(mbuf);
2499
2500 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
2501 label);
2502
2503 return (error);
2504}
2505
2506int
2507mac_check_kenv_dump(struct ucred *cred)
2508{
2509 int error;
2510
2511 if (!mac_enforce_system)
2512 return (0);
2513
2514 MAC_CHECK(check_kenv_dump, cred);
2515
2516 return (error);
2517}
2518
2519int
2520mac_check_kenv_get(struct ucred *cred, char *name)
2521{
2522 int error;
2523
2524 if (!mac_enforce_system)
2525 return (0);
2526
2527 MAC_CHECK(check_kenv_get, cred, name);
2528
2529 return (error);
2530}
2531
2532int
2533mac_check_kenv_set(struct ucred *cred, char *name, char *value)
2534{
2535 int error;
2536
2537 if (!mac_enforce_system)
2538 return (0);
2539
2540 MAC_CHECK(check_kenv_set, cred, name, value);
2541
2542 return (error);
2543}
2544
2545int
2546mac_check_kenv_unset(struct ucred *cred, char *name)
2547{
2548 int error;
2549
2550 if (!mac_enforce_system)
2551 return (0);
2552
2553 MAC_CHECK(check_kenv_unset, cred, name);
2554
2555 return (error);
2556}
2557
2558int
2559mac_check_kld_load(struct ucred *cred, struct vnode *vp)
2560{
2561 int error;
2562
2563 ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
2564
2565 if (!mac_enforce_kld)
2566 return (0);
2567
2568 MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
2569
2570 return (error);
2571}
2572
2573int
2574mac_check_kld_stat(struct ucred *cred)
2575{
2576 int error;
2577
2578 if (!mac_enforce_kld)
2579 return (0);
2580
2581 MAC_CHECK(check_kld_stat, cred);
2582
2583 return (error);
2584}
2585
2586int
2587mac_check_kld_unload(struct ucred *cred)
2588{
2589 int error;
2590
2591 if (!mac_enforce_kld)
2592 return (0);
2593
2594 MAC_CHECK(check_kld_unload, cred);
2595
2596 return (error);
2597}
2598
2599int
2600mac_check_mount_stat(struct ucred *cred, struct mount *mount)
2601{
2602 int error;
2603
2604 if (!mac_enforce_fs)
2605 return (0);
2606
2607 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
2608
2609 return (error);
2610}
2611
2612int
2613mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
2614 void *data)
2615{
2616 int error;
2617
2618 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2619
2620 if (!mac_enforce_pipe)
2621 return (0);
2622
2623 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
2624
2625 return (error);
2626}
2627
2628int
2629mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
2630{
2631 int error;
2632
2633 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2634
2635 if (!mac_enforce_pipe)
2636 return (0);
2637
2638 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2639
2640 return (error);
2641}
2642
2643int
2644mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2645{
2646 int error;
2647
2648 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2649
2650 if (!mac_enforce_pipe)
2651 return (0);
2652
2653 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
2654
2655 return (error);
2656}
2657
2658static int
2659mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
2660 struct label *newlabel)
2661{
2662 int error;
2663
2664 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2665
2666 if (!mac_enforce_pipe)
2667 return (0);
2668
2669 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
2670
2671 return (error);
2672}
2673
2674int
2675mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2676{
2677 int error;
2678
2679 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2680
2681 if (!mac_enforce_pipe)
2682 return (0);
2683
2684 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2685
2686 return (error);
2687}
2688
2689int
2690mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2691{
2692 int error;
2693
2694 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
2695
2696 if (!mac_enforce_pipe)
2697 return (0);
2698
2699 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2700
2701 return (error);
2702}
2703
2704int
2705mac_check_proc_debug(struct ucred *cred, struct proc *proc)
2706{
2707 int error;
2708
2709 PROC_LOCK_ASSERT(proc, MA_OWNED);
2710
2711 if (!mac_enforce_process)
2712 return (0);
2713
2714 MAC_CHECK(check_proc_debug, cred, proc);
2715
2716 return (error);
2717}
2718
2719int
2720mac_check_proc_sched(struct ucred *cred, struct proc *proc)
2721{
2722 int error;
2723
2724 PROC_LOCK_ASSERT(proc, MA_OWNED);
2725
2726 if (!mac_enforce_process)
2727 return (0);
2728
2729 MAC_CHECK(check_proc_sched, cred, proc);
2730
2731 return (error);
2732}
2733
2734int
2735mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2736{
2737 int error;
2738
2739 PROC_LOCK_ASSERT(proc, MA_OWNED);
2740
2741 if (!mac_enforce_process)
2742 return (0);
2743
2744 MAC_CHECK(check_proc_signal, cred, proc, signum);
2745
2746 return (error);
2747}
2748
2749int
2750mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
2751 struct sockaddr *sockaddr)
2752{
2753 int error;
2754
2755 if (!mac_enforce_socket)
2756 return (0);
2757
2758 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
2759 sockaddr);
2760
2761 return (error);
2762}
2763
2764int
2765mac_check_socket_connect(struct ucred *cred, struct socket *socket,
2766 struct sockaddr *sockaddr)
2767{
2768 int error;
2769
2770 if (!mac_enforce_socket)
2771 return (0);
2772
2773 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
2774 sockaddr);
2775
2776 return (error);
2777}
2778
2779int
2780mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2781{
2782 struct label *label;
2783 int error;
2784
2785 if (!mac_enforce_socket)
2786 return (0);
2787
2788 label = mbuf_to_label(mbuf);
2789
2790 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
2791 label);
2792
2793 return (error);
2794}
2795
2796int
2797mac_check_socket_listen(struct ucred *cred, struct socket *socket)
2798{
2799 int error;
2800
2801 if (!mac_enforce_socket)
2802 return (0);
2803
2804 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
2805 return (error);
2806}
2807
2808int
2809mac_check_socket_receive(struct ucred *cred, struct socket *so)
2810{
2811 int error;
2812
2813 if (!mac_enforce_socket)
2814 return (0);
2815
2816 MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
2817
2818 return (error);
2819}
2820
2821static int
2822mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
2823 struct label *newlabel)
2824{
2825 int error;
2826
2827 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
2828 newlabel);
2829
2830 return (error);
2831}
2832
2833int
2834mac_check_socket_send(struct ucred *cred, struct socket *so)
2835{
2836 int error;
2837
2838 if (!mac_enforce_socket)
2839 return (0);
2840
2841 MAC_CHECK(check_socket_send, cred, so, &so->so_label);
2842
2843 return (error);
2844}
2845
2846int
2847mac_check_socket_visible(struct ucred *cred, struct socket *socket)
2848{
2849 int error;
2850
2851 if (!mac_enforce_socket)
2852 return (0);
2853
2854 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
2855
2856 return (error);
2857}
2858
2859int
2860mac_check_sysarch_ioperm(struct ucred *cred)
2861{
2862 int error;
2863
2864 if (!mac_enforce_system)
2865 return (0);
2866
2867 MAC_CHECK(check_sysarch_ioperm, cred);
2868 return (error);
2869}
2870
2871int
2872mac_check_system_acct(struct ucred *cred, struct vnode *vp)
2873{
2874 int error;
2875
2876 if (vp != NULL) {
2877 ASSERT_VOP_LOCKED(vp, "mac_check_system_acct");
2878 }
2879
2880 if (!mac_enforce_system)
2881 return (0);
2882
2883 MAC_CHECK(check_system_acct, cred, vp,
2884 vp != NULL ? &vp->v_label : NULL);
2885
2886 return (error);
2887}
2888
2889int
2890mac_check_system_nfsd(struct ucred *cred)
2891{
2892 int error;
2893
2894 if (!mac_enforce_system)
2895 return (0);
2896
2897 MAC_CHECK(check_system_nfsd, cred);
2898
2899 return (error);
2900}
2901
2902int
2903mac_check_system_reboot(struct ucred *cred, int howto)
2904{
2905 int error;
2906
2907 if (!mac_enforce_system)
2908 return (0);
2909
2910 MAC_CHECK(check_system_reboot, cred, howto);
2911
2912 return (error);
2913}
2914
2915int
2916mac_check_system_settime(struct ucred *cred)
2917{
2918 int error;
2919
2920 if (!mac_enforce_system)
2921 return (0);
2922
2923 MAC_CHECK(check_system_settime, cred);
2924
2925 return (error);
2926}
2927
2928int
2929mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
2930{
2931 int error;
2932
2933 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon");
2934
2935 if (!mac_enforce_system)
2936 return (0);
2937
2938 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label);
2939 return (error);
2940}
2941
2942int
2943mac_check_system_swapoff(struct ucred *cred, struct vnode *vp)
2944{
2945 int error;
2946
2947 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff");
2948
2949 if (!mac_enforce_system)
2950 return (0);
2951
2952 MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label);
2953 return (error);
2954}
2955
2956int
2957mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
2958 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
2959{
2960 int error;
2961
2962 /*
2963 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
2964 * but since it's not exported from kern_sysctl.c, we can't.
2965 */
2966 if (!mac_enforce_system)
2967 return (0);
2968
2969 MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
2970 inkernel, new, newlen);
2971
2972 return (error);
2973}
2974
2975int
2976mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
2977 struct ifnet *ifnet)
2978{
2979 char *elements, *buffer;
2980 struct mac mac;
2981 int error;
2982
2983 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
2984 if (error)
2985 return (error);
2986
2987 error = mac_check_structmac_consistent(&mac);
2988 if (error)
2989 return (error);
2990
2991 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
2992 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
2993 if (error) {
2994 free(elements, M_MACTEMP);
2995 return (error);
2996 }
2997
2998 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
2999 error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
3000 buffer, mac.m_buflen, M_WAITOK);
3001 if (error == 0)
3002 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
3003
3004 free(buffer, M_MACTEMP);
3005 free(elements, M_MACTEMP);
3006
3007 return (error);
3008}
3009
3010int
3011mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
3012 struct ifnet *ifnet)
3013{
3014 struct label intlabel;
3015 struct mac mac;
3016 char *buffer;
3017 int error;
3018
3019 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
3020 if (error)
3021 return (error);
3022
3023 error = mac_check_structmac_consistent(&mac);
3024 if (error)
3025 return (error);
3026
3027 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
3028 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
3029 if (error) {
3030 free(buffer, M_MACTEMP);
3031 return (error);
3032 }
3033
3034 mac_init_ifnet_label(&intlabel);
3035 error = mac_internalize_ifnet_label(&intlabel, buffer);
3036 free(buffer, M_MACTEMP);
3037 if (error) {
3038 mac_destroy_ifnet_label(&intlabel);
3039 return (error);
3040 }
3041
3042 /*
3043 * XXX: Note that this is a redundant privilege check, since
3044 * policies impose this check themselves if required by the
3045 * policy. Eventually, this should go away.
3046 */
3047 error = suser_cred(cred, 0);
3048 if (error) {
3049 mac_destroy_ifnet_label(&intlabel);
3050 return (error);
3051 }
3052
3053 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
3054 &intlabel);
3055 if (error) {
3056 mac_destroy_ifnet_label(&intlabel);
3057 return (error);
3058 }
3059
3060 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
3061
3062 mac_destroy_ifnet_label(&intlabel);
3063 return (0);
3064}
3065
3066void
3067mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de)
3068{
3069
3070 MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label);
3071}
3072
3073void
3074mac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
3075 struct devfs_dirent *dd, struct devfs_dirent *de)
3076{
3077
3078 MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de,
3079 &de->de_label);
3080}
3081
3082void
3083mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen,
3084 struct devfs_dirent *de)
3085{
3086
3087 MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de,
3088 &de->de_label);
3089}
3090
3091int
3092mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
3093 struct mac *mac)
3094{
3095 struct label intlabel;
3096 char *buffer;
3097 int error;
3098
3099 error = mac_check_structmac_consistent(mac);
3100 if (error)
3101 return (error);
3102
3103 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3104 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
3105 if (error) {
3106 free(buffer, M_MACTEMP);
3107 return (error);
3108 }
3109
3110 mac_init_socket_label(&intlabel, M_WAITOK);
3111 error = mac_internalize_socket_label(&intlabel, buffer);
3112 free(buffer, M_MACTEMP);
3113 if (error) {
3114 mac_destroy_socket_label(&intlabel);
3115 return (error);
3116 }
3117
3118 mac_check_socket_relabel(cred, so, &intlabel);
3119 if (error) {
3120 mac_destroy_socket_label(&intlabel);
3121 return (error);
3122 }
3123
3124 mac_relabel_socket(cred, so, &intlabel);
3125
3126 mac_destroy_socket_label(&intlabel);
3127 return (0);
3128}
3129
3130int
3131mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
3132{
3133 int error;
3134
3135 PIPE_LOCK_ASSERT(pipe, MA_OWNED);
3136
3137 error = mac_check_pipe_relabel(cred, pipe, label);
3138 if (error)
3139 return (error);
3140
3141 mac_relabel_pipe(cred, pipe, label);
3142
3143 return (0);
3144}
3145
3146int
3147mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
3148 struct mac *mac)
3149{
3150 char *buffer, *elements;
3151 int error;
3152
3153 error = mac_check_structmac_consistent(mac);
3154 if (error)
3155 return (error);
3156
3157 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3158 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3159 if (error) {
3160 free(elements, M_MACTEMP);
3161 return (error);
3162 }
3163
3164 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3165 error = mac_externalize_socket_label(&so->so_label, elements,
3166 buffer, mac->m_buflen, M_WAITOK);
3167 if (error == 0)
3168 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3169
3170 free(buffer, M_MACTEMP);
3171 free(elements, M_MACTEMP);
3172
3173 return (error);
3174}
3175
3176int
3177mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
3178 struct mac *mac)
3179{
3180 char *elements, *buffer;
3181 int error;
3182
3183 error = mac_check_structmac_consistent(mac);
3184 if (error)
3185 return (error);
3186
3187 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
3188 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
3189 if (error) {
3190 free(elements, M_MACTEMP);
3191 return (error);
3192 }
3193
3194 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
3195 error = mac_externalize_socket_peer_label(&so->so_peerlabel,
3196 elements, buffer, mac->m_buflen, M_WAITOK);
3197 if (error == 0)
3198 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
3199
3200 free(buffer, M_MACTEMP);
3201 free(elements, M_MACTEMP);
3202
3203 return (error);
3204}
3205
3206/*
3207 * Implementation of VOP_SETLABEL() that relies on extended attributes
3208 * to store label data. Can be referenced by filesystems supporting
3209 * extended attributes.
3210 */
3211int
3212vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
3213{
3214 struct vnode *vp = ap->a_vp;
3215 struct label *intlabel = ap->a_label;
3216 int error;
3217
3218 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
3219
3220 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3221 return (EOPNOTSUPP);
3222
3223 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
3224 if (error)
3225 return (error);
3226
3227 mac_relabel_vnode(ap->a_cred, vp, intlabel);
3228
3229 return (0);
3230}
3231
3232static int
3233vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
3234{
3235 int error;
3236
3237 if (vp->v_mount == NULL) {
3238 /* printf("vn_setlabel: null v_mount\n"); */
3239 if (vp->v_type != VNON)
3240 printf("vn_setlabel: null v_mount with non-VNON\n");
3241 return (EBADF);
3242 }
3243
3244 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
3245 return (EOPNOTSUPP);
3246
3247 /*
3248 * Multi-phase commit. First check the policies to confirm the
3249 * change is OK. Then commit via the filesystem. Finally,
3250 * update the actual vnode label. Question: maybe the filesystem
3251 * should update the vnode at the end as part of VOP_SETLABEL()?
3252 */
3253 error = mac_check_vnode_relabel(cred, vp, intlabel);
3254 if (error)
3255 return (error);
3256
3257 /*
3258 * VADMIN provides the opportunity for the filesystem to make
3259 * decisions about who is and is not able to modify labels
3260 * and protections on files. This might not be right. We can't
3261 * assume VOP_SETLABEL() will do it, because we might implement
3262 * that as part of vop_stdsetlabel_ea().
3263 */
3264 error = VOP_ACCESS(vp, VADMIN, cred, curthread);
3265 if (error)
3266 return (error);
3267
3268 error = VOP_SETLABEL(vp, intlabel, cred, curthread);
3269 if (error)
3270 return (error);
3271
3272 return (0);
3273}
3274
3275int
|