diff options
Diffstat (limited to 'security/selinux')
| -rw-r--r-- | security/selinux/Kconfig | 15 | ||||
| -rw-r--r-- | security/selinux/Makefile | 2 | ||||
| -rw-r--r-- | security/selinux/avc.c | 199 | ||||
| -rw-r--r-- | security/selinux/exports.c | 23 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 420 | ||||
| -rw-r--r-- | security/selinux/include/audit.h | 7 | ||||
| -rw-r--r-- | security/selinux/include/avc.h | 6 | ||||
| -rw-r--r-- | security/selinux/include/objsec.h | 38 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 3 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 4 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 41 | ||||
| -rw-r--r-- | security/selinux/xfrm.c | 4 |
12 files changed, 314 insertions, 448 deletions
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index 8af7a690eb40..55f032f1fc2d 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig | |||
| @@ -22,21 +22,6 @@ config SECURITY_SELINUX_BOOTPARAM | |||
| 22 | 22 | ||
| 23 | If you are unsure how to answer this question, answer N. | 23 | If you are unsure how to answer this question, answer N. |
| 24 | 24 | ||
| 25 | config SECURITY_SELINUX_BOOTPARAM_VALUE | ||
| 26 | int "NSA SELinux boot parameter default value" | ||
| 27 | depends on SECURITY_SELINUX_BOOTPARAM | ||
| 28 | range 0 1 | ||
| 29 | default 1 | ||
| 30 | help | ||
| 31 | This option sets the default value for the kernel parameter | ||
| 32 | 'selinux', which allows SELinux to be disabled at boot. If this | ||
| 33 | option is set to 0 (zero), the SELinux kernel parameter will | ||
| 34 | default to 0, disabling SELinux at bootup. If this option is | ||
| 35 | set to 1 (one), the SELinux kernel parameter will default to 1, | ||
| 36 | enabling SELinux at bootup. | ||
| 37 | |||
| 38 | If you are unsure how to answer this question, answer 1. | ||
| 39 | |||
| 40 | config SECURITY_SELINUX_DISABLE | 25 | config SECURITY_SELINUX_DISABLE |
| 41 | bool "NSA SELinux runtime disable" | 26 | bool "NSA SELinux runtime disable" |
| 42 | depends on SECURITY_SELINUX | 27 | depends on SECURITY_SELINUX |
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index c7161f8792b2..ccf950409384 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o | 6 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o |
| 7 | 7 | ||
| 8 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ | 8 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ |
| 9 | netnode.o netport.o ibpkey.o exports.o \ | 9 | netnode.o netport.o ibpkey.o \ |
| 10 | ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \ | 10 | ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \ |
| 11 | ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o | 11 | ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o |
| 12 | 12 | ||
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 635e5c1e3e48..8346a4f7c5d7 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -130,75 +130,6 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) | |||
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | /** | 132 | /** |
| 133 | * avc_dump_av - Display an access vector in human-readable form. | ||
| 134 | * @tclass: target security class | ||
| 135 | * @av: access vector | ||
| 136 | */ | ||
| 137 | static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av) | ||
| 138 | { | ||
| 139 | const char **perms; | ||
| 140 | int i, perm; | ||
| 141 | |||
| 142 | if (av == 0) { | ||
| 143 | audit_log_format(ab, " null"); | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | |||
| 147 | BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map)); | ||
| 148 | perms = secclass_map[tclass-1].perms; | ||
| 149 | |||
| 150 | audit_log_format(ab, " {"); | ||
| 151 | i = 0; | ||
| 152 | perm = 1; | ||
| 153 | while (i < (sizeof(av) * 8)) { | ||
| 154 | if ((perm & av) && perms[i]) { | ||
| 155 | audit_log_format(ab, " %s", perms[i]); | ||
| 156 | av &= ~perm; | ||
| 157 | } | ||
| 158 | i++; | ||
| 159 | perm <<= 1; | ||
| 160 | } | ||
| 161 | |||
| 162 | if (av) | ||
| 163 | audit_log_format(ab, " 0x%x", av); | ||
| 164 | |||
| 165 | audit_log_format(ab, " }"); | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * avc_dump_query - Display a SID pair and a class in human-readable form. | ||
| 170 | * @ssid: source security identifier | ||
| 171 | * @tsid: target security identifier | ||
| 172 | * @tclass: target security class | ||
| 173 | */ | ||
| 174 | static void avc_dump_query(struct audit_buffer *ab, struct selinux_state *state, | ||
| 175 | u32 ssid, u32 tsid, u16 tclass) | ||
| 176 | { | ||
| 177 | int rc; | ||
| 178 | char *scontext; | ||
| 179 | u32 scontext_len; | ||
| 180 | |||
| 181 | rc = security_sid_to_context(state, ssid, &scontext, &scontext_len); | ||
| 182 | if (rc) | ||
| 183 | audit_log_format(ab, "ssid=%d", ssid); | ||
| 184 | else { | ||
| 185 | audit_log_format(ab, "scontext=%s", scontext); | ||
| 186 | kfree(scontext); | ||
| 187 | } | ||
| 188 | |||
| 189 | rc = security_sid_to_context(state, tsid, &scontext, &scontext_len); | ||
| 190 | if (rc) | ||
| 191 | audit_log_format(ab, " tsid=%d", tsid); | ||
| 192 | else { | ||
| 193 | audit_log_format(ab, " tcontext=%s", scontext); | ||
| 194 | kfree(scontext); | ||
| 195 | } | ||
| 196 | |||
| 197 | BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map)); | ||
| 198 | audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name); | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * avc_init - Initialize the AVC. | 133 | * avc_init - Initialize the AVC. |
| 203 | * | 134 | * |
| 204 | * Initialize the access vector cache. | 135 | * Initialize the access vector cache. |
| @@ -735,11 +666,36 @@ out: | |||
| 735 | static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) | 666 | static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) |
| 736 | { | 667 | { |
| 737 | struct common_audit_data *ad = a; | 668 | struct common_audit_data *ad = a; |
| 738 | audit_log_format(ab, "avc: %s ", | 669 | struct selinux_audit_data *sad = ad->selinux_audit_data; |
| 739 | ad->selinux_audit_data->denied ? "denied" : "granted"); | 670 | u32 av = sad->audited; |
| 740 | avc_dump_av(ab, ad->selinux_audit_data->tclass, | 671 | const char **perms; |
| 741 | ad->selinux_audit_data->audited); | 672 | int i, perm; |
| 742 | audit_log_format(ab, " for "); | 673 | |
| 674 | audit_log_format(ab, "avc: %s ", sad->denied ? "denied" : "granted"); | ||
| 675 | |||
| 676 | if (av == 0) { | ||
| 677 | audit_log_format(ab, " null"); | ||
| 678 | return; | ||
| 679 | } | ||
| 680 | |||
| 681 | perms = secclass_map[sad->tclass-1].perms; | ||
| 682 | |||
| 683 | audit_log_format(ab, " {"); | ||
| 684 | i = 0; | ||
| 685 | perm = 1; | ||
| 686 | while (i < (sizeof(av) * 8)) { | ||
| 687 | if ((perm & av) && perms[i]) { | ||
| 688 | audit_log_format(ab, " %s", perms[i]); | ||
| 689 | av &= ~perm; | ||
| 690 | } | ||
| 691 | i++; | ||
| 692 | perm <<= 1; | ||
| 693 | } | ||
| 694 | |||
| 695 | if (av) | ||
| 696 | audit_log_format(ab, " 0x%x", av); | ||
| 697 | |||
| 698 | audit_log_format(ab, " } for "); | ||
| 743 | } | 699 | } |
| 744 | 700 | ||
| 745 | /** | 701 | /** |
| @@ -751,14 +707,47 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) | |||
| 751 | static void avc_audit_post_callback(struct audit_buffer *ab, void *a) | 707 | static void avc_audit_post_callback(struct audit_buffer *ab, void *a) |
| 752 | { | 708 | { |
| 753 | struct common_audit_data *ad = a; | 709 | struct common_audit_data *ad = a; |
| 754 | audit_log_format(ab, " "); | 710 | struct selinux_audit_data *sad = ad->selinux_audit_data; |
| 755 | avc_dump_query(ab, ad->selinux_audit_data->state, | 711 | char *scontext; |
| 756 | ad->selinux_audit_data->ssid, | 712 | u32 scontext_len; |
| 757 | ad->selinux_audit_data->tsid, | 713 | int rc; |
| 758 | ad->selinux_audit_data->tclass); | 714 | |
| 759 | if (ad->selinux_audit_data->denied) { | 715 | rc = security_sid_to_context(sad->state, sad->ssid, &scontext, |
| 760 | audit_log_format(ab, " permissive=%u", | 716 | &scontext_len); |
| 761 | ad->selinux_audit_data->result ? 0 : 1); | 717 | if (rc) |
| 718 | audit_log_format(ab, " ssid=%d", sad->ssid); | ||
| 719 | else { | ||
| 720 | audit_log_format(ab, " scontext=%s", scontext); | ||
| 721 | kfree(scontext); | ||
| 722 | } | ||
| 723 | |||
| 724 | rc = security_sid_to_context(sad->state, sad->tsid, &scontext, | ||
| 725 | &scontext_len); | ||
| 726 | if (rc) | ||
| 727 | audit_log_format(ab, " tsid=%d", sad->tsid); | ||
| 728 | else { | ||
| 729 | audit_log_format(ab, " tcontext=%s", scontext); | ||
| 730 | kfree(scontext); | ||
| 731 | } | ||
| 732 | |||
| 733 | audit_log_format(ab, " tclass=%s", secclass_map[sad->tclass-1].name); | ||
| 734 | |||
| 735 | if (sad->denied) | ||
| 736 | audit_log_format(ab, " permissive=%u", sad->result ? 0 : 1); | ||
| 737 | |||
| 738 | /* in case of invalid context report also the actual context string */ | ||
| 739 | rc = security_sid_to_context_inval(sad->state, sad->ssid, &scontext, | ||
| 740 | &scontext_len); | ||
| 741 | if (!rc && scontext) { | ||
| 742 | audit_log_format(ab, " srawcon=%s", scontext); | ||
| 743 | kfree(scontext); | ||
| 744 | } | ||
| 745 | |||
| 746 | rc = security_sid_to_context_inval(sad->state, sad->tsid, &scontext, | ||
| 747 | &scontext_len); | ||
| 748 | if (!rc && scontext) { | ||
| 749 | audit_log_format(ab, " trawcon=%s", scontext); | ||
| 750 | kfree(scontext); | ||
| 762 | } | 751 | } |
| 763 | } | 752 | } |
| 764 | 753 | ||
| @@ -772,6 +761,9 @@ noinline int slow_avc_audit(struct selinux_state *state, | |||
| 772 | struct common_audit_data stack_data; | 761 | struct common_audit_data stack_data; |
| 773 | struct selinux_audit_data sad; | 762 | struct selinux_audit_data sad; |
| 774 | 763 | ||
| 764 | if (WARN_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map))) | ||
| 765 | return -EINVAL; | ||
| 766 | |||
| 775 | if (!a) { | 767 | if (!a) { |
| 776 | a = &stack_data; | 768 | a = &stack_data; |
| 777 | a->type = LSM_AUDIT_DATA_NONE; | 769 | a->type = LSM_AUDIT_DATA_NONE; |
| @@ -838,6 +830,7 @@ out: | |||
| 838 | * @ssid,@tsid,@tclass : identifier of an AVC entry | 830 | * @ssid,@tsid,@tclass : identifier of an AVC entry |
| 839 | * @seqno : sequence number when decision was made | 831 | * @seqno : sequence number when decision was made |
| 840 | * @xpd: extended_perms_decision to be added to the node | 832 | * @xpd: extended_perms_decision to be added to the node |
| 833 | * @flags: the AVC_* flags, e.g. AVC_NONBLOCKING, AVC_EXTENDED_PERMS, or 0. | ||
| 841 | * | 834 | * |
| 842 | * if a valid AVC entry doesn't exist,this function returns -ENOENT. | 835 | * if a valid AVC entry doesn't exist,this function returns -ENOENT. |
| 843 | * if kmalloc() called internal returns NULL, this function returns -ENOMEM. | 836 | * if kmalloc() called internal returns NULL, this function returns -ENOMEM. |
| @@ -856,6 +849,22 @@ static int avc_update_node(struct selinux_avc *avc, | |||
| 856 | struct hlist_head *head; | 849 | struct hlist_head *head; |
| 857 | spinlock_t *lock; | 850 | spinlock_t *lock; |
| 858 | 851 | ||
| 852 | /* | ||
| 853 | * If we are in a non-blocking code path, e.g. VFS RCU walk, | ||
| 854 | * then we must not add permissions to a cache entry | ||
| 855 | * because we cannot safely audit the denial. Otherwise, | ||
| 856 | * during the subsequent blocking retry (e.g. VFS ref walk), we | ||
| 857 | * will find the permissions already granted in the cache entry | ||
| 858 | * and won't audit anything at all, leading to silent denials in | ||
| 859 | * permissive mode that only appear when in enforcing mode. | ||
| 860 | * | ||
| 861 | * See the corresponding handling in slow_avc_audit(), and the | ||
| 862 | * logic in selinux_inode_permission for the MAY_NOT_BLOCK flag, | ||
| 863 | * which is transliterated into AVC_NONBLOCKING. | ||
| 864 | */ | ||
| 865 | if (flags & AVC_NONBLOCKING) | ||
| 866 | return 0; | ||
| 867 | |||
| 859 | node = avc_alloc_node(avc); | 868 | node = avc_alloc_node(avc); |
| 860 | if (!node) { | 869 | if (!node) { |
| 861 | rc = -ENOMEM; | 870 | rc = -ENOMEM; |
| @@ -1050,7 +1059,8 @@ int avc_has_extended_perms(struct selinux_state *state, | |||
| 1050 | int rc = 0, rc2; | 1059 | int rc = 0, rc2; |
| 1051 | 1060 | ||
| 1052 | xp_node = &local_xp_node; | 1061 | xp_node = &local_xp_node; |
| 1053 | BUG_ON(!requested); | 1062 | if (WARN_ON(!requested)) |
| 1063 | return -EACCES; | ||
| 1054 | 1064 | ||
| 1055 | rcu_read_lock(); | 1065 | rcu_read_lock(); |
| 1056 | 1066 | ||
| @@ -1115,7 +1125,7 @@ decision: | |||
| 1115 | * @tsid: target security identifier | 1125 | * @tsid: target security identifier |
| 1116 | * @tclass: target security class | 1126 | * @tclass: target security class |
| 1117 | * @requested: requested permissions, interpreted based on @tclass | 1127 | * @requested: requested permissions, interpreted based on @tclass |
| 1118 | * @flags: AVC_STRICT or 0 | 1128 | * @flags: AVC_STRICT, AVC_NONBLOCKING, or 0 |
| 1119 | * @avd: access vector decisions | 1129 | * @avd: access vector decisions |
| 1120 | * | 1130 | * |
| 1121 | * Check the AVC to determine whether the @requested permissions are granted | 1131 | * Check the AVC to determine whether the @requested permissions are granted |
| @@ -1140,7 +1150,8 @@ inline int avc_has_perm_noaudit(struct selinux_state *state, | |||
| 1140 | int rc = 0; | 1150 | int rc = 0; |
| 1141 | u32 denied; | 1151 | u32 denied; |
| 1142 | 1152 | ||
| 1143 | BUG_ON(!requested); | 1153 | if (WARN_ON(!requested)) |
| 1154 | return -EACCES; | ||
| 1144 | 1155 | ||
| 1145 | rcu_read_lock(); | 1156 | rcu_read_lock(); |
| 1146 | 1157 | ||
| @@ -1191,24 +1202,6 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, | |||
| 1191 | return rc; | 1202 | return rc; |
| 1192 | } | 1203 | } |
| 1193 | 1204 | ||
| 1194 | int avc_has_perm_flags(struct selinux_state *state, | ||
| 1195 | u32 ssid, u32 tsid, u16 tclass, u32 requested, | ||
| 1196 | struct common_audit_data *auditdata, | ||
| 1197 | int flags) | ||
| 1198 | { | ||
| 1199 | struct av_decision avd; | ||
| 1200 | int rc, rc2; | ||
| 1201 | |||
| 1202 | rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0, | ||
| 1203 | &avd); | ||
| 1204 | |||
| 1205 | rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, | ||
| 1206 | auditdata, flags); | ||
| 1207 | if (rc2) | ||
| 1208 | return rc2; | ||
| 1209 | return rc; | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | u32 avc_policy_seqno(struct selinux_state *state) | 1205 | u32 avc_policy_seqno(struct selinux_state *state) |
| 1213 | { | 1206 | { |
| 1214 | return state->avc->avc_cache.latest_notif; | 1207 | return state->avc->avc_cache.latest_notif; |
diff --git a/security/selinux/exports.c b/security/selinux/exports.c deleted file mode 100644 index e75dd94e2d2b..000000000000 --- a/security/selinux/exports.c +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * SELinux services exported to the rest of the kernel. | ||
| 3 | * | ||
| 4 | * Author: James Morris <jmorris@redhat.com> | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> | ||
| 7 | * Copyright (C) 2006 Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | ||
| 8 | * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez <tinytim@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2, | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/selinux.h> | ||
| 16 | |||
| 17 | #include "security.h" | ||
| 18 | |||
| 19 | bool selinux_is_enabled(void) | ||
| 20 | { | ||
| 21 | return selinux_enabled; | ||
| 22 | } | ||
| 23 | EXPORT_SYMBOL_GPL(selinux_is_enabled); | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f0e36c3492ba..2f82a54f8703 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -79,7 +79,6 @@ | |||
| 79 | #include <linux/personality.h> | 79 | #include <linux/personality.h> |
| 80 | #include <linux/audit.h> | 80 | #include <linux/audit.h> |
| 81 | #include <linux/string.h> | 81 | #include <linux/string.h> |
| 82 | #include <linux/selinux.h> | ||
| 83 | #include <linux/mutex.h> | 82 | #include <linux/mutex.h> |
| 84 | #include <linux/posix-timers.h> | 83 | #include <linux/posix-timers.h> |
| 85 | #include <linux/syslog.h> | 84 | #include <linux/syslog.h> |
| @@ -121,9 +120,8 @@ __setup("enforcing=", enforcing_setup); | |||
| 121 | #define selinux_enforcing_boot 1 | 120 | #define selinux_enforcing_boot 1 |
| 122 | #endif | 121 | #endif |
| 123 | 122 | ||
| 123 | int selinux_enabled __lsm_ro_after_init = 1; | ||
| 124 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM | 124 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM |
| 125 | int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE; | ||
| 126 | |||
| 127 | static int __init selinux_enabled_setup(char *str) | 125 | static int __init selinux_enabled_setup(char *str) |
| 128 | { | 126 | { |
| 129 | unsigned long enabled; | 127 | unsigned long enabled; |
| @@ -132,8 +130,6 @@ static int __init selinux_enabled_setup(char *str) | |||
| 132 | return 1; | 130 | return 1; |
| 133 | } | 131 | } |
| 134 | __setup("selinux=", selinux_enabled_setup); | 132 | __setup("selinux=", selinux_enabled_setup); |
| 135 | #else | ||
| 136 | int selinux_enabled = 1; | ||
| 137 | #endif | 133 | #endif |
| 138 | 134 | ||
| 139 | static unsigned int selinux_checkreqprot_boot = | 135 | static unsigned int selinux_checkreqprot_boot = |
| @@ -149,9 +145,6 @@ static int __init checkreqprot_setup(char *str) | |||
| 149 | } | 145 | } |
| 150 | __setup("checkreqprot=", checkreqprot_setup); | 146 | __setup("checkreqprot=", checkreqprot_setup); |
| 151 | 147 | ||
| 152 | static struct kmem_cache *sel_inode_cache; | ||
| 153 | static struct kmem_cache *file_security_cache; | ||
| 154 | |||
| 155 | /** | 148 | /** |
| 156 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled | 149 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled |
| 157 | * | 150 | * |
| @@ -214,12 +207,8 @@ static void cred_init_security(void) | |||
| 214 | struct cred *cred = (struct cred *) current->real_cred; | 207 | struct cred *cred = (struct cred *) current->real_cred; |
| 215 | struct task_security_struct *tsec; | 208 | struct task_security_struct *tsec; |
| 216 | 209 | ||
| 217 | tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); | 210 | tsec = selinux_cred(cred); |
| 218 | if (!tsec) | ||
| 219 | panic("SELinux: Failed to initialize initial task.\n"); | ||
| 220 | |||
| 221 | tsec->osid = tsec->sid = SECINITSID_KERNEL; | 211 | tsec->osid = tsec->sid = SECINITSID_KERNEL; |
| 222 | cred->security = tsec; | ||
| 223 | } | 212 | } |
| 224 | 213 | ||
| 225 | /* | 214 | /* |
| @@ -229,7 +218,7 @@ static inline u32 cred_sid(const struct cred *cred) | |||
| 229 | { | 218 | { |
| 230 | const struct task_security_struct *tsec; | 219 | const struct task_security_struct *tsec; |
| 231 | 220 | ||
| 232 | tsec = cred->security; | 221 | tsec = selinux_cred(cred); |
| 233 | return tsec->sid; | 222 | return tsec->sid; |
| 234 | } | 223 | } |
| 235 | 224 | ||
| @@ -250,13 +239,9 @@ static inline u32 task_sid(const struct task_struct *task) | |||
| 250 | 239 | ||
| 251 | static int inode_alloc_security(struct inode *inode) | 240 | static int inode_alloc_security(struct inode *inode) |
| 252 | { | 241 | { |
| 253 | struct inode_security_struct *isec; | 242 | struct inode_security_struct *isec = selinux_inode(inode); |
| 254 | u32 sid = current_sid(); | 243 | u32 sid = current_sid(); |
| 255 | 244 | ||
| 256 | isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS); | ||
| 257 | if (!isec) | ||
| 258 | return -ENOMEM; | ||
| 259 | |||
| 260 | spin_lock_init(&isec->lock); | 245 | spin_lock_init(&isec->lock); |
| 261 | INIT_LIST_HEAD(&isec->list); | 246 | INIT_LIST_HEAD(&isec->list); |
| 262 | isec->inode = inode; | 247 | isec->inode = inode; |
| @@ -264,7 +249,6 @@ static int inode_alloc_security(struct inode *inode) | |||
| 264 | isec->sclass = SECCLASS_FILE; | 249 | isec->sclass = SECCLASS_FILE; |
| 265 | isec->task_sid = sid; | 250 | isec->task_sid = sid; |
| 266 | isec->initialized = LABEL_INVALID; | 251 | isec->initialized = LABEL_INVALID; |
| 267 | inode->i_security = isec; | ||
| 268 | 252 | ||
| 269 | return 0; | 253 | return 0; |
| 270 | } | 254 | } |
| @@ -281,7 +265,7 @@ static int __inode_security_revalidate(struct inode *inode, | |||
| 281 | struct dentry *dentry, | 265 | struct dentry *dentry, |
| 282 | bool may_sleep) | 266 | bool may_sleep) |
| 283 | { | 267 | { |
| 284 | struct inode_security_struct *isec = inode->i_security; | 268 | struct inode_security_struct *isec = selinux_inode(inode); |
| 285 | 269 | ||
| 286 | might_sleep_if(may_sleep); | 270 | might_sleep_if(may_sleep); |
| 287 | 271 | ||
| @@ -302,7 +286,7 @@ static int __inode_security_revalidate(struct inode *inode, | |||
| 302 | 286 | ||
| 303 | static struct inode_security_struct *inode_security_novalidate(struct inode *inode) | 287 | static struct inode_security_struct *inode_security_novalidate(struct inode *inode) |
| 304 | { | 288 | { |
| 305 | return inode->i_security; | 289 | return selinux_inode(inode); |
| 306 | } | 290 | } |
| 307 | 291 | ||
| 308 | static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) | 292 | static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) |
| @@ -312,7 +296,7 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo | |||
| 312 | error = __inode_security_revalidate(inode, NULL, !rcu); | 296 | error = __inode_security_revalidate(inode, NULL, !rcu); |
| 313 | if (error) | 297 | if (error) |
| 314 | return ERR_PTR(error); | 298 | return ERR_PTR(error); |
| 315 | return inode->i_security; | 299 | return selinux_inode(inode); |
| 316 | } | 300 | } |
| 317 | 301 | ||
| 318 | /* | 302 | /* |
| @@ -321,14 +305,14 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo | |||
| 321 | static struct inode_security_struct *inode_security(struct inode *inode) | 305 | static struct inode_security_struct *inode_security(struct inode *inode) |
| 322 | { | 306 | { |
| 323 | __inode_security_revalidate(inode, NULL, true); | 307 | __inode_security_revalidate(inode, NULL, true); |
| 324 | return inode->i_security; | 308 | return selinux_inode(inode); |
| 325 | } | 309 | } |
| 326 | 310 | ||
| 327 | static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) | 311 | static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) |
| 328 | { | 312 | { |
| 329 | struct inode *inode = d_backing_inode(dentry); | 313 | struct inode *inode = d_backing_inode(dentry); |
| 330 | 314 | ||
| 331 | return inode->i_security; | 315 | return selinux_inode(inode); |
| 332 | } | 316 | } |
| 333 | 317 | ||
| 334 | /* | 318 | /* |
| @@ -339,22 +323,17 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr | |||
| 339 | struct inode *inode = d_backing_inode(dentry); | 323 | struct inode *inode = d_backing_inode(dentry); |
| 340 | 324 | ||
| 341 | __inode_security_revalidate(inode, dentry, true); | 325 | __inode_security_revalidate(inode, dentry, true); |
| 342 | return inode->i_security; | 326 | return selinux_inode(inode); |
| 343 | } | ||
| 344 | |||
| 345 | static void inode_free_rcu(struct rcu_head *head) | ||
| 346 | { | ||
| 347 | struct inode_security_struct *isec; | ||
| 348 | |||
| 349 | isec = container_of(head, struct inode_security_struct, rcu); | ||
| 350 | kmem_cache_free(sel_inode_cache, isec); | ||
| 351 | } | 327 | } |
| 352 | 328 | ||
| 353 | static void inode_free_security(struct inode *inode) | 329 | static void inode_free_security(struct inode *inode) |
| 354 | { | 330 | { |
| 355 | struct inode_security_struct *isec = inode->i_security; | 331 | struct inode_security_struct *isec = selinux_inode(inode); |
| 356 | struct superblock_security_struct *sbsec = inode->i_sb->s_security; | 332 | struct superblock_security_struct *sbsec; |
| 357 | 333 | ||
| 334 | if (!isec) | ||
| 335 | return; | ||
| 336 | sbsec = inode->i_sb->s_security; | ||
| 358 | /* | 337 | /* |
| 359 | * As not all inode security structures are in a list, we check for | 338 | * As not all inode security structures are in a list, we check for |
| 360 | * empty list outside of the lock to make sure that we won't waste | 339 | * empty list outside of the lock to make sure that we won't waste |
| @@ -370,42 +349,19 @@ static void inode_free_security(struct inode *inode) | |||
| 370 | list_del_init(&isec->list); | 349 | list_del_init(&isec->list); |
| 371 | spin_unlock(&sbsec->isec_lock); | 350 | spin_unlock(&sbsec->isec_lock); |
| 372 | } | 351 | } |
| 373 | |||
| 374 | /* | ||
| 375 | * The inode may still be referenced in a path walk and | ||
| 376 | * a call to selinux_inode_permission() can be made | ||
| 377 | * after inode_free_security() is called. Ideally, the VFS | ||
| 378 | * wouldn't do this, but fixing that is a much harder | ||
| 379 | * job. For now, simply free the i_security via RCU, and | ||
| 380 | * leave the current inode->i_security pointer intact. | ||
| 381 | * The inode will be freed after the RCU grace period too. | ||
| 382 | */ | ||
| 383 | call_rcu(&isec->rcu, inode_free_rcu); | ||
| 384 | } | 352 | } |
| 385 | 353 | ||
| 386 | static int file_alloc_security(struct file *file) | 354 | static int file_alloc_security(struct file *file) |
| 387 | { | 355 | { |
| 388 | struct file_security_struct *fsec; | 356 | struct file_security_struct *fsec = selinux_file(file); |
| 389 | u32 sid = current_sid(); | 357 | u32 sid = current_sid(); |
| 390 | 358 | ||
| 391 | fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL); | ||
| 392 | if (!fsec) | ||
| 393 | return -ENOMEM; | ||
| 394 | |||
| 395 | fsec->sid = sid; | 359 | fsec->sid = sid; |
| 396 | fsec->fown_sid = sid; | 360 | fsec->fown_sid = sid; |
| 397 | file->f_security = fsec; | ||
| 398 | 361 | ||
| 399 | return 0; | 362 | return 0; |
| 400 | } | 363 | } |
| 401 | 364 | ||
| 402 | static void file_free_security(struct file *file) | ||
| 403 | { | ||
| 404 | struct file_security_struct *fsec = file->f_security; | ||
| 405 | file->f_security = NULL; | ||
| 406 | kmem_cache_free(file_security_cache, fsec); | ||
| 407 | } | ||
| 408 | |||
| 409 | static int superblock_alloc_security(struct super_block *sb) | 365 | static int superblock_alloc_security(struct super_block *sb) |
| 410 | { | 366 | { |
| 411 | struct superblock_security_struct *sbsec; | 367 | struct superblock_security_struct *sbsec; |
| @@ -501,7 +457,7 @@ static int may_context_mount_sb_relabel(u32 sid, | |||
| 501 | struct superblock_security_struct *sbsec, | 457 | struct superblock_security_struct *sbsec, |
| 502 | const struct cred *cred) | 458 | const struct cred *cred) |
| 503 | { | 459 | { |
| 504 | const struct task_security_struct *tsec = cred->security; | 460 | const struct task_security_struct *tsec = selinux_cred(cred); |
| 505 | int rc; | 461 | int rc; |
| 506 | 462 | ||
| 507 | rc = avc_has_perm(&selinux_state, | 463 | rc = avc_has_perm(&selinux_state, |
| @@ -520,7 +476,7 @@ static int may_context_mount_inode_relabel(u32 sid, | |||
| 520 | struct superblock_security_struct *sbsec, | 476 | struct superblock_security_struct *sbsec, |
| 521 | const struct cred *cred) | 477 | const struct cred *cred) |
| 522 | { | 478 | { |
| 523 | const struct task_security_struct *tsec = cred->security; | 479 | const struct task_security_struct *tsec = selinux_cred(cred); |
| 524 | int rc; | 480 | int rc; |
| 525 | rc = avc_has_perm(&selinux_state, | 481 | rc = avc_has_perm(&selinux_state, |
| 526 | tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, | 482 | tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, |
| @@ -534,16 +490,10 @@ static int may_context_mount_inode_relabel(u32 sid, | |||
| 534 | return rc; | 490 | return rc; |
| 535 | } | 491 | } |
| 536 | 492 | ||
| 537 | static int selinux_is_sblabel_mnt(struct super_block *sb) | 493 | static int selinux_is_genfs_special_handling(struct super_block *sb) |
| 538 | { | 494 | { |
| 539 | struct superblock_security_struct *sbsec = sb->s_security; | 495 | /* Special handling. Genfs but also in-core setxattr handler */ |
| 540 | 496 | return !strcmp(sb->s_type->name, "sysfs") || | |
| 541 | return sbsec->behavior == SECURITY_FS_USE_XATTR || | ||
| 542 | sbsec->behavior == SECURITY_FS_USE_TRANS || | ||
| 543 | sbsec->behavior == SECURITY_FS_USE_TASK || | ||
| 544 | sbsec->behavior == SECURITY_FS_USE_NATIVE || | ||
| 545 | /* Special handling. Genfs but also in-core setxattr handler */ | ||
| 546 | !strcmp(sb->s_type->name, "sysfs") || | ||
| 547 | !strcmp(sb->s_type->name, "pstore") || | 497 | !strcmp(sb->s_type->name, "pstore") || |
| 548 | !strcmp(sb->s_type->name, "debugfs") || | 498 | !strcmp(sb->s_type->name, "debugfs") || |
| 549 | !strcmp(sb->s_type->name, "tracefs") || | 499 | !strcmp(sb->s_type->name, "tracefs") || |
| @@ -553,6 +503,34 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) | |||
| 553 | !strcmp(sb->s_type->name, "cgroup2"))); | 503 | !strcmp(sb->s_type->name, "cgroup2"))); |
| 554 | } | 504 | } |
| 555 | 505 | ||
| 506 | static int selinux_is_sblabel_mnt(struct super_block *sb) | ||
| 507 | { | ||
| 508 | struct superblock_security_struct *sbsec = sb->s_security; | ||
| 509 | |||
| 510 | /* | ||
| 511 | * IMPORTANT: Double-check logic in this function when adding a new | ||
| 512 | * SECURITY_FS_USE_* definition! | ||
| 513 | */ | ||
| 514 | BUILD_BUG_ON(SECURITY_FS_USE_MAX != 7); | ||
| 515 | |||
| 516 | switch (sbsec->behavior) { | ||
| 517 | case SECURITY_FS_USE_XATTR: | ||
| 518 | case SECURITY_FS_USE_TRANS: | ||
| 519 | case SECURITY_FS_USE_TASK: | ||
| 520 | case SECURITY_FS_USE_NATIVE: | ||
| 521 | return 1; | ||
| 522 | |||
| 523 | case SECURITY_FS_USE_GENFS: | ||
| 524 | return selinux_is_genfs_special_handling(sb); | ||
| 525 | |||
| 526 | /* Never allow relabeling on context mounts */ | ||
| 527 | case SECURITY_FS_USE_MNTPOINT: | ||
| 528 | case SECURITY_FS_USE_NONE: | ||
| 529 | default: | ||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 556 | static int sb_finish_set_opts(struct super_block *sb) | 534 | static int sb_finish_set_opts(struct super_block *sb) |
| 557 | { | 535 | { |
| 558 | struct superblock_security_struct *sbsec = sb->s_security; | 536 | struct superblock_security_struct *sbsec = sb->s_security; |
| @@ -1374,7 +1352,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry, | |||
| 1374 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) | 1352 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) |
| 1375 | { | 1353 | { |
| 1376 | struct superblock_security_struct *sbsec = NULL; | 1354 | struct superblock_security_struct *sbsec = NULL; |
| 1377 | struct inode_security_struct *isec = inode->i_security; | 1355 | struct inode_security_struct *isec = selinux_inode(inode); |
| 1378 | u32 task_sid, sid = 0; | 1356 | u32 task_sid, sid = 0; |
| 1379 | u16 sclass; | 1357 | u16 sclass; |
| 1380 | struct dentry *dentry; | 1358 | struct dentry *dentry; |
| @@ -1621,7 +1599,7 @@ static inline u32 signal_to_av(int sig) | |||
| 1621 | 1599 | ||
| 1622 | /* Check whether a task is allowed to use a capability. */ | 1600 | /* Check whether a task is allowed to use a capability. */ |
| 1623 | static int cred_has_capability(const struct cred *cred, | 1601 | static int cred_has_capability(const struct cred *cred, |
| 1624 | int cap, int audit, bool initns) | 1602 | int cap, unsigned int opts, bool initns) |
| 1625 | { | 1603 | { |
| 1626 | struct common_audit_data ad; | 1604 | struct common_audit_data ad; |
| 1627 | struct av_decision avd; | 1605 | struct av_decision avd; |
| @@ -1648,7 +1626,7 @@ static int cred_has_capability(const struct cred *cred, | |||
| 1648 | 1626 | ||
| 1649 | rc = avc_has_perm_noaudit(&selinux_state, | 1627 | rc = avc_has_perm_noaudit(&selinux_state, |
| 1650 | sid, sid, sclass, av, 0, &avd); | 1628 | sid, sid, sclass, av, 0, &avd); |
| 1651 | if (audit == SECURITY_CAP_AUDIT) { | 1629 | if (!(opts & CAP_OPT_NOAUDIT)) { |
| 1652 | int rc2 = avc_audit(&selinux_state, | 1630 | int rc2 = avc_audit(&selinux_state, |
| 1653 | sid, sid, sclass, av, &avd, rc, &ad, 0); | 1631 | sid, sid, sclass, av, &avd, rc, &ad, 0); |
| 1654 | if (rc2) | 1632 | if (rc2) |
| @@ -1674,7 +1652,7 @@ static int inode_has_perm(const struct cred *cred, | |||
| 1674 | return 0; | 1652 | return 0; |
| 1675 | 1653 | ||
| 1676 | sid = cred_sid(cred); | 1654 | sid = cred_sid(cred); |
| 1677 | isec = inode->i_security; | 1655 | isec = selinux_inode(inode); |
| 1678 | 1656 | ||
| 1679 | return avc_has_perm(&selinux_state, | 1657 | return avc_has_perm(&selinux_state, |
| 1680 | sid, isec->sid, isec->sclass, perms, adp); | 1658 | sid, isec->sid, isec->sclass, perms, adp); |
| @@ -1740,7 +1718,7 @@ static int file_has_perm(const struct cred *cred, | |||
| 1740 | struct file *file, | 1718 | struct file *file, |
| 1741 | u32 av) | 1719 | u32 av) |
| 1742 | { | 1720 | { |
| 1743 | struct file_security_struct *fsec = file->f_security; | 1721 | struct file_security_struct *fsec = selinux_file(file); |
| 1744 | struct inode *inode = file_inode(file); | 1722 | struct inode *inode = file_inode(file); |
| 1745 | struct common_audit_data ad; | 1723 | struct common_audit_data ad; |
| 1746 | u32 sid = cred_sid(cred); | 1724 | u32 sid = cred_sid(cred); |
| @@ -1806,7 +1784,7 @@ static int may_create(struct inode *dir, | |||
| 1806 | struct dentry *dentry, | 1784 | struct dentry *dentry, |
| 1807 | u16 tclass) | 1785 | u16 tclass) |
| 1808 | { | 1786 | { |
| 1809 | const struct task_security_struct *tsec = current_security(); | 1787 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
| 1810 | struct inode_security_struct *dsec; | 1788 | struct inode_security_struct *dsec; |
| 1811 | struct superblock_security_struct *sbsec; | 1789 | struct superblock_security_struct *sbsec; |
| 1812 | u32 sid, newsid; | 1790 | u32 sid, newsid; |
| @@ -1828,7 +1806,7 @@ static int may_create(struct inode *dir, | |||
| 1828 | if (rc) | 1806 | if (rc) |
| 1829 | return rc; | 1807 | return rc; |
| 1830 | 1808 | ||
| 1831 | rc = selinux_determine_inode_label(current_security(), dir, | 1809 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir, |
| 1832 | &dentry->d_name, tclass, &newsid); | 1810 | &dentry->d_name, tclass, &newsid); |
| 1833 | if (rc) | 1811 | if (rc) |
| 1834 | return rc; | 1812 | return rc; |
| @@ -2084,7 +2062,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
| 2084 | struct file *file) | 2062 | struct file *file) |
| 2085 | { | 2063 | { |
| 2086 | u32 sid = task_sid(to); | 2064 | u32 sid = task_sid(to); |
| 2087 | struct file_security_struct *fsec = file->f_security; | 2065 | struct file_security_struct *fsec = selinux_file(file); |
| 2088 | struct dentry *dentry = file->f_path.dentry; | 2066 | struct dentry *dentry = file->f_path.dentry; |
| 2089 | struct inode_security_struct *isec; | 2067 | struct inode_security_struct *isec; |
| 2090 | struct common_audit_data ad; | 2068 | struct common_audit_data ad; |
| @@ -2168,9 +2146,9 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
| 2168 | */ | 2146 | */ |
| 2169 | 2147 | ||
| 2170 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, | 2148 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
| 2171 | int cap, int audit) | 2149 | int cap, unsigned int opts) |
| 2172 | { | 2150 | { |
| 2173 | return cred_has_capability(cred, cap, audit, ns == &init_user_ns); | 2151 | return cred_has_capability(cred, cap, opts, ns == &init_user_ns); |
| 2174 | } | 2152 | } |
| 2175 | 2153 | ||
| 2176 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 2154 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
| @@ -2244,7 +2222,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 2244 | int rc, cap_sys_admin = 0; | 2222 | int rc, cap_sys_admin = 0; |
| 2245 | 2223 | ||
| 2246 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, | 2224 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, |
| 2247 | SECURITY_CAP_NOAUDIT, true); | 2225 | CAP_OPT_NOAUDIT, true); |
| 2248 | if (rc == 0) | 2226 | if (rc == 0) |
| 2249 | cap_sys_admin = 1; | 2227 | cap_sys_admin = 1; |
| 2250 | 2228 | ||
| @@ -2335,8 +2313,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
| 2335 | if (bprm->called_set_creds) | 2313 | if (bprm->called_set_creds) |
| 2336 | return 0; | 2314 | return 0; |
| 2337 | 2315 | ||
| 2338 | old_tsec = current_security(); | 2316 | old_tsec = selinux_cred(current_cred()); |
| 2339 | new_tsec = bprm->cred->security; | 2317 | new_tsec = selinux_cred(bprm->cred); |
| 2340 | isec = inode_security(inode); | 2318 | isec = inode_security(inode); |
| 2341 | 2319 | ||
| 2342 | /* Default to the current task SID. */ | 2320 | /* Default to the current task SID. */ |
| @@ -2500,7 +2478,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) | |||
| 2500 | struct rlimit *rlim, *initrlim; | 2478 | struct rlimit *rlim, *initrlim; |
| 2501 | int rc, i; | 2479 | int rc, i; |
| 2502 | 2480 | ||
| 2503 | new_tsec = bprm->cred->security; | 2481 | new_tsec = selinux_cred(bprm->cred); |
| 2504 | if (new_tsec->sid == new_tsec->osid) | 2482 | if (new_tsec->sid == new_tsec->osid) |
| 2505 | return; | 2483 | return; |
| 2506 | 2484 | ||
| @@ -2543,7 +2521,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) | |||
| 2543 | */ | 2521 | */ |
| 2544 | static void selinux_bprm_committed_creds(struct linux_binprm *bprm) | 2522 | static void selinux_bprm_committed_creds(struct linux_binprm *bprm) |
| 2545 | { | 2523 | { |
| 2546 | const struct task_security_struct *tsec = current_security(); | 2524 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
| 2547 | struct itimerval itimer; | 2525 | struct itimerval itimer; |
| 2548 | u32 osid, sid; | 2526 | u32 osid, sid; |
| 2549 | int rc, i; | 2527 | int rc, i; |
| @@ -2780,7 +2758,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, | |||
| 2780 | u32 newsid; | 2758 | u32 newsid; |
| 2781 | int rc; | 2759 | int rc; |
| 2782 | 2760 | ||
| 2783 | rc = selinux_determine_inode_label(current_security(), | 2761 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), |
| 2784 | d_inode(dentry->d_parent), name, | 2762 | d_inode(dentry->d_parent), name, |
| 2785 | inode_mode_to_security_class(mode), | 2763 | inode_mode_to_security_class(mode), |
| 2786 | &newsid); | 2764 | &newsid); |
| @@ -2800,14 +2778,14 @@ static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, | |||
| 2800 | int rc; | 2778 | int rc; |
| 2801 | struct task_security_struct *tsec; | 2779 | struct task_security_struct *tsec; |
| 2802 | 2780 | ||
| 2803 | rc = selinux_determine_inode_label(old->security, | 2781 | rc = selinux_determine_inode_label(selinux_cred(old), |
| 2804 | d_inode(dentry->d_parent), name, | 2782 | d_inode(dentry->d_parent), name, |
| 2805 | inode_mode_to_security_class(mode), | 2783 | inode_mode_to_security_class(mode), |
| 2806 | &newsid); | 2784 | &newsid); |
| 2807 | if (rc) | 2785 | if (rc) |
| 2808 | return rc; | 2786 | return rc; |
| 2809 | 2787 | ||
| 2810 | tsec = new->security; | 2788 | tsec = selinux_cred(new); |
| 2811 | tsec->create_sid = newsid; | 2789 | tsec->create_sid = newsid; |
| 2812 | return 0; | 2790 | return 0; |
| 2813 | } | 2791 | } |
| @@ -2817,7 +2795,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 2817 | const char **name, | 2795 | const char **name, |
| 2818 | void **value, size_t *len) | 2796 | void **value, size_t *len) |
| 2819 | { | 2797 | { |
| 2820 | const struct task_security_struct *tsec = current_security(); | 2798 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
| 2821 | struct superblock_security_struct *sbsec; | 2799 | struct superblock_security_struct *sbsec; |
| 2822 | u32 newsid, clen; | 2800 | u32 newsid, clen; |
| 2823 | int rc; | 2801 | int rc; |
| @@ -2827,7 +2805,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 2827 | 2805 | ||
| 2828 | newsid = tsec->create_sid; | 2806 | newsid = tsec->create_sid; |
| 2829 | 2807 | ||
| 2830 | rc = selinux_determine_inode_label(current_security(), | 2808 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), |
| 2831 | dir, qstr, | 2809 | dir, qstr, |
| 2832 | inode_mode_to_security_class(inode->i_mode), | 2810 | inode_mode_to_security_class(inode->i_mode), |
| 2833 | &newsid); | 2811 | &newsid); |
| @@ -2836,7 +2814,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 2836 | 2814 | ||
| 2837 | /* Possibly defer initialization to selinux_complete_init. */ | 2815 | /* Possibly defer initialization to selinux_complete_init. */ |
| 2838 | if (sbsec->flags & SE_SBINITIALIZED) { | 2816 | if (sbsec->flags & SE_SBINITIALIZED) { |
| 2839 | struct inode_security_struct *isec = inode->i_security; | 2817 | struct inode_security_struct *isec = selinux_inode(inode); |
| 2840 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 2818 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
| 2841 | isec->sid = newsid; | 2819 | isec->sid = newsid; |
| 2842 | isec->initialized = LABEL_INITIALIZED; | 2820 | isec->initialized = LABEL_INITIALIZED; |
| @@ -2925,9 +2903,8 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, | |||
| 2925 | if (IS_ERR(isec)) | 2903 | if (IS_ERR(isec)) |
| 2926 | return PTR_ERR(isec); | 2904 | return PTR_ERR(isec); |
| 2927 | 2905 | ||
| 2928 | return avc_has_perm_flags(&selinux_state, | 2906 | return avc_has_perm(&selinux_state, |
| 2929 | sid, isec->sid, isec->sclass, FILE__READ, &ad, | 2907 | sid, isec->sid, isec->sclass, FILE__READ, &ad); |
| 2930 | rcu ? MAY_NOT_BLOCK : 0); | ||
| 2931 | } | 2908 | } |
| 2932 | 2909 | ||
| 2933 | static noinline int audit_inode_permission(struct inode *inode, | 2910 | static noinline int audit_inode_permission(struct inode *inode, |
| @@ -2936,7 +2913,7 @@ static noinline int audit_inode_permission(struct inode *inode, | |||
| 2936 | unsigned flags) | 2913 | unsigned flags) |
| 2937 | { | 2914 | { |
| 2938 | struct common_audit_data ad; | 2915 | struct common_audit_data ad; |
| 2939 | struct inode_security_struct *isec = inode->i_security; | 2916 | struct inode_security_struct *isec = selinux_inode(inode); |
| 2940 | int rc; | 2917 | int rc; |
| 2941 | 2918 | ||
| 2942 | ad.type = LSM_AUDIT_DATA_INODE; | 2919 | ad.type = LSM_AUDIT_DATA_INODE; |
| @@ -2982,7 +2959,9 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
| 2982 | return PTR_ERR(isec); | 2959 | return PTR_ERR(isec); |
| 2983 | 2960 | ||
| 2984 | rc = avc_has_perm_noaudit(&selinux_state, | 2961 | rc = avc_has_perm_noaudit(&selinux_state, |
| 2985 | sid, isec->sid, isec->sclass, perms, 0, &avd); | 2962 | sid, isec->sid, isec->sclass, perms, |
| 2963 | (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0, | ||
| 2964 | &avd); | ||
| 2986 | audited = avc_audit_required(perms, &avd, rc, | 2965 | audited = avc_audit_required(perms, &avd, rc, |
| 2987 | from_access ? FILE__AUDIT_ACCESS : 0, | 2966 | from_access ? FILE__AUDIT_ACCESS : 0, |
| 2988 | &denied); | 2967 | &denied); |
| @@ -3031,11 +3010,11 @@ static int selinux_inode_getattr(const struct path *path) | |||
| 3031 | static bool has_cap_mac_admin(bool audit) | 3010 | static bool has_cap_mac_admin(bool audit) |
| 3032 | { | 3011 | { |
| 3033 | const struct cred *cred = current_cred(); | 3012 | const struct cred *cred = current_cred(); |
| 3034 | int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT; | 3013 | unsigned int opts = audit ? CAP_OPT_NONE : CAP_OPT_NOAUDIT; |
| 3035 | 3014 | ||
| 3036 | if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit)) | 3015 | if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, opts)) |
| 3037 | return false; | 3016 | return false; |
| 3038 | if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true)) | 3017 | if (cred_has_capability(cred, CAP_MAC_ADMIN, opts, true)) |
| 3039 | return false; | 3018 | return false; |
| 3040 | return true; | 3019 | return true; |
| 3041 | } | 3020 | } |
| @@ -3241,12 +3220,16 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
| 3241 | const void *value, size_t size, int flags) | 3220 | const void *value, size_t size, int flags) |
| 3242 | { | 3221 | { |
| 3243 | struct inode_security_struct *isec = inode_security_novalidate(inode); | 3222 | struct inode_security_struct *isec = inode_security_novalidate(inode); |
| 3223 | struct superblock_security_struct *sbsec = inode->i_sb->s_security; | ||
| 3244 | u32 newsid; | 3224 | u32 newsid; |
| 3245 | int rc; | 3225 | int rc; |
| 3246 | 3226 | ||
| 3247 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 3227 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) |
| 3248 | return -EOPNOTSUPP; | 3228 | return -EOPNOTSUPP; |
| 3249 | 3229 | ||
| 3230 | if (!(sbsec->flags & SBLABEL_MNT)) | ||
| 3231 | return -EOPNOTSUPP; | ||
| 3232 | |||
| 3250 | if (!value || !size) | 3233 | if (!value || !size) |
| 3251 | return -EACCES; | 3234 | return -EACCES; |
| 3252 | 3235 | ||
| @@ -3289,7 +3272,7 @@ static int selinux_inode_copy_up(struct dentry *src, struct cred **new) | |||
| 3289 | return -ENOMEM; | 3272 | return -ENOMEM; |
| 3290 | } | 3273 | } |
| 3291 | 3274 | ||
| 3292 | tsec = new_creds->security; | 3275 | tsec = selinux_cred(new_creds); |
| 3293 | /* Get label from overlay inode and set it in create_sid */ | 3276 | /* Get label from overlay inode and set it in create_sid */ |
| 3294 | selinux_inode_getsecid(d_inode(src), &sid); | 3277 | selinux_inode_getsecid(d_inode(src), &sid); |
| 3295 | tsec->create_sid = sid; | 3278 | tsec->create_sid = sid; |
| @@ -3330,7 +3313,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
| 3330 | static int selinux_file_permission(struct file *file, int mask) | 3313 | static int selinux_file_permission(struct file *file, int mask) |
| 3331 | { | 3314 | { |
| 3332 | struct inode *inode = file_inode(file); | 3315 | struct inode *inode = file_inode(file); |
| 3333 | struct file_security_struct *fsec = file->f_security; | 3316 | struct file_security_struct *fsec = selinux_file(file); |
| 3334 | struct inode_security_struct *isec; | 3317 | struct inode_security_struct *isec; |
| 3335 | u32 sid = current_sid(); | 3318 | u32 sid = current_sid(); |
| 3336 | 3319 | ||
| @@ -3352,11 +3335,6 @@ static int selinux_file_alloc_security(struct file *file) | |||
| 3352 | return file_alloc_security(file); | 3335 | return file_alloc_security(file); |
| 3353 | } | 3336 | } |
| 3354 | 3337 | ||
| 3355 | static void selinux_file_free_security(struct file *file) | ||
| 3356 | { | ||
| 3357 | file_free_security(file); | ||
| 3358 | } | ||
| 3359 | |||
| 3360 | /* | 3338 | /* |
| 3361 | * Check whether a task has the ioctl permission and cmd | 3339 | * Check whether a task has the ioctl permission and cmd |
| 3362 | * operation to an inode. | 3340 | * operation to an inode. |
| @@ -3365,7 +3343,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, | |||
| 3365 | u32 requested, u16 cmd) | 3343 | u32 requested, u16 cmd) |
| 3366 | { | 3344 | { |
| 3367 | struct common_audit_data ad; | 3345 | struct common_audit_data ad; |
| 3368 | struct file_security_struct *fsec = file->f_security; | 3346 | struct file_security_struct *fsec = selinux_file(file); |
| 3369 | struct inode *inode = file_inode(file); | 3347 | struct inode *inode = file_inode(file); |
| 3370 | struct inode_security_struct *isec; | 3348 | struct inode_security_struct *isec; |
| 3371 | struct lsm_ioctlop_audit ioctl; | 3349 | struct lsm_ioctlop_audit ioctl; |
| @@ -3435,7 +3413,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
| 3435 | case KDSKBENT: | 3413 | case KDSKBENT: |
| 3436 | case KDSKBSENT: | 3414 | case KDSKBSENT: |
| 3437 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, | 3415 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, |
| 3438 | SECURITY_CAP_AUDIT, true); | 3416 | CAP_OPT_NONE, true); |
| 3439 | break; | 3417 | break; |
| 3440 | 3418 | ||
| 3441 | /* default case assumes that the command will go | 3419 | /* default case assumes that the command will go |
| @@ -3617,7 +3595,7 @@ static void selinux_file_set_fowner(struct file *file) | |||
| 3617 | { | 3595 | { |
| 3618 | struct file_security_struct *fsec; | 3596 | struct file_security_struct *fsec; |
| 3619 | 3597 | ||
| 3620 | fsec = file->f_security; | 3598 | fsec = selinux_file(file); |
| 3621 | fsec->fown_sid = current_sid(); | 3599 | fsec->fown_sid = current_sid(); |
| 3622 | } | 3600 | } |
| 3623 | 3601 | ||
| @@ -3632,7 +3610,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, | |||
| 3632 | /* struct fown_struct is never outside the context of a struct file */ | 3610 | /* struct fown_struct is never outside the context of a struct file */ |
| 3633 | file = container_of(fown, struct file, f_owner); | 3611 | file = container_of(fown, struct file, f_owner); |
| 3634 | 3612 | ||
| 3635 | fsec = file->f_security; | 3613 | fsec = selinux_file(file); |
| 3636 | 3614 | ||
| 3637 | if (!signum) | 3615 | if (!signum) |
| 3638 | perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ | 3616 | perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ |
| @@ -3656,7 +3634,7 @@ static int selinux_file_open(struct file *file) | |||
| 3656 | struct file_security_struct *fsec; | 3634 | struct file_security_struct *fsec; |
| 3657 | struct inode_security_struct *isec; | 3635 | struct inode_security_struct *isec; |
| 3658 | 3636 | ||
| 3659 | fsec = file->f_security; | 3637 | fsec = selinux_file(file); |
| 3660 | isec = inode_security(file_inode(file)); | 3638 | isec = inode_security(file_inode(file)); |
| 3661 | /* | 3639 | /* |
| 3662 | * Save inode label and policy sequence number | 3640 | * Save inode label and policy sequence number |
| @@ -3690,52 +3668,15 @@ static int selinux_task_alloc(struct task_struct *task, | |||
| 3690 | } | 3668 | } |
| 3691 | 3669 | ||
| 3692 | /* | 3670 | /* |
| 3693 | * allocate the SELinux part of blank credentials | ||
| 3694 | */ | ||
| 3695 | static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
| 3696 | { | ||
| 3697 | struct task_security_struct *tsec; | ||
| 3698 | |||
| 3699 | tsec = kzalloc(sizeof(struct task_security_struct), gfp); | ||
| 3700 | if (!tsec) | ||
| 3701 | return -ENOMEM; | ||
| 3702 | |||
| 3703 | cred->security = tsec; | ||
| 3704 | return 0; | ||
| 3705 | } | ||
| 3706 | |||
| 3707 | /* | ||
| 3708 | * detach and free the LSM part of a set of credentials | ||
| 3709 | */ | ||
| 3710 | static void selinux_cred_free(struct cred *cred) | ||
| 3711 | { | ||
| 3712 | struct task_security_struct *tsec = cred->security; | ||
| 3713 | |||
| 3714 | /* | ||
| 3715 | * cred->security == NULL if security_cred_alloc_blank() or | ||
| 3716 | * security_prepare_creds() returned an error. | ||
| 3717 | */ | ||
| 3718 | BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE); | ||
| 3719 | cred->security = (void *) 0x7UL; | ||
| 3720 | kfree(tsec); | ||
| 3721 | } | ||
| 3722 | |||
| 3723 | /* | ||
| 3724 | * prepare a new set of credentials for modification | 3671 | * prepare a new set of credentials for modification |
| 3725 | */ | 3672 | */ |
| 3726 | static int selinux_cred_prepare(struct cred *new, const struct cred *old, | 3673 | static int selinux_cred_prepare(struct cred *new, const struct cred *old, |
| 3727 | gfp_t gfp) | 3674 | gfp_t gfp) |
| 3728 | { | 3675 | { |
| 3729 | const struct task_security_struct *old_tsec; | 3676 | const struct task_security_struct *old_tsec = selinux_cred(old); |
| 3730 | struct task_security_struct *tsec; | 3677 | struct task_security_struct *tsec = selinux_cred(new); |
| 3731 | |||
| 3732 | old_tsec = old->security; | ||
| 3733 | |||
| 3734 | tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp); | ||
| 3735 | if (!tsec) | ||
| 3736 | return -ENOMEM; | ||
| 3737 | 3678 | ||
| 3738 | new->security = tsec; | 3679 | *tsec = *old_tsec; |
| 3739 | return 0; | 3680 | return 0; |
| 3740 | } | 3681 | } |
| 3741 | 3682 | ||
| @@ -3744,8 +3685,8 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old, | |||
| 3744 | */ | 3685 | */ |
| 3745 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) | 3686 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) |
| 3746 | { | 3687 | { |
| 3747 | const struct task_security_struct *old_tsec = old->security; | 3688 | const struct task_security_struct *old_tsec = selinux_cred(old); |
| 3748 | struct task_security_struct *tsec = new->security; | 3689 | struct task_security_struct *tsec = selinux_cred(new); |
| 3749 | 3690 | ||
| 3750 | *tsec = *old_tsec; | 3691 | *tsec = *old_tsec; |
| 3751 | } | 3692 | } |
| @@ -3761,7 +3702,7 @@ static void selinux_cred_getsecid(const struct cred *c, u32 *secid) | |||
| 3761 | */ | 3702 | */ |
| 3762 | static int selinux_kernel_act_as(struct cred *new, u32 secid) | 3703 | static int selinux_kernel_act_as(struct cred *new, u32 secid) |
| 3763 | { | 3704 | { |
| 3764 | struct task_security_struct *tsec = new->security; | 3705 | struct task_security_struct *tsec = selinux_cred(new); |
| 3765 | u32 sid = current_sid(); | 3706 | u32 sid = current_sid(); |
| 3766 | int ret; | 3707 | int ret; |
| 3767 | 3708 | ||
| @@ -3786,7 +3727,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid) | |||
| 3786 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) | 3727 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) |
| 3787 | { | 3728 | { |
| 3788 | struct inode_security_struct *isec = inode_security(inode); | 3729 | struct inode_security_struct *isec = inode_security(inode); |
| 3789 | struct task_security_struct *tsec = new->security; | 3730 | struct task_security_struct *tsec = selinux_cred(new); |
| 3790 | u32 sid = current_sid(); | 3731 | u32 sid = current_sid(); |
| 3791 | int ret; | 3732 | int ret; |
| 3792 | 3733 | ||
| @@ -3832,7 +3773,7 @@ static int selinux_kernel_module_from_file(struct file *file) | |||
| 3832 | ad.type = LSM_AUDIT_DATA_FILE; | 3773 | ad.type = LSM_AUDIT_DATA_FILE; |
| 3833 | ad.u.file = file; | 3774 | ad.u.file = file; |
| 3834 | 3775 | ||
| 3835 | fsec = file->f_security; | 3776 | fsec = selinux_file(file); |
| 3836 | if (sid != fsec->sid) { | 3777 | if (sid != fsec->sid) { |
| 3837 | rc = avc_has_perm(&selinux_state, | 3778 | rc = avc_has_perm(&selinux_state, |
| 3838 | sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); | 3779 | sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); |
| @@ -3998,7 +3939,7 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info, | |||
| 3998 | static void selinux_task_to_inode(struct task_struct *p, | 3939 | static void selinux_task_to_inode(struct task_struct *p, |
| 3999 | struct inode *inode) | 3940 | struct inode *inode) |
| 4000 | { | 3941 | { |
| 4001 | struct inode_security_struct *isec = inode->i_security; | 3942 | struct inode_security_struct *isec = selinux_inode(inode); |
| 4002 | u32 sid = task_sid(p); | 3943 | u32 sid = task_sid(p); |
| 4003 | 3944 | ||
| 4004 | spin_lock(&isec->lock); | 3945 | spin_lock(&isec->lock); |
| @@ -4335,7 +4276,7 @@ static int sock_has_perm(struct sock *sk, u32 perms) | |||
| 4335 | static int selinux_socket_create(int family, int type, | 4276 | static int selinux_socket_create(int family, int type, |
| 4336 | int protocol, int kern) | 4277 | int protocol, int kern) |
| 4337 | { | 4278 | { |
| 4338 | const struct task_security_struct *tsec = current_security(); | 4279 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
| 4339 | u32 newsid; | 4280 | u32 newsid; |
| 4340 | u16 secclass; | 4281 | u16 secclass; |
| 4341 | int rc; | 4282 | int rc; |
| @@ -4355,7 +4296,7 @@ static int selinux_socket_create(int family, int type, | |||
| 4355 | static int selinux_socket_post_create(struct socket *sock, int family, | 4296 | static int selinux_socket_post_create(struct socket *sock, int family, |
| 4356 | int type, int protocol, int kern) | 4297 | int type, int protocol, int kern) |
| 4357 | { | 4298 | { |
| 4358 | const struct task_security_struct *tsec = current_security(); | 4299 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
| 4359 | struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); | 4300 | struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); |
| 4360 | struct sk_security_struct *sksec; | 4301 | struct sk_security_struct *sksec; |
| 4361 | u16 sclass = socket_type_to_security_class(family, type, protocol); | 4302 | u16 sclass = socket_type_to_security_class(family, type, protocol); |
| @@ -5236,7 +5177,7 @@ static int selinux_secmark_relabel_packet(u32 sid) | |||
| 5236 | const struct task_security_struct *__tsec; | 5177 | const struct task_security_struct *__tsec; |
| 5237 | u32 tsid; | 5178 | u32 tsid; |
| 5238 | 5179 | ||
| 5239 | __tsec = current_security(); | 5180 | __tsec = selinux_cred(current_cred()); |
| 5240 | tsid = __tsec->sid; | 5181 | tsid = __tsec->sid; |
| 5241 | 5182 | ||
| 5242 | return avc_has_perm(&selinux_state, | 5183 | return avc_has_perm(&selinux_state, |
| @@ -5711,51 +5652,22 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
| 5711 | return selinux_nlmsg_perm(sk, skb); | 5652 | return selinux_nlmsg_perm(sk, skb); |
| 5712 | } | 5653 | } |
| 5713 | 5654 | ||
| 5714 | static int ipc_alloc_security(struct kern_ipc_perm *perm, | 5655 | static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) |
| 5715 | u16 sclass) | ||
| 5716 | { | 5656 | { |
| 5717 | struct ipc_security_struct *isec; | ||
| 5718 | |||
| 5719 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); | ||
| 5720 | if (!isec) | ||
| 5721 | return -ENOMEM; | ||
| 5722 | |||
| 5723 | isec->sclass = sclass; | 5657 | isec->sclass = sclass; |
| 5724 | isec->sid = current_sid(); | 5658 | isec->sid = current_sid(); |
| 5725 | perm->security = isec; | ||
| 5726 | |||
| 5727 | return 0; | ||
| 5728 | } | ||
| 5729 | |||
| 5730 | static void ipc_free_security(struct kern_ipc_perm *perm) | ||
| 5731 | { | ||
| 5732 | struct ipc_security_struct *isec = perm->security; | ||
| 5733 | perm->security = NULL; | ||
| 5734 | kfree(isec); | ||
| 5735 | } | 5659 | } |
| 5736 | 5660 | ||
| 5737 | static int msg_msg_alloc_security(struct msg_msg *msg) | 5661 | static int msg_msg_alloc_security(struct msg_msg *msg) |
| 5738 | { | 5662 | { |
| 5739 | struct msg_security_struct *msec; | 5663 | struct msg_security_struct *msec; |
| 5740 | 5664 | ||
| 5741 | msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); | 5665 | msec = selinux_msg_msg(msg); |
| 5742 | if (!msec) | ||
| 5743 | return -ENOMEM; | ||
| 5744 | |||
| 5745 | msec->sid = SECINITSID_UNLABELED; | 5666 | msec->sid = SECINITSID_UNLABELED; |
| 5746 | msg->security = msec; | ||
| 5747 | 5667 | ||
| 5748 | return 0; | 5668 | return 0; |
| 5749 | } | 5669 | } |
| 5750 | 5670 | ||
| 5751 | static void msg_msg_free_security(struct msg_msg *msg) | ||
| 5752 | { | ||
| 5753 | struct msg_security_struct *msec = msg->security; | ||
| 5754 | |||
| 5755 | msg->security = NULL; | ||
| 5756 | kfree(msec); | ||
| 5757 | } | ||
| 5758 | |||
| 5759 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | 5671 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, |
| 5760 | u32 perms) | 5672 | u32 perms) |
| 5761 | { | 5673 | { |
| @@ -5763,7 +5675,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
| 5763 | struct common_audit_data ad; | 5675 | struct common_audit_data ad; |
| 5764 | u32 sid = current_sid(); | 5676 | u32 sid = current_sid(); |
| 5765 | 5677 | ||
| 5766 | isec = ipc_perms->security; | 5678 | isec = selinux_ipc(ipc_perms); |
| 5767 | 5679 | ||
| 5768 | ad.type = LSM_AUDIT_DATA_IPC; | 5680 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5769 | ad.u.ipc_id = ipc_perms->key; | 5681 | ad.u.ipc_id = ipc_perms->key; |
| @@ -5777,11 +5689,6 @@ static int selinux_msg_msg_alloc_security(struct msg_msg *msg) | |||
| 5777 | return msg_msg_alloc_security(msg); | 5689 | return msg_msg_alloc_security(msg); |
| 5778 | } | 5690 | } |
| 5779 | 5691 | ||
| 5780 | static void selinux_msg_msg_free_security(struct msg_msg *msg) | ||
| 5781 | { | ||
| 5782 | msg_msg_free_security(msg); | ||
| 5783 | } | ||
| 5784 | |||
| 5785 | /* message queue security operations */ | 5692 | /* message queue security operations */ |
| 5786 | static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | 5693 | static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) |
| 5787 | { | 5694 | { |
| @@ -5790,11 +5697,8 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | |||
| 5790 | u32 sid = current_sid(); | 5697 | u32 sid = current_sid(); |
| 5791 | int rc; | 5698 | int rc; |
| 5792 | 5699 | ||
| 5793 | rc = ipc_alloc_security(msq, SECCLASS_MSGQ); | 5700 | isec = selinux_ipc(msq); |
| 5794 | if (rc) | 5701 | ipc_init_security(isec, SECCLASS_MSGQ); |
| 5795 | return rc; | ||
| 5796 | |||
| 5797 | isec = msq->security; | ||
| 5798 | 5702 | ||
| 5799 | ad.type = LSM_AUDIT_DATA_IPC; | 5703 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5800 | ad.u.ipc_id = msq->key; | 5704 | ad.u.ipc_id = msq->key; |
| @@ -5802,16 +5706,7 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | |||
| 5802 | rc = avc_has_perm(&selinux_state, | 5706 | rc = avc_has_perm(&selinux_state, |
| 5803 | sid, isec->sid, SECCLASS_MSGQ, | 5707 | sid, isec->sid, SECCLASS_MSGQ, |
| 5804 | MSGQ__CREATE, &ad); | 5708 | MSGQ__CREATE, &ad); |
| 5805 | if (rc) { | 5709 | return rc; |
| 5806 | ipc_free_security(msq); | ||
| 5807 | return rc; | ||
| 5808 | } | ||
| 5809 | return 0; | ||
| 5810 | } | ||
| 5811 | |||
| 5812 | static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq) | ||
| 5813 | { | ||
| 5814 | ipc_free_security(msq); | ||
| 5815 | } | 5710 | } |
| 5816 | 5711 | ||
| 5817 | static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) | 5712 | static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) |
| @@ -5820,7 +5715,7 @@ static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) | |||
| 5820 | struct common_audit_data ad; | 5715 | struct common_audit_data ad; |
| 5821 | u32 sid = current_sid(); | 5716 | u32 sid = current_sid(); |
| 5822 | 5717 | ||
| 5823 | isec = msq->security; | 5718 | isec = selinux_ipc(msq); |
| 5824 | 5719 | ||
| 5825 | ad.type = LSM_AUDIT_DATA_IPC; | 5720 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5826 | ad.u.ipc_id = msq->key; | 5721 | ad.u.ipc_id = msq->key; |
| @@ -5869,8 +5764,8 @@ static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *m | |||
| 5869 | u32 sid = current_sid(); | 5764 | u32 sid = current_sid(); |
| 5870 | int rc; | 5765 | int rc; |
| 5871 | 5766 | ||
| 5872 | isec = msq->security; | 5767 | isec = selinux_ipc(msq); |
| 5873 | msec = msg->security; | 5768 | msec = selinux_msg_msg(msg); |
| 5874 | 5769 | ||
| 5875 | /* | 5770 | /* |
| 5876 | * First time through, need to assign label to the message | 5771 | * First time through, need to assign label to the message |
| @@ -5917,8 +5812,8 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m | |||
| 5917 | u32 sid = task_sid(target); | 5812 | u32 sid = task_sid(target); |
| 5918 | int rc; | 5813 | int rc; |
| 5919 | 5814 | ||
| 5920 | isec = msq->security; | 5815 | isec = selinux_ipc(msq); |
| 5921 | msec = msg->security; | 5816 | msec = selinux_msg_msg(msg); |
| 5922 | 5817 | ||
| 5923 | ad.type = LSM_AUDIT_DATA_IPC; | 5818 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5924 | ad.u.ipc_id = msq->key; | 5819 | ad.u.ipc_id = msq->key; |
| @@ -5941,11 +5836,8 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) | |||
| 5941 | u32 sid = current_sid(); | 5836 | u32 sid = current_sid(); |
| 5942 | int rc; | 5837 | int rc; |
| 5943 | 5838 | ||
| 5944 | rc = ipc_alloc_security(shp, SECCLASS_SHM); | 5839 | isec = selinux_ipc(shp); |
| 5945 | if (rc) | 5840 | ipc_init_security(isec, SECCLASS_SHM); |
| 5946 | return rc; | ||
| 5947 | |||
| 5948 | isec = shp->security; | ||
| 5949 | 5841 | ||
| 5950 | ad.type = LSM_AUDIT_DATA_IPC; | 5842 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5951 | ad.u.ipc_id = shp->key; | 5843 | ad.u.ipc_id = shp->key; |
| @@ -5953,16 +5845,7 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) | |||
| 5953 | rc = avc_has_perm(&selinux_state, | 5845 | rc = avc_has_perm(&selinux_state, |
| 5954 | sid, isec->sid, SECCLASS_SHM, | 5846 | sid, isec->sid, SECCLASS_SHM, |
| 5955 | SHM__CREATE, &ad); | 5847 | SHM__CREATE, &ad); |
| 5956 | if (rc) { | 5848 | return rc; |
| 5957 | ipc_free_security(shp); | ||
| 5958 | return rc; | ||
| 5959 | } | ||
| 5960 | return 0; | ||
| 5961 | } | ||
| 5962 | |||
| 5963 | static void selinux_shm_free_security(struct kern_ipc_perm *shp) | ||
| 5964 | { | ||
| 5965 | ipc_free_security(shp); | ||
| 5966 | } | 5849 | } |
| 5967 | 5850 | ||
| 5968 | static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) | 5851 | static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) |
| @@ -5971,7 +5854,7 @@ static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) | |||
| 5971 | struct common_audit_data ad; | 5854 | struct common_audit_data ad; |
| 5972 | u32 sid = current_sid(); | 5855 | u32 sid = current_sid(); |
| 5973 | 5856 | ||
| 5974 | isec = shp->security; | 5857 | isec = selinux_ipc(shp); |
| 5975 | 5858 | ||
| 5976 | ad.type = LSM_AUDIT_DATA_IPC; | 5859 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5977 | ad.u.ipc_id = shp->key; | 5860 | ad.u.ipc_id = shp->key; |
| @@ -6038,11 +5921,8 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) | |||
| 6038 | u32 sid = current_sid(); | 5921 | u32 sid = current_sid(); |
| 6039 | int rc; | 5922 | int rc; |
| 6040 | 5923 | ||
| 6041 | rc = ipc_alloc_security(sma, SECCLASS_SEM); | 5924 | isec = selinux_ipc(sma); |
| 6042 | if (rc) | 5925 | ipc_init_security(isec, SECCLASS_SEM); |
| 6043 | return rc; | ||
| 6044 | |||
| 6045 | isec = sma->security; | ||
| 6046 | 5926 | ||
| 6047 | ad.type = LSM_AUDIT_DATA_IPC; | 5927 | ad.type = LSM_AUDIT_DATA_IPC; |
| 6048 | ad.u.ipc_id = sma->key; | 5928 | ad.u.ipc_id = sma->key; |
| @@ -6050,16 +5930,7 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) | |||
| 6050 | rc = avc_has_perm(&selinux_state, | 5930 | rc = avc_has_perm(&selinux_state, |
| 6051 | sid, isec->sid, SECCLASS_SEM, | 5931 | sid, isec->sid, SECCLASS_SEM, |
| 6052 | SEM__CREATE, &ad); | 5932 | SEM__CREATE, &ad); |
| 6053 | if (rc) { | 5933 | return rc; |
| 6054 | ipc_free_security(sma); | ||
| 6055 | return rc; | ||
| 6056 | } | ||
| 6057 | return 0; | ||
| 6058 | } | ||
| 6059 | |||
| 6060 | static void selinux_sem_free_security(struct kern_ipc_perm *sma) | ||
| 6061 | { | ||
| 6062 | ipc_free_security(sma); | ||
| 6063 | } | 5934 | } |
| 6064 | 5935 | ||
| 6065 | static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) | 5936 | static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) |
| @@ -6068,7 +5939,7 @@ static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) | |||
| 6068 | struct common_audit_data ad; | 5939 | struct common_audit_data ad; |
| 6069 | u32 sid = current_sid(); | 5940 | u32 sid = current_sid(); |
| 6070 | 5941 | ||
| 6071 | isec = sma->security; | 5942 | isec = selinux_ipc(sma); |
| 6072 | 5943 | ||
| 6073 | ad.type = LSM_AUDIT_DATA_IPC; | 5944 | ad.type = LSM_AUDIT_DATA_IPC; |
| 6074 | ad.u.ipc_id = sma->key; | 5945 | ad.u.ipc_id = sma->key; |
| @@ -6154,7 +6025,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
| 6154 | 6025 | ||
| 6155 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | 6026 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) |
| 6156 | { | 6027 | { |
| 6157 | struct ipc_security_struct *isec = ipcp->security; | 6028 | struct ipc_security_struct *isec = selinux_ipc(ipcp); |
| 6158 | *secid = isec->sid; | 6029 | *secid = isec->sid; |
| 6159 | } | 6030 | } |
| 6160 | 6031 | ||
| @@ -6173,7 +6044,7 @@ static int selinux_getprocattr(struct task_struct *p, | |||
| 6173 | unsigned len; | 6044 | unsigned len; |
| 6174 | 6045 | ||
| 6175 | rcu_read_lock(); | 6046 | rcu_read_lock(); |
| 6176 | __tsec = __task_cred(p)->security; | 6047 | __tsec = selinux_cred(__task_cred(p)); |
| 6177 | 6048 | ||
| 6178 | if (current != p) { | 6049 | if (current != p) { |
| 6179 | error = avc_has_perm(&selinux_state, | 6050 | error = avc_has_perm(&selinux_state, |
| @@ -6296,7 +6167,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) | |||
| 6296 | operation. See selinux_bprm_set_creds for the execve | 6167 | operation. See selinux_bprm_set_creds for the execve |
| 6297 | checks and may_create for the file creation checks. The | 6168 | checks and may_create for the file creation checks. The |
| 6298 | operation will then fail if the context is not permitted. */ | 6169 | operation will then fail if the context is not permitted. */ |
| 6299 | tsec = new->security; | 6170 | tsec = selinux_cred(new); |
| 6300 | if (!strcmp(name, "exec")) { | 6171 | if (!strcmp(name, "exec")) { |
| 6301 | tsec->exec_sid = sid; | 6172 | tsec->exec_sid = sid; |
| 6302 | } else if (!strcmp(name, "fscreate")) { | 6173 | } else if (!strcmp(name, "fscreate")) { |
| @@ -6380,7 +6251,7 @@ static void selinux_release_secctx(char *secdata, u32 seclen) | |||
| 6380 | 6251 | ||
| 6381 | static void selinux_inode_invalidate_secctx(struct inode *inode) | 6252 | static void selinux_inode_invalidate_secctx(struct inode *inode) |
| 6382 | { | 6253 | { |
| 6383 | struct inode_security_struct *isec = inode->i_security; | 6254 | struct inode_security_struct *isec = selinux_inode(inode); |
| 6384 | 6255 | ||
| 6385 | spin_lock(&isec->lock); | 6256 | spin_lock(&isec->lock); |
| 6386 | isec->initialized = LABEL_INVALID; | 6257 | isec->initialized = LABEL_INVALID; |
| @@ -6392,7 +6263,10 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) | |||
| 6392 | */ | 6263 | */ |
| 6393 | static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | 6264 | static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) |
| 6394 | { | 6265 | { |
| 6395 | return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); | 6266 | int rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, |
| 6267 | ctx, ctxlen, 0); | ||
| 6268 | /* Do not return error when suppressing label (SBLABEL_MNT not set). */ | ||
| 6269 | return rc == -EOPNOTSUPP ? 0 : rc; | ||
| 6396 | } | 6270 | } |
| 6397 | 6271 | ||
| 6398 | /* | 6272 | /* |
| @@ -6425,7 +6299,7 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, | |||
| 6425 | if (!ksec) | 6299 | if (!ksec) |
| 6426 | return -ENOMEM; | 6300 | return -ENOMEM; |
| 6427 | 6301 | ||
| 6428 | tsec = cred->security; | 6302 | tsec = selinux_cred(cred); |
| 6429 | if (tsec->keycreate_sid) | 6303 | if (tsec->keycreate_sid) |
| 6430 | ksec->sid = tsec->keycreate_sid; | 6304 | ksec->sid = tsec->keycreate_sid; |
| 6431 | else | 6305 | else |
| @@ -6688,6 +6562,14 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux) | |||
| 6688 | } | 6562 | } |
| 6689 | #endif | 6563 | #endif |
| 6690 | 6564 | ||
| 6565 | struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { | ||
| 6566 | .lbs_cred = sizeof(struct task_security_struct), | ||
| 6567 | .lbs_file = sizeof(struct file_security_struct), | ||
| 6568 | .lbs_inode = sizeof(struct inode_security_struct), | ||
| 6569 | .lbs_ipc = sizeof(struct ipc_security_struct), | ||
| 6570 | .lbs_msg_msg = sizeof(struct msg_security_struct), | ||
| 6571 | }; | ||
| 6572 | |||
| 6691 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | 6573 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { |
| 6692 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), | 6574 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), |
| 6693 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), | 6575 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), |
| @@ -6757,7 +6639,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
| 6757 | 6639 | ||
| 6758 | LSM_HOOK_INIT(file_permission, selinux_file_permission), | 6640 | LSM_HOOK_INIT(file_permission, selinux_file_permission), |
| 6759 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), | 6641 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), |
| 6760 | LSM_HOOK_INIT(file_free_security, selinux_file_free_security), | ||
| 6761 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), | 6642 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), |
| 6762 | LSM_HOOK_INIT(mmap_file, selinux_mmap_file), | 6643 | LSM_HOOK_INIT(mmap_file, selinux_mmap_file), |
| 6763 | LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), | 6644 | LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), |
| @@ -6771,8 +6652,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
| 6771 | LSM_HOOK_INIT(file_open, selinux_file_open), | 6652 | LSM_HOOK_INIT(file_open, selinux_file_open), |
| 6772 | 6653 | ||
| 6773 | LSM_HOOK_INIT(task_alloc, selinux_task_alloc), | 6654 | LSM_HOOK_INIT(task_alloc, selinux_task_alloc), |
| 6774 | LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), | ||
| 6775 | LSM_HOOK_INIT(cred_free, selinux_cred_free), | ||
| 6776 | LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), | 6655 | LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), |
| 6777 | LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), | 6656 | LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), |
| 6778 | LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid), | 6657 | LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid), |
| @@ -6800,24 +6679,20 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
| 6800 | LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), | 6679 | LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), |
| 6801 | 6680 | ||
| 6802 | LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), | 6681 | LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), |
| 6803 | LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security), | ||
| 6804 | 6682 | ||
| 6805 | LSM_HOOK_INIT(msg_queue_alloc_security, | 6683 | LSM_HOOK_INIT(msg_queue_alloc_security, |
| 6806 | selinux_msg_queue_alloc_security), | 6684 | selinux_msg_queue_alloc_security), |
| 6807 | LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security), | ||
| 6808 | LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), | 6685 | LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), |
| 6809 | LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), | 6686 | LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), |
| 6810 | LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), | 6687 | LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), |
| 6811 | LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), | 6688 | LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), |
| 6812 | 6689 | ||
| 6813 | LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), | 6690 | LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), |
| 6814 | LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security), | ||
| 6815 | LSM_HOOK_INIT(shm_associate, selinux_shm_associate), | 6691 | LSM_HOOK_INIT(shm_associate, selinux_shm_associate), |
| 6816 | LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), | 6692 | LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), |
| 6817 | LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), | 6693 | LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), |
| 6818 | 6694 | ||
| 6819 | LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), | 6695 | LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), |
| 6820 | LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), | ||
| 6821 | LSM_HOOK_INIT(sem_associate, selinux_sem_associate), | 6696 | LSM_HOOK_INIT(sem_associate, selinux_sem_associate), |
| 6822 | LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), | 6697 | LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), |
| 6823 | LSM_HOOK_INIT(sem_semop, selinux_sem_semop), | 6698 | LSM_HOOK_INIT(sem_semop, selinux_sem_semop), |
| @@ -6928,16 +6803,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
| 6928 | 6803 | ||
| 6929 | static __init int selinux_init(void) | 6804 | static __init int selinux_init(void) |
| 6930 | { | 6805 | { |
| 6931 | if (!security_module_enable("selinux")) { | ||
| 6932 | selinux_enabled = 0; | ||
| 6933 | return 0; | ||
| 6934 | } | ||
| 6935 | |||
| 6936 | if (!selinux_enabled) { | ||
| 6937 | pr_info("SELinux: Disabled at boot.\n"); | ||
| 6938 | return 0; | ||
| 6939 | } | ||
| 6940 | |||
| 6941 | pr_info("SELinux: Initializing.\n"); | 6806 | pr_info("SELinux: Initializing.\n"); |
| 6942 | 6807 | ||
| 6943 | memset(&selinux_state, 0, sizeof(selinux_state)); | 6808 | memset(&selinux_state, 0, sizeof(selinux_state)); |
| @@ -6951,12 +6816,6 @@ static __init int selinux_init(void) | |||
| 6951 | 6816 | ||
| 6952 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); | 6817 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); |
| 6953 | 6818 | ||
| 6954 | sel_inode_cache = kmem_cache_create("selinux_inode_security", | ||
| 6955 | sizeof(struct inode_security_struct), | ||
| 6956 | 0, SLAB_PANIC, NULL); | ||
| 6957 | file_security_cache = kmem_cache_create("selinux_file_security", | ||
| 6958 | sizeof(struct file_security_struct), | ||
| 6959 | 0, SLAB_PANIC, NULL); | ||
| 6960 | avc_init(); | 6819 | avc_init(); |
| 6961 | 6820 | ||
| 6962 | avtab_cache_init(); | 6821 | avtab_cache_init(); |
| @@ -6999,6 +6858,9 @@ void selinux_complete_init(void) | |||
| 6999 | all processes and objects when they are created. */ | 6858 | all processes and objects when they are created. */ |
| 7000 | DEFINE_LSM(selinux) = { | 6859 | DEFINE_LSM(selinux) = { |
| 7001 | .name = "selinux", | 6860 | .name = "selinux", |
| 6861 | .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE, | ||
| 6862 | .enabled = &selinux_enabled, | ||
| 6863 | .blobs = &selinux_blob_sizes, | ||
| 7002 | .init = selinux_init, | 6864 | .init = selinux_init, |
| 7003 | }; | 6865 | }; |
| 7004 | 6866 | ||
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h index 1bdf973433cc..682e2b5de2a4 100644 --- a/security/selinux/include/audit.h +++ b/security/selinux/include/audit.h | |||
| @@ -1,9 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * SELinux support for the Audit LSM hooks | 2 | * SELinux support for the Audit LSM hooks |
| 3 | * | 3 | * |
| 4 | * Most of below header was moved from include/linux/selinux.h which | ||
| 5 | * is released under below copyrights: | ||
| 6 | * | ||
| 7 | * Author: James Morris <jmorris@redhat.com> | 4 | * Author: James Morris <jmorris@redhat.com> |
| 8 | * | 5 | * |
| 9 | * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> | 6 | * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> |
| @@ -46,13 +43,11 @@ void selinux_audit_rule_free(void *rule); | |||
| 46 | * @field: the field this rule refers to | 43 | * @field: the field this rule refers to |
| 47 | * @op: the operater the rule uses | 44 | * @op: the operater the rule uses |
| 48 | * @rule: pointer to the audit rule to check against | 45 | * @rule: pointer to the audit rule to check against |
| 49 | * @actx: the audit context (can be NULL) associated with the check | ||
| 50 | * | 46 | * |
| 51 | * Returns 1 if the context id matches the rule, 0 if it does not, and | 47 | * Returns 1 if the context id matches the rule, 0 if it does not, and |
| 52 | * -errno on failure. | 48 | * -errno on failure. |
| 53 | */ | 49 | */ |
| 54 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule, | 50 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule); |
| 55 | struct audit_context *actx); | ||
| 56 | 51 | ||
| 57 | /** | 52 | /** |
| 58 | * selinux_audit_rule_known - check to see if rule contains selinux fields. | 53 | * selinux_audit_rule_known - check to see if rule contains selinux fields. |
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index ef899bcfd2cb..7be0e1e90e8b 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h | |||
| @@ -142,6 +142,7 @@ static inline int avc_audit(struct selinux_state *state, | |||
| 142 | 142 | ||
| 143 | #define AVC_STRICT 1 /* Ignore permissive mode. */ | 143 | #define AVC_STRICT 1 /* Ignore permissive mode. */ |
| 144 | #define AVC_EXTENDED_PERMS 2 /* update extended permissions */ | 144 | #define AVC_EXTENDED_PERMS 2 /* update extended permissions */ |
| 145 | #define AVC_NONBLOCKING 4 /* non blocking */ | ||
| 145 | int avc_has_perm_noaudit(struct selinux_state *state, | 146 | int avc_has_perm_noaudit(struct selinux_state *state, |
| 146 | u32 ssid, u32 tsid, | 147 | u32 ssid, u32 tsid, |
| 147 | u16 tclass, u32 requested, | 148 | u16 tclass, u32 requested, |
| @@ -152,11 +153,6 @@ int avc_has_perm(struct selinux_state *state, | |||
| 152 | u32 ssid, u32 tsid, | 153 | u32 ssid, u32 tsid, |
| 153 | u16 tclass, u32 requested, | 154 | u16 tclass, u32 requested, |
| 154 | struct common_audit_data *auditdata); | 155 | struct common_audit_data *auditdata); |
| 155 | int avc_has_perm_flags(struct selinux_state *state, | ||
| 156 | u32 ssid, u32 tsid, | ||
| 157 | u16 tclass, u32 requested, | ||
| 158 | struct common_audit_data *auditdata, | ||
| 159 | int flags); | ||
| 160 | 156 | ||
| 161 | int avc_has_extended_perms(struct selinux_state *state, | 157 | int avc_has_extended_perms(struct selinux_state *state, |
| 162 | u32 ssid, u32 tsid, u16 tclass, u32 requested, | 158 | u32 ssid, u32 tsid, u16 tclass, u32 requested, |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index cc5e26b0161b..231262d8eac9 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <linux/binfmts.h> | 25 | #include <linux/binfmts.h> |
| 26 | #include <linux/in.h> | 26 | #include <linux/in.h> |
| 27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
| 28 | #include <linux/lsm_hooks.h> | ||
| 29 | #include <linux/msg.h> | ||
| 28 | #include <net/net_namespace.h> | 30 | #include <net/net_namespace.h> |
| 29 | #include "flask.h" | 31 | #include "flask.h" |
| 30 | #include "avc.h" | 32 | #include "avc.h" |
| @@ -56,10 +58,7 @@ enum label_initialized { | |||
| 56 | 58 | ||
| 57 | struct inode_security_struct { | 59 | struct inode_security_struct { |
| 58 | struct inode *inode; /* back pointer to inode object */ | 60 | struct inode *inode; /* back pointer to inode object */ |
| 59 | union { | 61 | struct list_head list; /* list of inode_security_struct */ |
| 60 | struct list_head list; /* list of inode_security_struct */ | ||
| 61 | struct rcu_head rcu; /* for freeing the inode_security_struct */ | ||
| 62 | }; | ||
| 63 | u32 task_sid; /* SID of creating task */ | 62 | u32 task_sid; /* SID of creating task */ |
| 64 | u32 sid; /* SID of this object */ | 63 | u32 sid; /* SID of this object */ |
| 65 | u16 sclass; /* security class of this object */ | 64 | u16 sclass; /* security class of this object */ |
| @@ -158,4 +157,35 @@ struct bpf_security_struct { | |||
| 158 | u32 sid; /*SID of bpf obj creater*/ | 157 | u32 sid; /*SID of bpf obj creater*/ |
| 159 | }; | 158 | }; |
| 160 | 159 | ||
| 160 | extern struct lsm_blob_sizes selinux_blob_sizes; | ||
| 161 | static inline struct task_security_struct *selinux_cred(const struct cred *cred) | ||
| 162 | { | ||
| 163 | return cred->security + selinux_blob_sizes.lbs_cred; | ||
| 164 | } | ||
| 165 | |||
| 166 | static inline struct file_security_struct *selinux_file(const struct file *file) | ||
| 167 | { | ||
| 168 | return file->f_security + selinux_blob_sizes.lbs_file; | ||
| 169 | } | ||
| 170 | |||
| 171 | static inline struct inode_security_struct *selinux_inode( | ||
| 172 | const struct inode *inode) | ||
| 173 | { | ||
| 174 | if (unlikely(!inode->i_security)) | ||
| 175 | return NULL; | ||
| 176 | return inode->i_security + selinux_blob_sizes.lbs_inode; | ||
| 177 | } | ||
| 178 | |||
| 179 | static inline struct msg_security_struct *selinux_msg_msg( | ||
| 180 | const struct msg_msg *msg_msg) | ||
| 181 | { | ||
| 182 | return msg_msg->security + selinux_blob_sizes.lbs_msg_msg; | ||
| 183 | } | ||
| 184 | |||
| 185 | static inline struct ipc_security_struct *selinux_ipc( | ||
| 186 | const struct kern_ipc_perm *ipc) | ||
| 187 | { | ||
| 188 | return ipc->security + selinux_blob_sizes.lbs_ipc; | ||
| 189 | } | ||
| 190 | |||
| 161 | #endif /* _SELINUX_OBJSEC_H_ */ | 191 | #endif /* _SELINUX_OBJSEC_H_ */ |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index ba8eedf42b90..f68fb25b5702 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -255,6 +255,9 @@ int security_sid_to_context(struct selinux_state *state, u32 sid, | |||
| 255 | int security_sid_to_context_force(struct selinux_state *state, | 255 | int security_sid_to_context_force(struct selinux_state *state, |
| 256 | u32 sid, char **scontext, u32 *scontext_len); | 256 | u32 sid, char **scontext, u32 *scontext_len); |
| 257 | 257 | ||
| 258 | int security_sid_to_context_inval(struct selinux_state *state, | ||
| 259 | u32 sid, char **scontext, u32 *scontext_len); | ||
| 260 | |||
| 258 | int security_context_to_sid(struct selinux_state *state, | 261 | int security_context_to_sid(struct selinux_state *state, |
| 259 | const char *scontext, u32 scontext_len, | 262 | const char *scontext, u32 scontext_len, |
| 260 | u32 *out_sid, gfp_t gfp); | 263 | u32 *out_sid, gfp_t gfp); |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index f3a5a138a096..145ee62f205a 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
| @@ -1378,7 +1378,7 @@ static int sel_make_bools(struct selinux_fs_info *fsi) | |||
| 1378 | goto out; | 1378 | goto out; |
| 1379 | } | 1379 | } |
| 1380 | 1380 | ||
| 1381 | isec = (struct inode_security_struct *)inode->i_security; | 1381 | isec = selinux_inode(inode); |
| 1382 | ret = security_genfs_sid(fsi->state, "selinuxfs", page, | 1382 | ret = security_genfs_sid(fsi->state, "selinuxfs", page, |
| 1383 | SECCLASS_FILE, &sid); | 1383 | SECCLASS_FILE, &sid); |
| 1384 | if (ret) { | 1384 | if (ret) { |
| @@ -1953,7 +1953,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1953 | } | 1953 | } |
| 1954 | 1954 | ||
| 1955 | inode->i_ino = ++fsi->last_ino; | 1955 | inode->i_ino = ++fsi->last_ino; |
| 1956 | isec = (struct inode_security_struct *)inode->i_security; | 1956 | isec = selinux_inode(inode); |
| 1957 | isec->sid = SECINITSID_DEVNULL; | 1957 | isec->sid = SECINITSID_DEVNULL; |
| 1958 | isec->sclass = SECCLASS_CHR_FILE; | 1958 | isec->sclass = SECCLASS_CHR_FILE; |
| 1959 | isec->initialized = LABEL_INITIALIZED; | 1959 | isec->initialized = LABEL_INITIALIZED; |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index dd44126c8d14..1269e2be3c2d 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -49,7 +49,6 @@ | |||
| 49 | #include <linux/sched.h> | 49 | #include <linux/sched.h> |
| 50 | #include <linux/audit.h> | 50 | #include <linux/audit.h> |
| 51 | #include <linux/mutex.h> | 51 | #include <linux/mutex.h> |
| 52 | #include <linux/selinux.h> | ||
| 53 | #include <linux/flex_array.h> | 52 | #include <linux/flex_array.h> |
| 54 | #include <linux/vmalloc.h> | 53 | #include <linux/vmalloc.h> |
| 55 | #include <net/netlabel.h> | 54 | #include <net/netlabel.h> |
| @@ -1281,7 +1280,8 @@ const char *security_get_initial_sid_context(u32 sid) | |||
| 1281 | 1280 | ||
| 1282 | static int security_sid_to_context_core(struct selinux_state *state, | 1281 | static int security_sid_to_context_core(struct selinux_state *state, |
| 1283 | u32 sid, char **scontext, | 1282 | u32 sid, char **scontext, |
| 1284 | u32 *scontext_len, int force) | 1283 | u32 *scontext_len, int force, |
| 1284 | int only_invalid) | ||
| 1285 | { | 1285 | { |
| 1286 | struct policydb *policydb; | 1286 | struct policydb *policydb; |
| 1287 | struct sidtab *sidtab; | 1287 | struct sidtab *sidtab; |
| @@ -1326,8 +1326,14 @@ static int security_sid_to_context_core(struct selinux_state *state, | |||
| 1326 | rc = -EINVAL; | 1326 | rc = -EINVAL; |
| 1327 | goto out_unlock; | 1327 | goto out_unlock; |
| 1328 | } | 1328 | } |
| 1329 | rc = context_struct_to_string(policydb, context, scontext, | 1329 | if (only_invalid && !context->len) { |
| 1330 | scontext_len); | 1330 | scontext = NULL; |
| 1331 | scontext_len = 0; | ||
| 1332 | rc = 0; | ||
| 1333 | } else { | ||
| 1334 | rc = context_struct_to_string(policydb, context, scontext, | ||
| 1335 | scontext_len); | ||
| 1336 | } | ||
| 1331 | out_unlock: | 1337 | out_unlock: |
| 1332 | read_unlock(&state->ss->policy_rwlock); | 1338 | read_unlock(&state->ss->policy_rwlock); |
| 1333 | out: | 1339 | out: |
| @@ -1349,14 +1355,34 @@ int security_sid_to_context(struct selinux_state *state, | |||
| 1349 | u32 sid, char **scontext, u32 *scontext_len) | 1355 | u32 sid, char **scontext, u32 *scontext_len) |
| 1350 | { | 1356 | { |
| 1351 | return security_sid_to_context_core(state, sid, scontext, | 1357 | return security_sid_to_context_core(state, sid, scontext, |
| 1352 | scontext_len, 0); | 1358 | scontext_len, 0, 0); |
| 1353 | } | 1359 | } |
| 1354 | 1360 | ||
| 1355 | int security_sid_to_context_force(struct selinux_state *state, u32 sid, | 1361 | int security_sid_to_context_force(struct selinux_state *state, u32 sid, |
| 1356 | char **scontext, u32 *scontext_len) | 1362 | char **scontext, u32 *scontext_len) |
| 1357 | { | 1363 | { |
| 1358 | return security_sid_to_context_core(state, sid, scontext, | 1364 | return security_sid_to_context_core(state, sid, scontext, |
| 1359 | scontext_len, 1); | 1365 | scontext_len, 1, 0); |
| 1366 | } | ||
| 1367 | |||
| 1368 | /** | ||
| 1369 | * security_sid_to_context_inval - Obtain a context for a given SID if it | ||
| 1370 | * is invalid. | ||
| 1371 | * @sid: security identifier, SID | ||
| 1372 | * @scontext: security context | ||
| 1373 | * @scontext_len: length in bytes | ||
| 1374 | * | ||
| 1375 | * Write the string representation of the context associated with @sid | ||
| 1376 | * into a dynamically allocated string of the correct size, but only if the | ||
| 1377 | * context is invalid in the current policy. Set @scontext to point to | ||
| 1378 | * this string (or NULL if the context is valid) and set @scontext_len to | ||
| 1379 | * the length of the string (or 0 if the context is valid). | ||
| 1380 | */ | ||
| 1381 | int security_sid_to_context_inval(struct selinux_state *state, u32 sid, | ||
| 1382 | char **scontext, u32 *scontext_len) | ||
| 1383 | { | ||
| 1384 | return security_sid_to_context_core(state, sid, scontext, | ||
| 1385 | scontext_len, 1, 1); | ||
| 1360 | } | 1386 | } |
| 1361 | 1387 | ||
| 1362 | /* | 1388 | /* |
| @@ -3376,8 +3402,7 @@ int selinux_audit_rule_known(struct audit_krule *rule) | |||
| 3376 | return 0; | 3402 | return 0; |
| 3377 | } | 3403 | } |
| 3378 | 3404 | ||
| 3379 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | 3405 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule) |
| 3380 | struct audit_context *actx) | ||
| 3381 | { | 3406 | { |
| 3382 | struct selinux_state *state = &selinux_state; | 3407 | struct selinux_state *state = &selinux_state; |
| 3383 | struct context *ctxt; | 3408 | struct context *ctxt; |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index bd7d18bdb147..7c57cb7e4146 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
| @@ -79,7 +79,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | |||
| 79 | gfp_t gfp) | 79 | gfp_t gfp) |
| 80 | { | 80 | { |
| 81 | int rc; | 81 | int rc; |
| 82 | const struct task_security_struct *tsec = current_security(); | 82 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
| 83 | struct xfrm_sec_ctx *ctx = NULL; | 83 | struct xfrm_sec_ctx *ctx = NULL; |
| 84 | u32 str_len; | 84 | u32 str_len; |
| 85 | 85 | ||
| @@ -138,7 +138,7 @@ static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx) | |||
| 138 | */ | 138 | */ |
| 139 | static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx) | 139 | static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx) |
| 140 | { | 140 | { |
| 141 | const struct task_security_struct *tsec = current_security(); | 141 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
| 142 | 142 | ||
| 143 | if (!ctx) | 143 | if (!ctx) |
| 144 | return 0; | 144 | return 0; |
