diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 337 |
1 files changed, 246 insertions, 91 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 15c2a08a66f1..bb230d5d7085 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -13,8 +13,8 @@ | |||
| 13 | * Eric Paris <eparis@redhat.com> | 13 | * Eric Paris <eparis@redhat.com> |
| 14 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 14 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
| 15 | * <dgoeddel@trustedcs.com> | 15 | * <dgoeddel@trustedcs.com> |
| 16 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. | 16 | * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P. |
| 17 | * Paul Moore <paul.moore@hp.com> | 17 | * Paul Moore <paul.moore@hp.com> |
| 18 | * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. | 18 | * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. |
| 19 | * Yuichi Nakamura <ynakam@hitachisoft.jp> | 19 | * Yuichi Nakamura <ynakam@hitachisoft.jp> |
| 20 | * | 20 | * |
| @@ -448,6 +448,10 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
| 448 | sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) | 448 | sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) |
| 449 | sbsec->flags &= ~SE_SBLABELSUPP; | 449 | sbsec->flags &= ~SE_SBLABELSUPP; |
| 450 | 450 | ||
| 451 | /* Special handling for sysfs. Is genfs but also has setxattr handler*/ | ||
| 452 | if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0) | ||
| 453 | sbsec->flags |= SE_SBLABELSUPP; | ||
| 454 | |||
| 451 | /* Initialize the root inode. */ | 455 | /* Initialize the root inode. */ |
| 452 | rc = inode_doinit_with_dentry(root_inode, root); | 456 | rc = inode_doinit_with_dentry(root_inode, root); |
| 453 | 457 | ||
| @@ -1285,6 +1289,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1285 | rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, | 1289 | rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, |
| 1286 | context, len); | 1290 | context, len); |
| 1287 | if (rc == -ERANGE) { | 1291 | if (rc == -ERANGE) { |
| 1292 | kfree(context); | ||
| 1293 | |||
| 1288 | /* Need a larger buffer. Query for the right size. */ | 1294 | /* Need a larger buffer. Query for the right size. */ |
| 1289 | rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, | 1295 | rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, |
| 1290 | NULL, 0); | 1296 | NULL, 0); |
| @@ -1292,7 +1298,6 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1292 | dput(dentry); | 1298 | dput(dentry); |
| 1293 | goto out_unlock; | 1299 | goto out_unlock; |
| 1294 | } | 1300 | } |
| 1295 | kfree(context); | ||
| 1296 | len = rc; | 1301 | len = rc; |
| 1297 | context = kmalloc(len+1, GFP_NOFS); | 1302 | context = kmalloc(len+1, GFP_NOFS); |
| 1298 | if (!context) { | 1303 | if (!context) { |
| @@ -1478,14 +1483,14 @@ static int task_has_capability(struct task_struct *tsk, | |||
| 1478 | const struct cred *cred, | 1483 | const struct cred *cred, |
| 1479 | int cap, int audit) | 1484 | int cap, int audit) |
| 1480 | { | 1485 | { |
| 1481 | struct avc_audit_data ad; | 1486 | struct common_audit_data ad; |
| 1482 | struct av_decision avd; | 1487 | struct av_decision avd; |
| 1483 | u16 sclass; | 1488 | u16 sclass; |
| 1484 | u32 sid = cred_sid(cred); | 1489 | u32 sid = cred_sid(cred); |
| 1485 | u32 av = CAP_TO_MASK(cap); | 1490 | u32 av = CAP_TO_MASK(cap); |
| 1486 | int rc; | 1491 | int rc; |
| 1487 | 1492 | ||
| 1488 | AVC_AUDIT_DATA_INIT(&ad, CAP); | 1493 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
| 1489 | ad.tsk = tsk; | 1494 | ad.tsk = tsk; |
| 1490 | ad.u.cap = cap; | 1495 | ad.u.cap = cap; |
| 1491 | 1496 | ||
| @@ -1524,12 +1529,14 @@ static int task_has_system(struct task_struct *tsk, | |||
| 1524 | static int inode_has_perm(const struct cred *cred, | 1529 | static int inode_has_perm(const struct cred *cred, |
| 1525 | struct inode *inode, | 1530 | struct inode *inode, |
| 1526 | u32 perms, | 1531 | u32 perms, |
| 1527 | struct avc_audit_data *adp) | 1532 | struct common_audit_data *adp) |
| 1528 | { | 1533 | { |
| 1529 | struct inode_security_struct *isec; | 1534 | struct inode_security_struct *isec; |
| 1530 | struct avc_audit_data ad; | 1535 | struct common_audit_data ad; |
| 1531 | u32 sid; | 1536 | u32 sid; |
| 1532 | 1537 | ||
| 1538 | validate_creds(cred); | ||
| 1539 | |||
| 1533 | if (unlikely(IS_PRIVATE(inode))) | 1540 | if (unlikely(IS_PRIVATE(inode))) |
| 1534 | return 0; | 1541 | return 0; |
| 1535 | 1542 | ||
| @@ -1538,7 +1545,7 @@ static int inode_has_perm(const struct cred *cred, | |||
| 1538 | 1545 | ||
| 1539 | if (!adp) { | 1546 | if (!adp) { |
| 1540 | adp = &ad; | 1547 | adp = &ad; |
| 1541 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1548 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 1542 | ad.u.fs.inode = inode; | 1549 | ad.u.fs.inode = inode; |
| 1543 | } | 1550 | } |
| 1544 | 1551 | ||
| @@ -1554,9 +1561,9 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
| 1554 | u32 av) | 1561 | u32 av) |
| 1555 | { | 1562 | { |
| 1556 | struct inode *inode = dentry->d_inode; | 1563 | struct inode *inode = dentry->d_inode; |
| 1557 | struct avc_audit_data ad; | 1564 | struct common_audit_data ad; |
| 1558 | 1565 | ||
| 1559 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1566 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 1560 | ad.u.fs.path.mnt = mnt; | 1567 | ad.u.fs.path.mnt = mnt; |
| 1561 | ad.u.fs.path.dentry = dentry; | 1568 | ad.u.fs.path.dentry = dentry; |
| 1562 | return inode_has_perm(cred, inode, av, &ad); | 1569 | return inode_has_perm(cred, inode, av, &ad); |
| @@ -1576,11 +1583,11 @@ static int file_has_perm(const struct cred *cred, | |||
| 1576 | { | 1583 | { |
| 1577 | struct file_security_struct *fsec = file->f_security; | 1584 | struct file_security_struct *fsec = file->f_security; |
| 1578 | struct inode *inode = file->f_path.dentry->d_inode; | 1585 | struct inode *inode = file->f_path.dentry->d_inode; |
| 1579 | struct avc_audit_data ad; | 1586 | struct common_audit_data ad; |
| 1580 | u32 sid = cred_sid(cred); | 1587 | u32 sid = cred_sid(cred); |
| 1581 | int rc; | 1588 | int rc; |
| 1582 | 1589 | ||
| 1583 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1590 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 1584 | ad.u.fs.path = file->f_path; | 1591 | ad.u.fs.path = file->f_path; |
| 1585 | 1592 | ||
| 1586 | if (sid != fsec->sid) { | 1593 | if (sid != fsec->sid) { |
| @@ -1611,7 +1618,7 @@ static int may_create(struct inode *dir, | |||
| 1611 | struct inode_security_struct *dsec; | 1618 | struct inode_security_struct *dsec; |
| 1612 | struct superblock_security_struct *sbsec; | 1619 | struct superblock_security_struct *sbsec; |
| 1613 | u32 sid, newsid; | 1620 | u32 sid, newsid; |
| 1614 | struct avc_audit_data ad; | 1621 | struct common_audit_data ad; |
| 1615 | int rc; | 1622 | int rc; |
| 1616 | 1623 | ||
| 1617 | dsec = dir->i_security; | 1624 | dsec = dir->i_security; |
| @@ -1620,7 +1627,7 @@ static int may_create(struct inode *dir, | |||
| 1620 | sid = tsec->sid; | 1627 | sid = tsec->sid; |
| 1621 | newsid = tsec->create_sid; | 1628 | newsid = tsec->create_sid; |
| 1622 | 1629 | ||
| 1623 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1630 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 1624 | ad.u.fs.path.dentry = dentry; | 1631 | ad.u.fs.path.dentry = dentry; |
| 1625 | 1632 | ||
| 1626 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, | 1633 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, |
| @@ -1664,7 +1671,7 @@ static int may_link(struct inode *dir, | |||
| 1664 | 1671 | ||
| 1665 | { | 1672 | { |
| 1666 | struct inode_security_struct *dsec, *isec; | 1673 | struct inode_security_struct *dsec, *isec; |
| 1667 | struct avc_audit_data ad; | 1674 | struct common_audit_data ad; |
| 1668 | u32 sid = current_sid(); | 1675 | u32 sid = current_sid(); |
| 1669 | u32 av; | 1676 | u32 av; |
| 1670 | int rc; | 1677 | int rc; |
| @@ -1672,7 +1679,7 @@ static int may_link(struct inode *dir, | |||
| 1672 | dsec = dir->i_security; | 1679 | dsec = dir->i_security; |
| 1673 | isec = dentry->d_inode->i_security; | 1680 | isec = dentry->d_inode->i_security; |
| 1674 | 1681 | ||
| 1675 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1682 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 1676 | ad.u.fs.path.dentry = dentry; | 1683 | ad.u.fs.path.dentry = dentry; |
| 1677 | 1684 | ||
| 1678 | av = DIR__SEARCH; | 1685 | av = DIR__SEARCH; |
| @@ -1707,7 +1714,7 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1707 | struct dentry *new_dentry) | 1714 | struct dentry *new_dentry) |
| 1708 | { | 1715 | { |
| 1709 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; | 1716 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; |
| 1710 | struct avc_audit_data ad; | 1717 | struct common_audit_data ad; |
| 1711 | u32 sid = current_sid(); | 1718 | u32 sid = current_sid(); |
| 1712 | u32 av; | 1719 | u32 av; |
| 1713 | int old_is_dir, new_is_dir; | 1720 | int old_is_dir, new_is_dir; |
| @@ -1718,7 +1725,7 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1718 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); | 1725 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); |
| 1719 | new_dsec = new_dir->i_security; | 1726 | new_dsec = new_dir->i_security; |
| 1720 | 1727 | ||
| 1721 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1728 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 1722 | 1729 | ||
| 1723 | ad.u.fs.path.dentry = old_dentry; | 1730 | ad.u.fs.path.dentry = old_dentry; |
| 1724 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, | 1731 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, |
| @@ -1760,7 +1767,7 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1760 | static int superblock_has_perm(const struct cred *cred, | 1767 | static int superblock_has_perm(const struct cred *cred, |
| 1761 | struct super_block *sb, | 1768 | struct super_block *sb, |
| 1762 | u32 perms, | 1769 | u32 perms, |
| 1763 | struct avc_audit_data *ad) | 1770 | struct common_audit_data *ad) |
| 1764 | { | 1771 | { |
| 1765 | struct superblock_security_struct *sbsec; | 1772 | struct superblock_security_struct *sbsec; |
| 1766 | u32 sid = cred_sid(cred); | 1773 | u32 sid = cred_sid(cred); |
| @@ -1854,12 +1861,12 @@ static inline u32 open_file_to_av(struct file *file) | |||
| 1854 | 1861 | ||
| 1855 | /* Hook functions begin here. */ | 1862 | /* Hook functions begin here. */ |
| 1856 | 1863 | ||
| 1857 | static int selinux_ptrace_may_access(struct task_struct *child, | 1864 | static int selinux_ptrace_access_check(struct task_struct *child, |
| 1858 | unsigned int mode) | 1865 | unsigned int mode) |
| 1859 | { | 1866 | { |
| 1860 | int rc; | 1867 | int rc; |
| 1861 | 1868 | ||
| 1862 | rc = cap_ptrace_may_access(child, mode); | 1869 | rc = cap_ptrace_access_check(child, mode); |
| 1863 | if (rc) | 1870 | if (rc) |
| 1864 | return rc; | 1871 | return rc; |
| 1865 | 1872 | ||
| @@ -2100,7 +2107,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
| 2100 | const struct task_security_struct *old_tsec; | 2107 | const struct task_security_struct *old_tsec; |
| 2101 | struct task_security_struct *new_tsec; | 2108 | struct task_security_struct *new_tsec; |
| 2102 | struct inode_security_struct *isec; | 2109 | struct inode_security_struct *isec; |
| 2103 | struct avc_audit_data ad; | 2110 | struct common_audit_data ad; |
| 2104 | struct inode *inode = bprm->file->f_path.dentry->d_inode; | 2111 | struct inode *inode = bprm->file->f_path.dentry->d_inode; |
| 2105 | int rc; | 2112 | int rc; |
| 2106 | 2113 | ||
| @@ -2138,7 +2145,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
| 2138 | return rc; | 2145 | return rc; |
| 2139 | } | 2146 | } |
| 2140 | 2147 | ||
| 2141 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2148 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 2142 | ad.u.fs.path = bprm->file->f_path; | 2149 | ad.u.fs.path = bprm->file->f_path; |
| 2143 | 2150 | ||
| 2144 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | 2151 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) |
| @@ -2231,7 +2238,7 @@ extern struct dentry *selinux_null; | |||
| 2231 | static inline void flush_unauthorized_files(const struct cred *cred, | 2238 | static inline void flush_unauthorized_files(const struct cred *cred, |
| 2232 | struct files_struct *files) | 2239 | struct files_struct *files) |
| 2233 | { | 2240 | { |
| 2234 | struct avc_audit_data ad; | 2241 | struct common_audit_data ad; |
| 2235 | struct file *file, *devnull = NULL; | 2242 | struct file *file, *devnull = NULL; |
| 2236 | struct tty_struct *tty; | 2243 | struct tty_struct *tty; |
| 2237 | struct fdtable *fdt; | 2244 | struct fdtable *fdt; |
| @@ -2265,7 +2272,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
| 2265 | 2272 | ||
| 2266 | /* Revalidate access to inherited open files. */ | 2273 | /* Revalidate access to inherited open files. */ |
| 2267 | 2274 | ||
| 2268 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2275 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 2269 | 2276 | ||
| 2270 | spin_lock(&files->file_lock); | 2277 | spin_lock(&files->file_lock); |
| 2271 | for (;;) { | 2278 | for (;;) { |
| @@ -2404,7 +2411,7 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) | |||
| 2404 | /* Wake up the parent if it is waiting so that it can recheck | 2411 | /* Wake up the parent if it is waiting so that it can recheck |
| 2405 | * wait permission to the new task SID. */ | 2412 | * wait permission to the new task SID. */ |
| 2406 | read_lock(&tasklist_lock); | 2413 | read_lock(&tasklist_lock); |
| 2407 | wake_up_interruptible(¤t->real_parent->signal->wait_chldexit); | 2414 | __wake_up_parent(current, current->real_parent); |
| 2408 | read_unlock(&tasklist_lock); | 2415 | read_unlock(&tasklist_lock); |
| 2409 | } | 2416 | } |
| 2410 | 2417 | ||
| @@ -2514,7 +2521,7 @@ out: | |||
| 2514 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | 2521 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 2515 | { | 2522 | { |
| 2516 | const struct cred *cred = current_cred(); | 2523 | const struct cred *cred = current_cred(); |
| 2517 | struct avc_audit_data ad; | 2524 | struct common_audit_data ad; |
| 2518 | int rc; | 2525 | int rc; |
| 2519 | 2526 | ||
| 2520 | rc = superblock_doinit(sb, data); | 2527 | rc = superblock_doinit(sb, data); |
| @@ -2525,7 +2532,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
| 2525 | if (flags & MS_KERNMOUNT) | 2532 | if (flags & MS_KERNMOUNT) |
| 2526 | return 0; | 2533 | return 0; |
| 2527 | 2534 | ||
| 2528 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2535 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 2529 | ad.u.fs.path.dentry = sb->s_root; | 2536 | ad.u.fs.path.dentry = sb->s_root; |
| 2530 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); | 2537 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); |
| 2531 | } | 2538 | } |
| @@ -2533,9 +2540,9 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
| 2533 | static int selinux_sb_statfs(struct dentry *dentry) | 2540 | static int selinux_sb_statfs(struct dentry *dentry) |
| 2534 | { | 2541 | { |
| 2535 | const struct cred *cred = current_cred(); | 2542 | const struct cred *cred = current_cred(); |
| 2536 | struct avc_audit_data ad; | 2543 | struct common_audit_data ad; |
| 2537 | 2544 | ||
| 2538 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2545 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 2539 | ad.u.fs.path.dentry = dentry->d_sb->s_root; | 2546 | ad.u.fs.path.dentry = dentry->d_sb->s_root; |
| 2540 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); | 2547 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
| 2541 | } | 2548 | } |
| @@ -2710,12 +2717,18 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
| 2710 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2717 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
| 2711 | { | 2718 | { |
| 2712 | const struct cred *cred = current_cred(); | 2719 | const struct cred *cred = current_cred(); |
| 2720 | unsigned int ia_valid = iattr->ia_valid; | ||
| 2721 | |||
| 2722 | /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */ | ||
| 2723 | if (ia_valid & ATTR_FORCE) { | ||
| 2724 | ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE | | ||
| 2725 | ATTR_FORCE); | ||
| 2726 | if (!ia_valid) | ||
| 2727 | return 0; | ||
| 2728 | } | ||
| 2713 | 2729 | ||
| 2714 | if (iattr->ia_valid & ATTR_FORCE) | 2730 | if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | |
| 2715 | return 0; | 2731 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) |
| 2716 | |||
| 2717 | if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | | ||
| 2718 | ATTR_ATIME_SET | ATTR_MTIME_SET)) | ||
| 2719 | return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); | 2732 | return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); |
| 2720 | 2733 | ||
| 2721 | return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); | 2734 | return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); |
| @@ -2755,7 +2768,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 2755 | struct inode *inode = dentry->d_inode; | 2768 | struct inode *inode = dentry->d_inode; |
| 2756 | struct inode_security_struct *isec = inode->i_security; | 2769 | struct inode_security_struct *isec = inode->i_security; |
| 2757 | struct superblock_security_struct *sbsec; | 2770 | struct superblock_security_struct *sbsec; |
| 2758 | struct avc_audit_data ad; | 2771 | struct common_audit_data ad; |
| 2759 | u32 newsid, sid = current_sid(); | 2772 | u32 newsid, sid = current_sid(); |
| 2760 | int rc = 0; | 2773 | int rc = 0; |
| 2761 | 2774 | ||
| @@ -2769,7 +2782,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 2769 | if (!is_owner_or_cap(inode)) | 2782 | if (!is_owner_or_cap(inode)) |
| 2770 | return -EPERM; | 2783 | return -EPERM; |
| 2771 | 2784 | ||
| 2772 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2785 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 2773 | ad.u.fs.path.dentry = dentry; | 2786 | ad.u.fs.path.dentry = dentry; |
| 2774 | 2787 | ||
| 2775 | rc = avc_has_perm(sid, isec->sid, isec->sclass, | 2788 | rc = avc_has_perm(sid, isec->sid, isec->sclass, |
| @@ -2914,6 +2927,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
| 2914 | return rc; | 2927 | return rc; |
| 2915 | 2928 | ||
| 2916 | isec->sid = newsid; | 2929 | isec->sid = newsid; |
| 2930 | isec->initialized = 1; | ||
| 2917 | return 0; | 2931 | return 0; |
| 2918 | } | 2932 | } |
| 2919 | 2933 | ||
| @@ -2938,11 +2952,6 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
| 2938 | const struct cred *cred = current_cred(); | 2952 | const struct cred *cred = current_cred(); |
| 2939 | struct inode *inode = file->f_path.dentry->d_inode; | 2953 | struct inode *inode = file->f_path.dentry->d_inode; |
| 2940 | 2954 | ||
| 2941 | if (!mask) { | ||
| 2942 | /* No permission to check. Existence test. */ | ||
| 2943 | return 0; | ||
| 2944 | } | ||
| 2945 | |||
| 2946 | /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ | 2955 | /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ |
| 2947 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) | 2956 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
| 2948 | mask |= MAY_APPEND; | 2957 | mask |= MAY_APPEND; |
| @@ -2953,10 +2962,20 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
| 2953 | 2962 | ||
| 2954 | static int selinux_file_permission(struct file *file, int mask) | 2963 | static int selinux_file_permission(struct file *file, int mask) |
| 2955 | { | 2964 | { |
| 2965 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 2966 | struct file_security_struct *fsec = file->f_security; | ||
| 2967 | struct inode_security_struct *isec = inode->i_security; | ||
| 2968 | u32 sid = current_sid(); | ||
| 2969 | |||
| 2956 | if (!mask) | 2970 | if (!mask) |
| 2957 | /* No permission to check. Existence test. */ | 2971 | /* No permission to check. Existence test. */ |
| 2958 | return 0; | 2972 | return 0; |
| 2959 | 2973 | ||
| 2974 | if (sid == fsec->sid && fsec->isid == isec->sid && | ||
| 2975 | fsec->pseqno == avc_policy_seqno()) | ||
| 2976 | /* No change since dentry_open check. */ | ||
| 2977 | return 0; | ||
| 2978 | |||
| 2960 | return selinux_revalidate_file_permission(file, mask); | 2979 | return selinux_revalidate_file_permission(file, mask); |
| 2961 | } | 2980 | } |
| 2962 | 2981 | ||
| @@ -3029,9 +3048,21 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot, | |||
| 3029 | int rc = 0; | 3048 | int rc = 0; |
| 3030 | u32 sid = current_sid(); | 3049 | u32 sid = current_sid(); |
| 3031 | 3050 | ||
| 3032 | if (addr < mmap_min_addr) | 3051 | /* |
| 3052 | * notice that we are intentionally putting the SELinux check before | ||
| 3053 | * the secondary cap_file_mmap check. This is such a likely attempt | ||
| 3054 | * at bad behaviour/exploit that we always want to get the AVC, even | ||
| 3055 | * if DAC would have also denied the operation. | ||
| 3056 | */ | ||
| 3057 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { | ||
| 3033 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, | 3058 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, |
| 3034 | MEMPROTECT__MMAP_ZERO, NULL); | 3059 | MEMPROTECT__MMAP_ZERO, NULL); |
| 3060 | if (rc) | ||
| 3061 | return rc; | ||
| 3062 | } | ||
| 3063 | |||
| 3064 | /* do DAC check on address space usage */ | ||
| 3065 | rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only); | ||
| 3035 | if (rc || addr_only) | 3066 | if (rc || addr_only) |
| 3036 | return rc; | 3067 | return rc; |
| 3037 | 3068 | ||
| @@ -3207,12 +3238,29 @@ static int selinux_task_create(unsigned long clone_flags) | |||
| 3207 | } | 3238 | } |
| 3208 | 3239 | ||
| 3209 | /* | 3240 | /* |
| 3241 | * allocate the SELinux part of blank credentials | ||
| 3242 | */ | ||
| 3243 | static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
| 3244 | { | ||
| 3245 | struct task_security_struct *tsec; | ||
| 3246 | |||
| 3247 | tsec = kzalloc(sizeof(struct task_security_struct), gfp); | ||
| 3248 | if (!tsec) | ||
| 3249 | return -ENOMEM; | ||
| 3250 | |||
| 3251 | cred->security = tsec; | ||
| 3252 | return 0; | ||
| 3253 | } | ||
| 3254 | |||
| 3255 | /* | ||
| 3210 | * detach and free the LSM part of a set of credentials | 3256 | * detach and free the LSM part of a set of credentials |
| 3211 | */ | 3257 | */ |
| 3212 | static void selinux_cred_free(struct cred *cred) | 3258 | static void selinux_cred_free(struct cred *cred) |
| 3213 | { | 3259 | { |
| 3214 | struct task_security_struct *tsec = cred->security; | 3260 | struct task_security_struct *tsec = cred->security; |
| 3215 | cred->security = NULL; | 3261 | |
| 3262 | BUG_ON((unsigned long) cred->security < PAGE_SIZE); | ||
| 3263 | cred->security = (void *) 0x7UL; | ||
| 3216 | kfree(tsec); | 3264 | kfree(tsec); |
| 3217 | } | 3265 | } |
| 3218 | 3266 | ||
| @@ -3236,6 +3284,17 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old, | |||
| 3236 | } | 3284 | } |
| 3237 | 3285 | ||
| 3238 | /* | 3286 | /* |
| 3287 | * transfer the SELinux data to a blank set of creds | ||
| 3288 | */ | ||
| 3289 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) | ||
| 3290 | { | ||
| 3291 | const struct task_security_struct *old_tsec = old->security; | ||
| 3292 | struct task_security_struct *tsec = new->security; | ||
| 3293 | |||
| 3294 | *tsec = *old_tsec; | ||
| 3295 | } | ||
| 3296 | |||
| 3297 | /* | ||
| 3239 | * set the security data for a kernel service | 3298 | * set the security data for a kernel service |
| 3240 | * - all the creation contexts are set to unlabelled | 3299 | * - all the creation contexts are set to unlabelled |
| 3241 | */ | 3300 | */ |
| @@ -3279,6 +3338,11 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
| 3279 | return 0; | 3338 | return 0; |
| 3280 | } | 3339 | } |
| 3281 | 3340 | ||
| 3341 | static int selinux_kernel_module_request(void) | ||
| 3342 | { | ||
| 3343 | return task_has_system(current, SYSTEM__MODULE_REQUEST); | ||
| 3344 | } | ||
| 3345 | |||
| 3282 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) | 3346 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) |
| 3283 | { | 3347 | { |
| 3284 | return current_has_perm(p, PROCESS__SETPGID); | 3348 | return current_has_perm(p, PROCESS__SETPGID); |
| @@ -3396,7 +3460,7 @@ static void selinux_task_to_inode(struct task_struct *p, | |||
| 3396 | 3460 | ||
| 3397 | /* Returns error only if unable to parse addresses */ | 3461 | /* Returns error only if unable to parse addresses */ |
| 3398 | static int selinux_parse_skb_ipv4(struct sk_buff *skb, | 3462 | static int selinux_parse_skb_ipv4(struct sk_buff *skb, |
| 3399 | struct avc_audit_data *ad, u8 *proto) | 3463 | struct common_audit_data *ad, u8 *proto) |
| 3400 | { | 3464 | { |
| 3401 | int offset, ihlen, ret = -EINVAL; | 3465 | int offset, ihlen, ret = -EINVAL; |
| 3402 | struct iphdr _iph, *ih; | 3466 | struct iphdr _iph, *ih; |
| @@ -3477,7 +3541,7 @@ out: | |||
| 3477 | 3541 | ||
| 3478 | /* Returns error only if unable to parse addresses */ | 3542 | /* Returns error only if unable to parse addresses */ |
| 3479 | static int selinux_parse_skb_ipv6(struct sk_buff *skb, | 3543 | static int selinux_parse_skb_ipv6(struct sk_buff *skb, |
| 3480 | struct avc_audit_data *ad, u8 *proto) | 3544 | struct common_audit_data *ad, u8 *proto) |
| 3481 | { | 3545 | { |
| 3482 | u8 nexthdr; | 3546 | u8 nexthdr; |
| 3483 | int ret = -EINVAL, offset; | 3547 | int ret = -EINVAL, offset; |
| @@ -3548,7 +3612,7 @@ out: | |||
| 3548 | 3612 | ||
| 3549 | #endif /* IPV6 */ | 3613 | #endif /* IPV6 */ |
| 3550 | 3614 | ||
| 3551 | static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, | 3615 | static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, |
| 3552 | char **_addrp, int src, u8 *proto) | 3616 | char **_addrp, int src, u8 *proto) |
| 3553 | { | 3617 | { |
| 3554 | char *addrp; | 3618 | char *addrp; |
| @@ -3630,7 +3694,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, | |||
| 3630 | u32 perms) | 3694 | u32 perms) |
| 3631 | { | 3695 | { |
| 3632 | struct inode_security_struct *isec; | 3696 | struct inode_security_struct *isec; |
| 3633 | struct avc_audit_data ad; | 3697 | struct common_audit_data ad; |
| 3634 | u32 sid; | 3698 | u32 sid; |
| 3635 | int err = 0; | 3699 | int err = 0; |
| 3636 | 3700 | ||
| @@ -3640,7 +3704,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, | |||
| 3640 | goto out; | 3704 | goto out; |
| 3641 | sid = task_sid(task); | 3705 | sid = task_sid(task); |
| 3642 | 3706 | ||
| 3643 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3707 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 3644 | ad.u.net.sk = sock->sk; | 3708 | ad.u.net.sk = sock->sk; |
| 3645 | err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); | 3709 | err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
| 3646 | 3710 | ||
| @@ -3727,7 +3791,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3727 | if (family == PF_INET || family == PF_INET6) { | 3791 | if (family == PF_INET || family == PF_INET6) { |
| 3728 | char *addrp; | 3792 | char *addrp; |
| 3729 | struct inode_security_struct *isec; | 3793 | struct inode_security_struct *isec; |
| 3730 | struct avc_audit_data ad; | 3794 | struct common_audit_data ad; |
| 3731 | struct sockaddr_in *addr4 = NULL; | 3795 | struct sockaddr_in *addr4 = NULL; |
| 3732 | struct sockaddr_in6 *addr6 = NULL; | 3796 | struct sockaddr_in6 *addr6 = NULL; |
| 3733 | unsigned short snum; | 3797 | unsigned short snum; |
| @@ -3756,7 +3820,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3756 | snum, &sid); | 3820 | snum, &sid); |
| 3757 | if (err) | 3821 | if (err) |
| 3758 | goto out; | 3822 | goto out; |
| 3759 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3823 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 3760 | ad.u.net.sport = htons(snum); | 3824 | ad.u.net.sport = htons(snum); |
| 3761 | ad.u.net.family = family; | 3825 | ad.u.net.family = family; |
| 3762 | err = avc_has_perm(isec->sid, sid, | 3826 | err = avc_has_perm(isec->sid, sid, |
| @@ -3789,7 +3853,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3789 | if (err) | 3853 | if (err) |
| 3790 | goto out; | 3854 | goto out; |
| 3791 | 3855 | ||
| 3792 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3856 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 3793 | ad.u.net.sport = htons(snum); | 3857 | ad.u.net.sport = htons(snum); |
| 3794 | ad.u.net.family = family; | 3858 | ad.u.net.family = family; |
| 3795 | 3859 | ||
| @@ -3823,7 +3887,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
| 3823 | isec = SOCK_INODE(sock)->i_security; | 3887 | isec = SOCK_INODE(sock)->i_security; |
| 3824 | if (isec->sclass == SECCLASS_TCP_SOCKET || | 3888 | if (isec->sclass == SECCLASS_TCP_SOCKET || |
| 3825 | isec->sclass == SECCLASS_DCCP_SOCKET) { | 3889 | isec->sclass == SECCLASS_DCCP_SOCKET) { |
| 3826 | struct avc_audit_data ad; | 3890 | struct common_audit_data ad; |
| 3827 | struct sockaddr_in *addr4 = NULL; | 3891 | struct sockaddr_in *addr4 = NULL; |
| 3828 | struct sockaddr_in6 *addr6 = NULL; | 3892 | struct sockaddr_in6 *addr6 = NULL; |
| 3829 | unsigned short snum; | 3893 | unsigned short snum; |
| @@ -3848,7 +3912,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
| 3848 | perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? | 3912 | perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? |
| 3849 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; | 3913 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; |
| 3850 | 3914 | ||
| 3851 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3915 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 3852 | ad.u.net.dport = htons(snum); | 3916 | ad.u.net.dport = htons(snum); |
| 3853 | ad.u.net.family = sk->sk_family; | 3917 | ad.u.net.family = sk->sk_family; |
| 3854 | err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); | 3918 | err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); |
| @@ -3938,13 +4002,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, | |||
| 3938 | struct sk_security_struct *ssec; | 4002 | struct sk_security_struct *ssec; |
| 3939 | struct inode_security_struct *isec; | 4003 | struct inode_security_struct *isec; |
| 3940 | struct inode_security_struct *other_isec; | 4004 | struct inode_security_struct *other_isec; |
| 3941 | struct avc_audit_data ad; | 4005 | struct common_audit_data ad; |
| 3942 | int err; | 4006 | int err; |
| 3943 | 4007 | ||
| 3944 | isec = SOCK_INODE(sock)->i_security; | 4008 | isec = SOCK_INODE(sock)->i_security; |
| 3945 | other_isec = SOCK_INODE(other)->i_security; | 4009 | other_isec = SOCK_INODE(other)->i_security; |
| 3946 | 4010 | ||
| 3947 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4011 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 3948 | ad.u.net.sk = other->sk; | 4012 | ad.u.net.sk = other->sk; |
| 3949 | 4013 | ||
| 3950 | err = avc_has_perm(isec->sid, other_isec->sid, | 4014 | err = avc_has_perm(isec->sid, other_isec->sid, |
| @@ -3970,13 +4034,13 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
| 3970 | { | 4034 | { |
| 3971 | struct inode_security_struct *isec; | 4035 | struct inode_security_struct *isec; |
| 3972 | struct inode_security_struct *other_isec; | 4036 | struct inode_security_struct *other_isec; |
| 3973 | struct avc_audit_data ad; | 4037 | struct common_audit_data ad; |
| 3974 | int err; | 4038 | int err; |
| 3975 | 4039 | ||
| 3976 | isec = SOCK_INODE(sock)->i_security; | 4040 | isec = SOCK_INODE(sock)->i_security; |
| 3977 | other_isec = SOCK_INODE(other)->i_security; | 4041 | other_isec = SOCK_INODE(other)->i_security; |
| 3978 | 4042 | ||
| 3979 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4043 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 3980 | ad.u.net.sk = other->sk; | 4044 | ad.u.net.sk = other->sk; |
| 3981 | 4045 | ||
| 3982 | err = avc_has_perm(isec->sid, other_isec->sid, | 4046 | err = avc_has_perm(isec->sid, other_isec->sid, |
| @@ -3989,7 +4053,7 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
| 3989 | 4053 | ||
| 3990 | static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, | 4054 | static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, |
| 3991 | u32 peer_sid, | 4055 | u32 peer_sid, |
| 3992 | struct avc_audit_data *ad) | 4056 | struct common_audit_data *ad) |
| 3993 | { | 4057 | { |
| 3994 | int err; | 4058 | int err; |
| 3995 | u32 if_sid; | 4059 | u32 if_sid; |
| @@ -4017,10 +4081,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
| 4017 | struct sk_security_struct *sksec = sk->sk_security; | 4081 | struct sk_security_struct *sksec = sk->sk_security; |
| 4018 | u32 peer_sid; | 4082 | u32 peer_sid; |
| 4019 | u32 sk_sid = sksec->sid; | 4083 | u32 sk_sid = sksec->sid; |
| 4020 | struct avc_audit_data ad; | 4084 | struct common_audit_data ad; |
| 4021 | char *addrp; | 4085 | char *addrp; |
| 4022 | 4086 | ||
| 4023 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4087 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 4024 | ad.u.net.netif = skb->iif; | 4088 | ad.u.net.netif = skb->iif; |
| 4025 | ad.u.net.family = family; | 4089 | ad.u.net.family = family; |
| 4026 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4090 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
| @@ -4058,7 +4122,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
| 4058 | struct sk_security_struct *sksec = sk->sk_security; | 4122 | struct sk_security_struct *sksec = sk->sk_security; |
| 4059 | u16 family = sk->sk_family; | 4123 | u16 family = sk->sk_family; |
| 4060 | u32 sk_sid = sksec->sid; | 4124 | u32 sk_sid = sksec->sid; |
| 4061 | struct avc_audit_data ad; | 4125 | struct common_audit_data ad; |
| 4062 | char *addrp; | 4126 | char *addrp; |
| 4063 | u8 secmark_active; | 4127 | u8 secmark_active; |
| 4064 | u8 peerlbl_active; | 4128 | u8 peerlbl_active; |
| @@ -4082,7 +4146,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
| 4082 | if (!secmark_active && !peerlbl_active) | 4146 | if (!secmark_active && !peerlbl_active) |
| 4083 | return 0; | 4147 | return 0; |
| 4084 | 4148 | ||
| 4085 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4149 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 4086 | ad.u.net.netif = skb->iif; | 4150 | ad.u.net.netif = skb->iif; |
| 4087 | ad.u.net.family = family; | 4151 | ad.u.net.family = family; |
| 4088 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4152 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
| @@ -4296,6 +4360,59 @@ static void selinux_req_classify_flow(const struct request_sock *req, | |||
| 4296 | fl->secid = req->secid; | 4360 | fl->secid = req->secid; |
| 4297 | } | 4361 | } |
| 4298 | 4362 | ||
| 4363 | static int selinux_tun_dev_create(void) | ||
| 4364 | { | ||
| 4365 | u32 sid = current_sid(); | ||
| 4366 | |||
| 4367 | /* we aren't taking into account the "sockcreate" SID since the socket | ||
| 4368 | * that is being created here is not a socket in the traditional sense, | ||
| 4369 | * instead it is a private sock, accessible only to the kernel, and | ||
| 4370 | * representing a wide range of network traffic spanning multiple | ||
| 4371 | * connections unlike traditional sockets - check the TUN driver to | ||
| 4372 | * get a better understanding of why this socket is special */ | ||
| 4373 | |||
| 4374 | return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE, | ||
| 4375 | NULL); | ||
| 4376 | } | ||
| 4377 | |||
| 4378 | static void selinux_tun_dev_post_create(struct sock *sk) | ||
| 4379 | { | ||
| 4380 | struct sk_security_struct *sksec = sk->sk_security; | ||
| 4381 | |||
| 4382 | /* we don't currently perform any NetLabel based labeling here and it | ||
| 4383 | * isn't clear that we would want to do so anyway; while we could apply | ||
| 4384 | * labeling without the support of the TUN user the resulting labeled | ||
| 4385 | * traffic from the other end of the connection would almost certainly | ||
| 4386 | * cause confusion to the TUN user that had no idea network labeling | ||
| 4387 | * protocols were being used */ | ||
| 4388 | |||
| 4389 | /* see the comments in selinux_tun_dev_create() about why we don't use | ||
| 4390 | * the sockcreate SID here */ | ||
| 4391 | |||
| 4392 | sksec->sid = current_sid(); | ||
| 4393 | sksec->sclass = SECCLASS_TUN_SOCKET; | ||
| 4394 | } | ||
| 4395 | |||
| 4396 | static int selinux_tun_dev_attach(struct sock *sk) | ||
| 4397 | { | ||
| 4398 | struct sk_security_struct *sksec = sk->sk_security; | ||
| 4399 | u32 sid = current_sid(); | ||
| 4400 | int err; | ||
| 4401 | |||
| 4402 | err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, | ||
| 4403 | TUN_SOCKET__RELABELFROM, NULL); | ||
| 4404 | if (err) | ||
| 4405 | return err; | ||
| 4406 | err = avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, | ||
| 4407 | TUN_SOCKET__RELABELTO, NULL); | ||
| 4408 | if (err) | ||
| 4409 | return err; | ||
| 4410 | |||
| 4411 | sksec->sid = sid; | ||
| 4412 | |||
| 4413 | return 0; | ||
| 4414 | } | ||
| 4415 | |||
| 4299 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | 4416 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) |
| 4300 | { | 4417 | { |
| 4301 | int err = 0; | 4418 | int err = 0; |
| @@ -4340,7 +4457,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
| 4340 | int err; | 4457 | int err; |
| 4341 | char *addrp; | 4458 | char *addrp; |
| 4342 | u32 peer_sid; | 4459 | u32 peer_sid; |
| 4343 | struct avc_audit_data ad; | 4460 | struct common_audit_data ad; |
| 4344 | u8 secmark_active; | 4461 | u8 secmark_active; |
| 4345 | u8 netlbl_active; | 4462 | u8 netlbl_active; |
| 4346 | u8 peerlbl_active; | 4463 | u8 peerlbl_active; |
| @@ -4357,7 +4474,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
| 4357 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) | 4474 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) |
| 4358 | return NF_DROP; | 4475 | return NF_DROP; |
| 4359 | 4476 | ||
| 4360 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4477 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 4361 | ad.u.net.netif = ifindex; | 4478 | ad.u.net.netif = ifindex; |
| 4362 | ad.u.net.family = family; | 4479 | ad.u.net.family = family; |
| 4363 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) | 4480 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) |
| @@ -4445,7 +4562,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
| 4445 | { | 4562 | { |
| 4446 | struct sock *sk = skb->sk; | 4563 | struct sock *sk = skb->sk; |
| 4447 | struct sk_security_struct *sksec; | 4564 | struct sk_security_struct *sksec; |
| 4448 | struct avc_audit_data ad; | 4565 | struct common_audit_data ad; |
| 4449 | char *addrp; | 4566 | char *addrp; |
| 4450 | u8 proto; | 4567 | u8 proto; |
| 4451 | 4568 | ||
| @@ -4453,7 +4570,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
| 4453 | return NF_ACCEPT; | 4570 | return NF_ACCEPT; |
| 4454 | sksec = sk->sk_security; | 4571 | sksec = sk->sk_security; |
| 4455 | 4572 | ||
| 4456 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4573 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 4457 | ad.u.net.netif = ifindex; | 4574 | ad.u.net.netif = ifindex; |
| 4458 | ad.u.net.family = family; | 4575 | ad.u.net.family = family; |
| 4459 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) | 4576 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) |
| @@ -4477,7 +4594,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
| 4477 | u32 secmark_perm; | 4594 | u32 secmark_perm; |
| 4478 | u32 peer_sid; | 4595 | u32 peer_sid; |
| 4479 | struct sock *sk; | 4596 | struct sock *sk; |
| 4480 | struct avc_audit_data ad; | 4597 | struct common_audit_data ad; |
| 4481 | char *addrp; | 4598 | char *addrp; |
| 4482 | u8 secmark_active; | 4599 | u8 secmark_active; |
| 4483 | u8 peerlbl_active; | 4600 | u8 peerlbl_active; |
| @@ -4536,7 +4653,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
| 4536 | secmark_perm = PACKET__SEND; | 4653 | secmark_perm = PACKET__SEND; |
| 4537 | } | 4654 | } |
| 4538 | 4655 | ||
| 4539 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4656 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
| 4540 | ad.u.net.netif = ifindex; | 4657 | ad.u.net.netif = ifindex; |
| 4541 | ad.u.net.family = family; | 4658 | ad.u.net.family = family; |
| 4542 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) | 4659 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) |
| @@ -4606,13 +4723,13 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
| 4606 | static int selinux_netlink_recv(struct sk_buff *skb, int capability) | 4723 | static int selinux_netlink_recv(struct sk_buff *skb, int capability) |
| 4607 | { | 4724 | { |
| 4608 | int err; | 4725 | int err; |
| 4609 | struct avc_audit_data ad; | 4726 | struct common_audit_data ad; |
| 4610 | 4727 | ||
| 4611 | err = cap_netlink_recv(skb, capability); | 4728 | err = cap_netlink_recv(skb, capability); |
| 4612 | if (err) | 4729 | if (err) |
| 4613 | return err; | 4730 | return err; |
| 4614 | 4731 | ||
| 4615 | AVC_AUDIT_DATA_INIT(&ad, CAP); | 4732 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
| 4616 | ad.u.cap = capability; | 4733 | ad.u.cap = capability; |
| 4617 | 4734 | ||
| 4618 | return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, | 4735 | return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, |
| @@ -4671,12 +4788,12 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
| 4671 | u32 perms) | 4788 | u32 perms) |
| 4672 | { | 4789 | { |
| 4673 | struct ipc_security_struct *isec; | 4790 | struct ipc_security_struct *isec; |
| 4674 | struct avc_audit_data ad; | 4791 | struct common_audit_data ad; |
| 4675 | u32 sid = current_sid(); | 4792 | u32 sid = current_sid(); |
| 4676 | 4793 | ||
| 4677 | isec = ipc_perms->security; | 4794 | isec = ipc_perms->security; |
| 4678 | 4795 | ||
| 4679 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4796 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4680 | ad.u.ipc_id = ipc_perms->key; | 4797 | ad.u.ipc_id = ipc_perms->key; |
| 4681 | 4798 | ||
| 4682 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); | 4799 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
| @@ -4696,7 +4813,7 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg) | |||
| 4696 | static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | 4813 | static int selinux_msg_queue_alloc_security(struct msg_queue *msq) |
| 4697 | { | 4814 | { |
| 4698 | struct ipc_security_struct *isec; | 4815 | struct ipc_security_struct *isec; |
| 4699 | struct avc_audit_data ad; | 4816 | struct common_audit_data ad; |
| 4700 | u32 sid = current_sid(); | 4817 | u32 sid = current_sid(); |
| 4701 | int rc; | 4818 | int rc; |
| 4702 | 4819 | ||
| @@ -4706,7 +4823,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
| 4706 | 4823 | ||
| 4707 | isec = msq->q_perm.security; | 4824 | isec = msq->q_perm.security; |
| 4708 | 4825 | ||
| 4709 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4826 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4710 | ad.u.ipc_id = msq->q_perm.key; | 4827 | ad.u.ipc_id = msq->q_perm.key; |
| 4711 | 4828 | ||
| 4712 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4829 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| @@ -4726,12 +4843,12 @@ static void selinux_msg_queue_free_security(struct msg_queue *msq) | |||
| 4726 | static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) | 4843 | static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) |
| 4727 | { | 4844 | { |
| 4728 | struct ipc_security_struct *isec; | 4845 | struct ipc_security_struct *isec; |
| 4729 | struct avc_audit_data ad; | 4846 | struct common_audit_data ad; |
| 4730 | u32 sid = current_sid(); | 4847 | u32 sid = current_sid(); |
| 4731 | 4848 | ||
| 4732 | isec = msq->q_perm.security; | 4849 | isec = msq->q_perm.security; |
| 4733 | 4850 | ||
| 4734 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4851 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4735 | ad.u.ipc_id = msq->q_perm.key; | 4852 | ad.u.ipc_id = msq->q_perm.key; |
| 4736 | 4853 | ||
| 4737 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4854 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| @@ -4770,7 +4887,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4770 | { | 4887 | { |
| 4771 | struct ipc_security_struct *isec; | 4888 | struct ipc_security_struct *isec; |
| 4772 | struct msg_security_struct *msec; | 4889 | struct msg_security_struct *msec; |
| 4773 | struct avc_audit_data ad; | 4890 | struct common_audit_data ad; |
| 4774 | u32 sid = current_sid(); | 4891 | u32 sid = current_sid(); |
| 4775 | int rc; | 4892 | int rc; |
| 4776 | 4893 | ||
| @@ -4791,7 +4908,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4791 | return rc; | 4908 | return rc; |
| 4792 | } | 4909 | } |
| 4793 | 4910 | ||
| 4794 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4911 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4795 | ad.u.ipc_id = msq->q_perm.key; | 4912 | ad.u.ipc_id = msq->q_perm.key; |
| 4796 | 4913 | ||
| 4797 | /* Can this process write to the queue? */ | 4914 | /* Can this process write to the queue? */ |
| @@ -4815,14 +4932,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4815 | { | 4932 | { |
| 4816 | struct ipc_security_struct *isec; | 4933 | struct ipc_security_struct *isec; |
| 4817 | struct msg_security_struct *msec; | 4934 | struct msg_security_struct *msec; |
| 4818 | struct avc_audit_data ad; | 4935 | struct common_audit_data ad; |
| 4819 | u32 sid = task_sid(target); | 4936 | u32 sid = task_sid(target); |
| 4820 | int rc; | 4937 | int rc; |
| 4821 | 4938 | ||
| 4822 | isec = msq->q_perm.security; | 4939 | isec = msq->q_perm.security; |
| 4823 | msec = msg->security; | 4940 | msec = msg->security; |
| 4824 | 4941 | ||
| 4825 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4942 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4826 | ad.u.ipc_id = msq->q_perm.key; | 4943 | ad.u.ipc_id = msq->q_perm.key; |
| 4827 | 4944 | ||
| 4828 | rc = avc_has_perm(sid, isec->sid, | 4945 | rc = avc_has_perm(sid, isec->sid, |
| @@ -4837,7 +4954,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4837 | static int selinux_shm_alloc_security(struct shmid_kernel *shp) | 4954 | static int selinux_shm_alloc_security(struct shmid_kernel *shp) |
| 4838 | { | 4955 | { |
| 4839 | struct ipc_security_struct *isec; | 4956 | struct ipc_security_struct *isec; |
| 4840 | struct avc_audit_data ad; | 4957 | struct common_audit_data ad; |
| 4841 | u32 sid = current_sid(); | 4958 | u32 sid = current_sid(); |
| 4842 | int rc; | 4959 | int rc; |
| 4843 | 4960 | ||
| @@ -4847,7 +4964,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
| 4847 | 4964 | ||
| 4848 | isec = shp->shm_perm.security; | 4965 | isec = shp->shm_perm.security; |
| 4849 | 4966 | ||
| 4850 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4967 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4851 | ad.u.ipc_id = shp->shm_perm.key; | 4968 | ad.u.ipc_id = shp->shm_perm.key; |
| 4852 | 4969 | ||
| 4853 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 4970 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
| @@ -4867,12 +4984,12 @@ static void selinux_shm_free_security(struct shmid_kernel *shp) | |||
| 4867 | static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) | 4984 | static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) |
| 4868 | { | 4985 | { |
| 4869 | struct ipc_security_struct *isec; | 4986 | struct ipc_security_struct *isec; |
| 4870 | struct avc_audit_data ad; | 4987 | struct common_audit_data ad; |
| 4871 | u32 sid = current_sid(); | 4988 | u32 sid = current_sid(); |
| 4872 | 4989 | ||
| 4873 | isec = shp->shm_perm.security; | 4990 | isec = shp->shm_perm.security; |
| 4874 | 4991 | ||
| 4875 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4992 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4876 | ad.u.ipc_id = shp->shm_perm.key; | 4993 | ad.u.ipc_id = shp->shm_perm.key; |
| 4877 | 4994 | ||
| 4878 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 4995 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
| @@ -4929,7 +5046,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, | |||
| 4929 | static int selinux_sem_alloc_security(struct sem_array *sma) | 5046 | static int selinux_sem_alloc_security(struct sem_array *sma) |
| 4930 | { | 5047 | { |
| 4931 | struct ipc_security_struct *isec; | 5048 | struct ipc_security_struct *isec; |
| 4932 | struct avc_audit_data ad; | 5049 | struct common_audit_data ad; |
| 4933 | u32 sid = current_sid(); | 5050 | u32 sid = current_sid(); |
| 4934 | int rc; | 5051 | int rc; |
| 4935 | 5052 | ||
| @@ -4939,7 +5056,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
| 4939 | 5056 | ||
| 4940 | isec = sma->sem_perm.security; | 5057 | isec = sma->sem_perm.security; |
| 4941 | 5058 | ||
| 4942 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 5059 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4943 | ad.u.ipc_id = sma->sem_perm.key; | 5060 | ad.u.ipc_id = sma->sem_perm.key; |
| 4944 | 5061 | ||
| 4945 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5062 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
| @@ -4959,12 +5076,12 @@ static void selinux_sem_free_security(struct sem_array *sma) | |||
| 4959 | static int selinux_sem_associate(struct sem_array *sma, int semflg) | 5076 | static int selinux_sem_associate(struct sem_array *sma, int semflg) |
| 4960 | { | 5077 | { |
| 4961 | struct ipc_security_struct *isec; | 5078 | struct ipc_security_struct *isec; |
| 4962 | struct avc_audit_data ad; | 5079 | struct common_audit_data ad; |
| 4963 | u32 sid = current_sid(); | 5080 | u32 sid = current_sid(); |
| 4964 | 5081 | ||
| 4965 | isec = sma->sem_perm.security; | 5082 | isec = sma->sem_perm.security; |
| 4966 | 5083 | ||
| 4967 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 5084 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
| 4968 | ad.u.ipc_id = sma->sem_perm.key; | 5085 | ad.u.ipc_id = sma->sem_perm.key; |
| 4969 | 5086 | ||
| 4970 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5087 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
| @@ -5182,7 +5299,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 5182 | 5299 | ||
| 5183 | /* Only allow single threaded processes to change context */ | 5300 | /* Only allow single threaded processes to change context */ |
| 5184 | error = -EPERM; | 5301 | error = -EPERM; |
| 5185 | if (!is_single_threaded(p)) { | 5302 | if (!current_is_single_threaded()) { |
| 5186 | error = security_bounded_transition(tsec->sid, sid); | 5303 | error = security_bounded_transition(tsec->sid, sid); |
| 5187 | if (error) | 5304 | if (error) |
| 5188 | goto abort_change; | 5305 | goto abort_change; |
| @@ -5239,6 +5356,32 @@ static void selinux_release_secctx(char *secdata, u32 seclen) | |||
| 5239 | kfree(secdata); | 5356 | kfree(secdata); |
| 5240 | } | 5357 | } |
| 5241 | 5358 | ||
| 5359 | /* | ||
| 5360 | * called with inode->i_mutex locked | ||
| 5361 | */ | ||
| 5362 | static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | ||
| 5363 | { | ||
| 5364 | return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); | ||
| 5365 | } | ||
| 5366 | |||
| 5367 | /* | ||
| 5368 | * called with inode->i_mutex locked | ||
| 5369 | */ | ||
| 5370 | static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) | ||
| 5371 | { | ||
| 5372 | return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0); | ||
| 5373 | } | ||
| 5374 | |||
| 5375 | static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) | ||
| 5376 | { | ||
| 5377 | int len = 0; | ||
| 5378 | len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX, | ||
| 5379 | ctx, true); | ||
| 5380 | if (len < 0) | ||
| 5381 | return len; | ||
| 5382 | *ctxlen = len; | ||
| 5383 | return 0; | ||
| 5384 | } | ||
| 5242 | #ifdef CONFIG_KEYS | 5385 | #ifdef CONFIG_KEYS |
| 5243 | 5386 | ||
| 5244 | static int selinux_key_alloc(struct key *k, const struct cred *cred, | 5387 | static int selinux_key_alloc(struct key *k, const struct cred *cred, |
| @@ -5310,7 +5453,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) | |||
| 5310 | static struct security_operations selinux_ops = { | 5453 | static struct security_operations selinux_ops = { |
| 5311 | .name = "selinux", | 5454 | .name = "selinux", |
| 5312 | 5455 | ||
| 5313 | .ptrace_may_access = selinux_ptrace_may_access, | 5456 | .ptrace_access_check = selinux_ptrace_access_check, |
| 5314 | .ptrace_traceme = selinux_ptrace_traceme, | 5457 | .ptrace_traceme = selinux_ptrace_traceme, |
| 5315 | .capget = selinux_capget, | 5458 | .capget = selinux_capget, |
| 5316 | .capset = selinux_capset, | 5459 | .capset = selinux_capset, |
| @@ -5383,10 +5526,13 @@ static struct security_operations selinux_ops = { | |||
| 5383 | .dentry_open = selinux_dentry_open, | 5526 | .dentry_open = selinux_dentry_open, |
| 5384 | 5527 | ||
| 5385 | .task_create = selinux_task_create, | 5528 | .task_create = selinux_task_create, |
| 5529 | .cred_alloc_blank = selinux_cred_alloc_blank, | ||
| 5386 | .cred_free = selinux_cred_free, | 5530 | .cred_free = selinux_cred_free, |
| 5387 | .cred_prepare = selinux_cred_prepare, | 5531 | .cred_prepare = selinux_cred_prepare, |
| 5532 | .cred_transfer = selinux_cred_transfer, | ||
| 5388 | .kernel_act_as = selinux_kernel_act_as, | 5533 | .kernel_act_as = selinux_kernel_act_as, |
| 5389 | .kernel_create_files_as = selinux_kernel_create_files_as, | 5534 | .kernel_create_files_as = selinux_kernel_create_files_as, |
| 5535 | .kernel_module_request = selinux_kernel_module_request, | ||
| 5390 | .task_setpgid = selinux_task_setpgid, | 5536 | .task_setpgid = selinux_task_setpgid, |
| 5391 | .task_getpgid = selinux_task_getpgid, | 5537 | .task_getpgid = selinux_task_getpgid, |
| 5392 | .task_getsid = selinux_task_getsid, | 5538 | .task_getsid = selinux_task_getsid, |
| @@ -5435,6 +5581,9 @@ static struct security_operations selinux_ops = { | |||
| 5435 | .secid_to_secctx = selinux_secid_to_secctx, | 5581 | .secid_to_secctx = selinux_secid_to_secctx, |
| 5436 | .secctx_to_secid = selinux_secctx_to_secid, | 5582 | .secctx_to_secid = selinux_secctx_to_secid, |
| 5437 | .release_secctx = selinux_release_secctx, | 5583 | .release_secctx = selinux_release_secctx, |
| 5584 | .inode_notifysecctx = selinux_inode_notifysecctx, | ||
| 5585 | .inode_setsecctx = selinux_inode_setsecctx, | ||
| 5586 | .inode_getsecctx = selinux_inode_getsecctx, | ||
| 5438 | 5587 | ||
| 5439 | .unix_stream_connect = selinux_socket_unix_stream_connect, | 5588 | .unix_stream_connect = selinux_socket_unix_stream_connect, |
| 5440 | .unix_may_send = selinux_socket_unix_may_send, | 5589 | .unix_may_send = selinux_socket_unix_may_send, |
| @@ -5464,6 +5613,9 @@ static struct security_operations selinux_ops = { | |||
| 5464 | .inet_csk_clone = selinux_inet_csk_clone, | 5613 | .inet_csk_clone = selinux_inet_csk_clone, |
| 5465 | .inet_conn_established = selinux_inet_conn_established, | 5614 | .inet_conn_established = selinux_inet_conn_established, |
| 5466 | .req_classify_flow = selinux_req_classify_flow, | 5615 | .req_classify_flow = selinux_req_classify_flow, |
| 5616 | .tun_dev_create = selinux_tun_dev_create, | ||
| 5617 | .tun_dev_post_create = selinux_tun_dev_post_create, | ||
| 5618 | .tun_dev_attach = selinux_tun_dev_attach, | ||
| 5467 | 5619 | ||
| 5468 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 5620 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 5469 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 5621 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |
| @@ -5678,6 +5830,9 @@ int selinux_disable(void) | |||
| 5678 | selinux_disabled = 1; | 5830 | selinux_disabled = 1; |
| 5679 | selinux_enabled = 0; | 5831 | selinux_enabled = 0; |
| 5680 | 5832 | ||
| 5833 | /* Try to destroy the avc node cache */ | ||
| 5834 | avc_disable(); | ||
| 5835 | |||
| 5681 | /* Reset security_ops to the secondary module, dummy or capability. */ | 5836 | /* Reset security_ops to the secondary module, dummy or capability. */ |
| 5682 | security_ops = secondary_ops; | 5837 | security_ops = secondary_ops; |
| 5683 | 5838 | ||
