diff options
| -rw-r--r-- | include/linux/lsm_hooks.h | 77 | ||||
| -rw-r--r-- | include/linux/security.h | 46 | ||||
| -rw-r--r-- | security/Makefile | 2 | ||||
| -rw-r--r-- | security/apparmor/domain.c | 12 | ||||
| -rw-r--r-- | security/apparmor/lsm.c | 51 | ||||
| -rw-r--r-- | security/commoncap.c | 41 | ||||
| -rw-r--r-- | security/security.c | 570 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 94 | ||||
| -rw-r--r-- | security/smack/smack.h | 2 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 53 | ||||
| -rw-r--r-- | security/smack/smackfs.c | 2 | ||||
| -rw-r--r-- | security/tomoyo/tomoyo.c | 14 | ||||
| -rw-r--r-- | security/yama/yama_lsm.c | 50 |
13 files changed, 627 insertions, 387 deletions
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 27dd6fcacccc..f014f2596e22 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
| @@ -25,21 +25,10 @@ | |||
| 25 | #define __LINUX_LSM_HOOKS_H | 25 | #define __LINUX_LSM_HOOKS_H |
| 26 | 26 | ||
| 27 | #include <linux/security.h> | 27 | #include <linux/security.h> |
| 28 | 28 | #include <linux/init.h> | |
| 29 | /* Maximum number of letters for an LSM name string */ | 29 | #include <linux/rculist.h> |
| 30 | #define SECURITY_NAME_MAX 10 | ||
| 31 | |||
| 32 | #ifdef CONFIG_SECURITY | ||
| 33 | 30 | ||
| 34 | /** | 31 | /** |
| 35 | * struct security_operations - main security structure | ||
| 36 | * | ||
| 37 | * Security module identifier. | ||
| 38 | * | ||
| 39 | * @name: | ||
| 40 | * A string that acts as a unique identifier for the LSM with max number | ||
| 41 | * of characters = SECURITY_NAME_MAX. | ||
| 42 | * | ||
| 43 | * Security hooks for program execution operations. | 32 | * Security hooks for program execution operations. |
| 44 | * | 33 | * |
| 45 | * @bprm_set_creds: | 34 | * @bprm_set_creds: |
| @@ -1310,9 +1299,7 @@ | |||
| 1310 | * This is the main security structure. | 1299 | * This is the main security structure. |
| 1311 | */ | 1300 | */ |
| 1312 | 1301 | ||
| 1313 | struct security_operations { | 1302 | union security_list_options { |
| 1314 | char name[SECURITY_NAME_MAX + 1]; | ||
| 1315 | |||
| 1316 | int (*binder_set_context_mgr)(struct task_struct *mgr); | 1303 | int (*binder_set_context_mgr)(struct task_struct *mgr); |
| 1317 | int (*binder_transaction)(struct task_struct *from, | 1304 | int (*binder_transaction)(struct task_struct *from, |
| 1318 | struct task_struct *to); | 1305 | struct task_struct *to); |
| @@ -1838,20 +1825,62 @@ struct security_hook_heads { | |||
| 1838 | }; | 1825 | }; |
| 1839 | 1826 | ||
| 1840 | /* | 1827 | /* |
| 1828 | * Security module hook list structure. | ||
| 1829 | * For use with generic list macros for common operations. | ||
| 1830 | */ | ||
| 1831 | struct security_hook_list { | ||
| 1832 | struct list_head list; | ||
| 1833 | struct list_head *head; | ||
| 1834 | union security_list_options hook; | ||
| 1835 | }; | ||
| 1836 | |||
| 1837 | /* | ||
| 1841 | * Initializing a security_hook_list structure takes | 1838 | * Initializing a security_hook_list structure takes |
| 1842 | * up a lot of space in a source file. This macro takes | 1839 | * up a lot of space in a source file. This macro takes |
| 1843 | * care of the common case and reduces the amount of | 1840 | * care of the common case and reduces the amount of |
| 1844 | * text involved. | 1841 | * text involved. |
| 1845 | * Casey says: Comment is true in the next patch. | ||
| 1846 | */ | 1842 | */ |
| 1847 | #define LSM_HOOK_INIT(HEAD, HOOK) .HEAD = HOOK | 1843 | #define LSM_HOOK_INIT(HEAD, HOOK) \ |
| 1844 | { .head = &security_hook_heads.HEAD, .hook = { .HEAD = HOOK } } | ||
| 1845 | |||
| 1846 | extern struct security_hook_heads security_hook_heads; | ||
| 1847 | |||
| 1848 | static inline void security_add_hooks(struct security_hook_list *hooks, | ||
| 1849 | int count) | ||
| 1850 | { | ||
| 1851 | int i; | ||
| 1848 | 1852 | ||
| 1849 | /* prototypes */ | 1853 | for (i = 0; i < count; i++) |
| 1850 | extern int security_module_enable(struct security_operations *ops); | 1854 | list_add_tail_rcu(&hooks[i].list, hooks[i].head); |
| 1851 | extern int register_security(struct security_operations *ops); | 1855 | } |
| 1852 | extern void __init security_fixup_ops(struct security_operations *ops); | ||
| 1853 | extern void reset_security_ops(void); | ||
| 1854 | 1856 | ||
| 1855 | #endif /* CONFIG_SECURITY */ | 1857 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE |
| 1858 | /* | ||
| 1859 | * Assuring the safety of deleting a security module is up to | ||
| 1860 | * the security module involved. This may entail ordering the | ||
| 1861 | * module's hook list in a particular way, refusing to disable | ||
| 1862 | * the module once a policy is loaded or any number of other | ||
| 1863 | * actions better imagined than described. | ||
| 1864 | * | ||
| 1865 | * The name of the configuration option reflects the only module | ||
| 1866 | * that currently uses the mechanism. Any developer who thinks | ||
| 1867 | * disabling their module is a good idea needs to be at least as | ||
| 1868 | * careful as the SELinux team. | ||
| 1869 | */ | ||
| 1870 | static inline void security_delete_hooks(struct security_hook_list *hooks, | ||
| 1871 | int count) | ||
| 1872 | { | ||
| 1873 | int i; | ||
| 1874 | |||
| 1875 | for (i = 0; i < count; i++) | ||
| 1876 | list_del_rcu(&hooks[i].list); | ||
| 1877 | } | ||
| 1878 | #endif /* CONFIG_SECURITY_SELINUX_DISABLE */ | ||
| 1879 | |||
| 1880 | extern int __init security_module_enable(const char *module); | ||
| 1881 | extern void __init capability_add_hooks(void); | ||
| 1882 | #ifdef CONFIG_SECURITY_YAMA_STACKED | ||
| 1883 | void __init yama_add_hooks(void); | ||
| 1884 | #endif | ||
| 1856 | 1885 | ||
| 1857 | #endif /* ! __LINUX_LSM_HOOKS_H */ | 1886 | #endif /* ! __LINUX_LSM_HOOKS_H */ |
diff --git a/include/linux/security.h b/include/linux/security.h index a2a100e7ac6e..8c8175d41b4c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| 28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
| 29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
| 30 | #include <linux/mm.h> | ||
| 30 | 31 | ||
| 31 | struct linux_binprm; | 32 | struct linux_binprm; |
| 32 | struct cred; | 33 | struct cred; |
| @@ -54,9 +55,6 @@ struct xattr; | |||
| 54 | struct xfrm_sec_ctx; | 55 | struct xfrm_sec_ctx; |
| 55 | struct mm_struct; | 56 | struct mm_struct; |
| 56 | 57 | ||
| 57 | /* Maximum number of letters for an LSM name string */ | ||
| 58 | #define SECURITY_NAME_MAX 10 | ||
| 59 | |||
| 60 | /* If capable should audit the security request */ | 58 | /* If capable should audit the security request */ |
| 61 | #define SECURITY_CAP_NOAUDIT 0 | 59 | #define SECURITY_CAP_NOAUDIT 0 |
| 62 | #define SECURITY_CAP_AUDIT 1 | 60 | #define SECURITY_CAP_AUDIT 1 |
| @@ -69,10 +67,7 @@ struct audit_krule; | |||
| 69 | struct user_namespace; | 67 | struct user_namespace; |
| 70 | struct timezone; | 68 | struct timezone; |
| 71 | 69 | ||
| 72 | /* | 70 | /* These functions are in security/commoncap.c */ |
| 73 | * These functions are in security/capability.c and are used | ||
| 74 | * as the default capabilities functions | ||
| 75 | */ | ||
| 76 | extern int cap_capable(const struct cred *cred, struct user_namespace *ns, | 71 | extern int cap_capable(const struct cred *cred, struct user_namespace *ns, |
| 77 | int cap, int audit); | 72 | int cap, int audit); |
| 78 | extern int cap_settime(const struct timespec *ts, const struct timezone *tz); | 73 | extern int cap_settime(const struct timespec *ts, const struct timezone *tz); |
| @@ -114,8 +109,6 @@ struct xfrm_state; | |||
| 114 | struct xfrm_user_sec_ctx; | 109 | struct xfrm_user_sec_ctx; |
| 115 | struct seq_file; | 110 | struct seq_file; |
| 116 | 111 | ||
| 117 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); | ||
| 118 | |||
| 119 | #ifdef CONFIG_MMU | 112 | #ifdef CONFIG_MMU |
| 120 | extern unsigned long mmap_min_addr; | 113 | extern unsigned long mmap_min_addr; |
| 121 | extern unsigned long dac_mmap_min_addr; | 114 | extern unsigned long dac_mmap_min_addr; |
| @@ -472,7 +465,7 @@ static inline int security_settime(const struct timespec *ts, | |||
| 472 | 465 | ||
| 473 | static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) | 466 | static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) |
| 474 | { | 467 | { |
| 475 | return cap_vm_enough_memory(mm, pages); | 468 | return __vm_enough_memory(mm, pages, cap_vm_enough_memory(mm, pages)); |
| 476 | } | 469 | } |
| 477 | 470 | ||
| 478 | static inline int security_bprm_set_creds(struct linux_binprm *bprm) | 471 | static inline int security_bprm_set_creds(struct linux_binprm *bprm) |
| @@ -1075,7 +1068,7 @@ static inline int security_setprocattr(struct task_struct *p, char *name, void * | |||
| 1075 | 1068 | ||
| 1076 | static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb) | 1069 | static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 1077 | { | 1070 | { |
| 1078 | return cap_netlink_send(sk, skb); | 1071 | return 0; |
| 1079 | } | 1072 | } |
| 1080 | 1073 | ||
| 1081 | static inline int security_ismaclabel(const char *name) | 1074 | static inline int security_ismaclabel(const char *name) |
| @@ -1643,36 +1636,5 @@ static inline void free_secdata(void *secdata) | |||
| 1643 | { } | 1636 | { } |
| 1644 | #endif /* CONFIG_SECURITY */ | 1637 | #endif /* CONFIG_SECURITY */ |
| 1645 | 1638 | ||
| 1646 | #ifdef CONFIG_SECURITY_YAMA | ||
| 1647 | extern int yama_ptrace_access_check(struct task_struct *child, | ||
| 1648 | unsigned int mode); | ||
| 1649 | extern int yama_ptrace_traceme(struct task_struct *parent); | ||
| 1650 | extern void yama_task_free(struct task_struct *task); | ||
| 1651 | extern int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, | ||
| 1652 | unsigned long arg4, unsigned long arg5); | ||
| 1653 | #else | ||
| 1654 | static inline int yama_ptrace_access_check(struct task_struct *child, | ||
| 1655 | unsigned int mode) | ||
| 1656 | { | ||
| 1657 | return 0; | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | static inline int yama_ptrace_traceme(struct task_struct *parent) | ||
| 1661 | { | ||
| 1662 | return 0; | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | static inline void yama_task_free(struct task_struct *task) | ||
| 1666 | { | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | static inline int yama_task_prctl(int option, unsigned long arg2, | ||
| 1670 | unsigned long arg3, unsigned long arg4, | ||
| 1671 | unsigned long arg5) | ||
| 1672 | { | ||
| 1673 | return -ENOSYS; | ||
| 1674 | } | ||
| 1675 | #endif /* CONFIG_SECURITY_YAMA */ | ||
| 1676 | |||
| 1677 | #endif /* ! __LINUX_SECURITY_H */ | 1639 | #endif /* ! __LINUX_SECURITY_H */ |
| 1678 | 1640 | ||
diff --git a/security/Makefile b/security/Makefile index 05f1c934d74b..c9bfbc84ff50 100644 --- a/security/Makefile +++ b/security/Makefile | |||
| @@ -14,7 +14,7 @@ obj-y += commoncap.o | |||
| 14 | obj-$(CONFIG_MMU) += min_addr.o | 14 | obj-$(CONFIG_MMU) += min_addr.o |
| 15 | 15 | ||
| 16 | # Object file lists | 16 | # Object file lists |
| 17 | obj-$(CONFIG_SECURITY) += security.o capability.o | 17 | obj-$(CONFIG_SECURITY) += security.o |
| 18 | obj-$(CONFIG_SECURITYFS) += inode.o | 18 | obj-$(CONFIG_SECURITYFS) += inode.o |
| 19 | obj-$(CONFIG_SECURITY_SELINUX) += selinux/ | 19 | obj-$(CONFIG_SECURITY_SELINUX) += selinux/ |
| 20 | obj-$(CONFIG_SECURITY_SMACK) += smack/ | 20 | obj-$(CONFIG_SECURITY_SMACK) += smack/ |
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index d97cba3e3849..dc0027b28b04 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
| @@ -347,9 +347,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) | |||
| 347 | file_inode(bprm->file)->i_mode | 347 | file_inode(bprm->file)->i_mode |
| 348 | }; | 348 | }; |
| 349 | const char *name = NULL, *target = NULL, *info = NULL; | 349 | const char *name = NULL, *target = NULL, *info = NULL; |
| 350 | int error = cap_bprm_set_creds(bprm); | 350 | int error = 0; |
| 351 | if (error) | ||
| 352 | return error; | ||
| 353 | 351 | ||
| 354 | if (bprm->cred_prepared) | 352 | if (bprm->cred_prepared) |
| 355 | return 0; | 353 | return 0; |
| @@ -531,15 +529,13 @@ cleanup: | |||
| 531 | */ | 529 | */ |
| 532 | int apparmor_bprm_secureexec(struct linux_binprm *bprm) | 530 | int apparmor_bprm_secureexec(struct linux_binprm *bprm) |
| 533 | { | 531 | { |
| 534 | int ret = cap_bprm_secureexec(bprm); | ||
| 535 | |||
| 536 | /* the decision to use secure exec is computed in set_creds | 532 | /* the decision to use secure exec is computed in set_creds |
| 537 | * and stored in bprm->unsafe. | 533 | * and stored in bprm->unsafe. |
| 538 | */ | 534 | */ |
| 539 | if (!ret && (bprm->unsafe & AA_SECURE_X_NEEDED)) | 535 | if (bprm->unsafe & AA_SECURE_X_NEEDED) |
| 540 | ret = 1; | 536 | return 1; |
| 541 | 537 | ||
| 542 | return ret; | 538 | return 0; |
| 543 | } | 539 | } |
| 544 | 540 | ||
| 545 | /** | 541 | /** |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index f54253258fb8..5696874e8062 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
| @@ -96,19 +96,11 @@ static void apparmor_cred_transfer(struct cred *new, const struct cred *old) | |||
| 96 | static int apparmor_ptrace_access_check(struct task_struct *child, | 96 | static int apparmor_ptrace_access_check(struct task_struct *child, |
| 97 | unsigned int mode) | 97 | unsigned int mode) |
| 98 | { | 98 | { |
| 99 | int error = cap_ptrace_access_check(child, mode); | ||
| 100 | if (error) | ||
| 101 | return error; | ||
| 102 | |||
| 103 | return aa_ptrace(current, child, mode); | 99 | return aa_ptrace(current, child, mode); |
| 104 | } | 100 | } |
| 105 | 101 | ||
| 106 | static int apparmor_ptrace_traceme(struct task_struct *parent) | 102 | static int apparmor_ptrace_traceme(struct task_struct *parent) |
| 107 | { | 103 | { |
| 108 | int error = cap_ptrace_traceme(parent); | ||
| 109 | if (error) | ||
| 110 | return error; | ||
| 111 | |||
| 112 | return aa_ptrace(parent, current, PTRACE_MODE_ATTACH); | 104 | return aa_ptrace(parent, current, PTRACE_MODE_ATTACH); |
| 113 | } | 105 | } |
| 114 | 106 | ||
| @@ -123,10 +115,10 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, | |||
| 123 | cred = __task_cred(target); | 115 | cred = __task_cred(target); |
| 124 | profile = aa_cred_profile(cred); | 116 | profile = aa_cred_profile(cred); |
| 125 | 117 | ||
| 126 | *effective = cred->cap_effective; | 118 | /* |
| 127 | *inheritable = cred->cap_inheritable; | 119 | * cap_capget is stacked ahead of this and will |
| 128 | *permitted = cred->cap_permitted; | 120 | * initialize effective and permitted. |
| 129 | 121 | */ | |
| 130 | if (!unconfined(profile) && !COMPLAIN_MODE(profile)) { | 122 | if (!unconfined(profile) && !COMPLAIN_MODE(profile)) { |
| 131 | *effective = cap_intersect(*effective, profile->caps.allow); | 123 | *effective = cap_intersect(*effective, profile->caps.allow); |
| 132 | *permitted = cap_intersect(*permitted, profile->caps.allow); | 124 | *permitted = cap_intersect(*permitted, profile->caps.allow); |
| @@ -140,13 +132,11 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, | |||
| 140 | int cap, int audit) | 132 | int cap, int audit) |
| 141 | { | 133 | { |
| 142 | struct aa_profile *profile; | 134 | struct aa_profile *profile; |
| 143 | /* cap_capable returns 0 on success, else -EPERM */ | 135 | int error = 0; |
| 144 | int error = cap_capable(cred, ns, cap, audit); | 136 | |
| 145 | if (!error) { | 137 | profile = aa_cred_profile(cred); |
| 146 | profile = aa_cred_profile(cred); | 138 | if (!unconfined(profile)) |
| 147 | if (!unconfined(profile)) | 139 | error = aa_capable(profile, cap, audit); |
| 148 | error = aa_capable(profile, cap, audit); | ||
| 149 | } | ||
| 150 | return error; | 140 | return error; |
| 151 | } | 141 | } |
| 152 | 142 | ||
| @@ -615,9 +605,7 @@ static int apparmor_task_setrlimit(struct task_struct *task, | |||
| 615 | return error; | 605 | return error; |
| 616 | } | 606 | } |
| 617 | 607 | ||
| 618 | static struct security_operations apparmor_ops = { | 608 | static struct security_hook_list apparmor_hooks[] = { |
| 619 | LSM_HOOK_INIT(name, "apparmor"), | ||
| 620 | |||
| 621 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), | 609 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), |
| 622 | LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), | 610 | LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), |
| 623 | LSM_HOOK_INIT(capget, apparmor_capget), | 611 | LSM_HOOK_INIT(capget, apparmor_capget), |
| @@ -640,7 +628,6 @@ static struct security_operations apparmor_ops = { | |||
| 640 | LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security), | 628 | LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security), |
| 641 | LSM_HOOK_INIT(file_free_security, apparmor_file_free_security), | 629 | LSM_HOOK_INIT(file_free_security, apparmor_file_free_security), |
| 642 | LSM_HOOK_INIT(mmap_file, apparmor_mmap_file), | 630 | LSM_HOOK_INIT(mmap_file, apparmor_mmap_file), |
| 643 | LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), | ||
| 644 | LSM_HOOK_INIT(file_mprotect, apparmor_file_mprotect), | 631 | LSM_HOOK_INIT(file_mprotect, apparmor_file_mprotect), |
| 645 | LSM_HOOK_INIT(file_lock, apparmor_file_lock), | 632 | LSM_HOOK_INIT(file_lock, apparmor_file_lock), |
| 646 | 633 | ||
| @@ -898,7 +885,7 @@ static int __init apparmor_init(void) | |||
| 898 | { | 885 | { |
| 899 | int error; | 886 | int error; |
| 900 | 887 | ||
| 901 | if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) { | 888 | if (!apparmor_enabled || !security_module_enable("apparmor")) { |
| 902 | aa_info_message("AppArmor disabled by boot time parameter"); | 889 | aa_info_message("AppArmor disabled by boot time parameter"); |
| 903 | apparmor_enabled = 0; | 890 | apparmor_enabled = 0; |
| 904 | return 0; | 891 | return 0; |
| @@ -913,17 +900,10 @@ static int __init apparmor_init(void) | |||
| 913 | error = set_init_cxt(); | 900 | error = set_init_cxt(); |
| 914 | if (error) { | 901 | if (error) { |
| 915 | AA_ERROR("Failed to set context on init task\n"); | 902 | AA_ERROR("Failed to set context on init task\n"); |
| 916 | goto register_security_out; | 903 | aa_free_root_ns(); |
| 917 | } | 904 | goto alloc_out; |
| 918 | |||
| 919 | error = register_security(&apparmor_ops); | ||
| 920 | if (error) { | ||
| 921 | struct cred *cred = (struct cred *)current->real_cred; | ||
| 922 | aa_free_task_context(cred_cxt(cred)); | ||
| 923 | cred_cxt(cred) = NULL; | ||
| 924 | AA_ERROR("Unable to register AppArmor\n"); | ||
| 925 | goto register_security_out; | ||
| 926 | } | 905 | } |
| 906 | security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks)); | ||
| 927 | 907 | ||
| 928 | /* Report that AppArmor successfully initialized */ | 908 | /* Report that AppArmor successfully initialized */ |
| 929 | apparmor_initialized = 1; | 909 | apparmor_initialized = 1; |
| @@ -936,9 +916,6 @@ static int __init apparmor_init(void) | |||
| 936 | 916 | ||
| 937 | return error; | 917 | return error; |
| 938 | 918 | ||
| 939 | register_security_out: | ||
| 940 | aa_free_root_ns(); | ||
| 941 | |||
| 942 | alloc_out: | 919 | alloc_out: |
| 943 | aa_destroy_aafs(); | 920 | aa_destroy_aafs(); |
| 944 | 921 | ||
diff --git a/security/commoncap.c b/security/commoncap.c index f2875cd9f677..d103f5a4043d 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/security.h> | 15 | #include <linux/lsm_hooks.h> |
| 16 | #include <linux/file.h> | 16 | #include <linux/file.h> |
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
| @@ -53,11 +53,6 @@ static void warn_setuid_and_fcaps_mixed(const char *fname) | |||
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) | ||
| 57 | { | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | 56 | /** |
| 62 | * cap_capable - Determine whether a task has a particular effective capability | 57 | * cap_capable - Determine whether a task has a particular effective capability |
| 63 | * @cred: The credentials to use | 58 | * @cred: The credentials to use |
| @@ -941,7 +936,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
| 941 | * @pages: The size of the mapping | 936 | * @pages: The size of the mapping |
| 942 | * | 937 | * |
| 943 | * Determine whether the allocation of a new virtual mapping by the current | 938 | * Determine whether the allocation of a new virtual mapping by the current |
| 944 | * task is permitted, returning 0 if permission is granted, -ve if not. | 939 | * task is permitted, returning 1 if permission is granted, 0 if not. |
| 945 | */ | 940 | */ |
| 946 | int cap_vm_enough_memory(struct mm_struct *mm, long pages) | 941 | int cap_vm_enough_memory(struct mm_struct *mm, long pages) |
| 947 | { | 942 | { |
| @@ -950,7 +945,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 950 | if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, | 945 | if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, |
| 951 | SECURITY_CAP_NOAUDIT) == 0) | 946 | SECURITY_CAP_NOAUDIT) == 0) |
| 952 | cap_sys_admin = 1; | 947 | cap_sys_admin = 1; |
| 953 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 948 | return cap_sys_admin; |
| 954 | } | 949 | } |
| 955 | 950 | ||
| 956 | /* | 951 | /* |
| @@ -981,3 +976,33 @@ int cap_mmap_file(struct file *file, unsigned long reqprot, | |||
| 981 | { | 976 | { |
| 982 | return 0; | 977 | return 0; |
| 983 | } | 978 | } |
| 979 | |||
| 980 | #ifdef CONFIG_SECURITY | ||
| 981 | |||
| 982 | struct security_hook_list capability_hooks[] = { | ||
| 983 | LSM_HOOK_INIT(capable, cap_capable), | ||
| 984 | LSM_HOOK_INIT(settime, cap_settime), | ||
| 985 | LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check), | ||
| 986 | LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme), | ||
| 987 | LSM_HOOK_INIT(capget, cap_capget), | ||
| 988 | LSM_HOOK_INIT(capset, cap_capset), | ||
| 989 | LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), | ||
| 990 | LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec), | ||
| 991 | LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), | ||
| 992 | LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), | ||
| 993 | LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), | ||
| 994 | LSM_HOOK_INIT(mmap_file, cap_mmap_file), | ||
| 995 | LSM_HOOK_INIT(task_fix_setuid, cap_task_fix_setuid), | ||
| 996 | LSM_HOOK_INIT(task_prctl, cap_task_prctl), | ||
| 997 | LSM_HOOK_INIT(task_setscheduler, cap_task_setscheduler), | ||
| 998 | LSM_HOOK_INIT(task_setioprio, cap_task_setioprio), | ||
| 999 | LSM_HOOK_INIT(task_setnice, cap_task_setnice), | ||
| 1000 | LSM_HOOK_INIT(vm_enough_memory, cap_vm_enough_memory), | ||
| 1001 | }; | ||
| 1002 | |||
| 1003 | void __init capability_add_hooks(void) | ||
| 1004 | { | ||
| 1005 | security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks)); | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | #endif /* CONFIG_SECURITY */ | ||
diff --git a/security/security.c b/security/security.c index 02dc72006afa..bd4c5f6a5b78 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -29,24 +29,13 @@ | |||
| 29 | 29 | ||
| 30 | #define MAX_LSM_EVM_XATTR 2 | 30 | #define MAX_LSM_EVM_XATTR 2 |
| 31 | 31 | ||
| 32 | /* Maximum number of letters for an LSM name string */ | ||
| 33 | #define SECURITY_NAME_MAX 10 | ||
| 34 | |||
| 32 | /* Boot-time LSM user choice */ | 35 | /* Boot-time LSM user choice */ |
| 33 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = | 36 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = |
| 34 | CONFIG_DEFAULT_SECURITY; | 37 | CONFIG_DEFAULT_SECURITY; |
| 35 | 38 | ||
| 36 | static struct security_operations *security_ops; | ||
| 37 | static struct security_operations default_security_ops = { | ||
| 38 | .name = "default", | ||
| 39 | }; | ||
| 40 | |||
| 41 | static inline int __init verify(struct security_operations *ops) | ||
| 42 | { | ||
| 43 | /* verify the security_operations structure exists */ | ||
| 44 | if (!ops) | ||
| 45 | return -EINVAL; | ||
| 46 | security_fixup_ops(ops); | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void __init do_security_initcalls(void) | 39 | static void __init do_security_initcalls(void) |
| 51 | { | 40 | { |
| 52 | initcall_t *call; | 41 | initcall_t *call; |
| @@ -64,20 +53,27 @@ static void __init do_security_initcalls(void) | |||
| 64 | */ | 53 | */ |
| 65 | int __init security_init(void) | 54 | int __init security_init(void) |
| 66 | { | 55 | { |
| 67 | printk(KERN_INFO "Security Framework initialized\n"); | 56 | pr_info("Security Framework initialized\n"); |
| 68 | 57 | ||
| 69 | security_fixup_ops(&default_security_ops); | 58 | /* |
| 70 | security_ops = &default_security_ops; | 59 | * Always load the capability module. |
| 60 | */ | ||
| 61 | capability_add_hooks(); | ||
| 62 | #ifdef CONFIG_SECURITY_YAMA_STACKED | ||
| 63 | /* | ||
| 64 | * If Yama is configured for stacking load it next. | ||
| 65 | */ | ||
| 66 | yama_add_hooks(); | ||
| 67 | #endif | ||
| 68 | /* | ||
| 69 | * Load the chosen module if there is one. | ||
| 70 | * This will also find yama if it is stacking | ||
| 71 | */ | ||
| 71 | do_security_initcalls(); | 72 | do_security_initcalls(); |
| 72 | 73 | ||
| 73 | return 0; | 74 | return 0; |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | void reset_security_ops(void) | ||
| 77 | { | ||
| 78 | security_ops = &default_security_ops; | ||
| 79 | } | ||
| 80 | |||
| 81 | /* Save user chosen LSM */ | 77 | /* Save user chosen LSM */ |
| 82 | static int __init choose_lsm(char *str) | 78 | static int __init choose_lsm(char *str) |
| 83 | { | 79 | { |
| @@ -88,7 +84,7 @@ __setup("security=", choose_lsm); | |||
| 88 | 84 | ||
| 89 | /** | 85 | /** |
| 90 | * security_module_enable - Load given security module on boot ? | 86 | * security_module_enable - Load given security module on boot ? |
| 91 | * @ops: a pointer to the struct security_operations that is to be checked. | 87 | * @module: the name of the module |
| 92 | * | 88 | * |
| 93 | * Each LSM must pass this method before registering its own operations | 89 | * Each LSM must pass this method before registering its own operations |
| 94 | * to avoid security registration races. This method may also be used | 90 | * to avoid security registration races. This method may also be used |
| @@ -100,41 +96,13 @@ __setup("security=", choose_lsm); | |||
| 100 | * choose an alternate LSM at boot time. | 96 | * choose an alternate LSM at boot time. |
| 101 | * Otherwise, return false. | 97 | * Otherwise, return false. |
| 102 | */ | 98 | */ |
| 103 | int __init security_module_enable(struct security_operations *ops) | 99 | int __init security_module_enable(const char *module) |
| 104 | { | 100 | { |
| 105 | return !strcmp(ops->name, chosen_lsm); | 101 | return !strcmp(module, chosen_lsm); |
| 106 | } | ||
| 107 | |||
| 108 | /** | ||
| 109 | * register_security - registers a security framework with the kernel | ||
| 110 | * @ops: a pointer to the struct security_options that is to be registered | ||
| 111 | * | ||
| 112 | * This function allows a security module to register itself with the | ||
| 113 | * kernel security subsystem. Some rudimentary checking is done on the @ops | ||
| 114 | * value passed to this function. You'll need to check first if your LSM | ||
| 115 | * is allowed to register its @ops by calling security_module_enable(@ops). | ||
| 116 | * | ||
| 117 | * If there is already a security module registered with the kernel, | ||
| 118 | * an error will be returned. Otherwise %0 is returned on success. | ||
| 119 | */ | ||
| 120 | int __init register_security(struct security_operations *ops) | ||
| 121 | { | ||
| 122 | if (verify(ops)) { | ||
| 123 | printk(KERN_DEBUG "%s could not verify " | ||
| 124 | "security_operations structure.\n", __func__); | ||
| 125 | return -EINVAL; | ||
| 126 | } | ||
| 127 | |||
| 128 | if (security_ops != &default_security_ops) | ||
| 129 | return -EAGAIN; | ||
| 130 | |||
| 131 | security_ops = ops; | ||
| 132 | |||
| 133 | return 0; | ||
| 134 | } | 102 | } |
| 135 | 103 | ||
| 136 | /* | 104 | /* |
| 137 | * Hook operation macros. | 105 | * Hook list operation macros. |
| 138 | * | 106 | * |
| 139 | * call_void_hook: | 107 | * call_void_hook: |
| 140 | * This is a hook that does not return a value. | 108 | * This is a hook that does not return a value. |
| @@ -143,8 +111,27 @@ int __init register_security(struct security_operations *ops) | |||
| 143 | * This is a hook that returns a value. | 111 | * This is a hook that returns a value. |
| 144 | */ | 112 | */ |
| 145 | 113 | ||
| 146 | #define call_void_hook(FUNC, ...) security_ops->FUNC(__VA_ARGS__) | 114 | #define call_void_hook(FUNC, ...) \ |
| 147 | #define call_int_hook(FUNC, IRC, ...) security_ops->FUNC(__VA_ARGS__) | 115 | do { \ |
| 116 | struct security_hook_list *P; \ | ||
| 117 | \ | ||
| 118 | list_for_each_entry(P, &security_hook_heads.FUNC, list) \ | ||
| 119 | P->hook.FUNC(__VA_ARGS__); \ | ||
| 120 | } while (0) | ||
| 121 | |||
| 122 | #define call_int_hook(FUNC, IRC, ...) ({ \ | ||
| 123 | int RC = IRC; \ | ||
| 124 | do { \ | ||
| 125 | struct security_hook_list *P; \ | ||
| 126 | \ | ||
| 127 | list_for_each_entry(P, &security_hook_heads.FUNC, list) { \ | ||
| 128 | RC = P->hook.FUNC(__VA_ARGS__); \ | ||
| 129 | if (RC != 0) \ | ||
| 130 | break; \ | ||
| 131 | } \ | ||
| 132 | } while (0); \ | ||
| 133 | RC; \ | ||
| 134 | }) | ||
| 148 | 135 | ||
| 149 | /* Security operations */ | 136 | /* Security operations */ |
| 150 | 137 | ||
| @@ -173,23 +160,11 @@ int security_binder_transfer_file(struct task_struct *from, | |||
| 173 | 160 | ||
| 174 | int security_ptrace_access_check(struct task_struct *child, unsigned int mode) | 161 | int security_ptrace_access_check(struct task_struct *child, unsigned int mode) |
| 175 | { | 162 | { |
| 176 | #ifdef CONFIG_SECURITY_YAMA_STACKED | ||
| 177 | int rc; | ||
| 178 | rc = yama_ptrace_access_check(child, mode); | ||
| 179 | if (rc) | ||
| 180 | return rc; | ||
| 181 | #endif | ||
| 182 | return call_int_hook(ptrace_access_check, 0, child, mode); | 163 | return call_int_hook(ptrace_access_check, 0, child, mode); |
| 183 | } | 164 | } |
| 184 | 165 | ||
| 185 | int security_ptrace_traceme(struct task_struct *parent) | 166 | int security_ptrace_traceme(struct task_struct *parent) |
| 186 | { | 167 | { |
| 187 | #ifdef CONFIG_SECURITY_YAMA_STACKED | ||
| 188 | int rc; | ||
| 189 | rc = yama_ptrace_traceme(parent); | ||
| 190 | if (rc) | ||
| 191 | return rc; | ||
| 192 | #endif | ||
| 193 | return call_int_hook(ptrace_traceme, 0, parent); | 168 | return call_int_hook(ptrace_traceme, 0, parent); |
| 194 | } | 169 | } |
| 195 | 170 | ||
| @@ -245,7 +220,25 @@ int security_settime(const struct timespec *ts, const struct timezone *tz) | |||
| 245 | 220 | ||
| 246 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) | 221 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) |
| 247 | { | 222 | { |
| 248 | return call_int_hook(vm_enough_memory, 0, mm, pages); | 223 | struct security_hook_list *hp; |
| 224 | int cap_sys_admin = 1; | ||
| 225 | int rc; | ||
| 226 | |||
| 227 | /* | ||
| 228 | * The module will respond with a positive value if | ||
| 229 | * it thinks the __vm_enough_memory() call should be | ||
| 230 | * made with the cap_sys_admin set. If all of the modules | ||
| 231 | * agree that it should be set it will. If any module | ||
| 232 | * thinks it should not be set it won't. | ||
| 233 | */ | ||
| 234 | list_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) { | ||
| 235 | rc = hp->hook.vm_enough_memory(mm, pages); | ||
| 236 | if (rc <= 0) { | ||
| 237 | cap_sys_admin = 0; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | return __vm_enough_memory(mm, pages, cap_sys_admin); | ||
| 249 | } | 242 | } |
| 250 | 243 | ||
| 251 | int security_bprm_set_creds(struct linux_binprm *bprm) | 244 | int security_bprm_set_creds(struct linux_binprm *bprm) |
| @@ -335,8 +328,9 @@ int security_sb_set_mnt_opts(struct super_block *sb, | |||
| 335 | unsigned long kern_flags, | 328 | unsigned long kern_flags, |
| 336 | unsigned long *set_kern_flags) | 329 | unsigned long *set_kern_flags) |
| 337 | { | 330 | { |
| 338 | return call_int_hook(sb_set_mnt_opts, 0, sb, opts, kern_flags, | 331 | return call_int_hook(sb_set_mnt_opts, |
| 339 | set_kern_flags); | 332 | opts->num_mnt_opts ? -EOPNOTSUPP : 0, sb, |
| 333 | opts, kern_flags, set_kern_flags); | ||
| 340 | } | 334 | } |
| 341 | EXPORT_SYMBOL(security_sb_set_mnt_opts); | 335 | EXPORT_SYMBOL(security_sb_set_mnt_opts); |
| 342 | 336 | ||
| @@ -369,8 +363,8 @@ int security_dentry_init_security(struct dentry *dentry, int mode, | |||
| 369 | struct qstr *name, void **ctx, | 363 | struct qstr *name, void **ctx, |
| 370 | u32 *ctxlen) | 364 | u32 *ctxlen) |
| 371 | { | 365 | { |
| 372 | return call_int_hook(dentry_init_security, 0, dentry, mode, name, | 366 | return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode, |
| 373 | ctx, ctxlen); | 367 | name, ctx, ctxlen); |
| 374 | } | 368 | } |
| 375 | EXPORT_SYMBOL(security_dentry_init_security); | 369 | EXPORT_SYMBOL(security_dentry_init_security); |
| 376 | 370 | ||
| @@ -390,7 +384,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 390 | NULL, NULL, NULL); | 384 | NULL, NULL, NULL); |
| 391 | memset(new_xattrs, 0, sizeof(new_xattrs)); | 385 | memset(new_xattrs, 0, sizeof(new_xattrs)); |
| 392 | lsm_xattr = new_xattrs; | 386 | lsm_xattr = new_xattrs; |
| 393 | ret = call_int_hook(inode_init_security, 0, inode, dir, qstr, | 387 | ret = call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr, |
| 394 | &lsm_xattr->name, | 388 | &lsm_xattr->name, |
| 395 | &lsm_xattr->value, | 389 | &lsm_xattr->value, |
| 396 | &lsm_xattr->value_len); | 390 | &lsm_xattr->value_len); |
| @@ -636,8 +630,15 @@ int security_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 636 | 630 | ||
| 637 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) | 631 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 638 | return 0; | 632 | return 0; |
| 639 | ret = call_int_hook(inode_setxattr, 0, dentry, name, value, size, | 633 | /* |
| 634 | * SELinux and Smack integrate the cap call, | ||
| 635 | * so assume that all LSMs supplying this call do so. | ||
| 636 | */ | ||
| 637 | ret = call_int_hook(inode_setxattr, 1, dentry, name, value, size, | ||
| 640 | flags); | 638 | flags); |
| 639 | |||
| 640 | if (ret == 1) | ||
| 641 | ret = cap_inode_setxattr(dentry, name, value, size, flags); | ||
| 641 | if (ret) | 642 | if (ret) |
| 642 | return ret; | 643 | return ret; |
| 643 | ret = ima_inode_setxattr(dentry, name, value, size); | 644 | ret = ima_inode_setxattr(dentry, name, value, size); |
| @@ -675,7 +676,13 @@ int security_inode_removexattr(struct dentry *dentry, const char *name) | |||
| 675 | 676 | ||
| 676 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) | 677 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
| 677 | return 0; | 678 | return 0; |
| 678 | ret = call_int_hook(inode_removexattr, 0, dentry, name); | 679 | /* |
| 680 | * SELinux and Smack integrate the cap call, | ||
| 681 | * so assume that all LSMs supplying this call do so. | ||
| 682 | */ | ||
| 683 | ret = call_int_hook(inode_removexattr, 1, dentry, name); | ||
| 684 | if (ret == 1) | ||
| 685 | ret = cap_inode_removexattr(dentry, name); | ||
| 679 | if (ret) | 686 | if (ret) |
| 680 | return ret; | 687 | return ret; |
| 681 | ret = ima_inode_removexattr(dentry, name); | 688 | ret = ima_inode_removexattr(dentry, name); |
| @@ -698,15 +705,16 @@ int security_inode_getsecurity(const struct inode *inode, const char *name, void | |||
| 698 | { | 705 | { |
| 699 | if (unlikely(IS_PRIVATE(inode))) | 706 | if (unlikely(IS_PRIVATE(inode))) |
| 700 | return -EOPNOTSUPP; | 707 | return -EOPNOTSUPP; |
| 701 | return call_int_hook(inode_getsecurity, 0, inode, name, buffer, alloc); | 708 | return call_int_hook(inode_getsecurity, -EOPNOTSUPP, inode, name, |
| 709 | buffer, alloc); | ||
| 702 | } | 710 | } |
| 703 | 711 | ||
| 704 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) | 712 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) |
| 705 | { | 713 | { |
| 706 | if (unlikely(IS_PRIVATE(inode))) | 714 | if (unlikely(IS_PRIVATE(inode))) |
| 707 | return -EOPNOTSUPP; | 715 | return -EOPNOTSUPP; |
| 708 | return call_int_hook(inode_setsecurity, 0, inode, name, value, size, | 716 | return call_int_hook(inode_setsecurity, -EOPNOTSUPP, inode, name, |
| 709 | flags); | 717 | value, size, flags); |
| 710 | } | 718 | } |
| 711 | 719 | ||
| 712 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) | 720 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) |
| @@ -847,9 +855,6 @@ int security_task_create(unsigned long clone_flags) | |||
| 847 | 855 | ||
| 848 | void security_task_free(struct task_struct *task) | 856 | void security_task_free(struct task_struct *task) |
| 849 | { | 857 | { |
| 850 | #ifdef CONFIG_SECURITY_YAMA_STACKED | ||
| 851 | yama_task_free(task); | ||
| 852 | #endif | ||
| 853 | call_void_hook(task_free, task); | 858 | call_void_hook(task_free, task); |
| 854 | } | 859 | } |
| 855 | 860 | ||
| @@ -932,6 +937,7 @@ int security_task_getsid(struct task_struct *p) | |||
| 932 | 937 | ||
| 933 | void security_task_getsecid(struct task_struct *p, u32 *secid) | 938 | void security_task_getsecid(struct task_struct *p, u32 *secid) |
| 934 | { | 939 | { |
| 940 | *secid = 0; | ||
| 935 | call_void_hook(task_getsecid, p, secid); | 941 | call_void_hook(task_getsecid, p, secid); |
| 936 | } | 942 | } |
| 937 | EXPORT_SYMBOL(security_task_getsecid); | 943 | EXPORT_SYMBOL(security_task_getsecid); |
| @@ -986,13 +992,19 @@ int security_task_wait(struct task_struct *p) | |||
| 986 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 992 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
| 987 | unsigned long arg4, unsigned long arg5) | 993 | unsigned long arg4, unsigned long arg5) |
| 988 | { | 994 | { |
| 989 | #ifdef CONFIG_SECURITY_YAMA_STACKED | 995 | int thisrc; |
| 990 | int rc; | 996 | int rc = -ENOSYS; |
| 991 | rc = yama_task_prctl(option, arg2, arg3, arg4, arg5); | 997 | struct security_hook_list *hp; |
| 992 | if (rc != -ENOSYS) | 998 | |
| 993 | return rc; | 999 | list_for_each_entry(hp, &security_hook_heads.task_prctl, list) { |
| 994 | #endif | 1000 | thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5); |
| 995 | return call_int_hook(task_prctl, 0, option, arg2, arg3, arg4, arg5); | 1001 | if (thisrc != -ENOSYS) { |
| 1002 | rc = thisrc; | ||
| 1003 | if (thisrc != 0) | ||
| 1004 | break; | ||
| 1005 | } | ||
| 1006 | } | ||
| 1007 | return rc; | ||
| 996 | } | 1008 | } |
| 997 | 1009 | ||
| 998 | void security_task_to_inode(struct task_struct *p, struct inode *inode) | 1010 | void security_task_to_inode(struct task_struct *p, struct inode *inode) |
| @@ -1007,6 +1019,7 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
| 1007 | 1019 | ||
| 1008 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | 1020 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) |
| 1009 | { | 1021 | { |
| 1022 | *secid = 0; | ||
| 1010 | call_void_hook(ipc_getsecid, ipcp, secid); | 1023 | call_void_hook(ipc_getsecid, ipcp, secid); |
| 1011 | } | 1024 | } |
| 1012 | 1025 | ||
| @@ -1113,12 +1126,12 @@ EXPORT_SYMBOL(security_d_instantiate); | |||
| 1113 | 1126 | ||
| 1114 | int security_getprocattr(struct task_struct *p, char *name, char **value) | 1127 | int security_getprocattr(struct task_struct *p, char *name, char **value) |
| 1115 | { | 1128 | { |
| 1116 | return call_int_hook(getprocattr, 0, p, name, value); | 1129 | return call_int_hook(getprocattr, -EINVAL, p, name, value); |
| 1117 | } | 1130 | } |
| 1118 | 1131 | ||
| 1119 | int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size) | 1132 | int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size) |
| 1120 | { | 1133 | { |
| 1121 | return call_int_hook(setprocattr, 0, p, name, value, size); | 1134 | return call_int_hook(setprocattr, -EINVAL, p, name, value, size); |
| 1122 | } | 1135 | } |
| 1123 | 1136 | ||
| 1124 | int security_netlink_send(struct sock *sk, struct sk_buff *skb) | 1137 | int security_netlink_send(struct sock *sk, struct sk_buff *skb) |
| @@ -1134,12 +1147,14 @@ EXPORT_SYMBOL(security_ismaclabel); | |||
| 1134 | 1147 | ||
| 1135 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | 1148 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) |
| 1136 | { | 1149 | { |
| 1137 | return call_int_hook(secid_to_secctx, 0, secid, secdata, seclen); | 1150 | return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, |
| 1151 | seclen); | ||
| 1138 | } | 1152 | } |
| 1139 | EXPORT_SYMBOL(security_secid_to_secctx); | 1153 | EXPORT_SYMBOL(security_secid_to_secctx); |
| 1140 | 1154 | ||
| 1141 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) | 1155 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
| 1142 | { | 1156 | { |
| 1157 | *secid = 0; | ||
| 1143 | return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); | 1158 | return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); |
| 1144 | } | 1159 | } |
| 1145 | EXPORT_SYMBOL(security_secctx_to_secid); | 1160 | EXPORT_SYMBOL(security_secctx_to_secid); |
| @@ -1164,7 +1179,7 @@ EXPORT_SYMBOL(security_inode_setsecctx); | |||
| 1164 | 1179 | ||
| 1165 | int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) | 1180 | int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) |
| 1166 | { | 1181 | { |
| 1167 | return call_int_hook(inode_getsecctx, 0, inode, ctx, ctxlen); | 1182 | return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen); |
| 1168 | } | 1183 | } |
| 1169 | EXPORT_SYMBOL(security_inode_getsecctx); | 1184 | EXPORT_SYMBOL(security_inode_getsecctx); |
| 1170 | 1185 | ||
| @@ -1259,8 +1274,8 @@ EXPORT_SYMBOL(security_sock_rcv_skb); | |||
| 1259 | int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, | 1274 | int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, |
| 1260 | int __user *optlen, unsigned len) | 1275 | int __user *optlen, unsigned len) |
| 1261 | { | 1276 | { |
| 1262 | return call_int_hook(socket_getpeersec_stream, 0, sock, optval, | 1277 | return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock, |
| 1263 | optlen, len); | 1278 | optval, optlen, len); |
| 1264 | } | 1279 | } |
| 1265 | 1280 | ||
| 1266 | int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) | 1281 | int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) |
| @@ -1438,7 +1453,24 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x, | |||
| 1438 | struct xfrm_policy *xp, | 1453 | struct xfrm_policy *xp, |
| 1439 | const struct flowi *fl) | 1454 | const struct flowi *fl) |
| 1440 | { | 1455 | { |
| 1441 | return call_int_hook(xfrm_state_pol_flow_match, 0, x, xp, fl); | 1456 | struct security_hook_list *hp; |
| 1457 | int rc = 1; | ||
| 1458 | |||
| 1459 | /* | ||
| 1460 | * Since this function is expected to return 0 or 1, the judgment | ||
| 1461 | * becomes difficult if multiple LSMs supply this call. Fortunately, | ||
| 1462 | * we can use the first LSM's judgment because currently only SELinux | ||
| 1463 | * supplies this call. | ||
| 1464 | * | ||
| 1465 | * For speed optimization, we explicitly break the loop rather than | ||
| 1466 | * using the macro | ||
| 1467 | */ | ||
| 1468 | list_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match, | ||
| 1469 | list) { | ||
| 1470 | rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl); | ||
| 1471 | break; | ||
| 1472 | } | ||
| 1473 | return rc; | ||
| 1442 | } | 1474 | } |
| 1443 | 1475 | ||
| 1444 | int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) | 1476 | int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) |
| @@ -1478,6 +1510,7 @@ int security_key_permission(key_ref_t key_ref, | |||
| 1478 | 1510 | ||
| 1479 | int security_key_getsecurity(struct key *key, char **_buffer) | 1511 | int security_key_getsecurity(struct key *key, char **_buffer) |
| 1480 | { | 1512 | { |
| 1513 | *_buffer = NULL; | ||
| 1481 | return call_int_hook(key_getsecurity, 0, key, _buffer); | 1514 | return call_int_hook(key_getsecurity, 0, key, _buffer); |
| 1482 | } | 1515 | } |
| 1483 | 1516 | ||
| @@ -1506,5 +1539,350 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, | |||
| 1506 | return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule, | 1539 | return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule, |
| 1507 | actx); | 1540 | actx); |
| 1508 | } | 1541 | } |
| 1542 | #endif /* CONFIG_AUDIT */ | ||
| 1509 | 1543 | ||
| 1544 | struct security_hook_heads security_hook_heads = { | ||
| 1545 | .binder_set_context_mgr = | ||
| 1546 | LIST_HEAD_INIT(security_hook_heads.binder_set_context_mgr), | ||
| 1547 | .binder_transaction = | ||
| 1548 | LIST_HEAD_INIT(security_hook_heads.binder_transaction), | ||
| 1549 | .binder_transfer_binder = | ||
| 1550 | LIST_HEAD_INIT(security_hook_heads.binder_transfer_binder), | ||
| 1551 | .binder_transfer_file = | ||
| 1552 | LIST_HEAD_INIT(security_hook_heads.binder_transfer_file), | ||
| 1553 | |||
| 1554 | .ptrace_access_check = | ||
| 1555 | LIST_HEAD_INIT(security_hook_heads.ptrace_access_check), | ||
| 1556 | .ptrace_traceme = | ||
| 1557 | LIST_HEAD_INIT(security_hook_heads.ptrace_traceme), | ||
| 1558 | .capget = LIST_HEAD_INIT(security_hook_heads.capget), | ||
| 1559 | .capset = LIST_HEAD_INIT(security_hook_heads.capset), | ||
| 1560 | .capable = LIST_HEAD_INIT(security_hook_heads.capable), | ||
| 1561 | .quotactl = LIST_HEAD_INIT(security_hook_heads.quotactl), | ||
| 1562 | .quota_on = LIST_HEAD_INIT(security_hook_heads.quota_on), | ||
| 1563 | .syslog = LIST_HEAD_INIT(security_hook_heads.syslog), | ||
| 1564 | .settime = LIST_HEAD_INIT(security_hook_heads.settime), | ||
| 1565 | .vm_enough_memory = | ||
| 1566 | LIST_HEAD_INIT(security_hook_heads.vm_enough_memory), | ||
| 1567 | .bprm_set_creds = | ||
| 1568 | LIST_HEAD_INIT(security_hook_heads.bprm_set_creds), | ||
| 1569 | .bprm_check_security = | ||
| 1570 | LIST_HEAD_INIT(security_hook_heads.bprm_check_security), | ||
| 1571 | .bprm_secureexec = | ||
| 1572 | LIST_HEAD_INIT(security_hook_heads.bprm_secureexec), | ||
| 1573 | .bprm_committing_creds = | ||
| 1574 | LIST_HEAD_INIT(security_hook_heads.bprm_committing_creds), | ||
| 1575 | .bprm_committed_creds = | ||
| 1576 | LIST_HEAD_INIT(security_hook_heads.bprm_committed_creds), | ||
| 1577 | .sb_alloc_security = | ||
| 1578 | LIST_HEAD_INIT(security_hook_heads.sb_alloc_security), | ||
| 1579 | .sb_free_security = | ||
| 1580 | LIST_HEAD_INIT(security_hook_heads.sb_free_security), | ||
| 1581 | .sb_copy_data = LIST_HEAD_INIT(security_hook_heads.sb_copy_data), | ||
| 1582 | .sb_remount = LIST_HEAD_INIT(security_hook_heads.sb_remount), | ||
| 1583 | .sb_kern_mount = | ||
| 1584 | LIST_HEAD_INIT(security_hook_heads.sb_kern_mount), | ||
| 1585 | .sb_show_options = | ||
| 1586 | LIST_HEAD_INIT(security_hook_heads.sb_show_options), | ||
| 1587 | .sb_statfs = LIST_HEAD_INIT(security_hook_heads.sb_statfs), | ||
| 1588 | .sb_mount = LIST_HEAD_INIT(security_hook_heads.sb_mount), | ||
| 1589 | .sb_umount = LIST_HEAD_INIT(security_hook_heads.sb_umount), | ||
| 1590 | .sb_pivotroot = LIST_HEAD_INIT(security_hook_heads.sb_pivotroot), | ||
| 1591 | .sb_set_mnt_opts = | ||
| 1592 | LIST_HEAD_INIT(security_hook_heads.sb_set_mnt_opts), | ||
| 1593 | .sb_clone_mnt_opts = | ||
| 1594 | LIST_HEAD_INIT(security_hook_heads.sb_clone_mnt_opts), | ||
| 1595 | .sb_parse_opts_str = | ||
| 1596 | LIST_HEAD_INIT(security_hook_heads.sb_parse_opts_str), | ||
| 1597 | .dentry_init_security = | ||
| 1598 | LIST_HEAD_INIT(security_hook_heads.dentry_init_security), | ||
| 1599 | #ifdef CONFIG_SECURITY_PATH | ||
| 1600 | .path_unlink = LIST_HEAD_INIT(security_hook_heads.path_unlink), | ||
| 1601 | .path_mkdir = LIST_HEAD_INIT(security_hook_heads.path_mkdir), | ||
| 1602 | .path_rmdir = LIST_HEAD_INIT(security_hook_heads.path_rmdir), | ||
| 1603 | .path_mknod = LIST_HEAD_INIT(security_hook_heads.path_mknod), | ||
| 1604 | .path_truncate = | ||
| 1605 | LIST_HEAD_INIT(security_hook_heads.path_truncate), | ||
| 1606 | .path_symlink = LIST_HEAD_INIT(security_hook_heads.path_symlink), | ||
| 1607 | .path_link = LIST_HEAD_INIT(security_hook_heads.path_link), | ||
| 1608 | .path_rename = LIST_HEAD_INIT(security_hook_heads.path_rename), | ||
| 1609 | .path_chmod = LIST_HEAD_INIT(security_hook_heads.path_chmod), | ||
| 1610 | .path_chown = LIST_HEAD_INIT(security_hook_heads.path_chown), | ||
| 1611 | .path_chroot = LIST_HEAD_INIT(security_hook_heads.path_chroot), | ||
| 1612 | #endif | ||
| 1613 | .inode_alloc_security = | ||
| 1614 | LIST_HEAD_INIT(security_hook_heads.inode_alloc_security), | ||
| 1615 | .inode_free_security = | ||
| 1616 | LIST_HEAD_INIT(security_hook_heads.inode_free_security), | ||
| 1617 | .inode_init_security = | ||
| 1618 | LIST_HEAD_INIT(security_hook_heads.inode_init_security), | ||
| 1619 | .inode_create = LIST_HEAD_INIT(security_hook_heads.inode_create), | ||
| 1620 | .inode_link = LIST_HEAD_INIT(security_hook_heads.inode_link), | ||
| 1621 | .inode_unlink = LIST_HEAD_INIT(security_hook_heads.inode_unlink), | ||
| 1622 | .inode_symlink = | ||
| 1623 | LIST_HEAD_INIT(security_hook_heads.inode_symlink), | ||
| 1624 | .inode_mkdir = LIST_HEAD_INIT(security_hook_heads.inode_mkdir), | ||
| 1625 | .inode_rmdir = LIST_HEAD_INIT(security_hook_heads.inode_rmdir), | ||
| 1626 | .inode_mknod = LIST_HEAD_INIT(security_hook_heads.inode_mknod), | ||
| 1627 | .inode_rename = LIST_HEAD_INIT(security_hook_heads.inode_rename), | ||
| 1628 | .inode_readlink = | ||
| 1629 | LIST_HEAD_INIT(security_hook_heads.inode_readlink), | ||
| 1630 | .inode_follow_link = | ||
| 1631 | LIST_HEAD_INIT(security_hook_heads.inode_follow_link), | ||
| 1632 | .inode_permission = | ||
| 1633 | LIST_HEAD_INIT(security_hook_heads.inode_permission), | ||
| 1634 | .inode_setattr = | ||
| 1635 | LIST_HEAD_INIT(security_hook_heads.inode_setattr), | ||
| 1636 | .inode_getattr = | ||
| 1637 | LIST_HEAD_INIT(security_hook_heads.inode_getattr), | ||
| 1638 | .inode_setxattr = | ||
| 1639 | LIST_HEAD_INIT(security_hook_heads.inode_setxattr), | ||
| 1640 | .inode_post_setxattr = | ||
| 1641 | LIST_HEAD_INIT(security_hook_heads.inode_post_setxattr), | ||
| 1642 | .inode_getxattr = | ||
| 1643 | LIST_HEAD_INIT(security_hook_heads.inode_getxattr), | ||
| 1644 | .inode_listxattr = | ||
| 1645 | LIST_HEAD_INIT(security_hook_heads.inode_listxattr), | ||
| 1646 | .inode_removexattr = | ||
| 1647 | LIST_HEAD_INIT(security_hook_heads.inode_removexattr), | ||
| 1648 | .inode_need_killpriv = | ||
| 1649 | LIST_HEAD_INIT(security_hook_heads.inode_need_killpriv), | ||
| 1650 | .inode_killpriv = | ||
| 1651 | LIST_HEAD_INIT(security_hook_heads.inode_killpriv), | ||
| 1652 | .inode_getsecurity = | ||
| 1653 | LIST_HEAD_INIT(security_hook_heads.inode_getsecurity), | ||
| 1654 | .inode_setsecurity = | ||
| 1655 | LIST_HEAD_INIT(security_hook_heads.inode_setsecurity), | ||
| 1656 | .inode_listsecurity = | ||
| 1657 | LIST_HEAD_INIT(security_hook_heads.inode_listsecurity), | ||
| 1658 | .inode_getsecid = | ||
| 1659 | LIST_HEAD_INIT(security_hook_heads.inode_getsecid), | ||
| 1660 | .file_permission = | ||
| 1661 | LIST_HEAD_INIT(security_hook_heads.file_permission), | ||
| 1662 | .file_alloc_security = | ||
| 1663 | LIST_HEAD_INIT(security_hook_heads.file_alloc_security), | ||
| 1664 | .file_free_security = | ||
| 1665 | LIST_HEAD_INIT(security_hook_heads.file_free_security), | ||
| 1666 | .file_ioctl = LIST_HEAD_INIT(security_hook_heads.file_ioctl), | ||
| 1667 | .mmap_addr = LIST_HEAD_INIT(security_hook_heads.mmap_addr), | ||
| 1668 | .mmap_file = LIST_HEAD_INIT(security_hook_heads.mmap_file), | ||
| 1669 | .file_mprotect = | ||
| 1670 | LIST_HEAD_INIT(security_hook_heads.file_mprotect), | ||
| 1671 | .file_lock = LIST_HEAD_INIT(security_hook_heads.file_lock), | ||
| 1672 | .file_fcntl = LIST_HEAD_INIT(security_hook_heads.file_fcntl), | ||
| 1673 | .file_set_fowner = | ||
| 1674 | LIST_HEAD_INIT(security_hook_heads.file_set_fowner), | ||
| 1675 | .file_send_sigiotask = | ||
| 1676 | LIST_HEAD_INIT(security_hook_heads.file_send_sigiotask), | ||
| 1677 | .file_receive = LIST_HEAD_INIT(security_hook_heads.file_receive), | ||
| 1678 | .file_open = LIST_HEAD_INIT(security_hook_heads.file_open), | ||
| 1679 | .task_create = LIST_HEAD_INIT(security_hook_heads.task_create), | ||
| 1680 | .task_free = LIST_HEAD_INIT(security_hook_heads.task_free), | ||
| 1681 | .cred_alloc_blank = | ||
| 1682 | LIST_HEAD_INIT(security_hook_heads.cred_alloc_blank), | ||
| 1683 | .cred_free = LIST_HEAD_INIT(security_hook_heads.cred_free), | ||
| 1684 | .cred_prepare = LIST_HEAD_INIT(security_hook_heads.cred_prepare), | ||
| 1685 | .cred_transfer = | ||
| 1686 | LIST_HEAD_INIT(security_hook_heads.cred_transfer), | ||
| 1687 | .kernel_act_as = | ||
| 1688 | LIST_HEAD_INIT(security_hook_heads.kernel_act_as), | ||
| 1689 | .kernel_create_files_as = | ||
| 1690 | LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as), | ||
| 1691 | .kernel_fw_from_file = | ||
| 1692 | LIST_HEAD_INIT(security_hook_heads.kernel_fw_from_file), | ||
| 1693 | .kernel_module_request = | ||
| 1694 | LIST_HEAD_INIT(security_hook_heads.kernel_module_request), | ||
| 1695 | .kernel_module_from_file = | ||
| 1696 | LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file), | ||
| 1697 | .task_fix_setuid = | ||
| 1698 | LIST_HEAD_INIT(security_hook_heads.task_fix_setuid), | ||
| 1699 | .task_setpgid = LIST_HEAD_INIT(security_hook_heads.task_setpgid), | ||
| 1700 | .task_getpgid = LIST_HEAD_INIT(security_hook_heads.task_getpgid), | ||
| 1701 | .task_getsid = LIST_HEAD_INIT(security_hook_heads.task_getsid), | ||
| 1702 | .task_getsecid = | ||
| 1703 | LIST_HEAD_INIT(security_hook_heads.task_getsecid), | ||
| 1704 | .task_setnice = LIST_HEAD_INIT(security_hook_heads.task_setnice), | ||
| 1705 | .task_setioprio = | ||
| 1706 | LIST_HEAD_INIT(security_hook_heads.task_setioprio), | ||
| 1707 | .task_getioprio = | ||
| 1708 | LIST_HEAD_INIT(security_hook_heads.task_getioprio), | ||
| 1709 | .task_setrlimit = | ||
| 1710 | LIST_HEAD_INIT(security_hook_heads.task_setrlimit), | ||
| 1711 | .task_setscheduler = | ||
| 1712 | LIST_HEAD_INIT(security_hook_heads.task_setscheduler), | ||
| 1713 | .task_getscheduler = | ||
| 1714 | LIST_HEAD_INIT(security_hook_heads.task_getscheduler), | ||
| 1715 | .task_movememory = | ||
| 1716 | LIST_HEAD_INIT(security_hook_heads.task_movememory), | ||
| 1717 | .task_kill = LIST_HEAD_INIT(security_hook_heads.task_kill), | ||
| 1718 | .task_wait = LIST_HEAD_INIT(security_hook_heads.task_wait), | ||
| 1719 | .task_prctl = LIST_HEAD_INIT(security_hook_heads.task_prctl), | ||
| 1720 | .task_to_inode = | ||
| 1721 | LIST_HEAD_INIT(security_hook_heads.task_to_inode), | ||
| 1722 | .ipc_permission = | ||
| 1723 | LIST_HEAD_INIT(security_hook_heads.ipc_permission), | ||
| 1724 | .ipc_getsecid = LIST_HEAD_INIT(security_hook_heads.ipc_getsecid), | ||
| 1725 | .msg_msg_alloc_security = | ||
| 1726 | LIST_HEAD_INIT(security_hook_heads.msg_msg_alloc_security), | ||
| 1727 | .msg_msg_free_security = | ||
| 1728 | LIST_HEAD_INIT(security_hook_heads.msg_msg_free_security), | ||
| 1729 | .msg_queue_alloc_security = | ||
| 1730 | LIST_HEAD_INIT(security_hook_heads.msg_queue_alloc_security), | ||
| 1731 | .msg_queue_free_security = | ||
| 1732 | LIST_HEAD_INIT(security_hook_heads.msg_queue_free_security), | ||
| 1733 | .msg_queue_associate = | ||
| 1734 | LIST_HEAD_INIT(security_hook_heads.msg_queue_associate), | ||
| 1735 | .msg_queue_msgctl = | ||
| 1736 | LIST_HEAD_INIT(security_hook_heads.msg_queue_msgctl), | ||
| 1737 | .msg_queue_msgsnd = | ||
| 1738 | LIST_HEAD_INIT(security_hook_heads.msg_queue_msgsnd), | ||
| 1739 | .msg_queue_msgrcv = | ||
| 1740 | LIST_HEAD_INIT(security_hook_heads.msg_queue_msgrcv), | ||
| 1741 | .shm_alloc_security = | ||
| 1742 | LIST_HEAD_INIT(security_hook_heads.shm_alloc_security), | ||
| 1743 | .shm_free_security = | ||
| 1744 | LIST_HEAD_INIT(security_hook_heads.shm_free_security), | ||
| 1745 | .shm_associate = | ||
| 1746 | LIST_HEAD_INIT(security_hook_heads.shm_associate), | ||
| 1747 | .shm_shmctl = LIST_HEAD_INIT(security_hook_heads.shm_shmctl), | ||
| 1748 | .shm_shmat = LIST_HEAD_INIT(security_hook_heads.shm_shmat), | ||
| 1749 | .sem_alloc_security = | ||
| 1750 | LIST_HEAD_INIT(security_hook_heads.sem_alloc_security), | ||
| 1751 | .sem_free_security = | ||
| 1752 | LIST_HEAD_INIT(security_hook_heads.sem_free_security), | ||
| 1753 | .sem_associate = | ||
| 1754 | LIST_HEAD_INIT(security_hook_heads.sem_associate), | ||
| 1755 | .sem_semctl = LIST_HEAD_INIT(security_hook_heads.sem_semctl), | ||
| 1756 | .sem_semop = LIST_HEAD_INIT(security_hook_heads.sem_semop), | ||
| 1757 | .netlink_send = LIST_HEAD_INIT(security_hook_heads.netlink_send), | ||
| 1758 | .d_instantiate = | ||
| 1759 | LIST_HEAD_INIT(security_hook_heads.d_instantiate), | ||
| 1760 | .getprocattr = LIST_HEAD_INIT(security_hook_heads.getprocattr), | ||
| 1761 | .setprocattr = LIST_HEAD_INIT(security_hook_heads.setprocattr), | ||
| 1762 | .ismaclabel = LIST_HEAD_INIT(security_hook_heads.ismaclabel), | ||
| 1763 | .secid_to_secctx = | ||
| 1764 | LIST_HEAD_INIT(security_hook_heads.secid_to_secctx), | ||
| 1765 | .secctx_to_secid = | ||
| 1766 | LIST_HEAD_INIT(security_hook_heads.secctx_to_secid), | ||
| 1767 | .release_secctx = | ||
| 1768 | LIST_HEAD_INIT(security_hook_heads.release_secctx), | ||
| 1769 | .inode_notifysecctx = | ||
| 1770 | LIST_HEAD_INIT(security_hook_heads.inode_notifysecctx), | ||
| 1771 | .inode_setsecctx = | ||
| 1772 | LIST_HEAD_INIT(security_hook_heads.inode_setsecctx), | ||
| 1773 | .inode_getsecctx = | ||
| 1774 | LIST_HEAD_INIT(security_hook_heads.inode_getsecctx), | ||
| 1775 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 1776 | .unix_stream_connect = | ||
| 1777 | LIST_HEAD_INIT(security_hook_heads.unix_stream_connect), | ||
| 1778 | .unix_may_send = | ||
| 1779 | LIST_HEAD_INIT(security_hook_heads.unix_may_send), | ||
| 1780 | .socket_create = | ||
| 1781 | LIST_HEAD_INIT(security_hook_heads.socket_create), | ||
| 1782 | .socket_post_create = | ||
| 1783 | LIST_HEAD_INIT(security_hook_heads.socket_post_create), | ||
| 1784 | .socket_bind = LIST_HEAD_INIT(security_hook_heads.socket_bind), | ||
| 1785 | .socket_connect = | ||
| 1786 | LIST_HEAD_INIT(security_hook_heads.socket_connect), | ||
| 1787 | .socket_listen = | ||
| 1788 | LIST_HEAD_INIT(security_hook_heads.socket_listen), | ||
| 1789 | .socket_accept = | ||
| 1790 | LIST_HEAD_INIT(security_hook_heads.socket_accept), | ||
| 1791 | .socket_sendmsg = | ||
| 1792 | LIST_HEAD_INIT(security_hook_heads.socket_sendmsg), | ||
| 1793 | .socket_recvmsg = | ||
| 1794 | LIST_HEAD_INIT(security_hook_heads.socket_recvmsg), | ||
| 1795 | .socket_getsockname = | ||
| 1796 | LIST_HEAD_INIT(security_hook_heads.socket_getsockname), | ||
| 1797 | .socket_getpeername = | ||
| 1798 | LIST_HEAD_INIT(security_hook_heads.socket_getpeername), | ||
| 1799 | .socket_getsockopt = | ||
| 1800 | LIST_HEAD_INIT(security_hook_heads.socket_getsockopt), | ||
| 1801 | .socket_setsockopt = | ||
| 1802 | LIST_HEAD_INIT(security_hook_heads.socket_setsockopt), | ||
| 1803 | .socket_shutdown = | ||
| 1804 | LIST_HEAD_INIT(security_hook_heads.socket_shutdown), | ||
| 1805 | .socket_sock_rcv_skb = | ||
| 1806 | LIST_HEAD_INIT(security_hook_heads.socket_sock_rcv_skb), | ||
| 1807 | .socket_getpeersec_stream = | ||
| 1808 | LIST_HEAD_INIT(security_hook_heads.socket_getpeersec_stream), | ||
| 1809 | .socket_getpeersec_dgram = | ||
| 1810 | LIST_HEAD_INIT(security_hook_heads.socket_getpeersec_dgram), | ||
| 1811 | .sk_alloc_security = | ||
| 1812 | LIST_HEAD_INIT(security_hook_heads.sk_alloc_security), | ||
| 1813 | .sk_free_security = | ||
| 1814 | LIST_HEAD_INIT(security_hook_heads.sk_free_security), | ||
| 1815 | .sk_clone_security = | ||
| 1816 | LIST_HEAD_INIT(security_hook_heads.sk_clone_security), | ||
| 1817 | .sk_getsecid = LIST_HEAD_INIT(security_hook_heads.sk_getsecid), | ||
| 1818 | .sock_graft = LIST_HEAD_INIT(security_hook_heads.sock_graft), | ||
| 1819 | .inet_conn_request = | ||
| 1820 | LIST_HEAD_INIT(security_hook_heads.inet_conn_request), | ||
| 1821 | .inet_csk_clone = | ||
| 1822 | LIST_HEAD_INIT(security_hook_heads.inet_csk_clone), | ||
| 1823 | .inet_conn_established = | ||
| 1824 | LIST_HEAD_INIT(security_hook_heads.inet_conn_established), | ||
| 1825 | .secmark_relabel_packet = | ||
| 1826 | LIST_HEAD_INIT(security_hook_heads.secmark_relabel_packet), | ||
| 1827 | .secmark_refcount_inc = | ||
| 1828 | LIST_HEAD_INIT(security_hook_heads.secmark_refcount_inc), | ||
| 1829 | .secmark_refcount_dec = | ||
| 1830 | LIST_HEAD_INIT(security_hook_heads.secmark_refcount_dec), | ||
| 1831 | .req_classify_flow = | ||
| 1832 | LIST_HEAD_INIT(security_hook_heads.req_classify_flow), | ||
| 1833 | .tun_dev_alloc_security = | ||
| 1834 | LIST_HEAD_INIT(security_hook_heads.tun_dev_alloc_security), | ||
| 1835 | .tun_dev_free_security = | ||
| 1836 | LIST_HEAD_INIT(security_hook_heads.tun_dev_free_security), | ||
| 1837 | .tun_dev_create = | ||
| 1838 | LIST_HEAD_INIT(security_hook_heads.tun_dev_create), | ||
| 1839 | .tun_dev_attach_queue = | ||
| 1840 | LIST_HEAD_INIT(security_hook_heads.tun_dev_attach_queue), | ||
| 1841 | .tun_dev_attach = | ||
| 1842 | LIST_HEAD_INIT(security_hook_heads.tun_dev_attach), | ||
| 1843 | .tun_dev_open = LIST_HEAD_INIT(security_hook_heads.tun_dev_open), | ||
| 1844 | .skb_owned_by = LIST_HEAD_INIT(security_hook_heads.skb_owned_by), | ||
| 1845 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
| 1846 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
| 1847 | .xfrm_policy_alloc_security = | ||
| 1848 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_alloc_security), | ||
| 1849 | .xfrm_policy_clone_security = | ||
| 1850 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_clone_security), | ||
| 1851 | .xfrm_policy_free_security = | ||
| 1852 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_free_security), | ||
| 1853 | .xfrm_policy_delete_security = | ||
| 1854 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_delete_security), | ||
| 1855 | .xfrm_state_alloc = | ||
| 1856 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_alloc), | ||
| 1857 | .xfrm_state_alloc_acquire = | ||
| 1858 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_alloc_acquire), | ||
| 1859 | .xfrm_state_free_security = | ||
| 1860 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_free_security), | ||
| 1861 | .xfrm_state_delete_security = | ||
| 1862 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_delete_security), | ||
| 1863 | .xfrm_policy_lookup = | ||
| 1864 | LIST_HEAD_INIT(security_hook_heads.xfrm_policy_lookup), | ||
| 1865 | .xfrm_state_pol_flow_match = | ||
| 1866 | LIST_HEAD_INIT(security_hook_heads.xfrm_state_pol_flow_match), | ||
| 1867 | .xfrm_decode_session = | ||
| 1868 | LIST_HEAD_INIT(security_hook_heads.xfrm_decode_session), | ||
| 1869 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
| 1870 | #ifdef CONFIG_KEYS | ||
| 1871 | .key_alloc = LIST_HEAD_INIT(security_hook_heads.key_alloc), | ||
| 1872 | .key_free = LIST_HEAD_INIT(security_hook_heads.key_free), | ||
| 1873 | .key_permission = | ||
| 1874 | LIST_HEAD_INIT(security_hook_heads.key_permission), | ||
| 1875 | .key_getsecurity = | ||
| 1876 | LIST_HEAD_INIT(security_hook_heads.key_getsecurity), | ||
| 1877 | #endif /* CONFIG_KEYS */ | ||
| 1878 | #ifdef CONFIG_AUDIT | ||
| 1879 | .audit_rule_init = | ||
| 1880 | LIST_HEAD_INIT(security_hook_heads.audit_rule_init), | ||
| 1881 | .audit_rule_known = | ||
| 1882 | LIST_HEAD_INIT(security_hook_heads.audit_rule_known), | ||
| 1883 | .audit_rule_match = | ||
| 1884 | LIST_HEAD_INIT(security_hook_heads.audit_rule_match), | ||
| 1885 | .audit_rule_free = | ||
| 1886 | LIST_HEAD_INIT(security_hook_heads.audit_rule_free), | ||
| 1510 | #endif /* CONFIG_AUDIT */ | 1887 | #endif /* CONFIG_AUDIT */ |
| 1888 | }; | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0cf105f346d4..06c9dd962c3c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -1990,12 +1990,6 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
| 1990 | static int selinux_ptrace_access_check(struct task_struct *child, | 1990 | static int selinux_ptrace_access_check(struct task_struct *child, |
| 1991 | unsigned int mode) | 1991 | unsigned int mode) |
| 1992 | { | 1992 | { |
| 1993 | int rc; | ||
| 1994 | |||
| 1995 | rc = cap_ptrace_access_check(child, mode); | ||
| 1996 | if (rc) | ||
| 1997 | return rc; | ||
| 1998 | |||
| 1999 | if (mode & PTRACE_MODE_READ) { | 1993 | if (mode & PTRACE_MODE_READ) { |
| 2000 | u32 sid = current_sid(); | 1994 | u32 sid = current_sid(); |
| 2001 | u32 csid = task_sid(child); | 1995 | u32 csid = task_sid(child); |
| @@ -2007,25 +2001,13 @@ static int selinux_ptrace_access_check(struct task_struct *child, | |||
| 2007 | 2001 | ||
| 2008 | static int selinux_ptrace_traceme(struct task_struct *parent) | 2002 | static int selinux_ptrace_traceme(struct task_struct *parent) |
| 2009 | { | 2003 | { |
| 2010 | int rc; | ||
| 2011 | |||
| 2012 | rc = cap_ptrace_traceme(parent); | ||
| 2013 | if (rc) | ||
| 2014 | return rc; | ||
| 2015 | |||
| 2016 | return task_has_perm(parent, current, PROCESS__PTRACE); | 2004 | return task_has_perm(parent, current, PROCESS__PTRACE); |
| 2017 | } | 2005 | } |
| 2018 | 2006 | ||
| 2019 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | 2007 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, |
| 2020 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 2008 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
| 2021 | { | 2009 | { |
| 2022 | int error; | 2010 | return current_has_perm(target, PROCESS__GETCAP); |
| 2023 | |||
| 2024 | error = current_has_perm(target, PROCESS__GETCAP); | ||
| 2025 | if (error) | ||
| 2026 | return error; | ||
| 2027 | |||
| 2028 | return cap_capget(target, effective, inheritable, permitted); | ||
| 2029 | } | 2011 | } |
| 2030 | 2012 | ||
| 2031 | static int selinux_capset(struct cred *new, const struct cred *old, | 2013 | static int selinux_capset(struct cred *new, const struct cred *old, |
| @@ -2033,13 +2015,6 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
| 2033 | const kernel_cap_t *inheritable, | 2015 | const kernel_cap_t *inheritable, |
| 2034 | const kernel_cap_t *permitted) | 2016 | const kernel_cap_t *permitted) |
| 2035 | { | 2017 | { |
| 2036 | int error; | ||
| 2037 | |||
| 2038 | error = cap_capset(new, old, | ||
| 2039 | effective, inheritable, permitted); | ||
| 2040 | if (error) | ||
| 2041 | return error; | ||
| 2042 | |||
| 2043 | return cred_has_perm(old, new, PROCESS__SETCAP); | 2018 | return cred_has_perm(old, new, PROCESS__SETCAP); |
| 2044 | } | 2019 | } |
| 2045 | 2020 | ||
| @@ -2056,12 +2031,6 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
| 2056 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, | 2031 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
| 2057 | int cap, int audit) | 2032 | int cap, int audit) |
| 2058 | { | 2033 | { |
| 2059 | int rc; | ||
| 2060 | |||
| 2061 | rc = cap_capable(cred, ns, cap, audit); | ||
| 2062 | if (rc) | ||
| 2063 | return rc; | ||
| 2064 | |||
| 2065 | return cred_has_capability(cred, cap, audit); | 2034 | return cred_has_capability(cred, cap, audit); |
| 2066 | } | 2035 | } |
| 2067 | 2036 | ||
| @@ -2139,12 +2108,12 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 2139 | { | 2108 | { |
| 2140 | int rc, cap_sys_admin = 0; | 2109 | int rc, cap_sys_admin = 0; |
| 2141 | 2110 | ||
| 2142 | rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, | 2111 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, |
| 2143 | SECURITY_CAP_NOAUDIT); | 2112 | SECURITY_CAP_NOAUDIT); |
| 2144 | if (rc == 0) | 2113 | if (rc == 0) |
| 2145 | cap_sys_admin = 1; | 2114 | cap_sys_admin = 1; |
| 2146 | 2115 | ||
| 2147 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 2116 | return cap_sys_admin; |
| 2148 | } | 2117 | } |
| 2149 | 2118 | ||
| 2150 | /* binprm security operations */ | 2119 | /* binprm security operations */ |
| @@ -2193,10 +2162,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
| 2193 | struct inode *inode = file_inode(bprm->file); | 2162 | struct inode *inode = file_inode(bprm->file); |
| 2194 | int rc; | 2163 | int rc; |
| 2195 | 2164 | ||
| 2196 | rc = cap_bprm_set_creds(bprm); | ||
| 2197 | if (rc) | ||
| 2198 | return rc; | ||
| 2199 | |||
| 2200 | /* SELinux context only depends on initial program or script and not | 2165 | /* SELinux context only depends on initial program or script and not |
| 2201 | * the script interpreter */ | 2166 | * the script interpreter */ |
| 2202 | if (bprm->cred_prepared) | 2167 | if (bprm->cred_prepared) |
| @@ -2320,7 +2285,7 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm) | |||
| 2320 | PROCESS__NOATSECURE, NULL); | 2285 | PROCESS__NOATSECURE, NULL); |
| 2321 | } | 2286 | } |
| 2322 | 2287 | ||
| 2323 | return (atsecure || cap_bprm_secureexec(bprm)); | 2288 | return !!atsecure; |
| 2324 | } | 2289 | } |
| 2325 | 2290 | ||
| 2326 | static int match_file(const void *p, struct file *file, unsigned fd) | 2291 | static int match_file(const void *p, struct file *file, unsigned fd) |
| @@ -3132,8 +3097,11 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
| 3132 | * and lack of permission just means that we fall back to the | 3097 | * and lack of permission just means that we fall back to the |
| 3133 | * in-core context value, not a denial. | 3098 | * in-core context value, not a denial. |
| 3134 | */ | 3099 | */ |
| 3135 | error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, | 3100 | error = cap_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, |
| 3136 | SECURITY_CAP_NOAUDIT); | 3101 | SECURITY_CAP_NOAUDIT); |
| 3102 | if (!error) | ||
| 3103 | error = cred_has_capability(current_cred(), CAP_MAC_ADMIN, | ||
| 3104 | SECURITY_CAP_NOAUDIT); | ||
| 3137 | if (!error) | 3105 | if (!error) |
| 3138 | error = security_sid_to_context_force(isec->sid, &context, | 3106 | error = security_sid_to_context_force(isec->sid, &context, |
| 3139 | &size); | 3107 | &size); |
| @@ -3318,12 +3286,7 @@ error: | |||
| 3318 | 3286 | ||
| 3319 | static int selinux_mmap_addr(unsigned long addr) | 3287 | static int selinux_mmap_addr(unsigned long addr) |
| 3320 | { | 3288 | { |
| 3321 | int rc; | 3289 | int rc = 0; |
| 3322 | |||
| 3323 | /* do DAC check on address space usage */ | ||
| 3324 | rc = cap_mmap_addr(addr); | ||
| 3325 | if (rc) | ||
| 3326 | return rc; | ||
| 3327 | 3290 | ||
| 3328 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { | 3291 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { |
| 3329 | u32 sid = current_sid(); | 3292 | u32 sid = current_sid(); |
| @@ -3639,23 +3602,11 @@ static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | |||
| 3639 | 3602 | ||
| 3640 | static int selinux_task_setnice(struct task_struct *p, int nice) | 3603 | static int selinux_task_setnice(struct task_struct *p, int nice) |
| 3641 | { | 3604 | { |
| 3642 | int rc; | ||
| 3643 | |||
| 3644 | rc = cap_task_setnice(p, nice); | ||
| 3645 | if (rc) | ||
| 3646 | return rc; | ||
| 3647 | |||
| 3648 | return current_has_perm(p, PROCESS__SETSCHED); | 3605 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3649 | } | 3606 | } |
| 3650 | 3607 | ||
| 3651 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | 3608 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) |
| 3652 | { | 3609 | { |
| 3653 | int rc; | ||
| 3654 | |||
| 3655 | rc = cap_task_setioprio(p, ioprio); | ||
| 3656 | if (rc) | ||
| 3657 | return rc; | ||
| 3658 | |||
| 3659 | return current_has_perm(p, PROCESS__SETSCHED); | 3610 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3660 | } | 3611 | } |
| 3661 | 3612 | ||
| @@ -3681,12 +3632,6 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, | |||
| 3681 | 3632 | ||
| 3682 | static int selinux_task_setscheduler(struct task_struct *p) | 3633 | static int selinux_task_setscheduler(struct task_struct *p) |
| 3683 | { | 3634 | { |
| 3684 | int rc; | ||
| 3685 | |||
| 3686 | rc = cap_task_setscheduler(p); | ||
| 3687 | if (rc) | ||
| 3688 | return rc; | ||
| 3689 | |||
| 3690 | return current_has_perm(p, PROCESS__SETSCHED); | 3635 | return current_has_perm(p, PROCESS__SETSCHED); |
| 3691 | } | 3636 | } |
| 3692 | 3637 | ||
| @@ -5097,12 +5042,6 @@ static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops, | |||
| 5097 | 5042 | ||
| 5098 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | 5043 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 5099 | { | 5044 | { |
| 5100 | int err; | ||
| 5101 | |||
| 5102 | err = cap_netlink_send(sk, skb); | ||
| 5103 | if (err) | ||
| 5104 | return err; | ||
| 5105 | |||
| 5106 | return selinux_nlmsg_perm(sk, skb); | 5045 | return selinux_nlmsg_perm(sk, skb); |
| 5107 | } | 5046 | } |
| 5108 | 5047 | ||
| @@ -5840,9 +5779,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) | |||
| 5840 | 5779 | ||
| 5841 | #endif | 5780 | #endif |
| 5842 | 5781 | ||
| 5843 | static struct security_operations selinux_ops = { | 5782 | static struct security_hook_list selinux_hooks[] = { |
| 5844 | LSM_HOOK_INIT(name, "selinux"), | ||
| 5845 | |||
| 5846 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), | 5783 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), |
| 5847 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), | 5784 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), |
| 5848 | LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder), | 5785 | LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder), |
| @@ -6055,7 +5992,7 @@ static struct security_operations selinux_ops = { | |||
| 6055 | 5992 | ||
| 6056 | static __init int selinux_init(void) | 5993 | static __init int selinux_init(void) |
| 6057 | { | 5994 | { |
| 6058 | if (!security_module_enable(&selinux_ops)) { | 5995 | if (!security_module_enable("selinux")) { |
| 6059 | selinux_enabled = 0; | 5996 | selinux_enabled = 0; |
| 6060 | return 0; | 5997 | return 0; |
| 6061 | } | 5998 | } |
| @@ -6077,8 +6014,7 @@ static __init int selinux_init(void) | |||
| 6077 | 0, SLAB_PANIC, NULL); | 6014 | 0, SLAB_PANIC, NULL); |
| 6078 | avc_init(); | 6015 | avc_init(); |
| 6079 | 6016 | ||
| 6080 | if (register_security(&selinux_ops)) | 6017 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); |
| 6081 | panic("SELinux: Unable to register with kernel.\n"); | ||
| 6082 | 6018 | ||
| 6083 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) | 6019 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) |
| 6084 | panic("SELinux: Unable to register AVC netcache callback\n"); | 6020 | panic("SELinux: Unable to register AVC netcache callback\n"); |
| @@ -6206,7 +6142,7 @@ int selinux_disable(void) | |||
| 6206 | selinux_disabled = 1; | 6142 | selinux_disabled = 1; |
| 6207 | selinux_enabled = 0; | 6143 | selinux_enabled = 0; |
| 6208 | 6144 | ||
| 6209 | reset_security_ops(); | 6145 | security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); |
| 6210 | 6146 | ||
| 6211 | /* Try to destroy the avc node cache */ | 6147 | /* Try to destroy the avc node cache */ |
| 6212 | avc_disable(); | 6148 | avc_disable(); |
diff --git a/security/smack/smack.h b/security/smack/smack.h index 262dad8dfbc6..b8c1a869d85e 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -276,8 +276,6 @@ extern struct mutex smack_known_lock; | |||
| 276 | extern struct list_head smack_known_list; | 276 | extern struct list_head smack_known_list; |
| 277 | extern struct list_head smk_netlbladdr_list; | 277 | extern struct list_head smk_netlbladdr_list; |
| 278 | 278 | ||
| 279 | extern struct security_operations smack_ops; | ||
| 280 | |||
| 281 | #define SMACK_HASH_SLOTS 16 | 279 | #define SMACK_HASH_SLOTS 16 |
| 282 | extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; | 280 | extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; |
| 283 | 281 | ||
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 4313bf44c3f0..5eae42c8d0d5 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -436,17 +436,11 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, | |||
| 436 | */ | 436 | */ |
| 437 | static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) | 437 | static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) |
| 438 | { | 438 | { |
| 439 | int rc; | ||
| 440 | struct smack_known *skp; | 439 | struct smack_known *skp; |
| 441 | 440 | ||
| 442 | rc = cap_ptrace_access_check(ctp, mode); | ||
| 443 | if (rc != 0) | ||
| 444 | return rc; | ||
| 445 | |||
| 446 | skp = smk_of_task_struct(ctp); | 441 | skp = smk_of_task_struct(ctp); |
| 447 | 442 | ||
| 448 | rc = smk_ptrace_rule_check(current, skp, mode, __func__); | 443 | return smk_ptrace_rule_check(current, skp, mode, __func__); |
| 449 | return rc; | ||
| 450 | } | 444 | } |
| 451 | 445 | ||
| 452 | /** | 446 | /** |
| @@ -462,10 +456,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp) | |||
| 462 | int rc; | 456 | int rc; |
| 463 | struct smack_known *skp; | 457 | struct smack_known *skp; |
| 464 | 458 | ||
| 465 | rc = cap_ptrace_traceme(ptp); | ||
| 466 | if (rc != 0) | ||
| 467 | return rc; | ||
| 468 | |||
| 469 | skp = smk_of_task(current_security()); | 459 | skp = smk_of_task(current_security()); |
| 470 | 460 | ||
| 471 | rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__); | 461 | rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__); |
| @@ -721,10 +711,6 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) | |||
| 721 | struct inode_smack *isp; | 711 | struct inode_smack *isp; |
| 722 | int rc; | 712 | int rc; |
| 723 | 713 | ||
| 724 | rc = cap_bprm_set_creds(bprm); | ||
| 725 | if (rc != 0) | ||
| 726 | return rc; | ||
| 727 | |||
| 728 | if (bprm->cred_prepared) | 714 | if (bprm->cred_prepared) |
| 729 | return 0; | 715 | return 0; |
| 730 | 716 | ||
| @@ -779,12 +765,11 @@ static void smack_bprm_committing_creds(struct linux_binprm *bprm) | |||
| 779 | static int smack_bprm_secureexec(struct linux_binprm *bprm) | 765 | static int smack_bprm_secureexec(struct linux_binprm *bprm) |
| 780 | { | 766 | { |
| 781 | struct task_smack *tsp = current_security(); | 767 | struct task_smack *tsp = current_security(); |
| 782 | int ret = cap_bprm_secureexec(bprm); | ||
| 783 | 768 | ||
| 784 | if (!ret && (tsp->smk_task != tsp->smk_forked)) | 769 | if (tsp->smk_task != tsp->smk_forked) |
| 785 | ret = 1; | 770 | return 1; |
| 786 | 771 | ||
| 787 | return ret; | 772 | return 0; |
| 788 | } | 773 | } |
| 789 | 774 | ||
| 790 | /* | 775 | /* |
| @@ -1934,12 +1919,7 @@ static void smack_task_getsecid(struct task_struct *p, u32 *secid) | |||
| 1934 | */ | 1919 | */ |
| 1935 | static int smack_task_setnice(struct task_struct *p, int nice) | 1920 | static int smack_task_setnice(struct task_struct *p, int nice) |
| 1936 | { | 1921 | { |
| 1937 | int rc; | 1922 | return smk_curacc_on_task(p, MAY_WRITE, __func__); |
| 1938 | |||
| 1939 | rc = cap_task_setnice(p, nice); | ||
| 1940 | if (rc == 0) | ||
| 1941 | rc = smk_curacc_on_task(p, MAY_WRITE, __func__); | ||
| 1942 | return rc; | ||
| 1943 | } | 1923 | } |
| 1944 | 1924 | ||
| 1945 | /** | 1925 | /** |
| @@ -1951,12 +1931,7 @@ static int smack_task_setnice(struct task_struct *p, int nice) | |||
| 1951 | */ | 1931 | */ |
| 1952 | static int smack_task_setioprio(struct task_struct *p, int ioprio) | 1932 | static int smack_task_setioprio(struct task_struct *p, int ioprio) |
| 1953 | { | 1933 | { |
| 1954 | int rc; | 1934 | return smk_curacc_on_task(p, MAY_WRITE, __func__); |
| 1955 | |||
| 1956 | rc = cap_task_setioprio(p, ioprio); | ||
| 1957 | if (rc == 0) | ||
| 1958 | rc = smk_curacc_on_task(p, MAY_WRITE, __func__); | ||
| 1959 | return rc; | ||
| 1960 | } | 1935 | } |
| 1961 | 1936 | ||
| 1962 | /** | 1937 | /** |
| @@ -1980,12 +1955,7 @@ static int smack_task_getioprio(struct task_struct *p) | |||
| 1980 | */ | 1955 | */ |
| 1981 | static int smack_task_setscheduler(struct task_struct *p) | 1956 | static int smack_task_setscheduler(struct task_struct *p) |
| 1982 | { | 1957 | { |
| 1983 | int rc; | 1958 | return smk_curacc_on_task(p, MAY_WRITE, __func__); |
| 1984 | |||
| 1985 | rc = cap_task_setscheduler(p); | ||
| 1986 | if (rc == 0) | ||
| 1987 | rc = smk_curacc_on_task(p, MAY_WRITE, __func__); | ||
| 1988 | return rc; | ||
| 1989 | } | 1959 | } |
| 1990 | 1960 | ||
| 1991 | /** | 1961 | /** |
| @@ -4266,9 +4236,7 @@ static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) | |||
| 4266 | return 0; | 4236 | return 0; |
| 4267 | } | 4237 | } |
| 4268 | 4238 | ||
| 4269 | struct security_operations smack_ops = { | 4239 | struct security_hook_list smack_hooks[] = { |
| 4270 | LSM_HOOK_INIT(name, "smack"), | ||
| 4271 | |||
| 4272 | LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), | 4240 | LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), |
| 4273 | LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), | 4241 | LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), |
| 4274 | LSM_HOOK_INIT(syslog, smack_syslog), | 4242 | LSM_HOOK_INIT(syslog, smack_syslog), |
| @@ -4451,7 +4419,7 @@ static __init int smack_init(void) | |||
| 4451 | struct cred *cred; | 4419 | struct cred *cred; |
| 4452 | struct task_smack *tsp; | 4420 | struct task_smack *tsp; |
| 4453 | 4421 | ||
| 4454 | if (!security_module_enable(&smack_ops)) | 4422 | if (!security_module_enable("smack")) |
| 4455 | return 0; | 4423 | return 0; |
| 4456 | 4424 | ||
| 4457 | smack_enabled = 1; | 4425 | smack_enabled = 1; |
| @@ -4481,8 +4449,7 @@ static __init int smack_init(void) | |||
| 4481 | /* | 4449 | /* |
| 4482 | * Register with LSM | 4450 | * Register with LSM |
| 4483 | */ | 4451 | */ |
| 4484 | if (register_security(&smack_ops)) | 4452 | security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks)); |
| 4485 | panic("smack: Unable to register with kernel.\n"); | ||
| 4486 | 4453 | ||
| 4487 | return 0; | 4454 | return 0; |
| 4488 | } | 4455 | } |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index d9682985349e..4aa12c8d3c63 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -2547,7 +2547,7 @@ static int __init init_smk_fs(void) | |||
| 2547 | int err; | 2547 | int err; |
| 2548 | int rc; | 2548 | int rc; |
| 2549 | 2549 | ||
| 2550 | if (!security_module_enable(&smack_ops)) | 2550 | if (!security_module_enable("smack")) |
| 2551 | return 0; | 2551 | return 0; |
| 2552 | 2552 | ||
| 2553 | err = smk_init_sysfs(); | 2553 | err = smk_init_sysfs(); |
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index bce13583efda..cbf3df422c87 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c | |||
| @@ -72,12 +72,6 @@ static void tomoyo_cred_free(struct cred *cred) | |||
| 72 | */ | 72 | */ |
| 73 | static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) | 73 | static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) |
| 74 | { | 74 | { |
| 75 | int rc; | ||
| 76 | |||
| 77 | rc = cap_bprm_set_creds(bprm); | ||
| 78 | if (rc) | ||
| 79 | return rc; | ||
| 80 | |||
| 81 | /* | 75 | /* |
| 82 | * Do only if this function is called for the first time of an execve | 76 | * Do only if this function is called for the first time of an execve |
| 83 | * operation. | 77 | * operation. |
| @@ -502,8 +496,7 @@ static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
| 502 | * tomoyo_security_ops is a "struct security_operations" which is used for | 496 | * tomoyo_security_ops is a "struct security_operations" which is used for |
| 503 | * registering TOMOYO. | 497 | * registering TOMOYO. |
| 504 | */ | 498 | */ |
| 505 | static struct security_operations tomoyo_security_ops = { | 499 | static struct security_hook_list tomoyo_hooks[] = { |
| 506 | LSM_HOOK_INIT(name, "tomoyo"), | ||
| 507 | LSM_HOOK_INIT(cred_alloc_blank, tomoyo_cred_alloc_blank), | 500 | LSM_HOOK_INIT(cred_alloc_blank, tomoyo_cred_alloc_blank), |
| 508 | LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare), | 501 | LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare), |
| 509 | LSM_HOOK_INIT(cred_transfer, tomoyo_cred_transfer), | 502 | LSM_HOOK_INIT(cred_transfer, tomoyo_cred_transfer), |
| @@ -546,11 +539,10 @@ static int __init tomoyo_init(void) | |||
| 546 | { | 539 | { |
| 547 | struct cred *cred = (struct cred *) current_cred(); | 540 | struct cred *cred = (struct cred *) current_cred(); |
| 548 | 541 | ||
| 549 | if (!security_module_enable(&tomoyo_security_ops)) | 542 | if (!security_module_enable("tomoyo")) |
| 550 | return 0; | 543 | return 0; |
| 551 | /* register ourselves with the security framework */ | 544 | /* register ourselves with the security framework */ |
| 552 | if (register_security(&tomoyo_security_ops)) | 545 | security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks)); |
| 553 | panic("Failure registering TOMOYO Linux"); | ||
| 554 | printk(KERN_INFO "TOMOYO Linux initialized\n"); | 546 | printk(KERN_INFO "TOMOYO Linux initialized\n"); |
| 555 | cred->security = &tomoyo_kernel_domain; | 547 | cred->security = &tomoyo_kernel_domain; |
| 556 | tomoyo_mm_init(); | 548 | tomoyo_mm_init(); |
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 23dd4c6246b2..9ed32502470e 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c | |||
| @@ -154,13 +154,9 @@ void yama_task_free(struct task_struct *task) | |||
| 154 | int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 154 | int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
| 155 | unsigned long arg4, unsigned long arg5) | 155 | unsigned long arg4, unsigned long arg5) |
| 156 | { | 156 | { |
| 157 | int rc; | 157 | int rc = -ENOSYS; |
| 158 | struct task_struct *myself = current; | 158 | struct task_struct *myself = current; |
| 159 | 159 | ||
| 160 | rc = cap_task_prctl(option, arg2, arg3, arg4, arg5); | ||
| 161 | if (rc != -ENOSYS) | ||
| 162 | return rc; | ||
| 163 | |||
| 164 | switch (option) { | 160 | switch (option) { |
| 165 | case PR_SET_PTRACER: | 161 | case PR_SET_PTRACER: |
| 166 | /* Since a thread can call prctl(), find the group leader | 162 | /* Since a thread can call prctl(), find the group leader |
| @@ -279,17 +275,10 @@ static int ptracer_exception_found(struct task_struct *tracer, | |||
| 279 | * | 275 | * |
| 280 | * Returns 0 if following the ptrace is allowed, -ve on error. | 276 | * Returns 0 if following the ptrace is allowed, -ve on error. |
| 281 | */ | 277 | */ |
| 282 | int yama_ptrace_access_check(struct task_struct *child, | 278 | static int yama_ptrace_access_check(struct task_struct *child, |
| 283 | unsigned int mode) | 279 | unsigned int mode) |
| 284 | { | 280 | { |
| 285 | int rc; | 281 | int rc = 0; |
| 286 | |||
| 287 | /* If standard caps disallows it, so does Yama. We should | ||
| 288 | * only tighten restrictions further. | ||
| 289 | */ | ||
| 290 | rc = cap_ptrace_access_check(child, mode); | ||
| 291 | if (rc) | ||
| 292 | return rc; | ||
| 293 | 282 | ||
| 294 | /* require ptrace target be a child of ptracer on attach */ | 283 | /* require ptrace target be a child of ptracer on attach */ |
| 295 | if (mode == PTRACE_MODE_ATTACH) { | 284 | if (mode == PTRACE_MODE_ATTACH) { |
| @@ -335,14 +324,7 @@ int yama_ptrace_access_check(struct task_struct *child, | |||
| 335 | */ | 324 | */ |
| 336 | int yama_ptrace_traceme(struct task_struct *parent) | 325 | int yama_ptrace_traceme(struct task_struct *parent) |
| 337 | { | 326 | { |
| 338 | int rc; | 327 | int rc = 0; |
| 339 | |||
| 340 | /* If standard caps disallows it, so does Yama. We should | ||
| 341 | * only tighten restrictions further. | ||
| 342 | */ | ||
| 343 | rc = cap_ptrace_traceme(parent); | ||
| 344 | if (rc) | ||
| 345 | return rc; | ||
| 346 | 328 | ||
| 347 | /* Only disallow PTRACE_TRACEME on more aggressive settings. */ | 329 | /* Only disallow PTRACE_TRACEME on more aggressive settings. */ |
| 348 | switch (ptrace_scope) { | 330 | switch (ptrace_scope) { |
| @@ -364,16 +346,17 @@ int yama_ptrace_traceme(struct task_struct *parent) | |||
| 364 | return rc; | 346 | return rc; |
| 365 | } | 347 | } |
| 366 | 348 | ||
| 367 | #ifndef CONFIG_SECURITY_YAMA_STACKED | 349 | static struct security_hook_list yama_hooks[] = { |
| 368 | static struct security_operations yama_ops = { | ||
| 369 | LSM_HOOK_INIT(name, "yama"), | ||
| 370 | |||
| 371 | LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), | 350 | LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), |
| 372 | LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), | 351 | LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), |
| 373 | LSM_HOOK_INIT(task_prctl, yama_task_prctl), | 352 | LSM_HOOK_INIT(task_prctl, yama_task_prctl), |
| 374 | LSM_HOOK_INIT(task_free, yama_task_free), | 353 | LSM_HOOK_INIT(task_free, yama_task_free), |
| 375 | }; | 354 | }; |
| 376 | #endif | 355 | |
| 356 | void __init yama_add_hooks(void) | ||
| 357 | { | ||
| 358 | security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks)); | ||
| 359 | } | ||
| 377 | 360 | ||
| 378 | #ifdef CONFIG_SYSCTL | 361 | #ifdef CONFIG_SYSCTL |
| 379 | static int yama_dointvec_minmax(struct ctl_table *table, int write, | 362 | static int yama_dointvec_minmax(struct ctl_table *table, int write, |
| @@ -418,16 +401,13 @@ static struct ctl_table yama_sysctl_table[] = { | |||
| 418 | static __init int yama_init(void) | 401 | static __init int yama_init(void) |
| 419 | { | 402 | { |
| 420 | #ifndef CONFIG_SECURITY_YAMA_STACKED | 403 | #ifndef CONFIG_SECURITY_YAMA_STACKED |
| 421 | if (!security_module_enable(&yama_ops)) | 404 | /* |
| 405 | * If yama is being stacked this is already taken care of. | ||
| 406 | */ | ||
| 407 | if (!security_module_enable("yama")) | ||
| 422 | return 0; | 408 | return 0; |
| 423 | #endif | 409 | #endif |
| 424 | 410 | pr_info("Yama: becoming mindful.\n"); | |
| 425 | printk(KERN_INFO "Yama: becoming mindful.\n"); | ||
| 426 | |||
| 427 | #ifndef CONFIG_SECURITY_YAMA_STACKED | ||
| 428 | if (register_security(&yama_ops)) | ||
| 429 | panic("Yama: kernel registration failed.\n"); | ||
| 430 | #endif | ||
| 431 | 411 | ||
| 432 | #ifdef CONFIG_SYSCTL | 412 | #ifdef CONFIG_SYSCTL |
| 433 | if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) | 413 | if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) |
