diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 733 |
1 files changed, 405 insertions, 328 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d39b59cf8a08..04acb5af8317 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -4,22 +4,22 @@ | |||
| 4 | * This file contains the SELinux hook function implementations. | 4 | * This file contains the SELinux hook function implementations. |
| 5 | * | 5 | * |
| 6 | * Authors: Stephen Smalley, <sds@epoch.ncsc.mil> | 6 | * Authors: Stephen Smalley, <sds@epoch.ncsc.mil> |
| 7 | * Chris Vance, <cvance@nai.com> | 7 | * Chris Vance, <cvance@nai.com> |
| 8 | * Wayne Salamon, <wsalamon@nai.com> | 8 | * Wayne Salamon, <wsalamon@nai.com> |
| 9 | * James Morris <jmorris@redhat.com> | 9 | * James Morris <jmorris@redhat.com> |
| 10 | * | 10 | * |
| 11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. | 11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. |
| 12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
| 13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
| 14 | * <dgoeddel@trustedcs.com> | 14 | * <dgoeddel@trustedcs.com> |
| 15 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. | 15 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. |
| 16 | * Paul Moore <paul.moore@hp.com> | 16 | * Paul Moore <paul.moore@hp.com> |
| 17 | * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. | 17 | * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. |
| 18 | * Yuichi Nakamura <ynakam@hitachisoft.jp> | 18 | * Yuichi Nakamura <ynakam@hitachisoft.jp> |
| 19 | * | 19 | * |
| 20 | * This program is free software; you can redistribute it and/or modify | 20 | * This program is free software; you can redistribute it and/or modify |
| 21 | * it under the terms of the GNU General Public License version 2, | 21 | * it under the terms of the GNU General Public License version 2, |
| 22 | * as published by the Free Software Foundation. | 22 | * as published by the Free Software Foundation. |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| @@ -80,8 +80,10 @@ | |||
| 80 | #include "objsec.h" | 80 | #include "objsec.h" |
| 81 | #include "netif.h" | 81 | #include "netif.h" |
| 82 | #include "netnode.h" | 82 | #include "netnode.h" |
| 83 | #include "netport.h" | ||
| 83 | #include "xfrm.h" | 84 | #include "xfrm.h" |
| 84 | #include "netlabel.h" | 85 | #include "netlabel.h" |
| 86 | #include "audit.h" | ||
| 85 | 87 | ||
| 86 | #define XATTR_SELINUX_SUFFIX "selinux" | 88 | #define XATTR_SELINUX_SUFFIX "selinux" |
| 87 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX | 89 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX |
| @@ -97,11 +99,11 @@ extern struct security_operations *security_ops; | |||
| 97 | atomic_t selinux_secmark_refcount = ATOMIC_INIT(0); | 99 | atomic_t selinux_secmark_refcount = ATOMIC_INIT(0); |
| 98 | 100 | ||
| 99 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP | 101 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP |
| 100 | int selinux_enforcing = 0; | 102 | int selinux_enforcing; |
| 101 | 103 | ||
| 102 | static int __init enforcing_setup(char *str) | 104 | static int __init enforcing_setup(char *str) |
| 103 | { | 105 | { |
| 104 | selinux_enforcing = simple_strtol(str,NULL,0); | 106 | selinux_enforcing = simple_strtol(str, NULL, 0); |
| 105 | return 1; | 107 | return 1; |
| 106 | } | 108 | } |
| 107 | __setup("enforcing=", enforcing_setup); | 109 | __setup("enforcing=", enforcing_setup); |
| @@ -121,13 +123,13 @@ int selinux_enabled = 1; | |||
| 121 | #endif | 123 | #endif |
| 122 | 124 | ||
| 123 | /* Original (dummy) security module. */ | 125 | /* Original (dummy) security module. */ |
| 124 | static struct security_operations *original_ops = NULL; | 126 | static struct security_operations *original_ops; |
| 125 | 127 | ||
| 126 | /* Minimal support for a secondary security module, | 128 | /* Minimal support for a secondary security module, |
| 127 | just to allow the use of the dummy or capability modules. | 129 | just to allow the use of the dummy or capability modules. |
| 128 | The owlsm module can alternatively be used as a secondary | 130 | The owlsm module can alternatively be used as a secondary |
| 129 | module as long as CONFIG_OWLSM_FD is not enabled. */ | 131 | module as long as CONFIG_OWLSM_FD is not enabled. */ |
| 130 | static struct security_operations *secondary_ops = NULL; | 132 | static struct security_operations *secondary_ops; |
| 131 | 133 | ||
| 132 | /* Lists of inode and superblock security structures initialized | 134 | /* Lists of inode and superblock security structures initialized |
| 133 | before the policy was loaded. */ | 135 | before the policy was loaded. */ |
| @@ -161,8 +163,7 @@ static int task_alloc_security(struct task_struct *task) | |||
| 161 | if (!tsec) | 163 | if (!tsec) |
| 162 | return -ENOMEM; | 164 | return -ENOMEM; |
| 163 | 165 | ||
| 164 | tsec->task = task; | 166 | tsec->osid = tsec->sid = SECINITSID_UNLABELED; |
| 165 | tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; | ||
| 166 | task->security = tsec; | 167 | task->security = tsec; |
| 167 | 168 | ||
| 168 | return 0; | 169 | return 0; |
| @@ -218,7 +219,6 @@ static int file_alloc_security(struct file *file) | |||
| 218 | if (!fsec) | 219 | if (!fsec) |
| 219 | return -ENOMEM; | 220 | return -ENOMEM; |
| 220 | 221 | ||
| 221 | fsec->file = file; | ||
| 222 | fsec->sid = tsec->sid; | 222 | fsec->sid = tsec->sid; |
| 223 | fsec->fown_sid = tsec->sid; | 223 | fsec->fown_sid = tsec->sid; |
| 224 | file->f_security = fsec; | 224 | file->f_security = fsec; |
| @@ -275,12 +275,11 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
| 275 | if (!ssec) | 275 | if (!ssec) |
| 276 | return -ENOMEM; | 276 | return -ENOMEM; |
| 277 | 277 | ||
| 278 | ssec->sk = sk; | ||
| 279 | ssec->peer_sid = SECINITSID_UNLABELED; | 278 | ssec->peer_sid = SECINITSID_UNLABELED; |
| 280 | ssec->sid = SECINITSID_UNLABELED; | 279 | ssec->sid = SECINITSID_UNLABELED; |
| 281 | sk->sk_security = ssec; | 280 | sk->sk_security = ssec; |
| 282 | 281 | ||
| 283 | selinux_netlbl_sk_security_init(ssec, family); | 282 | selinux_netlbl_sk_security_reset(ssec, family); |
| 284 | 283 | ||
| 285 | return 0; | 284 | return 0; |
| 286 | } | 285 | } |
| @@ -324,10 +323,10 @@ enum { | |||
| 324 | }; | 323 | }; |
| 325 | 324 | ||
| 326 | static match_table_t tokens = { | 325 | static match_table_t tokens = { |
| 327 | {Opt_context, "context=%s"}, | 326 | {Opt_context, CONTEXT_STR "%s"}, |
| 328 | {Opt_fscontext, "fscontext=%s"}, | 327 | {Opt_fscontext, FSCONTEXT_STR "%s"}, |
| 329 | {Opt_defcontext, "defcontext=%s"}, | 328 | {Opt_defcontext, DEFCONTEXT_STR "%s"}, |
| 330 | {Opt_rootcontext, "rootcontext=%s"}, | 329 | {Opt_rootcontext, ROOTCONTEXT_STR "%s"}, |
| 331 | {Opt_error, NULL}, | 330 | {Opt_error, NULL}, |
| 332 | }; | 331 | }; |
| 333 | 332 | ||
| @@ -576,8 +575,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 576 | goto out; | 575 | goto out; |
| 577 | } | 576 | } |
| 578 | rc = -EINVAL; | 577 | rc = -EINVAL; |
| 579 | printk(KERN_WARNING "Unable to set superblock options before " | 578 | printk(KERN_WARNING "SELinux: Unable to set superblock options " |
| 580 | "the security server is initialized\n"); | 579 | "before the security server is initialized\n"); |
| 581 | goto out; | 580 | goto out; |
| 582 | } | 581 | } |
| 583 | 582 | ||
| @@ -671,7 +670,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 671 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); | 670 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); |
| 672 | if (rc) { | 671 | if (rc) { |
| 673 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", | 672 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", |
| 674 | __FUNCTION__, sb->s_type->name, rc); | 673 | __func__, sb->s_type->name, rc); |
| 675 | goto out; | 674 | goto out; |
| 676 | } | 675 | } |
| 677 | 676 | ||
| @@ -756,9 +755,18 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
| 756 | int set_context = (oldsbsec->flags & CONTEXT_MNT); | 755 | int set_context = (oldsbsec->flags & CONTEXT_MNT); |
| 757 | int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT); | 756 | int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT); |
| 758 | 757 | ||
| 759 | /* we can't error, we can't save the info, this shouldn't get called | 758 | /* |
| 760 | * this early in the boot process. */ | 759 | * if the parent was able to be mounted it clearly had no special lsm |
| 761 | BUG_ON(!ss_initialized); | 760 | * mount options. thus we can safely put this sb on the list and deal |
| 761 | * with it later | ||
| 762 | */ | ||
| 763 | if (!ss_initialized) { | ||
| 764 | spin_lock(&sb_security_lock); | ||
| 765 | if (list_empty(&newsbsec->list)) | ||
| 766 | list_add(&newsbsec->list, &superblock_security_head); | ||
| 767 | spin_unlock(&sb_security_lock); | ||
| 768 | return; | ||
| 769 | } | ||
| 762 | 770 | ||
| 763 | /* how can we clone if the old one wasn't set up?? */ | 771 | /* how can we clone if the old one wasn't set up?? */ |
| 764 | BUG_ON(!oldsbsec->initialized); | 772 | BUG_ON(!oldsbsec->initialized); |
| @@ -1055,7 +1063,7 @@ static int selinux_proc_get_sid(struct proc_dir_entry *de, | |||
| 1055 | int buflen, rc; | 1063 | int buflen, rc; |
| 1056 | char *buffer, *path, *end; | 1064 | char *buffer, *path, *end; |
| 1057 | 1065 | ||
| 1058 | buffer = (char*)__get_free_page(GFP_KERNEL); | 1066 | buffer = (char *)__get_free_page(GFP_KERNEL); |
| 1059 | if (!buffer) | 1067 | if (!buffer) |
| 1060 | return -ENOMEM; | 1068 | return -ENOMEM; |
| 1061 | 1069 | ||
| @@ -1136,8 +1144,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1136 | dentry = d_find_alias(inode); | 1144 | dentry = d_find_alias(inode); |
| 1137 | } | 1145 | } |
| 1138 | if (!dentry) { | 1146 | if (!dentry) { |
| 1139 | printk(KERN_WARNING "%s: no dentry for dev=%s " | 1147 | printk(KERN_WARNING "SELinux: %s: no dentry for dev=%s " |
| 1140 | "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id, | 1148 | "ino=%ld\n", __func__, inode->i_sb->s_id, |
| 1141 | inode->i_ino); | 1149 | inode->i_ino); |
| 1142 | goto out_unlock; | 1150 | goto out_unlock; |
| 1143 | } | 1151 | } |
| @@ -1174,8 +1182,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1174 | dput(dentry); | 1182 | dput(dentry); |
| 1175 | if (rc < 0) { | 1183 | if (rc < 0) { |
| 1176 | if (rc != -ENODATA) { | 1184 | if (rc != -ENODATA) { |
| 1177 | printk(KERN_WARNING "%s: getxattr returned " | 1185 | printk(KERN_WARNING "SELinux: %s: getxattr returned " |
| 1178 | "%d for dev=%s ino=%ld\n", __FUNCTION__, | 1186 | "%d for dev=%s ino=%ld\n", __func__, |
| 1179 | -rc, inode->i_sb->s_id, inode->i_ino); | 1187 | -rc, inode->i_sb->s_id, inode->i_ino); |
| 1180 | kfree(context); | 1188 | kfree(context); |
| 1181 | goto out_unlock; | 1189 | goto out_unlock; |
| @@ -1188,9 +1196,9 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1188 | sbsec->def_sid, | 1196 | sbsec->def_sid, |
| 1189 | GFP_NOFS); | 1197 | GFP_NOFS); |
| 1190 | if (rc) { | 1198 | if (rc) { |
| 1191 | printk(KERN_WARNING "%s: context_to_sid(%s) " | 1199 | printk(KERN_WARNING "SELinux: %s: context_to_sid(%s) " |
| 1192 | "returned %d for dev=%s ino=%ld\n", | 1200 | "returned %d for dev=%s ino=%ld\n", |
| 1193 | __FUNCTION__, context, -rc, | 1201 | __func__, context, -rc, |
| 1194 | inode->i_sb->s_id, inode->i_ino); | 1202 | inode->i_sb->s_id, inode->i_ino); |
| 1195 | kfree(context); | 1203 | kfree(context); |
| 1196 | /* Leave with the unlabeled SID */ | 1204 | /* Leave with the unlabeled SID */ |
| @@ -1306,7 +1314,7 @@ static int task_has_capability(struct task_struct *tsk, | |||
| 1306 | 1314 | ||
| 1307 | tsec = tsk->security; | 1315 | tsec = tsk->security; |
| 1308 | 1316 | ||
| 1309 | AVC_AUDIT_DATA_INIT(&ad,CAP); | 1317 | AVC_AUDIT_DATA_INIT(&ad, CAP); |
| 1310 | ad.tsk = tsk; | 1318 | ad.tsk = tsk; |
| 1311 | ad.u.cap = cap; | 1319 | ad.u.cap = cap; |
| 1312 | 1320 | ||
| @@ -1349,7 +1357,7 @@ static int inode_has_perm(struct task_struct *tsk, | |||
| 1349 | struct inode_security_struct *isec; | 1357 | struct inode_security_struct *isec; |
| 1350 | struct avc_audit_data ad; | 1358 | struct avc_audit_data ad; |
| 1351 | 1359 | ||
| 1352 | if (unlikely (IS_PRIVATE (inode))) | 1360 | if (unlikely(IS_PRIVATE(inode))) |
| 1353 | return 0; | 1361 | return 0; |
| 1354 | 1362 | ||
| 1355 | tsec = tsk->security; | 1363 | tsec = tsk->security; |
| @@ -1374,7 +1382,7 @@ static inline int dentry_has_perm(struct task_struct *tsk, | |||
| 1374 | { | 1382 | { |
| 1375 | struct inode *inode = dentry->d_inode; | 1383 | struct inode *inode = dentry->d_inode; |
| 1376 | struct avc_audit_data ad; | 1384 | struct avc_audit_data ad; |
| 1377 | AVC_AUDIT_DATA_INIT(&ad,FS); | 1385 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1378 | ad.u.fs.path.mnt = mnt; | 1386 | ad.u.fs.path.mnt = mnt; |
| 1379 | ad.u.fs.path.dentry = dentry; | 1387 | ad.u.fs.path.dentry = dentry; |
| 1380 | return inode_has_perm(tsk, inode, av, &ad); | 1388 | return inode_has_perm(tsk, inode, av, &ad); |
| @@ -1471,9 +1479,9 @@ static int may_create_key(u32 ksid, | |||
| 1471 | return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL); | 1479 | return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL); |
| 1472 | } | 1480 | } |
| 1473 | 1481 | ||
| 1474 | #define MAY_LINK 0 | 1482 | #define MAY_LINK 0 |
| 1475 | #define MAY_UNLINK 1 | 1483 | #define MAY_UNLINK 1 |
| 1476 | #define MAY_RMDIR 2 | 1484 | #define MAY_RMDIR 2 |
| 1477 | 1485 | ||
| 1478 | /* Check whether a task can link, unlink, or rmdir a file/directory. */ | 1486 | /* Check whether a task can link, unlink, or rmdir a file/directory. */ |
| 1479 | static int may_link(struct inode *dir, | 1487 | static int may_link(struct inode *dir, |
| @@ -1511,7 +1519,8 @@ static int may_link(struct inode *dir, | |||
| 1511 | av = DIR__RMDIR; | 1519 | av = DIR__RMDIR; |
| 1512 | break; | 1520 | break; |
| 1513 | default: | 1521 | default: |
| 1514 | printk(KERN_WARNING "may_link: unrecognized kind %d\n", kind); | 1522 | printk(KERN_WARNING "SELinux: %s: unrecognized kind %d\n", |
| 1523 | __func__, kind); | ||
| 1515 | return 0; | 1524 | return 0; |
| 1516 | } | 1525 | } |
| 1517 | 1526 | ||
| @@ -1618,6 +1627,35 @@ static inline u32 file_mask_to_av(int mode, int mask) | |||
| 1618 | return av; | 1627 | return av; |
| 1619 | } | 1628 | } |
| 1620 | 1629 | ||
| 1630 | /* | ||
| 1631 | * Convert a file mask to an access vector and include the correct open | ||
| 1632 | * open permission. | ||
| 1633 | */ | ||
| 1634 | static inline u32 open_file_mask_to_av(int mode, int mask) | ||
| 1635 | { | ||
| 1636 | u32 av = file_mask_to_av(mode, mask); | ||
| 1637 | |||
| 1638 | if (selinux_policycap_openperm) { | ||
| 1639 | /* | ||
| 1640 | * lnk files and socks do not really have an 'open' | ||
| 1641 | */ | ||
| 1642 | if (S_ISREG(mode)) | ||
| 1643 | av |= FILE__OPEN; | ||
| 1644 | else if (S_ISCHR(mode)) | ||
| 1645 | av |= CHR_FILE__OPEN; | ||
| 1646 | else if (S_ISBLK(mode)) | ||
| 1647 | av |= BLK_FILE__OPEN; | ||
| 1648 | else if (S_ISFIFO(mode)) | ||
| 1649 | av |= FIFO_FILE__OPEN; | ||
| 1650 | else if (S_ISDIR(mode)) | ||
| 1651 | av |= DIR__OPEN; | ||
| 1652 | else | ||
| 1653 | printk(KERN_ERR "SELinux: WARNING: inside %s with " | ||
| 1654 | "unknown mode:%x\n", __func__, mode); | ||
| 1655 | } | ||
| 1656 | return av; | ||
| 1657 | } | ||
| 1658 | |||
| 1621 | /* Convert a Linux file to an access vector. */ | 1659 | /* Convert a Linux file to an access vector. */ |
| 1622 | static inline u32 file_to_av(struct file *file) | 1660 | static inline u32 file_to_av(struct file *file) |
| 1623 | { | 1661 | { |
| @@ -1645,23 +1683,17 @@ static inline u32 file_to_av(struct file *file) | |||
| 1645 | 1683 | ||
| 1646 | static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) | 1684 | static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) |
| 1647 | { | 1685 | { |
| 1648 | struct task_security_struct *psec = parent->security; | ||
| 1649 | struct task_security_struct *csec = child->security; | ||
| 1650 | int rc; | 1686 | int rc; |
| 1651 | 1687 | ||
| 1652 | rc = secondary_ops->ptrace(parent,child); | 1688 | rc = secondary_ops->ptrace(parent, child); |
| 1653 | if (rc) | 1689 | if (rc) |
| 1654 | return rc; | 1690 | return rc; |
| 1655 | 1691 | ||
| 1656 | rc = task_has_perm(parent, child, PROCESS__PTRACE); | 1692 | return task_has_perm(parent, child, PROCESS__PTRACE); |
| 1657 | /* Save the SID of the tracing process for later use in apply_creds. */ | ||
| 1658 | if (!(child->ptrace & PT_PTRACED) && !rc) | ||
| 1659 | csec->ptrace_sid = psec->sid; | ||
| 1660 | return rc; | ||
| 1661 | } | 1693 | } |
| 1662 | 1694 | ||
| 1663 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | 1695 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, |
| 1664 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 1696 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
| 1665 | { | 1697 | { |
| 1666 | int error; | 1698 | int error; |
| 1667 | 1699 | ||
| @@ -1673,7 +1705,7 @@ static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | |||
| 1673 | } | 1705 | } |
| 1674 | 1706 | ||
| 1675 | static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective, | 1707 | static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective, |
| 1676 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 1708 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
| 1677 | { | 1709 | { |
| 1678 | int error; | 1710 | int error; |
| 1679 | 1711 | ||
| @@ -1685,7 +1717,7 @@ static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effect | |||
| 1685 | } | 1717 | } |
| 1686 | 1718 | ||
| 1687 | static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective, | 1719 | static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective, |
| 1688 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 1720 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
| 1689 | { | 1721 | { |
| 1690 | secondary_ops->capset_set(target, effective, inheritable, permitted); | 1722 | secondary_ops->capset_set(target, effective, inheritable, permitted); |
| 1691 | } | 1723 | } |
| @@ -1698,7 +1730,7 @@ static int selinux_capable(struct task_struct *tsk, int cap) | |||
| 1698 | if (rc) | 1730 | if (rc) |
| 1699 | return rc; | 1731 | return rc; |
| 1700 | 1732 | ||
| 1701 | return task_has_capability(tsk,cap); | 1733 | return task_has_capability(tsk, cap); |
| 1702 | } | 1734 | } |
| 1703 | 1735 | ||
| 1704 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) | 1736 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) |
| @@ -1707,7 +1739,7 @@ static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) | |||
| 1707 | char *buffer, *path, *end; | 1739 | char *buffer, *path, *end; |
| 1708 | 1740 | ||
| 1709 | rc = -ENOMEM; | 1741 | rc = -ENOMEM; |
| 1710 | buffer = (char*)__get_free_page(GFP_KERNEL); | 1742 | buffer = (char *)__get_free_page(GFP_KERNEL); |
| 1711 | if (!buffer) | 1743 | if (!buffer) |
| 1712 | goto out; | 1744 | goto out; |
| 1713 | 1745 | ||
| @@ -1765,7 +1797,7 @@ static int selinux_sysctl(ctl_table *table, int op) | |||
| 1765 | 1797 | ||
| 1766 | /* The op values are "defined" in sysctl.c, thereby creating | 1798 | /* The op values are "defined" in sysctl.c, thereby creating |
| 1767 | * a bad coupling between this module and sysctl.c */ | 1799 | * a bad coupling between this module and sysctl.c */ |
| 1768 | if(op == 001) { | 1800 | if (op == 001) { |
| 1769 | error = avc_has_perm(tsec->sid, tsid, | 1801 | error = avc_has_perm(tsec->sid, tsid, |
| 1770 | SECCLASS_DIR, DIR__SEARCH, NULL); | 1802 | SECCLASS_DIR, DIR__SEARCH, NULL); |
| 1771 | } else { | 1803 | } else { |
| @@ -1777,7 +1809,7 @@ static int selinux_sysctl(ctl_table *table, int op) | |||
| 1777 | if (av) | 1809 | if (av) |
| 1778 | error = avc_has_perm(tsec->sid, tsid, | 1810 | error = avc_has_perm(tsec->sid, tsid, |
| 1779 | SECCLASS_FILE, av, NULL); | 1811 | SECCLASS_FILE, av, NULL); |
| 1780 | } | 1812 | } |
| 1781 | 1813 | ||
| 1782 | return error; | 1814 | return error; |
| 1783 | } | 1815 | } |
| @@ -1790,25 +1822,23 @@ static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | |||
| 1790 | return 0; | 1822 | return 0; |
| 1791 | 1823 | ||
| 1792 | switch (cmds) { | 1824 | switch (cmds) { |
| 1793 | case Q_SYNC: | 1825 | case Q_SYNC: |
| 1794 | case Q_QUOTAON: | 1826 | case Q_QUOTAON: |
| 1795 | case Q_QUOTAOFF: | 1827 | case Q_QUOTAOFF: |
| 1796 | case Q_SETINFO: | 1828 | case Q_SETINFO: |
| 1797 | case Q_SETQUOTA: | 1829 | case Q_SETQUOTA: |
| 1798 | rc = superblock_has_perm(current, | 1830 | rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAMOD, |
| 1799 | sb, | 1831 | NULL); |
| 1800 | FILESYSTEM__QUOTAMOD, NULL); | 1832 | break; |
| 1801 | break; | 1833 | case Q_GETFMT: |
| 1802 | case Q_GETFMT: | 1834 | case Q_GETINFO: |
| 1803 | case Q_GETINFO: | 1835 | case Q_GETQUOTA: |
| 1804 | case Q_GETQUOTA: | 1836 | rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAGET, |
| 1805 | rc = superblock_has_perm(current, | 1837 | NULL); |
| 1806 | sb, | 1838 | break; |
| 1807 | FILESYSTEM__QUOTAGET, NULL); | 1839 | default: |
| 1808 | break; | 1840 | rc = 0; /* let the kernel handle invalid cmds */ |
| 1809 | default: | 1841 | break; |
| 1810 | rc = 0; /* let the kernel handle invalid cmds */ | ||
| 1811 | break; | ||
| 1812 | } | 1842 | } |
| 1813 | return rc; | 1843 | return rc; |
| 1814 | } | 1844 | } |
| @@ -1827,23 +1857,23 @@ static int selinux_syslog(int type) | |||
| 1827 | return rc; | 1857 | return rc; |
| 1828 | 1858 | ||
| 1829 | switch (type) { | 1859 | switch (type) { |
| 1830 | case 3: /* Read last kernel messages */ | 1860 | case 3: /* Read last kernel messages */ |
| 1831 | case 10: /* Return size of the log buffer */ | 1861 | case 10: /* Return size of the log buffer */ |
| 1832 | rc = task_has_system(current, SYSTEM__SYSLOG_READ); | 1862 | rc = task_has_system(current, SYSTEM__SYSLOG_READ); |
| 1833 | break; | 1863 | break; |
| 1834 | case 6: /* Disable logging to console */ | 1864 | case 6: /* Disable logging to console */ |
| 1835 | case 7: /* Enable logging to console */ | 1865 | case 7: /* Enable logging to console */ |
| 1836 | case 8: /* Set level of messages printed to console */ | 1866 | case 8: /* Set level of messages printed to console */ |
| 1837 | rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); | 1867 | rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); |
| 1838 | break; | 1868 | break; |
| 1839 | case 0: /* Close log */ | 1869 | case 0: /* Close log */ |
| 1840 | case 1: /* Open log */ | 1870 | case 1: /* Open log */ |
| 1841 | case 2: /* Read from log */ | 1871 | case 2: /* Read from log */ |
| 1842 | case 4: /* Read/clear last kernel messages */ | 1872 | case 4: /* Read/clear last kernel messages */ |
| 1843 | case 5: /* Clear ring buffer */ | 1873 | case 5: /* Clear ring buffer */ |
| 1844 | default: | 1874 | default: |
| 1845 | rc = task_has_system(current, SYSTEM__SYSLOG_MOD); | 1875 | rc = task_has_system(current, SYSTEM__SYSLOG_MOD); |
| 1846 | break; | 1876 | break; |
| 1847 | } | 1877 | } |
| 1848 | return rc; | 1878 | return rc; |
| 1849 | } | 1879 | } |
| @@ -1879,6 +1909,22 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 1879 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 1909 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
| 1880 | } | 1910 | } |
| 1881 | 1911 | ||
| 1912 | /** | ||
| 1913 | * task_tracer_task - return the task that is tracing the given task | ||
| 1914 | * @task: task to consider | ||
| 1915 | * | ||
| 1916 | * Returns NULL if noone is tracing @task, or the &struct task_struct | ||
| 1917 | * pointer to its tracer. | ||
| 1918 | * | ||
| 1919 | * Must be called under rcu_read_lock(). | ||
| 1920 | */ | ||
| 1921 | static struct task_struct *task_tracer_task(struct task_struct *task) | ||
| 1922 | { | ||
| 1923 | if (task->ptrace & PT_PTRACED) | ||
| 1924 | return rcu_dereference(task->parent); | ||
| 1925 | return NULL; | ||
| 1926 | } | ||
| 1927 | |||
| 1882 | /* binprm security operations */ | 1928 | /* binprm security operations */ |
| 1883 | 1929 | ||
| 1884 | static int selinux_bprm_alloc_security(struct linux_binprm *bprm) | 1930 | static int selinux_bprm_alloc_security(struct linux_binprm *bprm) |
| @@ -1889,7 +1935,6 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) | |||
| 1889 | if (!bsec) | 1935 | if (!bsec) |
| 1890 | return -ENOMEM; | 1936 | return -ENOMEM; |
| 1891 | 1937 | ||
| 1892 | bsec->bprm = bprm; | ||
| 1893 | bsec->sid = SECINITSID_UNLABELED; | 1938 | bsec->sid = SECINITSID_UNLABELED; |
| 1894 | bsec->set = 0; | 1939 | bsec->set = 0; |
| 1895 | 1940 | ||
| @@ -1934,7 +1979,7 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) | |||
| 1934 | } else { | 1979 | } else { |
| 1935 | /* Check for a default transition on this program. */ | 1980 | /* Check for a default transition on this program. */ |
| 1936 | rc = security_transition_sid(tsec->sid, isec->sid, | 1981 | rc = security_transition_sid(tsec->sid, isec->sid, |
| 1937 | SECCLASS_PROCESS, &newsid); | 1982 | SECCLASS_PROCESS, &newsid); |
| 1938 | if (rc) | 1983 | if (rc) |
| 1939 | return rc; | 1984 | return rc; |
| 1940 | } | 1985 | } |
| @@ -1945,7 +1990,7 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) | |||
| 1945 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | 1990 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) |
| 1946 | newsid = tsec->sid; | 1991 | newsid = tsec->sid; |
| 1947 | 1992 | ||
| 1948 | if (tsec->sid == newsid) { | 1993 | if (tsec->sid == newsid) { |
| 1949 | rc = avc_has_perm(tsec->sid, isec->sid, | 1994 | rc = avc_has_perm(tsec->sid, isec->sid, |
| 1950 | SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad); | 1995 | SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad); |
| 1951 | if (rc) | 1996 | if (rc) |
| @@ -1973,13 +2018,13 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) | |||
| 1973 | return 0; | 2018 | return 0; |
| 1974 | } | 2019 | } |
| 1975 | 2020 | ||
| 1976 | static int selinux_bprm_check_security (struct linux_binprm *bprm) | 2021 | static int selinux_bprm_check_security(struct linux_binprm *bprm) |
| 1977 | { | 2022 | { |
| 1978 | return secondary_ops->bprm_check_security(bprm); | 2023 | return secondary_ops->bprm_check_security(bprm); |
| 1979 | } | 2024 | } |
| 1980 | 2025 | ||
| 1981 | 2026 | ||
| 1982 | static int selinux_bprm_secureexec (struct linux_binprm *bprm) | 2027 | static int selinux_bprm_secureexec(struct linux_binprm *bprm) |
| 1983 | { | 2028 | { |
| 1984 | struct task_security_struct *tsec = current->security; | 2029 | struct task_security_struct *tsec = current->security; |
| 1985 | int atsecure = 0; | 2030 | int atsecure = 0; |
| @@ -2006,7 +2051,7 @@ extern struct vfsmount *selinuxfs_mount; | |||
| 2006 | extern struct dentry *selinux_null; | 2051 | extern struct dentry *selinux_null; |
| 2007 | 2052 | ||
| 2008 | /* Derived from fs/exec.c:flush_old_files. */ | 2053 | /* Derived from fs/exec.c:flush_old_files. */ |
| 2009 | static inline void flush_unauthorized_files(struct files_struct * files) | 2054 | static inline void flush_unauthorized_files(struct files_struct *files) |
| 2010 | { | 2055 | { |
| 2011 | struct avc_audit_data ad; | 2056 | struct avc_audit_data ad; |
| 2012 | struct file *file, *devnull = NULL; | 2057 | struct file *file, *devnull = NULL; |
| @@ -2041,7 +2086,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) | |||
| 2041 | 2086 | ||
| 2042 | /* Revalidate access to inherited open files. */ | 2087 | /* Revalidate access to inherited open files. */ |
| 2043 | 2088 | ||
| 2044 | AVC_AUDIT_DATA_INIT(&ad,FS); | 2089 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 2045 | 2090 | ||
| 2046 | spin_lock(&files->file_lock); | 2091 | spin_lock(&files->file_lock); |
| 2047 | for (;;) { | 2092 | for (;;) { |
| @@ -2057,7 +2102,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) | |||
| 2057 | if (!set) | 2102 | if (!set) |
| 2058 | continue; | 2103 | continue; |
| 2059 | spin_unlock(&files->file_lock); | 2104 | spin_unlock(&files->file_lock); |
| 2060 | for ( ; set ; i++,set >>= 1) { | 2105 | for ( ; set ; i++, set >>= 1) { |
| 2061 | if (set & 1) { | 2106 | if (set & 1) { |
| 2062 | file = fget(i); | 2107 | file = fget(i); |
| 2063 | if (!file) | 2108 | if (!file) |
| @@ -2126,12 +2171,25 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) | |||
| 2126 | /* Check for ptracing, and update the task SID if ok. | 2171 | /* Check for ptracing, and update the task SID if ok. |
| 2127 | Otherwise, leave SID unchanged and kill. */ | 2172 | Otherwise, leave SID unchanged and kill. */ |
| 2128 | if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { | 2173 | if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { |
| 2129 | rc = avc_has_perm(tsec->ptrace_sid, sid, | 2174 | struct task_struct *tracer; |
| 2130 | SECCLASS_PROCESS, PROCESS__PTRACE, | 2175 | struct task_security_struct *sec; |
| 2131 | NULL); | 2176 | u32 ptsid = 0; |
| 2132 | if (rc) { | 2177 | |
| 2133 | bsec->unsafe = 1; | 2178 | rcu_read_lock(); |
| 2134 | return; | 2179 | tracer = task_tracer_task(current); |
| 2180 | if (likely(tracer != NULL)) { | ||
| 2181 | sec = tracer->security; | ||
| 2182 | ptsid = sec->sid; | ||
| 2183 | } | ||
| 2184 | rcu_read_unlock(); | ||
| 2185 | |||
| 2186 | if (ptsid != 0) { | ||
| 2187 | rc = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, | ||
| 2188 | PROCESS__PTRACE, NULL); | ||
| 2189 | if (rc) { | ||
| 2190 | bsec->unsafe = 1; | ||
| 2191 | return; | ||
| 2192 | } | ||
| 2135 | } | 2193 | } |
| 2136 | } | 2194 | } |
| 2137 | tsec->sid = sid; | 2195 | tsec->sid = sid; |
| @@ -2201,7 +2259,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) | |||
| 2201 | for (i = 0; i < RLIM_NLIMITS; i++) { | 2259 | for (i = 0; i < RLIM_NLIMITS; i++) { |
| 2202 | rlim = current->signal->rlim + i; | 2260 | rlim = current->signal->rlim + i; |
| 2203 | initrlim = init_task.signal->rlim+i; | 2261 | initrlim = init_task.signal->rlim+i; |
| 2204 | rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur); | 2262 | rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); |
| 2205 | } | 2263 | } |
| 2206 | if (current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | 2264 | if (current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { |
| 2207 | /* | 2265 | /* |
| @@ -2239,10 +2297,10 @@ static inline int match_prefix(char *prefix, int plen, char *option, int olen) | |||
| 2239 | 2297 | ||
| 2240 | static inline int selinux_option(char *option, int len) | 2298 | static inline int selinux_option(char *option, int len) |
| 2241 | { | 2299 | { |
| 2242 | return (match_prefix("context=", sizeof("context=")-1, option, len) || | 2300 | return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || |
| 2243 | match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) || | 2301 | match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || |
| 2244 | match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) || | 2302 | match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || |
| 2245 | match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len)); | 2303 | match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len)); |
| 2246 | } | 2304 | } |
| 2247 | 2305 | ||
| 2248 | static inline void take_option(char **to, char *from, int *first, int len) | 2306 | static inline void take_option(char **to, char *from, int *first, int len) |
| @@ -2256,16 +2314,15 @@ static inline void take_option(char **to, char *from, int *first, int len) | |||
| 2256 | *to += len; | 2314 | *to += len; |
| 2257 | } | 2315 | } |
| 2258 | 2316 | ||
| 2259 | static inline void take_selinux_option(char **to, char *from, int *first, | 2317 | static inline void take_selinux_option(char **to, char *from, int *first, |
| 2260 | int len) | 2318 | int len) |
| 2261 | { | 2319 | { |
| 2262 | int current_size = 0; | 2320 | int current_size = 0; |
| 2263 | 2321 | ||
| 2264 | if (!*first) { | 2322 | if (!*first) { |
| 2265 | **to = '|'; | 2323 | **to = '|'; |
| 2266 | *to += 1; | 2324 | *to += 1; |
| 2267 | } | 2325 | } else |
| 2268 | else | ||
| 2269 | *first = 0; | 2326 | *first = 0; |
| 2270 | 2327 | ||
| 2271 | while (current_size < len) { | 2328 | while (current_size < len) { |
| @@ -2329,7 +2386,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data) | |||
| 2329 | if (rc) | 2386 | if (rc) |
| 2330 | return rc; | 2387 | return rc; |
| 2331 | 2388 | ||
| 2332 | AVC_AUDIT_DATA_INIT(&ad,FS); | 2389 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 2333 | ad.u.fs.path.dentry = sb->s_root; | 2390 | ad.u.fs.path.dentry = sb->s_root; |
| 2334 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); | 2391 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); |
| 2335 | } | 2392 | } |
| @@ -2338,29 +2395,29 @@ static int selinux_sb_statfs(struct dentry *dentry) | |||
| 2338 | { | 2395 | { |
| 2339 | struct avc_audit_data ad; | 2396 | struct avc_audit_data ad; |
| 2340 | 2397 | ||
| 2341 | AVC_AUDIT_DATA_INIT(&ad,FS); | 2398 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 2342 | ad.u.fs.path.dentry = dentry->d_sb->s_root; | 2399 | ad.u.fs.path.dentry = dentry->d_sb->s_root; |
| 2343 | return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); | 2400 | return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
| 2344 | } | 2401 | } |
| 2345 | 2402 | ||
| 2346 | static int selinux_mount(char * dev_name, | 2403 | static int selinux_mount(char *dev_name, |
| 2347 | struct nameidata *nd, | 2404 | struct path *path, |
| 2348 | char * type, | 2405 | char *type, |
| 2349 | unsigned long flags, | 2406 | unsigned long flags, |
| 2350 | void * data) | 2407 | void *data) |
| 2351 | { | 2408 | { |
| 2352 | int rc; | 2409 | int rc; |
| 2353 | 2410 | ||
| 2354 | rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data); | 2411 | rc = secondary_ops->sb_mount(dev_name, path, type, flags, data); |
| 2355 | if (rc) | 2412 | if (rc) |
| 2356 | return rc; | 2413 | return rc; |
| 2357 | 2414 | ||
| 2358 | if (flags & MS_REMOUNT) | 2415 | if (flags & MS_REMOUNT) |
| 2359 | return superblock_has_perm(current, nd->path.mnt->mnt_sb, | 2416 | return superblock_has_perm(current, path->mnt->mnt_sb, |
| 2360 | FILESYSTEM__REMOUNT, NULL); | 2417 | FILESYSTEM__REMOUNT, NULL); |
| 2361 | else | 2418 | else |
| 2362 | return dentry_has_perm(current, nd->path.mnt, nd->path.dentry, | 2419 | return dentry_has_perm(current, path->mnt, path->dentry, |
| 2363 | FILE__MOUNTON); | 2420 | FILE__MOUNTON); |
| 2364 | } | 2421 | } |
| 2365 | 2422 | ||
| 2366 | static int selinux_umount(struct vfsmount *mnt, int flags) | 2423 | static int selinux_umount(struct vfsmount *mnt, int flags) |
| @@ -2371,8 +2428,8 @@ static int selinux_umount(struct vfsmount *mnt, int flags) | |||
| 2371 | if (rc) | 2428 | if (rc) |
| 2372 | return rc; | 2429 | return rc; |
| 2373 | 2430 | ||
| 2374 | return superblock_has_perm(current,mnt->mnt_sb, | 2431 | return superblock_has_perm(current, mnt->mnt_sb, |
| 2375 | FILESYSTEM__UNMOUNT,NULL); | 2432 | FILESYSTEM__UNMOUNT, NULL); |
| 2376 | } | 2433 | } |
| 2377 | 2434 | ||
| 2378 | /* inode security operations */ | 2435 | /* inode security operations */ |
| @@ -2412,7 +2469,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 2412 | printk(KERN_WARNING "%s: " | 2469 | printk(KERN_WARNING "%s: " |
| 2413 | "security_transition_sid failed, rc=%d (dev=%s " | 2470 | "security_transition_sid failed, rc=%d (dev=%s " |
| 2414 | "ino=%ld)\n", | 2471 | "ino=%ld)\n", |
| 2415 | __FUNCTION__, | 2472 | __func__, |
| 2416 | -rc, inode->i_sb->s_id, inode->i_ino); | 2473 | -rc, inode->i_sb->s_id, inode->i_ino); |
| 2417 | return rc; | 2474 | return rc; |
| 2418 | } | 2475 | } |
| @@ -2458,7 +2515,7 @@ static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, stru | |||
| 2458 | { | 2515 | { |
| 2459 | int rc; | 2516 | int rc; |
| 2460 | 2517 | ||
| 2461 | rc = secondary_ops->inode_link(old_dentry,dir,new_dentry); | 2518 | rc = secondary_ops->inode_link(old_dentry, dir, new_dentry); |
| 2462 | if (rc) | 2519 | if (rc) |
| 2463 | return rc; | 2520 | return rc; |
| 2464 | return may_link(dir, old_dentry, MAY_LINK); | 2521 | return may_link(dir, old_dentry, MAY_LINK); |
| @@ -2501,7 +2558,7 @@ static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mod | |||
| 2501 | } | 2558 | } |
| 2502 | 2559 | ||
| 2503 | static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, | 2560 | static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, |
| 2504 | struct inode *new_inode, struct dentry *new_dentry) | 2561 | struct inode *new_inode, struct dentry *new_dentry) |
| 2505 | { | 2562 | { |
| 2506 | return may_rename(old_inode, old_dentry, new_inode, new_dentry); | 2563 | return may_rename(old_inode, old_dentry, new_inode, new_dentry); |
| 2507 | } | 2564 | } |
| @@ -2515,7 +2572,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na | |||
| 2515 | { | 2572 | { |
| 2516 | int rc; | 2573 | int rc; |
| 2517 | 2574 | ||
| 2518 | rc = secondary_ops->inode_follow_link(dentry,nameidata); | 2575 | rc = secondary_ops->inode_follow_link(dentry, nameidata); |
| 2519 | if (rc) | 2576 | if (rc) |
| 2520 | return rc; | 2577 | return rc; |
| 2521 | return dentry_has_perm(current, NULL, dentry, FILE__READ); | 2578 | return dentry_has_perm(current, NULL, dentry, FILE__READ); |
| @@ -2536,7 +2593,7 @@ static int selinux_inode_permission(struct inode *inode, int mask, | |||
| 2536 | } | 2593 | } |
| 2537 | 2594 | ||
| 2538 | return inode_has_perm(current, inode, | 2595 | return inode_has_perm(current, inode, |
| 2539 | file_mask_to_av(inode->i_mode, mask), NULL); | 2596 | open_file_mask_to_av(inode->i_mode, mask), NULL); |
| 2540 | } | 2597 | } |
| 2541 | 2598 | ||
| 2542 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2599 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
| @@ -2601,7 +2658,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value | |||
| 2601 | if (!is_owner_or_cap(inode)) | 2658 | if (!is_owner_or_cap(inode)) |
| 2602 | return -EPERM; | 2659 | return -EPERM; |
| 2603 | 2660 | ||
| 2604 | AVC_AUDIT_DATA_INIT(&ad,FS); | 2661 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 2605 | ad.u.fs.path.dentry = dentry; | 2662 | ad.u.fs.path.dentry = dentry; |
| 2606 | 2663 | ||
| 2607 | rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, | 2664 | rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, |
| @@ -2619,7 +2676,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value | |||
| 2619 | return rc; | 2676 | return rc; |
| 2620 | 2677 | ||
| 2621 | rc = security_validate_transition(isec->sid, newsid, tsec->sid, | 2678 | rc = security_validate_transition(isec->sid, newsid, tsec->sid, |
| 2622 | isec->sclass); | 2679 | isec->sclass); |
| 2623 | if (rc) | 2680 | if (rc) |
| 2624 | return rc; | 2681 | return rc; |
| 2625 | 2682 | ||
| @@ -2631,7 +2688,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value | |||
| 2631 | } | 2688 | } |
| 2632 | 2689 | ||
| 2633 | static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, | 2690 | static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, |
| 2634 | void *value, size_t size, int flags) | 2691 | void *value, size_t size, int flags) |
| 2635 | { | 2692 | { |
| 2636 | struct inode *inode = dentry->d_inode; | 2693 | struct inode *inode = dentry->d_inode; |
| 2637 | struct inode_security_struct *isec = inode->i_security; | 2694 | struct inode_security_struct *isec = inode->i_security; |
| @@ -2646,7 +2703,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, | |||
| 2646 | rc = security_context_to_sid(value, size, &newsid); | 2703 | rc = security_context_to_sid(value, size, &newsid); |
| 2647 | if (rc) { | 2704 | if (rc) { |
| 2648 | printk(KERN_WARNING "%s: unable to obtain SID for context " | 2705 | printk(KERN_WARNING "%s: unable to obtain SID for context " |
| 2649 | "%s, rc=%d\n", __FUNCTION__, (char*)value, -rc); | 2706 | "%s, rc=%d\n", __func__, (char *)value, -rc); |
| 2650 | return; | 2707 | return; |
| 2651 | } | 2708 | } |
| 2652 | 2709 | ||
| @@ -2654,17 +2711,17 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, | |||
| 2654 | return; | 2711 | return; |
| 2655 | } | 2712 | } |
| 2656 | 2713 | ||
| 2657 | static int selinux_inode_getxattr (struct dentry *dentry, char *name) | 2714 | static int selinux_inode_getxattr(struct dentry *dentry, char *name) |
| 2658 | { | 2715 | { |
| 2659 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); | 2716 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); |
| 2660 | } | 2717 | } |
| 2661 | 2718 | ||
| 2662 | static int selinux_inode_listxattr (struct dentry *dentry) | 2719 | static int selinux_inode_listxattr(struct dentry *dentry) |
| 2663 | { | 2720 | { |
| 2664 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); | 2721 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); |
| 2665 | } | 2722 | } |
| 2666 | 2723 | ||
| 2667 | static int selinux_inode_removexattr (struct dentry *dentry, char *name) | 2724 | static int selinux_inode_removexattr(struct dentry *dentry, char *name) |
| 2668 | { | 2725 | { |
| 2669 | if (strcmp(name, XATTR_NAME_SELINUX)) | 2726 | if (strcmp(name, XATTR_NAME_SELINUX)) |
| 2670 | return selinux_inode_setotherxattr(dentry, name); | 2727 | return selinux_inode_setotherxattr(dentry, name); |
| @@ -2705,7 +2762,7 @@ out_nofree: | |||
| 2705 | } | 2762 | } |
| 2706 | 2763 | ||
| 2707 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, | 2764 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, |
| 2708 | const void *value, size_t size, int flags) | 2765 | const void *value, size_t size, int flags) |
| 2709 | { | 2766 | { |
| 2710 | struct inode_security_struct *isec = inode->i_security; | 2767 | struct inode_security_struct *isec = inode->i_security; |
| 2711 | u32 newsid; | 2768 | u32 newsid; |
| @@ -2717,7 +2774,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
| 2717 | if (!value || !size) | 2774 | if (!value || !size) |
| 2718 | return -EACCES; | 2775 | return -EACCES; |
| 2719 | 2776 | ||
| 2720 | rc = security_context_to_sid((void*)value, size, &newsid); | 2777 | rc = security_context_to_sid((void *)value, size, &newsid); |
| 2721 | if (rc) | 2778 | if (rc) |
| 2722 | return rc; | 2779 | return rc; |
| 2723 | 2780 | ||
| @@ -2743,6 +2800,12 @@ static int selinux_inode_killpriv(struct dentry *dentry) | |||
| 2743 | return secondary_ops->inode_killpriv(dentry); | 2800 | return secondary_ops->inode_killpriv(dentry); |
| 2744 | } | 2801 | } |
| 2745 | 2802 | ||
| 2803 | static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) | ||
| 2804 | { | ||
| 2805 | struct inode_security_struct *isec = inode->i_security; | ||
| 2806 | *secid = isec->sid; | ||
| 2807 | } | ||
| 2808 | |||
| 2746 | /* file security operations */ | 2809 | /* file security operations */ |
| 2747 | 2810 | ||
| 2748 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 2811 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
| @@ -2802,42 +2865,41 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
| 2802 | int error = 0; | 2865 | int error = 0; |
| 2803 | 2866 | ||
| 2804 | switch (cmd) { | 2867 | switch (cmd) { |
| 2805 | case FIONREAD: | 2868 | case FIONREAD: |
| 2806 | /* fall through */ | 2869 | /* fall through */ |
| 2807 | case FIBMAP: | 2870 | case FIBMAP: |
| 2808 | /* fall through */ | 2871 | /* fall through */ |
| 2809 | case FIGETBSZ: | 2872 | case FIGETBSZ: |
| 2810 | /* fall through */ | 2873 | /* fall through */ |
| 2811 | case EXT2_IOC_GETFLAGS: | 2874 | case EXT2_IOC_GETFLAGS: |
| 2812 | /* fall through */ | 2875 | /* fall through */ |
| 2813 | case EXT2_IOC_GETVERSION: | 2876 | case EXT2_IOC_GETVERSION: |
| 2814 | error = file_has_perm(current, file, FILE__GETATTR); | 2877 | error = file_has_perm(current, file, FILE__GETATTR); |
| 2815 | break; | 2878 | break; |
| 2816 | |||
| 2817 | case EXT2_IOC_SETFLAGS: | ||
| 2818 | /* fall through */ | ||
| 2819 | case EXT2_IOC_SETVERSION: | ||
| 2820 | error = file_has_perm(current, file, FILE__SETATTR); | ||
| 2821 | break; | ||
| 2822 | 2879 | ||
| 2823 | /* sys_ioctl() checks */ | 2880 | case EXT2_IOC_SETFLAGS: |
| 2824 | case FIONBIO: | 2881 | /* fall through */ |
| 2825 | /* fall through */ | 2882 | case EXT2_IOC_SETVERSION: |
| 2826 | case FIOASYNC: | 2883 | error = file_has_perm(current, file, FILE__SETATTR); |
| 2827 | error = file_has_perm(current, file, 0); | 2884 | break; |
| 2828 | break; | ||
| 2829 | 2885 | ||
| 2830 | case KDSKBENT: | 2886 | /* sys_ioctl() checks */ |
| 2831 | case KDSKBSENT: | 2887 | case FIONBIO: |
| 2832 | error = task_has_capability(current,CAP_SYS_TTY_CONFIG); | 2888 | /* fall through */ |
| 2833 | break; | 2889 | case FIOASYNC: |
| 2890 | error = file_has_perm(current, file, 0); | ||
| 2891 | break; | ||
| 2834 | 2892 | ||
| 2835 | /* default case assumes that the command will go | 2893 | case KDSKBENT: |
| 2836 | * to the file's ioctl() function. | 2894 | case KDSKBSENT: |
| 2837 | */ | 2895 | error = task_has_capability(current, CAP_SYS_TTY_CONFIG); |
| 2838 | default: | 2896 | break; |
| 2839 | error = file_has_perm(current, file, FILE__IOCTL); | ||
| 2840 | 2897 | ||
| 2898 | /* default case assumes that the command will go | ||
| 2899 | * to the file's ioctl() function. | ||
| 2900 | */ | ||
| 2901 | default: | ||
| 2902 | error = file_has_perm(current, file, FILE__IOCTL); | ||
| 2841 | } | 2903 | } |
| 2842 | return error; | 2904 | return error; |
| 2843 | } | 2905 | } |
| @@ -2878,7 +2940,7 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot, | |||
| 2878 | unsigned long addr, unsigned long addr_only) | 2940 | unsigned long addr, unsigned long addr_only) |
| 2879 | { | 2941 | { |
| 2880 | int rc = 0; | 2942 | int rc = 0; |
| 2881 | u32 sid = ((struct task_security_struct*)(current->security))->sid; | 2943 | u32 sid = ((struct task_security_struct *)(current->security))->sid; |
| 2882 | 2944 | ||
| 2883 | if (addr < mmap_min_addr) | 2945 | if (addr < mmap_min_addr) |
| 2884 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, | 2946 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, |
| @@ -2947,39 +3009,39 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, | |||
| 2947 | int err = 0; | 3009 | int err = 0; |
| 2948 | 3010 | ||
| 2949 | switch (cmd) { | 3011 | switch (cmd) { |
| 2950 | case F_SETFL: | 3012 | case F_SETFL: |
| 2951 | if (!file->f_path.dentry || !file->f_path.dentry->d_inode) { | 3013 | if (!file->f_path.dentry || !file->f_path.dentry->d_inode) { |
| 2952 | err = -EINVAL; | 3014 | err = -EINVAL; |
| 2953 | break; | 3015 | break; |
| 2954 | } | 3016 | } |
| 2955 | 3017 | ||
| 2956 | if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) { | 3018 | if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) { |
| 2957 | err = file_has_perm(current, file,FILE__WRITE); | 3019 | err = file_has_perm(current, file, FILE__WRITE); |
| 2958 | break; | ||
| 2959 | } | ||
| 2960 | /* fall through */ | ||
| 2961 | case F_SETOWN: | ||
| 2962 | case F_SETSIG: | ||
| 2963 | case F_GETFL: | ||
| 2964 | case F_GETOWN: | ||
| 2965 | case F_GETSIG: | ||
| 2966 | /* Just check FD__USE permission */ | ||
| 2967 | err = file_has_perm(current, file, 0); | ||
| 2968 | break; | 3020 | break; |
| 2969 | case F_GETLK: | 3021 | } |
| 2970 | case F_SETLK: | 3022 | /* fall through */ |
| 2971 | case F_SETLKW: | 3023 | case F_SETOWN: |
| 3024 | case F_SETSIG: | ||
| 3025 | case F_GETFL: | ||
| 3026 | case F_GETOWN: | ||
| 3027 | case F_GETSIG: | ||
| 3028 | /* Just check FD__USE permission */ | ||
| 3029 | err = file_has_perm(current, file, 0); | ||
| 3030 | break; | ||
| 3031 | case F_GETLK: | ||
| 3032 | case F_SETLK: | ||
| 3033 | case F_SETLKW: | ||
| 2972 | #if BITS_PER_LONG == 32 | 3034 | #if BITS_PER_LONG == 32 |
| 2973 | case F_GETLK64: | 3035 | case F_GETLK64: |
| 2974 | case F_SETLK64: | 3036 | case F_SETLK64: |
| 2975 | case F_SETLKW64: | 3037 | case F_SETLKW64: |
| 2976 | #endif | 3038 | #endif |
| 2977 | if (!file->f_path.dentry || !file->f_path.dentry->d_inode) { | 3039 | if (!file->f_path.dentry || !file->f_path.dentry->d_inode) { |
| 2978 | err = -EINVAL; | 3040 | err = -EINVAL; |
| 2979 | break; | ||
| 2980 | } | ||
| 2981 | err = file_has_perm(current, file, FILE__LOCK); | ||
| 2982 | break; | 3041 | break; |
| 3042 | } | ||
| 3043 | err = file_has_perm(current, file, FILE__LOCK); | ||
| 3044 | break; | ||
| 2983 | } | 3045 | } |
| 2984 | 3046 | ||
| 2985 | return err; | 3047 | return err; |
| @@ -3000,13 +3062,13 @@ static int selinux_file_set_fowner(struct file *file) | |||
| 3000 | static int selinux_file_send_sigiotask(struct task_struct *tsk, | 3062 | static int selinux_file_send_sigiotask(struct task_struct *tsk, |
| 3001 | struct fown_struct *fown, int signum) | 3063 | struct fown_struct *fown, int signum) |
| 3002 | { | 3064 | { |
| 3003 | struct file *file; | 3065 | struct file *file; |
| 3004 | u32 perm; | 3066 | u32 perm; |
| 3005 | struct task_security_struct *tsec; | 3067 | struct task_security_struct *tsec; |
| 3006 | struct file_security_struct *fsec; | 3068 | struct file_security_struct *fsec; |
| 3007 | 3069 | ||
| 3008 | /* struct fown_struct is never outside the context of a struct file */ | 3070 | /* struct fown_struct is never outside the context of a struct file */ |
| 3009 | file = container_of(fown, struct file, f_owner); | 3071 | file = container_of(fown, struct file, f_owner); |
| 3010 | 3072 | ||
| 3011 | tsec = tsk->security; | 3073 | tsec = tsk->security; |
| 3012 | fsec = file->f_security; | 3074 | fsec = file->f_security; |
| @@ -3087,11 +3149,6 @@ static int selinux_task_alloc_security(struct task_struct *tsk) | |||
| 3087 | tsec2->keycreate_sid = tsec1->keycreate_sid; | 3149 | tsec2->keycreate_sid = tsec1->keycreate_sid; |
| 3088 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; | 3150 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; |
| 3089 | 3151 | ||
| 3090 | /* Retain ptracer SID across fork, if any. | ||
| 3091 | This will be reset by the ptrace hook upon any | ||
| 3092 | subsequent ptrace_attach operations. */ | ||
| 3093 | tsec2->ptrace_sid = tsec1->ptrace_sid; | ||
| 3094 | |||
| 3095 | return 0; | 3152 | return 0; |
| 3096 | } | 3153 | } |
| 3097 | 3154 | ||
| @@ -3113,7 +3170,7 @@ static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) | |||
| 3113 | 3170 | ||
| 3114 | static int selinux_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) | 3171 | static int selinux_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) |
| 3115 | { | 3172 | { |
| 3116 | return secondary_ops->task_post_setuid(id0,id1,id2,flags); | 3173 | return secondary_ops->task_post_setuid(id0, id1, id2, flags); |
| 3117 | } | 3174 | } |
| 3118 | 3175 | ||
| 3119 | static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags) | 3176 | static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags) |
| @@ -3139,7 +3196,8 @@ static int selinux_task_getsid(struct task_struct *p) | |||
| 3139 | 3196 | ||
| 3140 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | 3197 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) |
| 3141 | { | 3198 | { |
| 3142 | selinux_get_task_sid(p, secid); | 3199 | struct task_security_struct *tsec = p->security; |
| 3200 | *secid = tsec->sid; | ||
| 3143 | } | 3201 | } |
| 3144 | 3202 | ||
| 3145 | static int selinux_task_setgroups(struct group_info *group_info) | 3203 | static int selinux_task_setgroups(struct group_info *group_info) |
| @@ -3156,7 +3214,7 @@ static int selinux_task_setnice(struct task_struct *p, int nice) | |||
| 3156 | if (rc) | 3214 | if (rc) |
| 3157 | return rc; | 3215 | return rc; |
| 3158 | 3216 | ||
| 3159 | return task_has_perm(current,p, PROCESS__SETSCHED); | 3217 | return task_has_perm(current, p, PROCESS__SETSCHED); |
| 3160 | } | 3218 | } |
| 3161 | 3219 | ||
| 3162 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | 3220 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) |
| @@ -3245,12 +3303,13 @@ static int selinux_task_prctl(int option, | |||
| 3245 | unsigned long arg2, | 3303 | unsigned long arg2, |
| 3246 | unsigned long arg3, | 3304 | unsigned long arg3, |
| 3247 | unsigned long arg4, | 3305 | unsigned long arg4, |
| 3248 | unsigned long arg5) | 3306 | unsigned long arg5, |
| 3307 | long *rc_p) | ||
| 3249 | { | 3308 | { |
| 3250 | /* The current prctl operations do not appear to require | 3309 | /* The current prctl operations do not appear to require |
| 3251 | any SELinux controls since they merely observe or modify | 3310 | any SELinux controls since they merely observe or modify |
| 3252 | the state of the current process. */ | 3311 | the state of the current process. */ |
| 3253 | return 0; | 3312 | return secondary_ops->task_prctl(option, arg2, arg3, arg4, arg5, rc_p); |
| 3254 | } | 3313 | } |
| 3255 | 3314 | ||
| 3256 | static int selinux_task_wait(struct task_struct *p) | 3315 | static int selinux_task_wait(struct task_struct *p) |
| @@ -3260,7 +3319,7 @@ static int selinux_task_wait(struct task_struct *p) | |||
| 3260 | 3319 | ||
| 3261 | static void selinux_task_reparent_to_init(struct task_struct *p) | 3320 | static void selinux_task_reparent_to_init(struct task_struct *p) |
| 3262 | { | 3321 | { |
| 3263 | struct task_security_struct *tsec; | 3322 | struct task_security_struct *tsec; |
| 3264 | 3323 | ||
| 3265 | secondary_ops->task_reparent_to_init(p); | 3324 | secondary_ops->task_reparent_to_init(p); |
| 3266 | 3325 | ||
| @@ -3305,11 +3364,11 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, | |||
| 3305 | *proto = ih->protocol; | 3364 | *proto = ih->protocol; |
| 3306 | 3365 | ||
| 3307 | switch (ih->protocol) { | 3366 | switch (ih->protocol) { |
| 3308 | case IPPROTO_TCP: { | 3367 | case IPPROTO_TCP: { |
| 3309 | struct tcphdr _tcph, *th; | 3368 | struct tcphdr _tcph, *th; |
| 3310 | 3369 | ||
| 3311 | if (ntohs(ih->frag_off) & IP_OFFSET) | 3370 | if (ntohs(ih->frag_off) & IP_OFFSET) |
| 3312 | break; | 3371 | break; |
| 3313 | 3372 | ||
| 3314 | offset += ihlen; | 3373 | offset += ihlen; |
| 3315 | th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); | 3374 | th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); |
| @@ -3319,23 +3378,23 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, | |||
| 3319 | ad->u.net.sport = th->source; | 3378 | ad->u.net.sport = th->source; |
| 3320 | ad->u.net.dport = th->dest; | 3379 | ad->u.net.dport = th->dest; |
| 3321 | break; | 3380 | break; |
| 3322 | } | 3381 | } |
| 3323 | 3382 | ||
| 3324 | case IPPROTO_UDP: { | 3383 | case IPPROTO_UDP: { |
| 3325 | struct udphdr _udph, *uh; | 3384 | struct udphdr _udph, *uh; |
| 3326 | 3385 | ||
| 3327 | if (ntohs(ih->frag_off) & IP_OFFSET) | 3386 | if (ntohs(ih->frag_off) & IP_OFFSET) |
| 3328 | break; | 3387 | break; |
| 3329 | 3388 | ||
| 3330 | offset += ihlen; | 3389 | offset += ihlen; |
| 3331 | uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph); | 3390 | uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph); |
| 3332 | if (uh == NULL) | 3391 | if (uh == NULL) |
| 3333 | break; | 3392 | break; |
| 3334 | 3393 | ||
| 3335 | ad->u.net.sport = uh->source; | 3394 | ad->u.net.sport = uh->source; |
| 3336 | ad->u.net.dport = uh->dest; | 3395 | ad->u.net.dport = uh->dest; |
| 3337 | break; | 3396 | break; |
| 3338 | } | 3397 | } |
| 3339 | 3398 | ||
| 3340 | case IPPROTO_DCCP: { | 3399 | case IPPROTO_DCCP: { |
| 3341 | struct dccp_hdr _dccph, *dh; | 3400 | struct dccp_hdr _dccph, *dh; |
| @@ -3351,11 +3410,11 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, | |||
| 3351 | ad->u.net.sport = dh->dccph_sport; | 3410 | ad->u.net.sport = dh->dccph_sport; |
| 3352 | ad->u.net.dport = dh->dccph_dport; | 3411 | ad->u.net.dport = dh->dccph_dport; |
| 3353 | break; | 3412 | break; |
| 3354 | } | 3413 | } |
| 3355 | 3414 | ||
| 3356 | default: | 3415 | default: |
| 3357 | break; | 3416 | break; |
| 3358 | } | 3417 | } |
| 3359 | out: | 3418 | out: |
| 3360 | return ret; | 3419 | return ret; |
| 3361 | } | 3420 | } |
| @@ -3390,7 +3449,7 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, | |||
| 3390 | 3449 | ||
| 3391 | switch (nexthdr) { | 3450 | switch (nexthdr) { |
| 3392 | case IPPROTO_TCP: { | 3451 | case IPPROTO_TCP: { |
| 3393 | struct tcphdr _tcph, *th; | 3452 | struct tcphdr _tcph, *th; |
| 3394 | 3453 | ||
| 3395 | th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); | 3454 | th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); |
| 3396 | if (th == NULL) | 3455 | if (th == NULL) |
| @@ -3423,7 +3482,7 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, | |||
| 3423 | ad->u.net.sport = dh->dccph_sport; | 3482 | ad->u.net.sport = dh->dccph_sport; |
| 3424 | ad->u.net.dport = dh->dccph_dport; | 3483 | ad->u.net.dport = dh->dccph_dport; |
| 3425 | break; | 3484 | break; |
| 3426 | } | 3485 | } |
| 3427 | 3486 | ||
| 3428 | /* includes fragments */ | 3487 | /* includes fragments */ |
| 3429 | default: | 3488 | default: |
| @@ -3521,7 +3580,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, | |||
| 3521 | if (isec->sid == SECINITSID_KERNEL) | 3580 | if (isec->sid == SECINITSID_KERNEL) |
| 3522 | goto out; | 3581 | goto out; |
| 3523 | 3582 | ||
| 3524 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3583 | AVC_AUDIT_DATA_INIT(&ad, NET); |
| 3525 | ad.u.net.sk = sock->sk; | 3584 | ad.u.net.sk = sock->sk; |
| 3526 | err = avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad); | 3585 | err = avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad); |
| 3527 | 3586 | ||
| @@ -3627,13 +3686,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3627 | inet_get_local_port_range(&low, &high); | 3686 | inet_get_local_port_range(&low, &high); |
| 3628 | 3687 | ||
| 3629 | if (snum < max(PROT_SOCK, low) || snum > high) { | 3688 | if (snum < max(PROT_SOCK, low) || snum > high) { |
| 3630 | err = security_port_sid(sk->sk_family, | 3689 | err = sel_netport_sid(sk->sk_protocol, |
| 3631 | sk->sk_type, | 3690 | snum, &sid); |
| 3632 | sk->sk_protocol, snum, | ||
| 3633 | &sid); | ||
| 3634 | if (err) | 3691 | if (err) |
| 3635 | goto out; | 3692 | goto out; |
| 3636 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3693 | AVC_AUDIT_DATA_INIT(&ad, NET); |
| 3637 | ad.u.net.sport = htons(snum); | 3694 | ad.u.net.sport = htons(snum); |
| 3638 | ad.u.net.family = family; | 3695 | ad.u.net.family = family; |
| 3639 | err = avc_has_perm(isec->sid, sid, | 3696 | err = avc_has_perm(isec->sid, sid, |
| @@ -3643,12 +3700,12 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3643 | goto out; | 3700 | goto out; |
| 3644 | } | 3701 | } |
| 3645 | } | 3702 | } |
| 3646 | 3703 | ||
| 3647 | switch(isec->sclass) { | 3704 | switch (isec->sclass) { |
| 3648 | case SECCLASS_TCP_SOCKET: | 3705 | case SECCLASS_TCP_SOCKET: |
| 3649 | node_perm = TCP_SOCKET__NODE_BIND; | 3706 | node_perm = TCP_SOCKET__NODE_BIND; |
| 3650 | break; | 3707 | break; |
| 3651 | 3708 | ||
| 3652 | case SECCLASS_UDP_SOCKET: | 3709 | case SECCLASS_UDP_SOCKET: |
| 3653 | node_perm = UDP_SOCKET__NODE_BIND; | 3710 | node_perm = UDP_SOCKET__NODE_BIND; |
| 3654 | break; | 3711 | break; |
| @@ -3661,12 +3718,12 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3661 | node_perm = RAWIP_SOCKET__NODE_BIND; | 3718 | node_perm = RAWIP_SOCKET__NODE_BIND; |
| 3662 | break; | 3719 | break; |
| 3663 | } | 3720 | } |
| 3664 | 3721 | ||
| 3665 | err = sel_netnode_sid(addrp, family, &sid); | 3722 | err = sel_netnode_sid(addrp, family, &sid); |
| 3666 | if (err) | 3723 | if (err) |
| 3667 | goto out; | 3724 | goto out; |
| 3668 | 3725 | ||
| 3669 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3726 | AVC_AUDIT_DATA_INIT(&ad, NET); |
| 3670 | ad.u.net.sport = htons(snum); | 3727 | ad.u.net.sport = htons(snum); |
| 3671 | ad.u.net.family = family; | 3728 | ad.u.net.family = family; |
| 3672 | 3729 | ||
| @@ -3676,7 +3733,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3676 | ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr); | 3733 | ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr); |
| 3677 | 3734 | ||
| 3678 | err = avc_has_perm(isec->sid, sid, | 3735 | err = avc_has_perm(isec->sid, sid, |
| 3679 | isec->sclass, node_perm, &ad); | 3736 | isec->sclass, node_perm, &ad); |
| 3680 | if (err) | 3737 | if (err) |
| 3681 | goto out; | 3738 | goto out; |
| 3682 | } | 3739 | } |
| @@ -3718,15 +3775,14 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
| 3718 | snum = ntohs(addr6->sin6_port); | 3775 | snum = ntohs(addr6->sin6_port); |
| 3719 | } | 3776 | } |
| 3720 | 3777 | ||
| 3721 | err = security_port_sid(sk->sk_family, sk->sk_type, | 3778 | err = sel_netport_sid(sk->sk_protocol, snum, &sid); |
| 3722 | sk->sk_protocol, snum, &sid); | ||
| 3723 | if (err) | 3779 | if (err) |
| 3724 | goto out; | 3780 | goto out; |
| 3725 | 3781 | ||
| 3726 | perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? | 3782 | perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? |
| 3727 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; | 3783 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; |
| 3728 | 3784 | ||
| 3729 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3785 | AVC_AUDIT_DATA_INIT(&ad, NET); |
| 3730 | ad.u.net.dport = htons(snum); | 3786 | ad.u.net.dport = htons(snum); |
| 3731 | ad.u.net.family = sk->sk_family; | 3787 | ad.u.net.family = sk->sk_family; |
| 3732 | err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); | 3788 | err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); |
| @@ -3764,7 +3820,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | |||
| 3764 | } | 3820 | } |
| 3765 | 3821 | ||
| 3766 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, | 3822 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, |
| 3767 | int size) | 3823 | int size) |
| 3768 | { | 3824 | { |
| 3769 | int rc; | 3825 | int rc; |
| 3770 | 3826 | ||
| @@ -3791,7 +3847,7 @@ static int selinux_socket_getpeername(struct socket *sock) | |||
| 3791 | return socket_has_perm(current, sock, SOCKET__GETATTR); | 3847 | return socket_has_perm(current, sock, SOCKET__GETATTR); |
| 3792 | } | 3848 | } |
| 3793 | 3849 | ||
| 3794 | static int selinux_socket_setsockopt(struct socket *sock,int level,int optname) | 3850 | static int selinux_socket_setsockopt(struct socket *sock, int level, int optname) |
| 3795 | { | 3851 | { |
| 3796 | int err; | 3852 | int err; |
| 3797 | 3853 | ||
| @@ -3830,7 +3886,7 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, | |||
| 3830 | isec = SOCK_INODE(sock)->i_security; | 3886 | isec = SOCK_INODE(sock)->i_security; |
| 3831 | other_isec = SOCK_INODE(other)->i_security; | 3887 | other_isec = SOCK_INODE(other)->i_security; |
| 3832 | 3888 | ||
| 3833 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3889 | AVC_AUDIT_DATA_INIT(&ad, NET); |
| 3834 | ad.u.net.sk = other->sk; | 3890 | ad.u.net.sk = other->sk; |
| 3835 | 3891 | ||
| 3836 | err = avc_has_perm(isec->sid, other_isec->sid, | 3892 | err = avc_has_perm(isec->sid, other_isec->sid, |
| @@ -3842,7 +3898,7 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, | |||
| 3842 | /* connecting socket */ | 3898 | /* connecting socket */ |
| 3843 | ssec = sock->sk->sk_security; | 3899 | ssec = sock->sk->sk_security; |
| 3844 | ssec->peer_sid = other_isec->sid; | 3900 | ssec->peer_sid = other_isec->sid; |
| 3845 | 3901 | ||
| 3846 | /* server child socket */ | 3902 | /* server child socket */ |
| 3847 | ssec = newsk->sk_security; | 3903 | ssec = newsk->sk_security; |
| 3848 | ssec->peer_sid = isec->sid; | 3904 | ssec->peer_sid = isec->sid; |
| @@ -3862,7 +3918,7 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
| 3862 | isec = SOCK_INODE(sock)->i_security; | 3918 | isec = SOCK_INODE(sock)->i_security; |
| 3863 | other_isec = SOCK_INODE(other)->i_security; | 3919 | other_isec = SOCK_INODE(other)->i_security; |
| 3864 | 3920 | ||
| 3865 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3921 | AVC_AUDIT_DATA_INIT(&ad, NET); |
| 3866 | ad.u.net.sk = other->sk; | 3922 | ad.u.net.sk = other->sk; |
| 3867 | 3923 | ||
| 3868 | err = avc_has_perm(isec->sid, other_isec->sid, | 3924 | err = avc_has_perm(isec->sid, other_isec->sid, |
| @@ -3940,7 +3996,7 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk, | |||
| 3940 | err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad); | 3996 | err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad); |
| 3941 | if (err) | 3997 | if (err) |
| 3942 | return err; | 3998 | return err; |
| 3943 | 3999 | ||
| 3944 | err = sel_netnode_sid(addrp, family, &node_sid); | 4000 | err = sel_netnode_sid(addrp, family, &node_sid); |
| 3945 | if (err) | 4001 | if (err) |
| 3946 | return err; | 4002 | return err; |
| @@ -3950,9 +4006,8 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk, | |||
| 3950 | 4006 | ||
| 3951 | if (!recv_perm) | 4007 | if (!recv_perm) |
| 3952 | return 0; | 4008 | return 0; |
| 3953 | err = security_port_sid(sk->sk_family, sk->sk_type, | 4009 | err = sel_netport_sid(sk->sk_protocol, |
| 3954 | sk->sk_protocol, ntohs(ad->u.net.sport), | 4010 | ntohs(ad->u.net.sport), &port_sid); |
| 3955 | &port_sid); | ||
| 3956 | if (unlikely(err)) { | 4011 | if (unlikely(err)) { |
| 3957 | printk(KERN_WARNING | 4012 | printk(KERN_WARNING |
| 3958 | "SELinux: failure in" | 4013 | "SELinux: failure in" |
| @@ -4092,7 +4147,7 @@ out_len: | |||
| 4092 | err = -EFAULT; | 4147 | err = -EFAULT; |
| 4093 | 4148 | ||
| 4094 | kfree(scontext); | 4149 | kfree(scontext); |
| 4095 | out: | 4150 | out: |
| 4096 | return err; | 4151 | return err; |
| 4097 | } | 4152 | } |
| 4098 | 4153 | ||
| @@ -4109,7 +4164,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * | |||
| 4109 | goto out; | 4164 | goto out; |
| 4110 | 4165 | ||
| 4111 | if (sock && family == PF_UNIX) | 4166 | if (sock && family == PF_UNIX) |
| 4112 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); | 4167 | selinux_inode_getsecid(SOCK_INODE(sock), &peer_secid); |
| 4113 | else if (skb) | 4168 | else if (skb) |
| 4114 | selinux_skb_peerlbl_sid(skb, family, &peer_secid); | 4169 | selinux_skb_peerlbl_sid(skb, family, &peer_secid); |
| 4115 | 4170 | ||
| @@ -4139,7 +4194,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) | |||
| 4139 | newssec->peer_sid = ssec->peer_sid; | 4194 | newssec->peer_sid = ssec->peer_sid; |
| 4140 | newssec->sclass = ssec->sclass; | 4195 | newssec->sclass = ssec->sclass; |
| 4141 | 4196 | ||
| 4142 | selinux_netlbl_sk_security_clone(ssec, newssec); | 4197 | selinux_netlbl_sk_security_reset(newssec, newsk->sk_family); |
| 4143 | } | 4198 | } |
| 4144 | 4199 | ||
| 4145 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | 4200 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
| @@ -4153,7 +4208,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | |||
| 4153 | } | 4208 | } |
| 4154 | } | 4209 | } |
| 4155 | 4210 | ||
| 4156 | static void selinux_sock_graft(struct sock* sk, struct socket *parent) | 4211 | static void selinux_sock_graft(struct sock *sk, struct socket *parent) |
| 4157 | { | 4212 | { |
| 4158 | struct inode_security_struct *isec = SOCK_INODE(parent)->i_security; | 4213 | struct inode_security_struct *isec = SOCK_INODE(parent)->i_security; |
| 4159 | struct sk_security_struct *sksec = sk->sk_security; | 4214 | struct sk_security_struct *sksec = sk->sk_security; |
| @@ -4230,13 +4285,13 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | |||
| 4230 | struct nlmsghdr *nlh; | 4285 | struct nlmsghdr *nlh; |
| 4231 | struct socket *sock = sk->sk_socket; | 4286 | struct socket *sock = sk->sk_socket; |
| 4232 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; | 4287 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; |
| 4233 | 4288 | ||
| 4234 | if (skb->len < NLMSG_SPACE(0)) { | 4289 | if (skb->len < NLMSG_SPACE(0)) { |
| 4235 | err = -EINVAL; | 4290 | err = -EINVAL; |
| 4236 | goto out; | 4291 | goto out; |
| 4237 | } | 4292 | } |
| 4238 | nlh = nlmsg_hdr(skb); | 4293 | nlh = nlmsg_hdr(skb); |
| 4239 | 4294 | ||
| 4240 | err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm); | 4295 | err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm); |
| 4241 | if (err) { | 4296 | if (err) { |
| 4242 | if (err == -EINVAL) { | 4297 | if (err == -EINVAL) { |
| @@ -4362,7 +4417,7 @@ static int selinux_ip_postroute_iptables_compat(struct sock *sk, | |||
| 4362 | return err; | 4417 | return err; |
| 4363 | err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad); | 4418 | err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad); |
| 4364 | return err; | 4419 | return err; |
| 4365 | 4420 | ||
| 4366 | err = sel_netnode_sid(addrp, family, &node_sid); | 4421 | err = sel_netnode_sid(addrp, family, &node_sid); |
| 4367 | if (err) | 4422 | if (err) |
| 4368 | return err; | 4423 | return err; |
| @@ -4373,9 +4428,8 @@ static int selinux_ip_postroute_iptables_compat(struct sock *sk, | |||
| 4373 | if (send_perm != 0) | 4428 | if (send_perm != 0) |
| 4374 | return 0; | 4429 | return 0; |
| 4375 | 4430 | ||
| 4376 | err = security_port_sid(sk->sk_family, sk->sk_type, | 4431 | err = sel_netport_sid(sk->sk_protocol, |
| 4377 | sk->sk_protocol, ntohs(ad->u.net.dport), | 4432 | ntohs(ad->u.net.dport), &port_sid); |
| 4378 | &port_sid); | ||
| 4379 | if (unlikely(err)) { | 4433 | if (unlikely(err)) { |
| 4380 | printk(KERN_WARNING | 4434 | printk(KERN_WARNING |
| 4381 | "SELinux: failure in" | 4435 | "SELinux: failure in" |
| @@ -4546,7 +4600,7 @@ static int selinux_netlink_recv(struct sk_buff *skb, int capability) | |||
| 4546 | ad.u.cap = capability; | 4600 | ad.u.cap = capability; |
| 4547 | 4601 | ||
| 4548 | return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, | 4602 | return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, |
| 4549 | SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad); | 4603 | SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad); |
| 4550 | } | 4604 | } |
| 4551 | 4605 | ||
| 4552 | static int ipc_alloc_security(struct task_struct *task, | 4606 | static int ipc_alloc_security(struct task_struct *task, |
| @@ -4561,7 +4615,6 @@ static int ipc_alloc_security(struct task_struct *task, | |||
| 4561 | return -ENOMEM; | 4615 | return -ENOMEM; |
| 4562 | 4616 | ||
| 4563 | isec->sclass = sclass; | 4617 | isec->sclass = sclass; |
| 4564 | isec->ipc_perm = perm; | ||
| 4565 | isec->sid = tsec->sid; | 4618 | isec->sid = tsec->sid; |
| 4566 | perm->security = isec; | 4619 | perm->security = isec; |
| 4567 | 4620 | ||
| @@ -4583,7 +4636,6 @@ static int msg_msg_alloc_security(struct msg_msg *msg) | |||
| 4583 | if (!msec) | 4636 | if (!msec) |
| 4584 | return -ENOMEM; | 4637 | return -ENOMEM; |
| 4585 | 4638 | ||
| 4586 | msec->msg = msg; | ||
| 4587 | msec->sid = SECINITSID_UNLABELED; | 4639 | msec->sid = SECINITSID_UNLABELED; |
| 4588 | msg->security = msec; | 4640 | msg->security = msec; |
| 4589 | 4641 | ||
| @@ -4640,7 +4692,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
| 4640 | isec = msq->q_perm.security; | 4692 | isec = msq->q_perm.security; |
| 4641 | 4693 | ||
| 4642 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4694 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4643 | ad.u.ipc_id = msq->q_perm.key; | 4695 | ad.u.ipc_id = msq->q_perm.key; |
| 4644 | 4696 | ||
| 4645 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ, | 4697 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ, |
| 4646 | MSGQ__CREATE, &ad); | 4698 | MSGQ__CREATE, &ad); |
| @@ -4677,7 +4729,7 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
| 4677 | int err; | 4729 | int err; |
| 4678 | int perms; | 4730 | int perms; |
| 4679 | 4731 | ||
| 4680 | switch(cmd) { | 4732 | switch (cmd) { |
| 4681 | case IPC_INFO: | 4733 | case IPC_INFO: |
| 4682 | case MSG_INFO: | 4734 | case MSG_INFO: |
| 4683 | /* No specific object, just general system-wide information. */ | 4735 | /* No specific object, just general system-wide information. */ |
| @@ -4761,7 +4813,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4761 | msec = msg->security; | 4813 | msec = msg->security; |
| 4762 | 4814 | ||
| 4763 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4815 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4764 | ad.u.ipc_id = msq->q_perm.key; | 4816 | ad.u.ipc_id = msq->q_perm.key; |
| 4765 | 4817 | ||
| 4766 | rc = avc_has_perm(tsec->sid, isec->sid, | 4818 | rc = avc_has_perm(tsec->sid, isec->sid, |
| 4767 | SECCLASS_MSGQ, MSGQ__READ, &ad); | 4819 | SECCLASS_MSGQ, MSGQ__READ, &ad); |
| @@ -4787,7 +4839,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
| 4787 | isec = shp->shm_perm.security; | 4839 | isec = shp->shm_perm.security; |
| 4788 | 4840 | ||
| 4789 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4841 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4790 | ad.u.ipc_id = shp->shm_perm.key; | 4842 | ad.u.ipc_id = shp->shm_perm.key; |
| 4791 | 4843 | ||
| 4792 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM, | 4844 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM, |
| 4793 | SHM__CREATE, &ad); | 4845 | SHM__CREATE, &ad); |
| @@ -4825,7 +4877,7 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd) | |||
| 4825 | int perms; | 4877 | int perms; |
| 4826 | int err; | 4878 | int err; |
| 4827 | 4879 | ||
| 4828 | switch(cmd) { | 4880 | switch (cmd) { |
| 4829 | case IPC_INFO: | 4881 | case IPC_INFO: |
| 4830 | case SHM_INFO: | 4882 | case SHM_INFO: |
| 4831 | /* No specific object, just general system-wide information. */ | 4883 | /* No specific object, just general system-wide information. */ |
| @@ -4886,7 +4938,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
| 4886 | isec = sma->sem_perm.security; | 4938 | isec = sma->sem_perm.security; |
| 4887 | 4939 | ||
| 4888 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4940 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4889 | ad.u.ipc_id = sma->sem_perm.key; | 4941 | ad.u.ipc_id = sma->sem_perm.key; |
| 4890 | 4942 | ||
| 4891 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM, | 4943 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM, |
| 4892 | SEM__CREATE, &ad); | 4944 | SEM__CREATE, &ad); |
| @@ -4924,7 +4976,7 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd) | |||
| 4924 | int err; | 4976 | int err; |
| 4925 | u32 perms; | 4977 | u32 perms; |
| 4926 | 4978 | ||
| 4927 | switch(cmd) { | 4979 | switch (cmd) { |
| 4928 | case IPC_INFO: | 4980 | case IPC_INFO: |
| 4929 | case SEM_INFO: | 4981 | case SEM_INFO: |
| 4930 | /* No specific object, just general system-wide information. */ | 4982 | /* No specific object, just general system-wide information. */ |
| @@ -4989,25 +5041,31 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
| 4989 | return ipc_has_perm(ipcp, av); | 5041 | return ipc_has_perm(ipcp, av); |
| 4990 | } | 5042 | } |
| 4991 | 5043 | ||
| 5044 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | ||
| 5045 | { | ||
| 5046 | struct ipc_security_struct *isec = ipcp->security; | ||
| 5047 | *secid = isec->sid; | ||
| 5048 | } | ||
| 5049 | |||
| 4992 | /* module stacking operations */ | 5050 | /* module stacking operations */ |
| 4993 | static int selinux_register_security (const char *name, struct security_operations *ops) | 5051 | static int selinux_register_security(const char *name, struct security_operations *ops) |
| 4994 | { | 5052 | { |
| 4995 | if (secondary_ops != original_ops) { | 5053 | if (secondary_ops != original_ops) { |
| 4996 | printk(KERN_ERR "%s: There is already a secondary security " | 5054 | printk(KERN_ERR "%s: There is already a secondary security " |
| 4997 | "module registered.\n", __FUNCTION__); | 5055 | "module registered.\n", __func__); |
| 4998 | return -EINVAL; | 5056 | return -EINVAL; |
| 4999 | } | 5057 | } |
| 5000 | 5058 | ||
| 5001 | secondary_ops = ops; | 5059 | secondary_ops = ops; |
| 5002 | 5060 | ||
| 5003 | printk(KERN_INFO "%s: Registering secondary module %s\n", | 5061 | printk(KERN_INFO "%s: Registering secondary module %s\n", |
| 5004 | __FUNCTION__, | 5062 | __func__, |
| 5005 | name); | 5063 | name); |
| 5006 | 5064 | ||
| 5007 | return 0; | 5065 | return 0; |
| 5008 | } | 5066 | } |
| 5009 | 5067 | ||
| 5010 | static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) | 5068 | static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) |
| 5011 | { | 5069 | { |
| 5012 | if (inode) | 5070 | if (inode) |
| 5013 | inode_doinit_with_dentry(inode, dentry); | 5071 | inode_doinit_with_dentry(inode, dentry); |
| @@ -5057,6 +5115,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 5057 | char *name, void *value, size_t size) | 5115 | char *name, void *value, size_t size) |
| 5058 | { | 5116 | { |
| 5059 | struct task_security_struct *tsec; | 5117 | struct task_security_struct *tsec; |
| 5118 | struct task_struct *tracer; | ||
| 5060 | u32 sid = 0; | 5119 | u32 sid = 0; |
| 5061 | int error; | 5120 | int error; |
| 5062 | char *str = value; | 5121 | char *str = value; |
| @@ -5134,34 +5193,39 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 5134 | } | 5193 | } |
| 5135 | while_each_thread(g, t); | 5194 | while_each_thread(g, t); |
| 5136 | read_unlock(&tasklist_lock); | 5195 | read_unlock(&tasklist_lock); |
| 5137 | } | 5196 | } |
| 5138 | 5197 | ||
| 5139 | /* Check permissions for the transition. */ | 5198 | /* Check permissions for the transition. */ |
| 5140 | error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, | 5199 | error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, |
| 5141 | PROCESS__DYNTRANSITION, NULL); | 5200 | PROCESS__DYNTRANSITION, NULL); |
| 5142 | if (error) | 5201 | if (error) |
| 5143 | return error; | 5202 | return error; |
| 5144 | 5203 | ||
| 5145 | /* Check for ptracing, and update the task SID if ok. | 5204 | /* Check for ptracing, and update the task SID if ok. |
| 5146 | Otherwise, leave SID unchanged and fail. */ | 5205 | Otherwise, leave SID unchanged and fail. */ |
| 5147 | task_lock(p); | 5206 | task_lock(p); |
| 5148 | if (p->ptrace & PT_PTRACED) { | 5207 | rcu_read_lock(); |
| 5149 | error = avc_has_perm_noaudit(tsec->ptrace_sid, sid, | 5208 | tracer = task_tracer_task(p); |
| 5209 | if (tracer != NULL) { | ||
| 5210 | struct task_security_struct *ptsec = tracer->security; | ||
| 5211 | u32 ptsid = ptsec->sid; | ||
| 5212 | rcu_read_unlock(); | ||
| 5213 | error = avc_has_perm_noaudit(ptsid, sid, | ||
| 5150 | SECCLASS_PROCESS, | 5214 | SECCLASS_PROCESS, |
| 5151 | PROCESS__PTRACE, 0, &avd); | 5215 | PROCESS__PTRACE, 0, &avd); |
| 5152 | if (!error) | 5216 | if (!error) |
| 5153 | tsec->sid = sid; | 5217 | tsec->sid = sid; |
| 5154 | task_unlock(p); | 5218 | task_unlock(p); |
| 5155 | avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS, | 5219 | avc_audit(ptsid, sid, SECCLASS_PROCESS, |
| 5156 | PROCESS__PTRACE, &avd, error, NULL); | 5220 | PROCESS__PTRACE, &avd, error, NULL); |
| 5157 | if (error) | 5221 | if (error) |
| 5158 | return error; | 5222 | return error; |
| 5159 | } else { | 5223 | } else { |
| 5224 | rcu_read_unlock(); | ||
| 5160 | tsec->sid = sid; | 5225 | tsec->sid = sid; |
| 5161 | task_unlock(p); | 5226 | task_unlock(p); |
| 5162 | } | 5227 | } |
| 5163 | } | 5228 | } else |
| 5164 | else | ||
| 5165 | return -EINVAL; | 5229 | return -EINVAL; |
| 5166 | 5230 | ||
| 5167 | return size; | 5231 | return size; |
| @@ -5194,7 +5258,6 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk, | |||
| 5194 | if (!ksec) | 5258 | if (!ksec) |
| 5195 | return -ENOMEM; | 5259 | return -ENOMEM; |
| 5196 | 5260 | ||
| 5197 | ksec->obj = k; | ||
| 5198 | if (tsec->keycreate_sid) | 5261 | if (tsec->keycreate_sid) |
| 5199 | ksec->sid = tsec->keycreate_sid; | 5262 | ksec->sid = tsec->keycreate_sid; |
| 5200 | else | 5263 | else |
| @@ -5238,6 +5301,8 @@ static int selinux_key_permission(key_ref_t key_ref, | |||
| 5238 | #endif | 5301 | #endif |
| 5239 | 5302 | ||
| 5240 | static struct security_operations selinux_ops = { | 5303 | static struct security_operations selinux_ops = { |
| 5304 | .name = "selinux", | ||
| 5305 | |||
| 5241 | .ptrace = selinux_ptrace, | 5306 | .ptrace = selinux_ptrace, |
| 5242 | .capget = selinux_capget, | 5307 | .capget = selinux_capget, |
| 5243 | .capset_check = selinux_capset_check, | 5308 | .capset_check = selinux_capset_check, |
| @@ -5250,7 +5315,7 @@ static struct security_operations selinux_ops = { | |||
| 5250 | .vm_enough_memory = selinux_vm_enough_memory, | 5315 | .vm_enough_memory = selinux_vm_enough_memory, |
| 5251 | 5316 | ||
| 5252 | .netlink_send = selinux_netlink_send, | 5317 | .netlink_send = selinux_netlink_send, |
| 5253 | .netlink_recv = selinux_netlink_recv, | 5318 | .netlink_recv = selinux_netlink_recv, |
| 5254 | 5319 | ||
| 5255 | .bprm_alloc_security = selinux_bprm_alloc_security, | 5320 | .bprm_alloc_security = selinux_bprm_alloc_security, |
| 5256 | .bprm_free_security = selinux_bprm_free_security, | 5321 | .bprm_free_security = selinux_bprm_free_security, |
| @@ -5263,13 +5328,13 @@ static struct security_operations selinux_ops = { | |||
| 5263 | .sb_alloc_security = selinux_sb_alloc_security, | 5328 | .sb_alloc_security = selinux_sb_alloc_security, |
| 5264 | .sb_free_security = selinux_sb_free_security, | 5329 | .sb_free_security = selinux_sb_free_security, |
| 5265 | .sb_copy_data = selinux_sb_copy_data, | 5330 | .sb_copy_data = selinux_sb_copy_data, |
| 5266 | .sb_kern_mount = selinux_sb_kern_mount, | 5331 | .sb_kern_mount = selinux_sb_kern_mount, |
| 5267 | .sb_statfs = selinux_sb_statfs, | 5332 | .sb_statfs = selinux_sb_statfs, |
| 5268 | .sb_mount = selinux_mount, | 5333 | .sb_mount = selinux_mount, |
| 5269 | .sb_umount = selinux_umount, | 5334 | .sb_umount = selinux_umount, |
| 5270 | .sb_get_mnt_opts = selinux_get_mnt_opts, | 5335 | .sb_get_mnt_opts = selinux_get_mnt_opts, |
| 5271 | .sb_set_mnt_opts = selinux_set_mnt_opts, | 5336 | .sb_set_mnt_opts = selinux_set_mnt_opts, |
| 5272 | .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, | 5337 | .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, |
| 5273 | .sb_parse_opts_str = selinux_parse_opts_str, | 5338 | .sb_parse_opts_str = selinux_parse_opts_str, |
| 5274 | 5339 | ||
| 5275 | 5340 | ||
| @@ -5294,11 +5359,12 @@ static struct security_operations selinux_ops = { | |||
| 5294 | .inode_getxattr = selinux_inode_getxattr, | 5359 | .inode_getxattr = selinux_inode_getxattr, |
| 5295 | .inode_listxattr = selinux_inode_listxattr, | 5360 | .inode_listxattr = selinux_inode_listxattr, |
| 5296 | .inode_removexattr = selinux_inode_removexattr, | 5361 | .inode_removexattr = selinux_inode_removexattr, |
| 5297 | .inode_getsecurity = selinux_inode_getsecurity, | 5362 | .inode_getsecurity = selinux_inode_getsecurity, |
| 5298 | .inode_setsecurity = selinux_inode_setsecurity, | 5363 | .inode_setsecurity = selinux_inode_setsecurity, |
| 5299 | .inode_listsecurity = selinux_inode_listsecurity, | 5364 | .inode_listsecurity = selinux_inode_listsecurity, |
| 5300 | .inode_need_killpriv = selinux_inode_need_killpriv, | 5365 | .inode_need_killpriv = selinux_inode_need_killpriv, |
| 5301 | .inode_killpriv = selinux_inode_killpriv, | 5366 | .inode_killpriv = selinux_inode_killpriv, |
| 5367 | .inode_getsecid = selinux_inode_getsecid, | ||
| 5302 | 5368 | ||
| 5303 | .file_permission = selinux_file_permission, | 5369 | .file_permission = selinux_file_permission, |
| 5304 | .file_alloc_security = selinux_file_alloc_security, | 5370 | .file_alloc_security = selinux_file_alloc_security, |
| @@ -5312,7 +5378,7 @@ static struct security_operations selinux_ops = { | |||
| 5312 | .file_send_sigiotask = selinux_file_send_sigiotask, | 5378 | .file_send_sigiotask = selinux_file_send_sigiotask, |
| 5313 | .file_receive = selinux_file_receive, | 5379 | .file_receive = selinux_file_receive, |
| 5314 | 5380 | ||
| 5315 | .dentry_open = selinux_dentry_open, | 5381 | .dentry_open = selinux_dentry_open, |
| 5316 | 5382 | ||
| 5317 | .task_create = selinux_task_create, | 5383 | .task_create = selinux_task_create, |
| 5318 | .task_alloc_security = selinux_task_alloc_security, | 5384 | .task_alloc_security = selinux_task_alloc_security, |
| @@ -5322,7 +5388,7 @@ static struct security_operations selinux_ops = { | |||
| 5322 | .task_setgid = selinux_task_setgid, | 5388 | .task_setgid = selinux_task_setgid, |
| 5323 | .task_setpgid = selinux_task_setpgid, | 5389 | .task_setpgid = selinux_task_setpgid, |
| 5324 | .task_getpgid = selinux_task_getpgid, | 5390 | .task_getpgid = selinux_task_getpgid, |
| 5325 | .task_getsid = selinux_task_getsid, | 5391 | .task_getsid = selinux_task_getsid, |
| 5326 | .task_getsecid = selinux_task_getsecid, | 5392 | .task_getsecid = selinux_task_getsecid, |
| 5327 | .task_setgroups = selinux_task_setgroups, | 5393 | .task_setgroups = selinux_task_setgroups, |
| 5328 | .task_setnice = selinux_task_setnice, | 5394 | .task_setnice = selinux_task_setnice, |
| @@ -5336,9 +5402,10 @@ static struct security_operations selinux_ops = { | |||
| 5336 | .task_wait = selinux_task_wait, | 5402 | .task_wait = selinux_task_wait, |
| 5337 | .task_prctl = selinux_task_prctl, | 5403 | .task_prctl = selinux_task_prctl, |
| 5338 | .task_reparent_to_init = selinux_task_reparent_to_init, | 5404 | .task_reparent_to_init = selinux_task_reparent_to_init, |
| 5339 | .task_to_inode = selinux_task_to_inode, | 5405 | .task_to_inode = selinux_task_to_inode, |
| 5340 | 5406 | ||
| 5341 | .ipc_permission = selinux_ipc_permission, | 5407 | .ipc_permission = selinux_ipc_permission, |
| 5408 | .ipc_getsecid = selinux_ipc_getsecid, | ||
| 5342 | 5409 | ||
| 5343 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, | 5410 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, |
| 5344 | .msg_msg_free_security = selinux_msg_msg_free_security, | 5411 | .msg_msg_free_security = selinux_msg_msg_free_security, |
| @@ -5356,24 +5423,24 @@ static struct security_operations selinux_ops = { | |||
| 5356 | .shm_shmctl = selinux_shm_shmctl, | 5423 | .shm_shmctl = selinux_shm_shmctl, |
| 5357 | .shm_shmat = selinux_shm_shmat, | 5424 | .shm_shmat = selinux_shm_shmat, |
| 5358 | 5425 | ||
| 5359 | .sem_alloc_security = selinux_sem_alloc_security, | 5426 | .sem_alloc_security = selinux_sem_alloc_security, |
| 5360 | .sem_free_security = selinux_sem_free_security, | 5427 | .sem_free_security = selinux_sem_free_security, |
| 5361 | .sem_associate = selinux_sem_associate, | 5428 | .sem_associate = selinux_sem_associate, |
| 5362 | .sem_semctl = selinux_sem_semctl, | 5429 | .sem_semctl = selinux_sem_semctl, |
| 5363 | .sem_semop = selinux_sem_semop, | 5430 | .sem_semop = selinux_sem_semop, |
| 5364 | 5431 | ||
| 5365 | .register_security = selinux_register_security, | 5432 | .register_security = selinux_register_security, |
| 5366 | 5433 | ||
| 5367 | .d_instantiate = selinux_d_instantiate, | 5434 | .d_instantiate = selinux_d_instantiate, |
| 5368 | 5435 | ||
| 5369 | .getprocattr = selinux_getprocattr, | 5436 | .getprocattr = selinux_getprocattr, |
| 5370 | .setprocattr = selinux_setprocattr, | 5437 | .setprocattr = selinux_setprocattr, |
| 5371 | 5438 | ||
| 5372 | .secid_to_secctx = selinux_secid_to_secctx, | 5439 | .secid_to_secctx = selinux_secid_to_secctx, |
| 5373 | .secctx_to_secid = selinux_secctx_to_secid, | 5440 | .secctx_to_secid = selinux_secctx_to_secid, |
| 5374 | .release_secctx = selinux_release_secctx, | 5441 | .release_secctx = selinux_release_secctx, |
| 5375 | 5442 | ||
| 5376 | .unix_stream_connect = selinux_socket_unix_stream_connect, | 5443 | .unix_stream_connect = selinux_socket_unix_stream_connect, |
| 5377 | .unix_may_send = selinux_socket_unix_may_send, | 5444 | .unix_may_send = selinux_socket_unix_may_send, |
| 5378 | 5445 | ||
| 5379 | .socket_create = selinux_socket_create, | 5446 | .socket_create = selinux_socket_create, |
| @@ -5395,7 +5462,7 @@ static struct security_operations selinux_ops = { | |||
| 5395 | .sk_alloc_security = selinux_sk_alloc_security, | 5462 | .sk_alloc_security = selinux_sk_alloc_security, |
| 5396 | .sk_free_security = selinux_sk_free_security, | 5463 | .sk_free_security = selinux_sk_free_security, |
| 5397 | .sk_clone_security = selinux_sk_clone_security, | 5464 | .sk_clone_security = selinux_sk_clone_security, |
| 5398 | .sk_getsecid = selinux_sk_getsecid, | 5465 | .sk_getsecid = selinux_sk_getsecid, |
| 5399 | .sock_graft = selinux_sock_graft, | 5466 | .sock_graft = selinux_sock_graft, |
| 5400 | .inet_conn_request = selinux_inet_conn_request, | 5467 | .inet_conn_request = selinux_inet_conn_request, |
| 5401 | .inet_csk_clone = selinux_inet_csk_clone, | 5468 | .inet_csk_clone = selinux_inet_csk_clone, |
| @@ -5410,15 +5477,22 @@ static struct security_operations selinux_ops = { | |||
| 5410 | .xfrm_state_alloc_security = selinux_xfrm_state_alloc, | 5477 | .xfrm_state_alloc_security = selinux_xfrm_state_alloc, |
| 5411 | .xfrm_state_free_security = selinux_xfrm_state_free, | 5478 | .xfrm_state_free_security = selinux_xfrm_state_free, |
| 5412 | .xfrm_state_delete_security = selinux_xfrm_state_delete, | 5479 | .xfrm_state_delete_security = selinux_xfrm_state_delete, |
| 5413 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | 5480 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, |
| 5414 | .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match, | 5481 | .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match, |
| 5415 | .xfrm_decode_session = selinux_xfrm_decode_session, | 5482 | .xfrm_decode_session = selinux_xfrm_decode_session, |
| 5416 | #endif | 5483 | #endif |
| 5417 | 5484 | ||
| 5418 | #ifdef CONFIG_KEYS | 5485 | #ifdef CONFIG_KEYS |
| 5419 | .key_alloc = selinux_key_alloc, | 5486 | .key_alloc = selinux_key_alloc, |
| 5420 | .key_free = selinux_key_free, | 5487 | .key_free = selinux_key_free, |
| 5421 | .key_permission = selinux_key_permission, | 5488 | .key_permission = selinux_key_permission, |
| 5489 | #endif | ||
| 5490 | |||
| 5491 | #ifdef CONFIG_AUDIT | ||
| 5492 | .audit_rule_init = selinux_audit_rule_init, | ||
| 5493 | .audit_rule_known = selinux_audit_rule_known, | ||
| 5494 | .audit_rule_match = selinux_audit_rule_match, | ||
| 5495 | .audit_rule_free = selinux_audit_rule_free, | ||
| 5422 | #endif | 5496 | #endif |
| 5423 | }; | 5497 | }; |
| 5424 | 5498 | ||
| @@ -5426,6 +5500,11 @@ static __init int selinux_init(void) | |||
| 5426 | { | 5500 | { |
| 5427 | struct task_security_struct *tsec; | 5501 | struct task_security_struct *tsec; |
| 5428 | 5502 | ||
| 5503 | if (!security_module_enable(&selinux_ops)) { | ||
| 5504 | selinux_enabled = 0; | ||
| 5505 | return 0; | ||
| 5506 | } | ||
| 5507 | |||
| 5429 | if (!selinux_enabled) { | 5508 | if (!selinux_enabled) { |
| 5430 | printk(KERN_INFO "SELinux: Disabled at boot.\n"); | 5509 | printk(KERN_INFO "SELinux: Disabled at boot.\n"); |
| 5431 | return 0; | 5510 | return 0; |
| @@ -5446,15 +5525,14 @@ static __init int selinux_init(void) | |||
| 5446 | 5525 | ||
| 5447 | original_ops = secondary_ops = security_ops; | 5526 | original_ops = secondary_ops = security_ops; |
| 5448 | if (!secondary_ops) | 5527 | if (!secondary_ops) |
| 5449 | panic ("SELinux: No initial security operations\n"); | 5528 | panic("SELinux: No initial security operations\n"); |
| 5450 | if (register_security (&selinux_ops)) | 5529 | if (register_security(&selinux_ops)) |
| 5451 | panic("SELinux: Unable to register with kernel.\n"); | 5530 | panic("SELinux: Unable to register with kernel.\n"); |
| 5452 | 5531 | ||
| 5453 | if (selinux_enforcing) { | 5532 | if (selinux_enforcing) |
| 5454 | printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); | 5533 | printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); |
| 5455 | } else { | 5534 | else |
| 5456 | printk(KERN_DEBUG "SELinux: Starting in permissive mode\n"); | 5535 | printk(KERN_DEBUG "SELinux: Starting in permissive mode\n"); |
| 5457 | } | ||
| 5458 | 5536 | ||
| 5459 | #ifdef CONFIG_KEYS | 5537 | #ifdef CONFIG_KEYS |
| 5460 | /* Add security information to initial keyrings */ | 5538 | /* Add security information to initial keyrings */ |
| @@ -5479,8 +5557,8 @@ next_sb: | |||
| 5479 | if (!list_empty(&superblock_security_head)) { | 5557 | if (!list_empty(&superblock_security_head)) { |
| 5480 | struct superblock_security_struct *sbsec = | 5558 | struct superblock_security_struct *sbsec = |
| 5481 | list_entry(superblock_security_head.next, | 5559 | list_entry(superblock_security_head.next, |
| 5482 | struct superblock_security_struct, | 5560 | struct superblock_security_struct, |
| 5483 | list); | 5561 | list); |
| 5484 | struct super_block *sb = sbsec->sb; | 5562 | struct super_block *sb = sbsec->sb; |
| 5485 | sb->s_count++; | 5563 | sb->s_count++; |
| 5486 | spin_unlock(&sb_security_lock); | 5564 | spin_unlock(&sb_security_lock); |
| @@ -5599,10 +5677,11 @@ static void selinux_nf_ip_exit(void) | |||
| 5599 | #endif /* CONFIG_NETFILTER */ | 5677 | #endif /* CONFIG_NETFILTER */ |
| 5600 | 5678 | ||
| 5601 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE | 5679 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE |
| 5680 | static int selinux_disabled; | ||
| 5681 | |||
| 5602 | int selinux_disable(void) | 5682 | int selinux_disable(void) |
| 5603 | { | 5683 | { |
| 5604 | extern void exit_sel_fs(void); | 5684 | extern void exit_sel_fs(void); |
| 5605 | static int selinux_disabled = 0; | ||
| 5606 | 5685 | ||
| 5607 | if (ss_initialized) { | 5686 | if (ss_initialized) { |
| 5608 | /* Not permitted after initial policy load. */ | 5687 | /* Not permitted after initial policy load. */ |
| @@ -5631,5 +5710,3 @@ int selinux_disable(void) | |||
| 5631 | return 0; | 5710 | return 0; |
| 5632 | } | 5711 | } |
| 5633 | #endif | 5712 | #endif |
| 5634 | |||
| 5635 | |||
