aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 11:06:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 11:06:39 -0400
commitbb2cbf5e9367d8598fecd0c48dead69560750223 (patch)
treefb2c620451b90f41a31726bdd82077813f941e39 /security
parente7fda6c4c3c1a7d6996dd75fd84670fa0b5d448f (diff)
parent478d085524c57cf4283699f529d5a4c22188ea69 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "In this release: - PKCS#7 parser for the key management subsystem from David Howells - appoint Kees Cook as seccomp maintainer - bugfixes and general maintenance across the subsystem" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (94 commits) X.509: Need to export x509_request_asymmetric_key() netlabel: shorter names for the NetLabel catmap funcs/structs netlabel: fix the catmap walking functions netlabel: fix the horribly broken catmap functions netlabel: fix a problem when setting bits below the previously lowest bit PKCS#7: X.509 certificate issuer and subject are mandatory fields in the ASN.1 tpm: simplify code by using %*phN specifier tpm: Provide a generic means to override the chip returned timeouts tpm: missing tpm_chip_put in tpm_get_random() tpm: Properly clean sysfs entries in error path tpm: Add missing tpm_do_selftest to ST33 I2C driver PKCS#7: Use x509_request_asymmetric_key() Revert "selinux: fix the default socket labeling in sock_graft()" X.509: x509_request_asymmetric_keys() doesn't need string length arguments PKCS#7: fix sparse non static symbol warning KEYS: revert encrypted key change ima: add support for measuring and appraising firmware firmware_class: perform new LSM checks security: introduce kernel_fw_from_file hook PKCS#7: Missing inclusion of linux/err.h ...
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/domain.c4
-rw-r--r--security/capability.c6
-rw-r--r--security/commoncap.c75
-rw-r--r--security/integrity/digsig.c28
-rw-r--r--security/integrity/ima/Kconfig10
-rw-r--r--security/integrity/ima/ima.h15
-rw-r--r--security/integrity/ima/ima_appraise.c10
-rw-r--r--security/integrity/ima/ima_crypto.c312
-rw-r--r--security/integrity/ima/ima_main.c28
-rw-r--r--security/integrity/ima/ima_policy.c13
-rw-r--r--security/integrity/integrity.h14
-rw-r--r--security/keys/big_key.c41
-rw-r--r--security/keys/key.c49
-rw-r--r--security/keys/keyctl.c21
-rw-r--r--security/keys/keyring.c34
-rw-r--r--security/keys/request_key_auth.c13
-rw-r--r--security/keys/user_defined.c41
-rw-r--r--security/security.c11
-rw-r--r--security/selinux/hooks.c14
-rw-r--r--security/selinux/include/netif.h2
-rw-r--r--security/selinux/include/netnode.h2
-rw-r--r--security/selinux/include/netport.h2
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/netif.c15
-rw-r--r--security/selinux/netnode.c15
-rw-r--r--security/selinux/netport.c15
-rw-r--r--security/selinux/ss/conditional.c11
-rw-r--r--security/selinux/ss/ebitmap.c133
-rw-r--r--security/selinux/ss/ebitmap.h8
-rw-r--r--security/selinux/ss/policydb.c141
-rw-r--r--security/selinux/ss/services.c41
-rw-r--r--security/smack/smack_access.c11
-rw-r--r--security/smack/smack_lsm.c6
-rw-r--r--security/smack/smackfs.c14
34 files changed, 781 insertions, 377 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 452567d3a08e..d97cba3e3849 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -621,7 +621,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
621 * There is no exception for unconfined as change_hat is not 621 * There is no exception for unconfined as change_hat is not
622 * available. 622 * available.
623 */ 623 */
624 if (current->no_new_privs) 624 if (task_no_new_privs(current))
625 return -EPERM; 625 return -EPERM;
626 626
627 /* released below */ 627 /* released below */
@@ -776,7 +776,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
776 * no_new_privs is set because this aways results in a reduction 776 * no_new_privs is set because this aways results in a reduction
777 * of permissions. 777 * of permissions.
778 */ 778 */
779 if (current->no_new_privs && !unconfined(profile)) { 779 if (task_no_new_privs(current) && !unconfined(profile)) {
780 put_cred(cred); 780 put_cred(cred);
781 return -EPERM; 781 return -EPERM;
782 } 782 }
diff --git a/security/capability.c b/security/capability.c
index e76373de3129..a74fde6a7468 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -401,6 +401,11 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode)
401 return 0; 401 return 0;
402} 402}
403 403
404static int cap_kernel_fw_from_file(struct file *file, char *buf, size_t size)
405{
406 return 0;
407}
408
404static int cap_kernel_module_request(char *kmod_name) 409static int cap_kernel_module_request(char *kmod_name)
405{ 410{
406 return 0; 411 return 0;
@@ -1015,6 +1020,7 @@ void __init security_fixup_ops(struct security_operations *ops)
1015 set_to_cap_if_null(ops, cred_transfer); 1020 set_to_cap_if_null(ops, cred_transfer);
1016 set_to_cap_if_null(ops, kernel_act_as); 1021 set_to_cap_if_null(ops, kernel_act_as);
1017 set_to_cap_if_null(ops, kernel_create_files_as); 1022 set_to_cap_if_null(ops, kernel_create_files_as);
1023 set_to_cap_if_null(ops, kernel_fw_from_file);
1018 set_to_cap_if_null(ops, kernel_module_request); 1024 set_to_cap_if_null(ops, kernel_module_request);
1019 set_to_cap_if_null(ops, kernel_module_from_file); 1025 set_to_cap_if_null(ops, kernel_module_from_file);
1020 set_to_cap_if_null(ops, task_fix_setuid); 1026 set_to_cap_if_null(ops, task_fix_setuid);
diff --git a/security/commoncap.c b/security/commoncap.c
index b9d613e0ef14..bab0611afc1e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -421,6 +421,9 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
421 cpu_caps->inheritable.cap[i] = le32_to_cpu(caps.data[i].inheritable); 421 cpu_caps->inheritable.cap[i] = le32_to_cpu(caps.data[i].inheritable);
422 } 422 }
423 423
424 cpu_caps->permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
425 cpu_caps->inheritable.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
426
424 return 0; 427 return 0;
425} 428}
426 429
@@ -822,15 +825,20 @@ int cap_task_setnice(struct task_struct *p, int nice)
822 * Implement PR_CAPBSET_DROP. Attempt to remove the specified capability from 825 * Implement PR_CAPBSET_DROP. Attempt to remove the specified capability from
823 * the current task's bounding set. Returns 0 on success, -ve on error. 826 * the current task's bounding set. Returns 0 on success, -ve on error.
824 */ 827 */
825static long cap_prctl_drop(struct cred *new, unsigned long cap) 828static int cap_prctl_drop(unsigned long cap)
826{ 829{
830 struct cred *new;
831
827 if (!ns_capable(current_user_ns(), CAP_SETPCAP)) 832 if (!ns_capable(current_user_ns(), CAP_SETPCAP))
828 return -EPERM; 833 return -EPERM;
829 if (!cap_valid(cap)) 834 if (!cap_valid(cap))
830 return -EINVAL; 835 return -EINVAL;
831 836
837 new = prepare_creds();
838 if (!new)
839 return -ENOMEM;
832 cap_lower(new->cap_bset, cap); 840 cap_lower(new->cap_bset, cap);
833 return 0; 841 return commit_creds(new);
834} 842}
835 843
836/** 844/**
@@ -848,26 +856,17 @@ static long cap_prctl_drop(struct cred *new, unsigned long cap)
848int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, 856int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
849 unsigned long arg4, unsigned long arg5) 857 unsigned long arg4, unsigned long arg5)
850{ 858{
859 const struct cred *old = current_cred();
851 struct cred *new; 860 struct cred *new;
852 long error = 0;
853
854 new = prepare_creds();
855 if (!new)
856 return -ENOMEM;
857 861
858 switch (option) { 862 switch (option) {
859 case PR_CAPBSET_READ: 863 case PR_CAPBSET_READ:
860 error = -EINVAL;
861 if (!cap_valid(arg2)) 864 if (!cap_valid(arg2))
862 goto error; 865 return -EINVAL;
863 error = !!cap_raised(new->cap_bset, arg2); 866 return !!cap_raised(old->cap_bset, arg2);
864 goto no_change;
865 867
866 case PR_CAPBSET_DROP: 868 case PR_CAPBSET_DROP:
867 error = cap_prctl_drop(new, arg2); 869 return cap_prctl_drop(arg2);
868 if (error < 0)
869 goto error;
870 goto changed;
871 870
872 /* 871 /*
873 * The next four prctl's remain to assist with transitioning a 872 * The next four prctl's remain to assist with transitioning a
@@ -889,10 +888,9 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
889 * capability-based-privilege environment. 888 * capability-based-privilege environment.
890 */ 889 */
891 case PR_SET_SECUREBITS: 890 case PR_SET_SECUREBITS:
892 error = -EPERM; 891 if ((((old->securebits & SECURE_ALL_LOCKS) >> 1)
893 if ((((new->securebits & SECURE_ALL_LOCKS) >> 1) 892 & (old->securebits ^ arg2)) /*[1]*/
894 & (new->securebits ^ arg2)) /*[1]*/ 893 || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
895 || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
896 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ 894 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
897 || (cap_capable(current_cred(), 895 || (cap_capable(current_cred(),
898 current_cred()->user_ns, CAP_SETPCAP, 896 current_cred()->user_ns, CAP_SETPCAP,
@@ -906,46 +904,39 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
906 */ 904 */
907 ) 905 )
908 /* cannot change a locked bit */ 906 /* cannot change a locked bit */
909 goto error; 907 return -EPERM;
908
909 new = prepare_creds();
910 if (!new)
911 return -ENOMEM;
910 new->securebits = arg2; 912 new->securebits = arg2;
911 goto changed; 913 return commit_creds(new);
912 914
913 case PR_GET_SECUREBITS: 915 case PR_GET_SECUREBITS:
914 error = new->securebits; 916 return old->securebits;
915 goto no_change;
916 917
917 case PR_GET_KEEPCAPS: 918 case PR_GET_KEEPCAPS:
918 if (issecure(SECURE_KEEP_CAPS)) 919 return !!issecure(SECURE_KEEP_CAPS);
919 error = 1;
920 goto no_change;
921 920
922 case PR_SET_KEEPCAPS: 921 case PR_SET_KEEPCAPS:
923 error = -EINVAL;
924 if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */ 922 if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */
925 goto error; 923 return -EINVAL;
926 error = -EPERM;
927 if (issecure(SECURE_KEEP_CAPS_LOCKED)) 924 if (issecure(SECURE_KEEP_CAPS_LOCKED))
928 goto error; 925 return -EPERM;
926
927 new = prepare_creds();
928 if (!new)
929 return -ENOMEM;
929 if (arg2) 930 if (arg2)
930 new->securebits |= issecure_mask(SECURE_KEEP_CAPS); 931 new->securebits |= issecure_mask(SECURE_KEEP_CAPS);
931 else 932 else
932 new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); 933 new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
933 goto changed; 934 return commit_creds(new);
934 935
935 default: 936 default:
936 /* No functionality available - continue with default */ 937 /* No functionality available - continue with default */
937 error = -ENOSYS; 938 return -ENOSYS;
938 goto error;
939 } 939 }
940
941 /* Functionality provided */
942changed:
943 return commit_creds(new);
944
945no_change:
946error:
947 abort_creds(new);
948 return error;
949} 940}
950 941
951/** 942/**
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index b4af4ebc5be2..8d4fbff8b87c 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -13,7 +13,9 @@
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 14
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/sched.h>
16#include <linux/rbtree.h> 17#include <linux/rbtree.h>
18#include <linux/cred.h>
17#include <linux/key-type.h> 19#include <linux/key-type.h>
18#include <linux/digsig.h> 20#include <linux/digsig.h>
19 21
@@ -24,7 +26,11 @@ static struct key *keyring[INTEGRITY_KEYRING_MAX];
24static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { 26static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
25 "_evm", 27 "_evm",
26 "_module", 28 "_module",
29#ifndef CONFIG_IMA_TRUSTED_KEYRING
27 "_ima", 30 "_ima",
31#else
32 ".ima",
33#endif
28}; 34};
29 35
30int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 36int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
@@ -56,3 +62,25 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
56 62
57 return -EOPNOTSUPP; 63 return -EOPNOTSUPP;
58} 64}
65
66int integrity_init_keyring(const unsigned int id)
67{
68 const struct cred *cred = current_cred();
69 int err = 0;
70
71 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
72 KGIDT_INIT(0), cred,
73 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
74 KEY_USR_VIEW | KEY_USR_READ |
75 KEY_USR_WRITE | KEY_USR_SEARCH),
76 KEY_ALLOC_NOT_IN_QUOTA, NULL);
77 if (!IS_ERR(keyring[id]))
78 set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags);
79 else {
80 err = PTR_ERR(keyring[id]);
81 pr_info("Can't allocate %s keyring (%d)\n",
82 keyring_name[id], err);
83 keyring[id] = NULL;
84 }
85 return err;
86}
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 81a27971d884..08758fbd496f 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -123,3 +123,13 @@ config IMA_APPRAISE
123 For more information on integrity appraisal refer to: 123 For more information on integrity appraisal refer to:
124 <http://linux-ima.sourceforge.net> 124 <http://linux-ima.sourceforge.net>
125 If unsure, say N. 125 If unsure, say N.
126
127config IMA_TRUSTED_KEYRING
128 bool "Require all keys on the .ima keyring be signed"
129 depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
130 depends on INTEGRITY_ASYMMETRIC_KEYS
131 select KEYS_DEBUG_PROC_KEYS
132 default y
133 help
134 This option requires that all keys added to the .ima
135 keyring be signed by a key on the system trusted keyring.
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index f79fa8be203c..57da4bd7ba0c 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -158,7 +158,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
158struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 158struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
159 159
160/* IMA policy related functions */ 160/* IMA policy related functions */
161enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, POST_SETATTR }; 161enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };
162 162
163int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 163int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
164 int flags); 164 int flags);
@@ -171,6 +171,7 @@ void ima_delete_rules(void);
171#define IMA_APPRAISE_ENFORCE 0x01 171#define IMA_APPRAISE_ENFORCE 0x01
172#define IMA_APPRAISE_FIX 0x02 172#define IMA_APPRAISE_FIX 0x02
173#define IMA_APPRAISE_MODULES 0x04 173#define IMA_APPRAISE_MODULES 0x04
174#define IMA_APPRAISE_FIRMWARE 0x08
174 175
175#ifdef CONFIG_IMA_APPRAISE 176#ifdef CONFIG_IMA_APPRAISE
176int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 177int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
@@ -249,4 +250,16 @@ static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
249 return -EINVAL; 250 return -EINVAL;
250} 251}
251#endif /* CONFIG_IMA_LSM_RULES */ 252#endif /* CONFIG_IMA_LSM_RULES */
253
254#ifdef CONFIG_IMA_TRUSTED_KEYRING
255static inline int ima_init_keyring(const unsigned int id)
256{
257 return integrity_init_keyring(id);
258}
259#else
260static inline int ima_init_keyring(const unsigned int id)
261{
262 return 0;
263}
264#endif /* CONFIG_IMA_TRUSTED_KEYRING */
252#endif 265#endif
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index d3113d4aaa3c..86bfd5c5df85 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -75,6 +75,8 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
75 return iint->ima_bprm_status; 75 return iint->ima_bprm_status;
76 case MODULE_CHECK: 76 case MODULE_CHECK:
77 return iint->ima_module_status; 77 return iint->ima_module_status;
78 case FIRMWARE_CHECK:
79 return iint->ima_firmware_status;
78 case FILE_CHECK: 80 case FILE_CHECK:
79 default: 81 default:
80 return iint->ima_file_status; 82 return iint->ima_file_status;
@@ -94,6 +96,9 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
94 case MODULE_CHECK: 96 case MODULE_CHECK:
95 iint->ima_module_status = status; 97 iint->ima_module_status = status;
96 break; 98 break;
99 case FIRMWARE_CHECK:
100 iint->ima_firmware_status = status;
101 break;
97 case FILE_CHECK: 102 case FILE_CHECK:
98 default: 103 default:
99 iint->ima_file_status = status; 104 iint->ima_file_status = status;
@@ -113,6 +118,9 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
113 case MODULE_CHECK: 118 case MODULE_CHECK:
114 iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED); 119 iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
115 break; 120 break;
121 case FIRMWARE_CHECK:
122 iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED);
123 break;
116 case FILE_CHECK: 124 case FILE_CHECK:
117 default: 125 default:
118 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED); 126 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
@@ -214,7 +222,7 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
214 hash_start = 1; 222 hash_start = 1;
215 case IMA_XATTR_DIGEST: 223 case IMA_XATTR_DIGEST:
216 if (iint->flags & IMA_DIGSIG_REQUIRED) { 224 if (iint->flags & IMA_DIGSIG_REQUIRED) {
217 cause = "IMA signature required"; 225 cause = "IMA-signature-required";
218 status = INTEGRITY_FAIL; 226 status = INTEGRITY_FAIL;
219 break; 227 break;
220 } 228 }
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index ccd0ac8fa9a0..0bd732843fe7 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -16,6 +16,8 @@
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 17
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/moduleparam.h>
20#include <linux/ratelimit.h>
19#include <linux/file.h> 21#include <linux/file.h>
20#include <linux/crypto.h> 22#include <linux/crypto.h>
21#include <linux/scatterlist.h> 23#include <linux/scatterlist.h>
@@ -25,7 +27,45 @@
25#include <crypto/hash_info.h> 27#include <crypto/hash_info.h>
26#include "ima.h" 28#include "ima.h"
27 29
30struct ahash_completion {
31 struct completion completion;
32 int err;
33};
34
35/* minimum file size for ahash use */
36static unsigned long ima_ahash_minsize;
37module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644);
38MODULE_PARM_DESC(ahash_minsize, "Minimum file size for ahash use");
39
40/* default is 0 - 1 page. */
41static int ima_maxorder;
42static unsigned int ima_bufsize = PAGE_SIZE;
43
44static int param_set_bufsize(const char *val, const struct kernel_param *kp)
45{
46 unsigned long long size;
47 int order;
48
49 size = memparse(val, NULL);
50 order = get_order(size);
51 if (order >= MAX_ORDER)
52 return -EINVAL;
53 ima_maxorder = order;
54 ima_bufsize = PAGE_SIZE << order;
55 return 0;
56}
57
58static struct kernel_param_ops param_ops_bufsize = {
59 .set = param_set_bufsize,
60 .get = param_get_uint,
61};
62#define param_check_bufsize(name, p) __param_check(name, p, unsigned int)
63
64module_param_named(ahash_bufsize, ima_bufsize, bufsize, 0644);
65MODULE_PARM_DESC(ahash_bufsize, "Maximum ahash buffer size");
66
28static struct crypto_shash *ima_shash_tfm; 67static struct crypto_shash *ima_shash_tfm;
68static struct crypto_ahash *ima_ahash_tfm;
29 69
30/** 70/**
31 * ima_kernel_read - read file content 71 * ima_kernel_read - read file content
@@ -93,9 +133,246 @@ static void ima_free_tfm(struct crypto_shash *tfm)
93 crypto_free_shash(tfm); 133 crypto_free_shash(tfm);
94} 134}
95 135
96/* 136/**
97 * Calculate the MD5/SHA1 file digest 137 * ima_alloc_pages() - Allocate contiguous pages.
138 * @max_size: Maximum amount of memory to allocate.
139 * @allocated_size: Returned size of actual allocation.
140 * @last_warn: Should the min_size allocation warn or not.
141 *
142 * Tries to do opportunistic allocation for memory first trying to allocate
143 * max_size amount of memory and then splitting that until zero order is
144 * reached. Allocation is tried without generating allocation warnings unless
145 * last_warn is set. Last_warn set affects only last allocation of zero order.
146 *
147 * By default, ima_maxorder is 0 and it is equivalent to kmalloc(GFP_KERNEL)
148 *
149 * Return pointer to allocated memory, or NULL on failure.
150 */
151static void *ima_alloc_pages(loff_t max_size, size_t *allocated_size,
152 int last_warn)
153{
154 void *ptr;
155 int order = ima_maxorder;
156 gfp_t gfp_mask = __GFP_WAIT | __GFP_NOWARN | __GFP_NORETRY;
157
158 if (order)
159 order = min(get_order(max_size), order);
160
161 for (; order; order--) {
162 ptr = (void *)__get_free_pages(gfp_mask, order);
163 if (ptr) {
164 *allocated_size = PAGE_SIZE << order;
165 return ptr;
166 }
167 }
168
169 /* order is zero - one page */
170
171 gfp_mask = GFP_KERNEL;
172
173 if (!last_warn)
174 gfp_mask |= __GFP_NOWARN;
175
176 ptr = (void *)__get_free_pages(gfp_mask, 0);
177 if (ptr) {
178 *allocated_size = PAGE_SIZE;
179 return ptr;
180 }
181
182 *allocated_size = 0;
183 return NULL;
184}
185
186/**
187 * ima_free_pages() - Free pages allocated by ima_alloc_pages().
188 * @ptr: Pointer to allocated pages.
189 * @size: Size of allocated buffer.
98 */ 190 */
191static void ima_free_pages(void *ptr, size_t size)
192{
193 if (!ptr)
194 return;
195 free_pages((unsigned long)ptr, get_order(size));
196}
197
198static struct crypto_ahash *ima_alloc_atfm(enum hash_algo algo)
199{
200 struct crypto_ahash *tfm = ima_ahash_tfm;
201 int rc;
202
203 if ((algo != ima_hash_algo && algo < HASH_ALGO__LAST) || !tfm) {
204 tfm = crypto_alloc_ahash(hash_algo_name[algo], 0, 0);
205 if (!IS_ERR(tfm)) {
206 if (algo == ima_hash_algo)
207 ima_ahash_tfm = tfm;
208 } else {
209 rc = PTR_ERR(tfm);
210 pr_err("Can not allocate %s (reason: %d)\n",
211 hash_algo_name[algo], rc);
212 }
213 }
214 return tfm;
215}
216
217static void ima_free_atfm(struct crypto_ahash *tfm)
218{
219 if (tfm != ima_ahash_tfm)
220 crypto_free_ahash(tfm);
221}
222
223static void ahash_complete(struct crypto_async_request *req, int err)
224{
225 struct ahash_completion *res = req->data;
226
227 if (err == -EINPROGRESS)
228 return;
229 res->err = err;
230 complete(&res->completion);
231}
232
233static int ahash_wait(int err, struct ahash_completion *res)
234{
235 switch (err) {
236 case 0:
237 break;
238 case -EINPROGRESS:
239 case -EBUSY:
240 wait_for_completion(&res->completion);
241 reinit_completion(&res->completion);
242 err = res->err;
243 /* fall through */
244 default:
245 pr_crit_ratelimited("ahash calculation failed: err: %d\n", err);
246 }
247
248 return err;
249}
250
251static int ima_calc_file_hash_atfm(struct file *file,
252 struct ima_digest_data *hash,
253 struct crypto_ahash *tfm)
254{
255 loff_t i_size, offset;
256 char *rbuf[2] = { NULL, };
257 int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0;
258 struct ahash_request *req;
259 struct scatterlist sg[1];
260 struct ahash_completion res;
261 size_t rbuf_size[2];
262
263 hash->length = crypto_ahash_digestsize(tfm);
264
265 req = ahash_request_alloc(tfm, GFP_KERNEL);
266 if (!req)
267 return -ENOMEM;
268
269 init_completion(&res.completion);
270 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
271 CRYPTO_TFM_REQ_MAY_SLEEP,
272 ahash_complete, &res);
273
274 rc = ahash_wait(crypto_ahash_init(req), &res);
275 if (rc)
276 goto out1;
277
278 i_size = i_size_read(file_inode(file));
279
280 if (i_size == 0)
281 goto out2;
282
283 /*
284 * Try to allocate maximum size of memory.
285 * Fail if even a single page cannot be allocated.
286 */
287 rbuf[0] = ima_alloc_pages(i_size, &rbuf_size[0], 1);
288 if (!rbuf[0]) {
289 rc = -ENOMEM;
290 goto out1;
291 }
292
293 /* Only allocate one buffer if that is enough. */
294 if (i_size > rbuf_size[0]) {
295 /*
296 * Try to allocate secondary buffer. If that fails fallback to
297 * using single buffering. Use previous memory allocation size
298 * as baseline for possible allocation size.
299 */
300 rbuf[1] = ima_alloc_pages(i_size - rbuf_size[0],
301 &rbuf_size[1], 0);
302 }
303
304 if (!(file->f_mode & FMODE_READ)) {
305 file->f_mode |= FMODE_READ;
306 read = 1;
307 }
308
309 for (offset = 0; offset < i_size; offset += rbuf_len) {
310 if (!rbuf[1] && offset) {
311 /* Not using two buffers, and it is not the first
312 * read/request, wait for the completion of the
313 * previous ahash_update() request.
314 */
315 rc = ahash_wait(ahash_rc, &res);
316 if (rc)
317 goto out3;
318 }
319 /* read buffer */
320 rbuf_len = min_t(loff_t, i_size - offset, rbuf_size[active]);
321 rc = ima_kernel_read(file, offset, rbuf[active], rbuf_len);
322 if (rc != rbuf_len)
323 goto out3;
324
325 if (rbuf[1] && offset) {
326 /* Using two buffers, and it is not the first
327 * read/request, wait for the completion of the
328 * previous ahash_update() request.
329 */
330 rc = ahash_wait(ahash_rc, &res);
331 if (rc)
332 goto out3;
333 }
334
335 sg_init_one(&sg[0], rbuf[active], rbuf_len);
336 ahash_request_set_crypt(req, sg, NULL, rbuf_len);
337
338 ahash_rc = crypto_ahash_update(req);
339
340 if (rbuf[1])
341 active = !active; /* swap buffers, if we use two */
342 }
343 /* wait for the last update request to complete */
344 rc = ahash_wait(ahash_rc, &res);
345out3:
346 if (read)
347 file->f_mode &= ~FMODE_READ;
348 ima_free_pages(rbuf[0], rbuf_size[0]);
349 ima_free_pages(rbuf[1], rbuf_size[1]);
350out2:
351 if (!rc) {
352 ahash_request_set_crypt(req, NULL, hash->digest, 0);
353 rc = ahash_wait(crypto_ahash_final(req), &res);
354 }
355out1:
356 ahash_request_free(req);
357 return rc;
358}
359
360static int ima_calc_file_ahash(struct file *file, struct ima_digest_data *hash)
361{
362 struct crypto_ahash *tfm;
363 int rc;
364
365 tfm = ima_alloc_atfm(hash->algo);
366 if (IS_ERR(tfm))
367 return PTR_ERR(tfm);
368
369 rc = ima_calc_file_hash_atfm(file, hash, tfm);
370
371 ima_free_atfm(tfm);
372
373 return rc;
374}
375
99static int ima_calc_file_hash_tfm(struct file *file, 376static int ima_calc_file_hash_tfm(struct file *file,
100 struct ima_digest_data *hash, 377 struct ima_digest_data *hash,
101 struct crypto_shash *tfm) 378 struct crypto_shash *tfm)
@@ -156,7 +433,7 @@ out:
156 return rc; 433 return rc;
157} 434}
158 435
159int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) 436static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash)
160{ 437{
161 struct crypto_shash *tfm; 438 struct crypto_shash *tfm;
162 int rc; 439 int rc;
@@ -173,6 +450,35 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
173} 450}
174 451
175/* 452/*
453 * ima_calc_file_hash - calculate file hash
454 *
455 * Asynchronous hash (ahash) allows using HW acceleration for calculating
456 * a hash. ahash performance varies for different data sizes on different
457 * crypto accelerators. shash performance might be better for smaller files.
458 * The 'ima.ahash_minsize' module parameter allows specifying the best
459 * minimum file size for using ahash on the system.
460 *
461 * If the ima.ahash_minsize parameter is not specified, this function uses
462 * shash for the hash calculation. If ahash fails, it falls back to using
463 * shash.
464 */
465int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
466{
467 loff_t i_size;
468 int rc;
469
470 i_size = i_size_read(file_inode(file));
471
472 if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
473 rc = ima_calc_file_ahash(file, hash);
474 if (!rc)
475 return 0;
476 }
477
478 return ima_calc_file_shash(file, hash);
479}
480
481/*
176 * Calculate the hash of template data 482 * Calculate the hash of template data
177 */ 483 */
178static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data, 484static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 09baa335ebc7..2917f980bf30 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -88,8 +88,6 @@ static void ima_rdwr_violation_check(struct file *file)
88 if (!S_ISREG(inode->i_mode) || !ima_initialized) 88 if (!S_ISREG(inode->i_mode) || !ima_initialized)
89 return; 89 return;
90 90
91 mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */
92
93 if (mode & FMODE_WRITE) { 91 if (mode & FMODE_WRITE) {
94 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) { 92 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) {
95 struct integrity_iint_cache *iint; 93 struct integrity_iint_cache *iint;
@@ -104,8 +102,6 @@ static void ima_rdwr_violation_check(struct file *file)
104 send_writers = true; 102 send_writers = true;
105 } 103 }
106 104
107 mutex_unlock(&inode->i_mutex);
108
109 if (!send_tomtou && !send_writers) 105 if (!send_tomtou && !send_writers)
110 return; 106 return;
111 107
@@ -163,7 +159,7 @@ static int process_measurement(struct file *file, const char *filename,
163{ 159{
164 struct inode *inode = file_inode(file); 160 struct inode *inode = file_inode(file);
165 struct integrity_iint_cache *iint; 161 struct integrity_iint_cache *iint;
166 struct ima_template_desc *template_desc = ima_template_desc_current(); 162 struct ima_template_desc *template_desc;
167 char *pathbuf = NULL; 163 char *pathbuf = NULL;
168 const char *pathname = NULL; 164 const char *pathname = NULL;
169 int rc = -ENOMEM, action, must_appraise, _func; 165 int rc = -ENOMEM, action, must_appraise, _func;
@@ -207,6 +203,7 @@ static int process_measurement(struct file *file, const char *filename,
207 goto out_digsig; 203 goto out_digsig;
208 } 204 }
209 205
206 template_desc = ima_template_desc_current();
210 if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { 207 if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
211 if (action & IMA_APPRAISE_SUBMASK) 208 if (action & IMA_APPRAISE_SUBMASK)
212 xattr_ptr = &xattr_value; 209 xattr_ptr = &xattr_value;
@@ -322,14 +319,31 @@ int ima_module_check(struct file *file)
322 return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK); 319 return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK);
323} 320}
324 321
322int ima_fw_from_file(struct file *file, char *buf, size_t size)
323{
324 if (!file) {
325 if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
326 (ima_appraise & IMA_APPRAISE_ENFORCE))
327 return -EACCES; /* INTEGRITY_UNKNOWN */
328 return 0;
329 }
330 return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK);
331}
332
325static int __init init_ima(void) 333static int __init init_ima(void)
326{ 334{
327 int error; 335 int error;
328 336
329 hash_setup(CONFIG_IMA_DEFAULT_HASH); 337 hash_setup(CONFIG_IMA_DEFAULT_HASH);
330 error = ima_init(); 338 error = ima_init();
331 if (!error) 339 if (error)
332 ima_initialized = 1; 340 goto out;
341
342 error = ima_init_keyring(INTEGRITY_KEYRING_IMA);
343 if (error)
344 goto out;
345 ima_initialized = 1;
346out:
333 return error; 347 return error;
334} 348}
335 349
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 40a7488f6721..07099a8bc283 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -84,6 +84,7 @@ static struct ima_rule_entry default_rules[] = {
84 {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, 84 {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID,
85 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 85 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
86 {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, 86 {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
87 {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
87}; 88};
88 89
89static struct ima_rule_entry default_appraise_rules[] = { 90static struct ima_rule_entry default_appraise_rules[] = {
@@ -241,6 +242,8 @@ static int get_subaction(struct ima_rule_entry *rule, int func)
241 return IMA_BPRM_APPRAISE; 242 return IMA_BPRM_APPRAISE;
242 case MODULE_CHECK: 243 case MODULE_CHECK:
243 return IMA_MODULE_APPRAISE; 244 return IMA_MODULE_APPRAISE;
245 case FIRMWARE_CHECK:
246 return IMA_FIRMWARE_APPRAISE;
244 case FILE_CHECK: 247 case FILE_CHECK:
245 default: 248 default:
246 return IMA_FILE_APPRAISE; 249 return IMA_FILE_APPRAISE;
@@ -332,7 +335,7 @@ void __init ima_init_policy(void)
332void ima_update_policy(void) 335void ima_update_policy(void)
333{ 336{
334 static const char op[] = "policy_update"; 337 static const char op[] = "policy_update";
335 const char *cause = "already exists"; 338 const char *cause = "already-exists";
336 int result = 1; 339 int result = 1;
337 int audit_info = 0; 340 int audit_info = 0;
338 341
@@ -486,6 +489,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
486 entry->func = FILE_CHECK; 489 entry->func = FILE_CHECK;
487 else if (strcmp(args[0].from, "MODULE_CHECK") == 0) 490 else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
488 entry->func = MODULE_CHECK; 491 entry->func = MODULE_CHECK;
492 else if (strcmp(args[0].from, "FIRMWARE_CHECK") == 0)
493 entry->func = FIRMWARE_CHECK;
489 else if ((strcmp(args[0].from, "FILE_MMAP") == 0) 494 else if ((strcmp(args[0].from, "FILE_MMAP") == 0)
490 || (strcmp(args[0].from, "MMAP_CHECK") == 0)) 495 || (strcmp(args[0].from, "MMAP_CHECK") == 0))
491 entry->func = MMAP_CHECK; 496 entry->func = MMAP_CHECK;
@@ -636,6 +641,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
636 result = -EINVAL; 641 result = -EINVAL;
637 else if (entry->func == MODULE_CHECK) 642 else if (entry->func == MODULE_CHECK)
638 ima_appraise |= IMA_APPRAISE_MODULES; 643 ima_appraise |= IMA_APPRAISE_MODULES;
644 else if (entry->func == FIRMWARE_CHECK)
645 ima_appraise |= IMA_APPRAISE_FIRMWARE;
639 audit_log_format(ab, "res=%d", !result); 646 audit_log_format(ab, "res=%d", !result);
640 audit_log_end(ab); 647 audit_log_end(ab);
641 return result; 648 return result;
@@ -659,7 +666,7 @@ ssize_t ima_parse_add_rule(char *rule)
659 /* Prevent installed policy from changing */ 666 /* Prevent installed policy from changing */
660 if (ima_rules != &ima_default_rules) { 667 if (ima_rules != &ima_default_rules) {
661 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 668 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
662 NULL, op, "already exists", 669 NULL, op, "already-exists",
663 -EACCES, audit_info); 670 -EACCES, audit_info);
664 return -EACCES; 671 return -EACCES;
665 } 672 }
@@ -685,7 +692,7 @@ ssize_t ima_parse_add_rule(char *rule)
685 if (result) { 692 if (result) {
686 kfree(entry); 693 kfree(entry);
687 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 694 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
688 NULL, op, "invalid policy", result, 695 NULL, op, "invalid-policy", result,
689 audit_info); 696 audit_info);
690 return result; 697 return result;
691 } 698 }
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 33c0a70f6b15..19b8e314ca96 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -46,10 +46,14 @@
46#define IMA_BPRM_APPRAISED 0x00002000 46#define IMA_BPRM_APPRAISED 0x00002000
47#define IMA_MODULE_APPRAISE 0x00004000 47#define IMA_MODULE_APPRAISE 0x00004000
48#define IMA_MODULE_APPRAISED 0x00008000 48#define IMA_MODULE_APPRAISED 0x00008000
49#define IMA_FIRMWARE_APPRAISE 0x00010000
50#define IMA_FIRMWARE_APPRAISED 0x00020000
49#define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ 51#define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
50 IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE) 52 IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \
53 IMA_FIRMWARE_APPRAISE)
51#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ 54#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
52 IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED) 55 IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \
56 IMA_FIRMWARE_APPRAISED)
53 57
54enum evm_ima_xattr_type { 58enum evm_ima_xattr_type {
55 IMA_XATTR_DIGEST = 0x01, 59 IMA_XATTR_DIGEST = 0x01,
@@ -104,6 +108,7 @@ struct integrity_iint_cache {
104 enum integrity_status ima_mmap_status:4; 108 enum integrity_status ima_mmap_status:4;
105 enum integrity_status ima_bprm_status:4; 109 enum integrity_status ima_bprm_status:4;
106 enum integrity_status ima_module_status:4; 110 enum integrity_status ima_module_status:4;
111 enum integrity_status ima_firmware_status:4;
107 enum integrity_status evm_status:4; 112 enum integrity_status evm_status:4;
108 struct ima_digest_data *ima_hash; 113 struct ima_digest_data *ima_hash;
109}; 114};
@@ -124,6 +129,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
124int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 129int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
125 const char *digest, int digestlen); 130 const char *digest, int digestlen);
126 131
132int integrity_init_keyring(const unsigned int id);
127#else 133#else
128 134
129static inline int integrity_digsig_verify(const unsigned int id, 135static inline int integrity_digsig_verify(const unsigned int id,
@@ -133,6 +139,10 @@ static inline int integrity_digsig_verify(const unsigned int id,
133 return -EOPNOTSUPP; 139 return -EOPNOTSUPP;
134} 140}
135 141
142static inline int integrity_init_keyring(const unsigned int id)
143{
144 return 0;
145}
136#endif /* CONFIG_INTEGRITY_SIGNATURE */ 146#endif /* CONFIG_INTEGRITY_SIGNATURE */
137 147
138#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS 148#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 8137b27d641d..c2f91a0cf889 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -34,7 +34,9 @@ MODULE_LICENSE("GPL");
34struct key_type key_type_big_key = { 34struct key_type key_type_big_key = {
35 .name = "big_key", 35 .name = "big_key",
36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
37 .instantiate = big_key_instantiate, 37 .preparse = big_key_preparse,
38 .free_preparse = big_key_free_preparse,
39 .instantiate = generic_key_instantiate,
38 .match = user_match, 40 .match = user_match,
39 .revoke = big_key_revoke, 41 .revoke = big_key_revoke,
40 .destroy = big_key_destroy, 42 .destroy = big_key_destroy,
@@ -43,11 +45,11 @@ struct key_type key_type_big_key = {
43}; 45};
44 46
45/* 47/*
46 * Instantiate a big key 48 * Preparse a big key
47 */ 49 */
48int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 50int big_key_preparse(struct key_preparsed_payload *prep)
49{ 51{
50 struct path *path = (struct path *)&key->payload.data2; 52 struct path *path = (struct path *)&prep->payload;
51 struct file *file; 53 struct file *file;
52 ssize_t written; 54 ssize_t written;
53 size_t datalen = prep->datalen; 55 size_t datalen = prep->datalen;
@@ -58,11 +60,9 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
58 goto error; 60 goto error;
59 61
60 /* Set an arbitrary quota */ 62 /* Set an arbitrary quota */
61 ret = key_payload_reserve(key, 16); 63 prep->quotalen = 16;
62 if (ret < 0)
63 goto error;
64 64
65 key->type_data.x[1] = datalen; 65 prep->type_data[1] = (void *)(unsigned long)datalen;
66 66
67 if (datalen > BIG_KEY_FILE_THRESHOLD) { 67 if (datalen > BIG_KEY_FILE_THRESHOLD) {
68 /* Create a shmem file to store the data in. This will permit the data 68 /* Create a shmem file to store the data in. This will permit the data
@@ -73,7 +73,7 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
73 file = shmem_kernel_file_setup("", datalen, 0); 73 file = shmem_kernel_file_setup("", datalen, 0);
74 if (IS_ERR(file)) { 74 if (IS_ERR(file)) {
75 ret = PTR_ERR(file); 75 ret = PTR_ERR(file);
76 goto err_quota; 76 goto error;
77 } 77 }
78 78
79 written = kernel_write(file, prep->data, prep->datalen, 0); 79 written = kernel_write(file, prep->data, prep->datalen, 0);
@@ -93,24 +93,33 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
93 } else { 93 } else {
94 /* Just store the data in a buffer */ 94 /* Just store the data in a buffer */
95 void *data = kmalloc(datalen, GFP_KERNEL); 95 void *data = kmalloc(datalen, GFP_KERNEL);
96 if (!data) { 96 if (!data)
97 ret = -ENOMEM; 97 return -ENOMEM;
98 goto err_quota;
99 }
100 98
101 key->payload.data = memcpy(data, prep->data, prep->datalen); 99 prep->payload[0] = memcpy(data, prep->data, prep->datalen);
102 } 100 }
103 return 0; 101 return 0;
104 102
105err_fput: 103err_fput:
106 fput(file); 104 fput(file);
107err_quota:
108 key_payload_reserve(key, 0);
109error: 105error:
110 return ret; 106 return ret;
111} 107}
112 108
113/* 109/*
110 * Clear preparsement.
111 */
112void big_key_free_preparse(struct key_preparsed_payload *prep)
113{
114 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
115 struct path *path = (struct path *)&prep->payload;
116 path_put(path);
117 } else {
118 kfree(prep->payload[0]);
119 }
120}
121
122/*
114 * dispose of the links from a revoked keyring 123 * dispose of the links from a revoked keyring
115 * - called with the key sem write-locked 124 * - called with the key sem write-locked
116 */ 125 */
diff --git a/security/keys/key.c b/security/keys/key.c
index 2048a110e7f1..b90a68c4e2c4 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -437,6 +437,11 @@ static int __key_instantiate_and_link(struct key *key,
437 /* disable the authorisation key */ 437 /* disable the authorisation key */
438 if (authkey) 438 if (authkey)
439 key_revoke(authkey); 439 key_revoke(authkey);
440
441 if (prep->expiry != TIME_T_MAX) {
442 key->expiry = prep->expiry;
443 key_schedule_gc(prep->expiry + key_gc_delay);
444 }
440 } 445 }
441 } 446 }
442 447
@@ -479,6 +484,7 @@ int key_instantiate_and_link(struct key *key,
479 prep.data = data; 484 prep.data = data;
480 prep.datalen = datalen; 485 prep.datalen = datalen;
481 prep.quotalen = key->type->def_datalen; 486 prep.quotalen = key->type->def_datalen;
487 prep.expiry = TIME_T_MAX;
482 if (key->type->preparse) { 488 if (key->type->preparse) {
483 ret = key->type->preparse(&prep); 489 ret = key->type->preparse(&prep);
484 if (ret < 0) 490 if (ret < 0)
@@ -488,7 +494,7 @@ int key_instantiate_and_link(struct key *key,
488 if (keyring) { 494 if (keyring) {
489 ret = __key_link_begin(keyring, &key->index_key, &edit); 495 ret = __key_link_begin(keyring, &key->index_key, &edit);
490 if (ret < 0) 496 if (ret < 0)
491 goto error_free_preparse; 497 goto error;
492 } 498 }
493 499
494 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit); 500 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
@@ -496,10 +502,9 @@ int key_instantiate_and_link(struct key *key,
496 if (keyring) 502 if (keyring)
497 __key_link_end(keyring, &key->index_key, edit); 503 __key_link_end(keyring, &key->index_key, edit);
498 504
499error_free_preparse: 505error:
500 if (key->type->preparse) 506 if (key->type->preparse)
501 key->type->free_preparse(&prep); 507 key->type->free_preparse(&prep);
502error:
503 return ret; 508 return ret;
504} 509}
505 510
@@ -811,11 +816,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
811 prep.datalen = plen; 816 prep.datalen = plen;
812 prep.quotalen = index_key.type->def_datalen; 817 prep.quotalen = index_key.type->def_datalen;
813 prep.trusted = flags & KEY_ALLOC_TRUSTED; 818 prep.trusted = flags & KEY_ALLOC_TRUSTED;
819 prep.expiry = TIME_T_MAX;
814 if (index_key.type->preparse) { 820 if (index_key.type->preparse) {
815 ret = index_key.type->preparse(&prep); 821 ret = index_key.type->preparse(&prep);
816 if (ret < 0) { 822 if (ret < 0) {
817 key_ref = ERR_PTR(ret); 823 key_ref = ERR_PTR(ret);
818 goto error_put_type; 824 goto error_free_prep;
819 } 825 }
820 if (!index_key.description) 826 if (!index_key.description)
821 index_key.description = prep.description; 827 index_key.description = prep.description;
@@ -941,6 +947,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
941 prep.data = payload; 947 prep.data = payload;
942 prep.datalen = plen; 948 prep.datalen = plen;
943 prep.quotalen = key->type->def_datalen; 949 prep.quotalen = key->type->def_datalen;
950 prep.expiry = TIME_T_MAX;
944 if (key->type->preparse) { 951 if (key->type->preparse) {
945 ret = key->type->preparse(&prep); 952 ret = key->type->preparse(&prep);
946 if (ret < 0) 953 if (ret < 0)
@@ -956,9 +963,9 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
956 963
957 up_write(&key->sem); 964 up_write(&key->sem);
958 965
966error:
959 if (key->type->preparse) 967 if (key->type->preparse)
960 key->type->free_preparse(&prep); 968 key->type->free_preparse(&prep);
961error:
962 return ret; 969 return ret;
963} 970}
964EXPORT_SYMBOL(key_update); 971EXPORT_SYMBOL(key_update);
@@ -1024,6 +1031,38 @@ void key_invalidate(struct key *key)
1024EXPORT_SYMBOL(key_invalidate); 1031EXPORT_SYMBOL(key_invalidate);
1025 1032
1026/** 1033/**
1034 * generic_key_instantiate - Simple instantiation of a key from preparsed data
1035 * @key: The key to be instantiated
1036 * @prep: The preparsed data to load.
1037 *
1038 * Instantiate a key from preparsed data. We assume we can just copy the data
1039 * in directly and clear the old pointers.
1040 *
1041 * This can be pointed to directly by the key type instantiate op pointer.
1042 */
1043int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
1044{
1045 int ret;
1046
1047 pr_devel("==>%s()\n", __func__);
1048
1049 ret = key_payload_reserve(key, prep->quotalen);
1050 if (ret == 0) {
1051 key->type_data.p[0] = prep->type_data[0];
1052 key->type_data.p[1] = prep->type_data[1];
1053 rcu_assign_keypointer(key, prep->payload[0]);
1054 key->payload.data2[1] = prep->payload[1];
1055 prep->type_data[0] = NULL;
1056 prep->type_data[1] = NULL;
1057 prep->payload[0] = NULL;
1058 prep->payload[1] = NULL;
1059 }
1060 pr_devel("<==%s() = %d\n", __func__, ret);
1061 return ret;
1062}
1063EXPORT_SYMBOL(generic_key_instantiate);
1064
1065/**
1027 * register_key_type - Register a type of key. 1066 * register_key_type - Register a type of key.
1028 * @ktype: The new key type. 1067 * @ktype: The new key type.
1029 * 1068 *
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index cd5bd0cef25d..e26f860e5f2e 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -37,8 +37,6 @@ static int key_get_type_from_user(char *type,
37 return ret; 37 return ret;
38 if (ret == 0 || ret >= len) 38 if (ret == 0 || ret >= len)
39 return -EINVAL; 39 return -EINVAL;
40 if (type[0] == '.')
41 return -EPERM;
42 type[len - 1] = '\0'; 40 type[len - 1] = '\0';
43 return 0; 41 return 0;
44} 42}
@@ -86,6 +84,10 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
86 if (!*description) { 84 if (!*description) {
87 kfree(description); 85 kfree(description);
88 description = NULL; 86 description = NULL;
87 } else if ((description[0] == '.') &&
88 (strncmp(type, "keyring", 7) == 0)) {
89 ret = -EPERM;
90 goto error2;
89 } 91 }
90 } 92 }
91 93
@@ -404,12 +406,25 @@ long keyctl_invalidate_key(key_serial_t id)
404 key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH); 406 key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
405 if (IS_ERR(key_ref)) { 407 if (IS_ERR(key_ref)) {
406 ret = PTR_ERR(key_ref); 408 ret = PTR_ERR(key_ref);
409
410 /* Root is permitted to invalidate certain special keys */
411 if (capable(CAP_SYS_ADMIN)) {
412 key_ref = lookup_user_key(id, 0, 0);
413 if (IS_ERR(key_ref))
414 goto error;
415 if (test_bit(KEY_FLAG_ROOT_CAN_INVAL,
416 &key_ref_to_ptr(key_ref)->flags))
417 goto invalidate;
418 goto error_put;
419 }
420
407 goto error; 421 goto error;
408 } 422 }
409 423
424invalidate:
410 key_invalidate(key_ref_to_ptr(key_ref)); 425 key_invalidate(key_ref_to_ptr(key_ref));
411 ret = 0; 426 ret = 0;
412 427error_put:
413 key_ref_put(key_ref); 428 key_ref_put(key_ref);
414error: 429error:
415 kleave(" = %ld", ret); 430 kleave(" = %ld", ret);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 9cf2575f0d97..8314a7d2104d 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -73,6 +73,8 @@ static inline unsigned keyring_hash(const char *desc)
73 * can be treated as ordinary keys in addition to having their own special 73 * can be treated as ordinary keys in addition to having their own special
74 * operations. 74 * operations.
75 */ 75 */
76static int keyring_preparse(struct key_preparsed_payload *prep);
77static void keyring_free_preparse(struct key_preparsed_payload *prep);
76static int keyring_instantiate(struct key *keyring, 78static int keyring_instantiate(struct key *keyring,
77 struct key_preparsed_payload *prep); 79 struct key_preparsed_payload *prep);
78static void keyring_revoke(struct key *keyring); 80static void keyring_revoke(struct key *keyring);
@@ -84,6 +86,8 @@ static long keyring_read(const struct key *keyring,
84struct key_type key_type_keyring = { 86struct key_type key_type_keyring = {
85 .name = "keyring", 87 .name = "keyring",
86 .def_datalen = 0, 88 .def_datalen = 0,
89 .preparse = keyring_preparse,
90 .free_preparse = keyring_free_preparse,
87 .instantiate = keyring_instantiate, 91 .instantiate = keyring_instantiate,
88 .match = user_match, 92 .match = user_match,
89 .revoke = keyring_revoke, 93 .revoke = keyring_revoke,
@@ -123,6 +127,21 @@ static void keyring_publish_name(struct key *keyring)
123} 127}
124 128
125/* 129/*
130 * Preparse a keyring payload
131 */
132static int keyring_preparse(struct key_preparsed_payload *prep)
133{
134 return prep->datalen != 0 ? -EINVAL : 0;
135}
136
137/*
138 * Free a preparse of a user defined key payload
139 */
140static void keyring_free_preparse(struct key_preparsed_payload *prep)
141{
142}
143
144/*
126 * Initialise a keyring. 145 * Initialise a keyring.
127 * 146 *
128 * Returns 0 on success, -EINVAL if given any data. 147 * Returns 0 on success, -EINVAL if given any data.
@@ -130,17 +149,10 @@ static void keyring_publish_name(struct key *keyring)
130static int keyring_instantiate(struct key *keyring, 149static int keyring_instantiate(struct key *keyring,
131 struct key_preparsed_payload *prep) 150 struct key_preparsed_payload *prep)
132{ 151{
133 int ret; 152 assoc_array_init(&keyring->keys);
134 153 /* make the keyring available by name if it has one */
135 ret = -EINVAL; 154 keyring_publish_name(keyring);
136 if (prep->datalen == 0) { 155 return 0;
137 assoc_array_init(&keyring->keys);
138 /* make the keyring available by name if it has one */
139 keyring_publish_name(keyring);
140 ret = 0;
141 }
142
143 return ret;
144} 156}
145 157
146/* 158/*
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 7495a93b4b90..842e6f410d50 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -20,6 +20,8 @@
20#include "internal.h" 20#include "internal.h"
21#include <keys/user-type.h> 21#include <keys/user-type.h>
22 22
23static int request_key_auth_preparse(struct key_preparsed_payload *);
24static void request_key_auth_free_preparse(struct key_preparsed_payload *);
23static int request_key_auth_instantiate(struct key *, 25static int request_key_auth_instantiate(struct key *,
24 struct key_preparsed_payload *); 26 struct key_preparsed_payload *);
25static void request_key_auth_describe(const struct key *, struct seq_file *); 27static void request_key_auth_describe(const struct key *, struct seq_file *);
@@ -33,6 +35,8 @@ static long request_key_auth_read(const struct key *, char __user *, size_t);
33struct key_type key_type_request_key_auth = { 35struct key_type key_type_request_key_auth = {
34 .name = ".request_key_auth", 36 .name = ".request_key_auth",
35 .def_datalen = sizeof(struct request_key_auth), 37 .def_datalen = sizeof(struct request_key_auth),
38 .preparse = request_key_auth_preparse,
39 .free_preparse = request_key_auth_free_preparse,
36 .instantiate = request_key_auth_instantiate, 40 .instantiate = request_key_auth_instantiate,
37 .describe = request_key_auth_describe, 41 .describe = request_key_auth_describe,
38 .revoke = request_key_auth_revoke, 42 .revoke = request_key_auth_revoke,
@@ -40,6 +44,15 @@ struct key_type key_type_request_key_auth = {
40 .read = request_key_auth_read, 44 .read = request_key_auth_read,
41}; 45};
42 46
47int request_key_auth_preparse(struct key_preparsed_payload *prep)
48{
49 return 0;
50}
51
52void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
53{
54}
55
43/* 56/*
44 * Instantiate a request-key authorisation key. 57 * Instantiate a request-key authorisation key.
45 */ 58 */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index faa2caeb593f..eee340011f2b 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -27,7 +27,9 @@ static int logon_vet_description(const char *desc);
27struct key_type key_type_user = { 27struct key_type key_type_user = {
28 .name = "user", 28 .name = "user",
29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
30 .instantiate = user_instantiate, 30 .preparse = user_preparse,
31 .free_preparse = user_free_preparse,
32 .instantiate = generic_key_instantiate,
31 .update = user_update, 33 .update = user_update,
32 .match = user_match, 34 .match = user_match,
33 .revoke = user_revoke, 35 .revoke = user_revoke,
@@ -47,7 +49,9 @@ EXPORT_SYMBOL_GPL(key_type_user);
47struct key_type key_type_logon = { 49struct key_type key_type_logon = {
48 .name = "logon", 50 .name = "logon",
49 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 51 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
50 .instantiate = user_instantiate, 52 .preparse = user_preparse,
53 .free_preparse = user_free_preparse,
54 .instantiate = generic_key_instantiate,
51 .update = user_update, 55 .update = user_update,
52 .match = user_match, 56 .match = user_match,
53 .revoke = user_revoke, 57 .revoke = user_revoke,
@@ -58,38 +62,37 @@ struct key_type key_type_logon = {
58EXPORT_SYMBOL_GPL(key_type_logon); 62EXPORT_SYMBOL_GPL(key_type_logon);
59 63
60/* 64/*
61 * instantiate a user defined key 65 * Preparse a user defined key payload
62 */ 66 */
63int user_instantiate(struct key *key, struct key_preparsed_payload *prep) 67int user_preparse(struct key_preparsed_payload *prep)
64{ 68{
65 struct user_key_payload *upayload; 69 struct user_key_payload *upayload;
66 size_t datalen = prep->datalen; 70 size_t datalen = prep->datalen;
67 int ret;
68 71
69 ret = -EINVAL;
70 if (datalen <= 0 || datalen > 32767 || !prep->data) 72 if (datalen <= 0 || datalen > 32767 || !prep->data)
71 goto error; 73 return -EINVAL;
72
73 ret = key_payload_reserve(key, datalen);
74 if (ret < 0)
75 goto error;
76 74
77 ret = -ENOMEM;
78 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); 75 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
79 if (!upayload) 76 if (!upayload)
80 goto error; 77 return -ENOMEM;
81 78
82 /* attach the data */ 79 /* attach the data */
80 prep->quotalen = datalen;
81 prep->payload[0] = upayload;
83 upayload->datalen = datalen; 82 upayload->datalen = datalen;
84 memcpy(upayload->data, prep->data, datalen); 83 memcpy(upayload->data, prep->data, datalen);
85 rcu_assign_keypointer(key, upayload); 84 return 0;
86 ret = 0;
87
88error:
89 return ret;
90} 85}
86EXPORT_SYMBOL_GPL(user_preparse);
91 87
92EXPORT_SYMBOL_GPL(user_instantiate); 88/*
89 * Free a preparse of a user defined key payload
90 */
91void user_free_preparse(struct key_preparsed_payload *prep)
92{
93 kfree(prep->payload[0]);
94}
95EXPORT_SYMBOL_GPL(user_free_preparse);
93 96
94/* 97/*
95 * update a user defined key 98 * update a user defined key
diff --git a/security/security.c b/security/security.c
index 31614e9e96e5..e41b1a8d7644 100644
--- a/security/security.c
+++ b/security/security.c
@@ -845,6 +845,17 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
845 return security_ops->kernel_create_files_as(new, inode); 845 return security_ops->kernel_create_files_as(new, inode);
846} 846}
847 847
848int security_kernel_fw_from_file(struct file *file, char *buf, size_t size)
849{
850 int ret;
851
852 ret = security_ops->kernel_fw_from_file(file, buf, size);
853 if (ret)
854 return ret;
855 return ima_fw_from_file(file, buf, size);
856}
857EXPORT_SYMBOL_GPL(security_kernel_fw_from_file);
858
848int security_kernel_module_request(char *kmod_name) 859int security_kernel_module_request(char *kmod_name)
849{ 860{
850 return security_ops->kernel_module_request(kmod_name); 861 return security_ops->kernel_module_request(kmod_name);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 83d06db34d03..b0e940497e23 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -161,6 +161,17 @@ static int selinux_peerlbl_enabled(void)
161 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled()); 161 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
162} 162}
163 163
164static int selinux_netcache_avc_callback(u32 event)
165{
166 if (event == AVC_CALLBACK_RESET) {
167 sel_netif_flush();
168 sel_netnode_flush();
169 sel_netport_flush();
170 synchronize_net();
171 }
172 return 0;
173}
174
164/* 175/*
165 * initialise the security for the init task 176 * initialise the security for the init task
166 */ 177 */
@@ -5993,6 +6004,9 @@ static __init int selinux_init(void)
5993 if (register_security(&selinux_ops)) 6004 if (register_security(&selinux_ops))
5994 panic("SELinux: Unable to register with kernel.\n"); 6005 panic("SELinux: Unable to register with kernel.\n");
5995 6006
6007 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6008 panic("SELinux: Unable to register AVC netcache callback\n");
6009
5996 if (selinux_enforcing) 6010 if (selinux_enforcing)
5997 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); 6011 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
5998 else 6012 else
diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h
index 43d507242b42..57c6eae81eac 100644
--- a/security/selinux/include/netif.h
+++ b/security/selinux/include/netif.h
@@ -17,6 +17,8 @@
17#ifndef _SELINUX_NETIF_H_ 17#ifndef _SELINUX_NETIF_H_
18#define _SELINUX_NETIF_H_ 18#define _SELINUX_NETIF_H_
19 19
20void sel_netif_flush(void);
21
20int sel_netif_sid(int ifindex, u32 *sid); 22int sel_netif_sid(int ifindex, u32 *sid);
21 23
22#endif /* _SELINUX_NETIF_H_ */ 24#endif /* _SELINUX_NETIF_H_ */
diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h
index df7a5ed6c694..937668dd3024 100644
--- a/security/selinux/include/netnode.h
+++ b/security/selinux/include/netnode.h
@@ -27,6 +27,8 @@
27#ifndef _SELINUX_NETNODE_H 27#ifndef _SELINUX_NETNODE_H
28#define _SELINUX_NETNODE_H 28#define _SELINUX_NETNODE_H
29 29
30void sel_netnode_flush(void);
31
30int sel_netnode_sid(void *addr, u16 family, u32 *sid); 32int sel_netnode_sid(void *addr, u16 family, u32 *sid);
31 33
32#endif 34#endif
diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h
index 4d965b83d735..d1ce896b2cb0 100644
--- a/security/selinux/include/netport.h
+++ b/security/selinux/include/netport.h
@@ -26,6 +26,8 @@
26#ifndef _SELINUX_NETPORT_H 26#ifndef _SELINUX_NETPORT_H
27#define _SELINUX_NETPORT_H 27#define _SELINUX_NETPORT_H
28 28
29void sel_netport_flush(void);
30
29int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid); 31int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
30 32
31#endif 33#endif
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index ce7852cf526b..d1e0b239b602 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -8,6 +8,7 @@
8#ifndef _SELINUX_SECURITY_H_ 8#ifndef _SELINUX_SECURITY_H_
9#define _SELINUX_SECURITY_H_ 9#define _SELINUX_SECURITY_H_
10 10
11#include <linux/compiler.h>
11#include <linux/dcache.h> 12#include <linux/dcache.h>
12#include <linux/magic.h> 13#include <linux/magic.h>
13#include <linux/types.h> 14#include <linux/types.h>
@@ -220,7 +221,7 @@ struct selinux_kernel_status {
220 /* 221 /*
221 * The version > 0 supports above members. 222 * The version > 0 supports above members.
222 */ 223 */
223} __attribute__((packed)); 224} __packed;
224 225
225extern void selinux_status_update_setenforce(int enforcing); 226extern void selinux_status_update_setenforce(int enforcing);
226extern void selinux_status_update_policyload(int seqno); 227extern void selinux_status_update_policyload(int seqno);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 694e9e43855f..3c3de4ca0ebc 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -240,7 +240,7 @@ static void sel_netif_kill(int ifindex)
240 * Remove all entries from the network interface table. 240 * Remove all entries from the network interface table.
241 * 241 *
242 */ 242 */
243static void sel_netif_flush(void) 243void sel_netif_flush(void)
244{ 244{
245 int idx; 245 int idx;
246 struct sel_netif *netif; 246 struct sel_netif *netif;
@@ -252,15 +252,6 @@ static void sel_netif_flush(void)
252 spin_unlock_bh(&sel_netif_lock); 252 spin_unlock_bh(&sel_netif_lock);
253} 253}
254 254
255static int sel_netif_avc_callback(u32 event)
256{
257 if (event == AVC_CALLBACK_RESET) {
258 sel_netif_flush();
259 synchronize_net();
260 }
261 return 0;
262}
263
264static int sel_netif_netdev_notifier_handler(struct notifier_block *this, 255static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
265 unsigned long event, void *ptr) 256 unsigned long event, void *ptr)
266{ 257{
@@ -291,10 +282,6 @@ static __init int sel_netif_init(void)
291 282
292 register_netdevice_notifier(&sel_netif_netdev_notifier); 283 register_netdevice_notifier(&sel_netif_netdev_notifier);
293 284
294 err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET);
295 if (err)
296 panic("avc_add_callback() failed, error %d\n", err);
297
298 return err; 285 return err;
299} 286}
300 287
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 03a72c32afd7..ddf315260839 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -283,7 +283,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
283 * Remove all entries from the network address table. 283 * Remove all entries from the network address table.
284 * 284 *
285 */ 285 */
286static void sel_netnode_flush(void) 286void sel_netnode_flush(void)
287{ 287{
288 unsigned int idx; 288 unsigned int idx;
289 struct sel_netnode *node, *node_tmp; 289 struct sel_netnode *node, *node_tmp;
@@ -300,15 +300,6 @@ static void sel_netnode_flush(void)
300 spin_unlock_bh(&sel_netnode_lock); 300 spin_unlock_bh(&sel_netnode_lock);
301} 301}
302 302
303static int sel_netnode_avc_callback(u32 event)
304{
305 if (event == AVC_CALLBACK_RESET) {
306 sel_netnode_flush();
307 synchronize_net();
308 }
309 return 0;
310}
311
312static __init int sel_netnode_init(void) 303static __init int sel_netnode_init(void)
313{ 304{
314 int iter; 305 int iter;
@@ -322,10 +313,6 @@ static __init int sel_netnode_init(void)
322 sel_netnode_hash[iter].size = 0; 313 sel_netnode_hash[iter].size = 0;
323 } 314 }
324 315
325 ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET);
326 if (ret != 0)
327 panic("avc_add_callback() failed, error %d\n", ret);
328
329 return ret; 316 return ret;
330} 317}
331 318
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index d35379781c2c..73ac6784d091 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -217,7 +217,7 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
217 * Remove all entries from the network address table. 217 * Remove all entries from the network address table.
218 * 218 *
219 */ 219 */
220static void sel_netport_flush(void) 220void sel_netport_flush(void)
221{ 221{
222 unsigned int idx; 222 unsigned int idx;
223 struct sel_netport *port, *port_tmp; 223 struct sel_netport *port, *port_tmp;
@@ -234,15 +234,6 @@ static void sel_netport_flush(void)
234 spin_unlock_bh(&sel_netport_lock); 234 spin_unlock_bh(&sel_netport_lock);
235} 235}
236 236
237static int sel_netport_avc_callback(u32 event)
238{
239 if (event == AVC_CALLBACK_RESET) {
240 sel_netport_flush();
241 synchronize_net();
242 }
243 return 0;
244}
245
246static __init int sel_netport_init(void) 237static __init int sel_netport_init(void)
247{ 238{
248 int iter; 239 int iter;
@@ -256,10 +247,6 @@ static __init int sel_netport_init(void)
256 sel_netport_hash[iter].size = 0; 247 sel_netport_hash[iter].size = 0;
257 } 248 }
258 249
259 ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET);
260 if (ret != 0)
261 panic("avc_add_callback() failed, error %d\n", ret);
262
263 return ret; 250 return ret;
264} 251}
265 252
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 377d148e7157..62c6773be0b7 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -402,19 +402,14 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
402 int rc; 402 int rc;
403 struct cond_expr *expr = NULL, *last = NULL; 403 struct cond_expr *expr = NULL, *last = NULL;
404 404
405 rc = next_entry(buf, fp, sizeof(u32)); 405 rc = next_entry(buf, fp, sizeof(u32) * 2);
406 if (rc) 406 if (rc)
407 return rc; 407 goto err;
408 408
409 node->cur_state = le32_to_cpu(buf[0]); 409 node->cur_state = le32_to_cpu(buf[0]);
410 410
411 len = 0;
412 rc = next_entry(buf, fp, sizeof(u32));
413 if (rc)
414 return rc;
415
416 /* expr */ 411 /* expr */
417 len = le32_to_cpu(buf[0]); 412 len = le32_to_cpu(buf[1]);
418 413
419 for (i = 0; i < len; i++) { 414 for (i = 0; i < len; i++) {
420 rc = next_entry(buf, fp, sizeof(u32) * 2); 415 rc = next_entry(buf, fp, sizeof(u32) * 2);
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 820313a04d49..afe6a269ec17 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -86,51 +86,36 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
86 * 86 *
87 */ 87 */
88int ebitmap_netlbl_export(struct ebitmap *ebmap, 88int ebitmap_netlbl_export(struct ebitmap *ebmap,
89 struct netlbl_lsm_secattr_catmap **catmap) 89 struct netlbl_lsm_catmap **catmap)
90{ 90{
91 struct ebitmap_node *e_iter = ebmap->node; 91 struct ebitmap_node *e_iter = ebmap->node;
92 struct netlbl_lsm_secattr_catmap *c_iter; 92 unsigned long e_map;
93 u32 cmap_idx, cmap_sft; 93 u32 offset;
94 int i; 94 unsigned int iter;
95 95 int rc;
96 /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
97 * however, it is not always compatible with an array of unsigned long
98 * in ebitmap_node.
99 * In addition, you should pay attention the following implementation
100 * assumes unsigned long has a width equal with or less than 64-bit.
101 */
102 96
103 if (e_iter == NULL) { 97 if (e_iter == NULL) {
104 *catmap = NULL; 98 *catmap = NULL;
105 return 0; 99 return 0;
106 } 100 }
107 101
108 c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 102 if (*catmap != NULL)
109 if (c_iter == NULL) 103 netlbl_catmap_free(*catmap);
110 return -ENOMEM; 104 *catmap = NULL;
111 *catmap = c_iter;
112 c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
113 105
114 while (e_iter) { 106 while (e_iter) {
115 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 107 offset = e_iter->startbit;
116 unsigned int delta, e_startbit, c_endbit; 108 for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) {
117 109 e_map = e_iter->maps[iter];
118 e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE; 110 if (e_map != 0) {
119 c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE; 111 rc = netlbl_catmap_setlong(catmap,
120 if (e_startbit >= c_endbit) { 112 offset,
121 c_iter->next 113 e_map,
122 = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 114 GFP_ATOMIC);
123 if (c_iter->next == NULL) 115 if (rc != 0)
124 goto netlbl_export_failure; 116 goto netlbl_export_failure;
125 c_iter = c_iter->next;
126 c_iter->startbit
127 = e_startbit & ~(NETLBL_CATMAP_SIZE - 1);
128 } 117 }
129 delta = e_startbit - c_iter->startbit; 118 offset += EBITMAP_UNIT_SIZE;
130 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
131 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
132 c_iter->bitmap[cmap_idx]
133 |= e_iter->maps[i] << cmap_sft;
134 } 119 }
135 e_iter = e_iter->next; 120 e_iter = e_iter->next;
136 } 121 }
@@ -138,7 +123,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
138 return 0; 123 return 0;
139 124
140netlbl_export_failure: 125netlbl_export_failure:
141 netlbl_secattr_catmap_free(*catmap); 126 netlbl_catmap_free(*catmap);
142 return -ENOMEM; 127 return -ENOMEM;
143} 128}
144 129
@@ -153,58 +138,44 @@ netlbl_export_failure:
153 * 138 *
154 */ 139 */
155int ebitmap_netlbl_import(struct ebitmap *ebmap, 140int ebitmap_netlbl_import(struct ebitmap *ebmap,
156 struct netlbl_lsm_secattr_catmap *catmap) 141 struct netlbl_lsm_catmap *catmap)
157{ 142{
143 int rc;
158 struct ebitmap_node *e_iter = NULL; 144 struct ebitmap_node *e_iter = NULL;
159 struct ebitmap_node *emap_prev = NULL; 145 struct ebitmap_node *e_prev = NULL;
160 struct netlbl_lsm_secattr_catmap *c_iter = catmap; 146 u32 offset = 0, idx;
161 u32 c_idx, c_pos, e_idx, e_sft; 147 unsigned long bitmap;
162 148
163 /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64, 149 for (;;) {
164 * however, it is not always compatible with an array of unsigned long 150 rc = netlbl_catmap_getlong(catmap, &offset, &bitmap);
165 * in ebitmap_node. 151 if (rc < 0)
166 * In addition, you should pay attention the following implementation 152 goto netlbl_import_failure;
167 * assumes unsigned long has a width equal with or less than 64-bit. 153 if (offset == (u32)-1)
168 */ 154 return 0;
169
170 do {
171 for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) {
172 unsigned int delta;
173 u64 map = c_iter->bitmap[c_idx];
174
175 if (!map)
176 continue;
177 155
178 c_pos = c_iter->startbit 156 if (e_iter == NULL ||
179 + c_idx * NETLBL_CATMAP_MAPSIZE; 157 offset >= e_iter->startbit + EBITMAP_SIZE) {
180 if (!e_iter 158 e_prev = e_iter;
181 || c_pos >= e_iter->startbit + EBITMAP_SIZE) { 159 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
182 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 160 if (e_iter == NULL)
183 if (!e_iter) 161 goto netlbl_import_failure;
184 goto netlbl_import_failure; 162 e_iter->startbit = offset & ~(EBITMAP_SIZE - 1);
185 e_iter->startbit 163 if (e_prev == NULL)
186 = c_pos - (c_pos % EBITMAP_SIZE); 164 ebmap->node = e_iter;
187 if (emap_prev == NULL) 165 else
188 ebmap->node = e_iter; 166 e_prev->next = e_iter;
189 else 167 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
190 emap_prev->next = e_iter;
191 emap_prev = e_iter;
192 }
193 delta = c_pos - e_iter->startbit;
194 e_idx = delta / EBITMAP_UNIT_SIZE;
195 e_sft = delta % EBITMAP_UNIT_SIZE;
196 while (map) {
197 e_iter->maps[e_idx++] |= map & (-1UL);
198 map = EBITMAP_SHIFT_UNIT_SIZE(map);
199 }
200 } 168 }
201 c_iter = c_iter->next;
202 } while (c_iter);
203 if (e_iter != NULL)
204 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
205 else
206 ebitmap_destroy(ebmap);
207 169
170 /* offset will always be aligned to an unsigned long */
171 idx = EBITMAP_NODE_INDEX(e_iter, offset);
172 e_iter->maps[idx] = bitmap;
173
174 /* next */
175 offset += EBITMAP_UNIT_SIZE;
176 }
177
178 /* NOTE: we should never reach this return */
208 return 0; 179 return 0;
209 180
210netlbl_import_failure: 181netlbl_import_failure:
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 712c8a7b8e8b..9637b8c71085 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -132,17 +132,17 @@ int ebitmap_write(struct ebitmap *e, void *fp);
132 132
133#ifdef CONFIG_NETLABEL 133#ifdef CONFIG_NETLABEL
134int ebitmap_netlbl_export(struct ebitmap *ebmap, 134int ebitmap_netlbl_export(struct ebitmap *ebmap,
135 struct netlbl_lsm_secattr_catmap **catmap); 135 struct netlbl_lsm_catmap **catmap);
136int ebitmap_netlbl_import(struct ebitmap *ebmap, 136int ebitmap_netlbl_import(struct ebitmap *ebmap,
137 struct netlbl_lsm_secattr_catmap *catmap); 137 struct netlbl_lsm_catmap *catmap);
138#else 138#else
139static inline int ebitmap_netlbl_export(struct ebitmap *ebmap, 139static inline int ebitmap_netlbl_export(struct ebitmap *ebmap,
140 struct netlbl_lsm_secattr_catmap **catmap) 140 struct netlbl_lsm_catmap **catmap)
141{ 141{
142 return -ENOMEM; 142 return -ENOMEM;
143} 143}
144static inline int ebitmap_netlbl_import(struct ebitmap *ebmap, 144static inline int ebitmap_netlbl_import(struct ebitmap *ebmap,
145 struct netlbl_lsm_secattr_catmap *catmap) 145 struct netlbl_lsm_catmap *catmap)
146{ 146{
147 return -ENOMEM; 147 return -ENOMEM;
148} 148}
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 9c5cdc2caaef..bc2a586f095c 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1080,6 +1080,26 @@ out:
1080 * binary representation file. 1080 * binary representation file.
1081 */ 1081 */
1082 1082
1083static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
1084{
1085 int rc;
1086 char *str;
1087
1088 str = kmalloc(len + 1, flags);
1089 if (!str)
1090 return -ENOMEM;
1091
1092 /* it's expected the caller should free the str */
1093 *strp = str;
1094
1095 rc = next_entry(str, fp, len);
1096 if (rc)
1097 return rc;
1098
1099 str[len] = '\0';
1100 return 0;
1101}
1102
1083static int perm_read(struct policydb *p, struct hashtab *h, void *fp) 1103static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
1084{ 1104{
1085 char *key = NULL; 1105 char *key = NULL;
@@ -1100,15 +1120,9 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
1100 len = le32_to_cpu(buf[0]); 1120 len = le32_to_cpu(buf[0]);
1101 perdatum->value = le32_to_cpu(buf[1]); 1121 perdatum->value = le32_to_cpu(buf[1]);
1102 1122
1103 rc = -ENOMEM; 1123 rc = str_read(&key, GFP_KERNEL, fp, len);
1104 key = kmalloc(len + 1, GFP_KERNEL);
1105 if (!key)
1106 goto bad;
1107
1108 rc = next_entry(key, fp, len);
1109 if (rc) 1124 if (rc)
1110 goto bad; 1125 goto bad;
1111 key[len] = '\0';
1112 1126
1113 rc = hashtab_insert(h, key, perdatum); 1127 rc = hashtab_insert(h, key, perdatum);
1114 if (rc) 1128 if (rc)
@@ -1146,15 +1160,9 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1146 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1160 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1147 nel = le32_to_cpu(buf[3]); 1161 nel = le32_to_cpu(buf[3]);
1148 1162
1149 rc = -ENOMEM; 1163 rc = str_read(&key, GFP_KERNEL, fp, len);
1150 key = kmalloc(len + 1, GFP_KERNEL);
1151 if (!key)
1152 goto bad;
1153
1154 rc = next_entry(key, fp, len);
1155 if (rc) 1164 if (rc)
1156 goto bad; 1165 goto bad;
1157 key[len] = '\0';
1158 1166
1159 for (i = 0; i < nel; i++) { 1167 for (i = 0; i < nel; i++) {
1160 rc = perm_read(p, comdatum->permissions.table, fp); 1168 rc = perm_read(p, comdatum->permissions.table, fp);
@@ -1321,25 +1329,14 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1321 1329
1322 ncons = le32_to_cpu(buf[5]); 1330 ncons = le32_to_cpu(buf[5]);
1323 1331
1324 rc = -ENOMEM; 1332 rc = str_read(&key, GFP_KERNEL, fp, len);
1325 key = kmalloc(len + 1, GFP_KERNEL);
1326 if (!key)
1327 goto bad;
1328
1329 rc = next_entry(key, fp, len);
1330 if (rc) 1333 if (rc)
1331 goto bad; 1334 goto bad;
1332 key[len] = '\0';
1333 1335
1334 if (len2) { 1336 if (len2) {
1335 rc = -ENOMEM; 1337 rc = str_read(&cladatum->comkey, GFP_KERNEL, fp, len2);
1336 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
1337 if (!cladatum->comkey)
1338 goto bad;
1339 rc = next_entry(cladatum->comkey, fp, len2);
1340 if (rc) 1338 if (rc)
1341 goto bad; 1339 goto bad;
1342 cladatum->comkey[len2] = '\0';
1343 1340
1344 rc = -EINVAL; 1341 rc = -EINVAL;
1345 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); 1342 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
@@ -1422,15 +1419,9 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1422 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1419 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1423 role->bounds = le32_to_cpu(buf[2]); 1420 role->bounds = le32_to_cpu(buf[2]);
1424 1421
1425 rc = -ENOMEM; 1422 rc = str_read(&key, GFP_KERNEL, fp, len);
1426 key = kmalloc(len + 1, GFP_KERNEL);
1427 if (!key)
1428 goto bad;
1429
1430 rc = next_entry(key, fp, len);
1431 if (rc) 1423 if (rc)
1432 goto bad; 1424 goto bad;
1433 key[len] = '\0';
1434 1425
1435 rc = ebitmap_read(&role->dominates, fp); 1426 rc = ebitmap_read(&role->dominates, fp);
1436 if (rc) 1427 if (rc)
@@ -1495,14 +1486,9 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1495 typdatum->primary = le32_to_cpu(buf[2]); 1486 typdatum->primary = le32_to_cpu(buf[2]);
1496 } 1487 }
1497 1488
1498 rc = -ENOMEM; 1489 rc = str_read(&key, GFP_KERNEL, fp, len);
1499 key = kmalloc(len + 1, GFP_KERNEL);
1500 if (!key)
1501 goto bad;
1502 rc = next_entry(key, fp, len);
1503 if (rc) 1490 if (rc)
1504 goto bad; 1491 goto bad;
1505 key[len] = '\0';
1506 1492
1507 rc = hashtab_insert(h, key, typdatum); 1493 rc = hashtab_insert(h, key, typdatum);
1508 if (rc) 1494 if (rc)
@@ -1565,14 +1551,9 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1565 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1551 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1566 usrdatum->bounds = le32_to_cpu(buf[2]); 1552 usrdatum->bounds = le32_to_cpu(buf[2]);
1567 1553
1568 rc = -ENOMEM; 1554 rc = str_read(&key, GFP_KERNEL, fp, len);
1569 key = kmalloc(len + 1, GFP_KERNEL);
1570 if (!key)
1571 goto bad;
1572 rc = next_entry(key, fp, len);
1573 if (rc) 1555 if (rc)
1574 goto bad; 1556 goto bad;
1575 key[len] = '\0';
1576 1557
1577 rc = ebitmap_read(&usrdatum->roles, fp); 1558 rc = ebitmap_read(&usrdatum->roles, fp);
1578 if (rc) 1559 if (rc)
@@ -1616,14 +1597,9 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1616 len = le32_to_cpu(buf[0]); 1597 len = le32_to_cpu(buf[0]);
1617 levdatum->isalias = le32_to_cpu(buf[1]); 1598 levdatum->isalias = le32_to_cpu(buf[1]);
1618 1599
1619 rc = -ENOMEM; 1600 rc = str_read(&key, GFP_ATOMIC, fp, len);
1620 key = kmalloc(len + 1, GFP_ATOMIC);
1621 if (!key)
1622 goto bad;
1623 rc = next_entry(key, fp, len);
1624 if (rc) 1601 if (rc)
1625 goto bad; 1602 goto bad;
1626 key[len] = '\0';
1627 1603
1628 rc = -ENOMEM; 1604 rc = -ENOMEM;
1629 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1605 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
@@ -1664,14 +1640,9 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1664 catdatum->value = le32_to_cpu(buf[1]); 1640 catdatum->value = le32_to_cpu(buf[1]);
1665 catdatum->isalias = le32_to_cpu(buf[2]); 1641 catdatum->isalias = le32_to_cpu(buf[2]);
1666 1642
1667 rc = -ENOMEM; 1643 rc = str_read(&key, GFP_ATOMIC, fp, len);
1668 key = kmalloc(len + 1, GFP_ATOMIC);
1669 if (!key)
1670 goto bad;
1671 rc = next_entry(key, fp, len);
1672 if (rc) 1644 if (rc)
1673 goto bad; 1645 goto bad;
1674 key[len] = '\0';
1675 1646
1676 rc = hashtab_insert(h, key, catdatum); 1647 rc = hashtab_insert(h, key, catdatum);
1677 if (rc) 1648 if (rc)
@@ -1968,18 +1939,12 @@ static int filename_trans_read(struct policydb *p, void *fp)
1968 goto out; 1939 goto out;
1969 len = le32_to_cpu(buf[0]); 1940 len = le32_to_cpu(buf[0]);
1970 1941
1971 rc = -ENOMEM;
1972 name = kmalloc(len + 1, GFP_KERNEL);
1973 if (!name)
1974 goto out;
1975
1976 ft->name = name;
1977
1978 /* path component string */ 1942 /* path component string */
1979 rc = next_entry(name, fp, len); 1943 rc = str_read(&name, GFP_KERNEL, fp, len);
1980 if (rc) 1944 if (rc)
1981 goto out; 1945 goto out;
1982 name[len] = 0; 1946
1947 ft->name = name;
1983 1948
1984 rc = next_entry(buf, fp, sizeof(u32) * 4); 1949 rc = next_entry(buf, fp, sizeof(u32) * 4);
1985 if (rc) 1950 if (rc)
@@ -2045,17 +2010,10 @@ static int genfs_read(struct policydb *p, void *fp)
2045 if (!newgenfs) 2010 if (!newgenfs)
2046 goto out; 2011 goto out;
2047 2012
2048 rc = -ENOMEM; 2013 rc = str_read(&newgenfs->fstype, GFP_KERNEL, fp, len);
2049 newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL);
2050 if (!newgenfs->fstype)
2051 goto out;
2052
2053 rc = next_entry(newgenfs->fstype, fp, len);
2054 if (rc) 2014 if (rc)
2055 goto out; 2015 goto out;
2056 2016
2057 newgenfs->fstype[len] = 0;
2058
2059 for (genfs_p = NULL, genfs = p->genfs; genfs; 2017 for (genfs_p = NULL, genfs = p->genfs; genfs;
2060 genfs_p = genfs, genfs = genfs->next) { 2018 genfs_p = genfs, genfs = genfs->next) {
2061 rc = -EINVAL; 2019 rc = -EINVAL;
@@ -2091,15 +2049,9 @@ static int genfs_read(struct policydb *p, void *fp)
2091 if (!newc) 2049 if (!newc)
2092 goto out; 2050 goto out;
2093 2051
2094 rc = -ENOMEM; 2052 rc = str_read(&newc->u.name, GFP_KERNEL, fp, len);
2095 newc->u.name = kmalloc(len + 1, GFP_KERNEL);
2096 if (!newc->u.name)
2097 goto out;
2098
2099 rc = next_entry(newc->u.name, fp, len);
2100 if (rc) 2053 if (rc)
2101 goto out; 2054 goto out;
2102 newc->u.name[len] = 0;
2103 2055
2104 rc = next_entry(buf, fp, sizeof(u32)); 2056 rc = next_entry(buf, fp, sizeof(u32));
2105 if (rc) 2057 if (rc)
@@ -2189,16 +2141,10 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2189 goto out; 2141 goto out;
2190 len = le32_to_cpu(buf[0]); 2142 len = le32_to_cpu(buf[0]);
2191 2143
2192 rc = -ENOMEM; 2144 rc = str_read(&c->u.name, GFP_KERNEL, fp, len);
2193 c->u.name = kmalloc(len + 1, GFP_KERNEL);
2194 if (!c->u.name)
2195 goto out;
2196
2197 rc = next_entry(c->u.name, fp, len);
2198 if (rc) 2145 if (rc)
2199 goto out; 2146 goto out;
2200 2147
2201 c->u.name[len] = 0;
2202 rc = context_read_and_validate(&c->context[0], p, fp); 2148 rc = context_read_and_validate(&c->context[0], p, fp);
2203 if (rc) 2149 if (rc)
2204 goto out; 2150 goto out;
@@ -2240,16 +2186,11 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2240 if (c->v.behavior > SECURITY_FS_USE_MAX) 2186 if (c->v.behavior > SECURITY_FS_USE_MAX)
2241 goto out; 2187 goto out;
2242 2188
2243 rc = -ENOMEM;
2244 len = le32_to_cpu(buf[1]); 2189 len = le32_to_cpu(buf[1]);
2245 c->u.name = kmalloc(len + 1, GFP_KERNEL); 2190 rc = str_read(&c->u.name, GFP_KERNEL, fp, len);
2246 if (!c->u.name)
2247 goto out;
2248
2249 rc = next_entry(c->u.name, fp, len);
2250 if (rc) 2191 if (rc)
2251 goto out; 2192 goto out;
2252 c->u.name[len] = 0; 2193
2253 rc = context_read_and_validate(&c->context[0], p, fp); 2194 rc = context_read_and_validate(&c->context[0], p, fp);
2254 if (rc) 2195 if (rc)
2255 goto out; 2196 goto out;
@@ -2608,7 +2549,7 @@ static int mls_write_range_helper(struct mls_range *r, void *fp)
2608 if (!eq) 2549 if (!eq)
2609 buf[2] = cpu_to_le32(r->level[1].sens); 2550 buf[2] = cpu_to_le32(r->level[1].sens);
2610 2551
2611 BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); 2552 BUG_ON(items > ARRAY_SIZE(buf));
2612 2553
2613 rc = put_entry(buf, sizeof(u32), items, fp); 2554 rc = put_entry(buf, sizeof(u32), items, fp);
2614 if (rc) 2555 if (rc)
@@ -2990,7 +2931,7 @@ static int role_write(void *vkey, void *datum, void *ptr)
2990 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 2931 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2991 buf[items++] = cpu_to_le32(role->bounds); 2932 buf[items++] = cpu_to_le32(role->bounds);
2992 2933
2993 BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); 2934 BUG_ON(items > ARRAY_SIZE(buf));
2994 2935
2995 rc = put_entry(buf, sizeof(u32), items, fp); 2936 rc = put_entry(buf, sizeof(u32), items, fp);
2996 if (rc) 2937 if (rc)
@@ -3040,7 +2981,7 @@ static int type_write(void *vkey, void *datum, void *ptr)
3040 } else { 2981 } else {
3041 buf[items++] = cpu_to_le32(typdatum->primary); 2982 buf[items++] = cpu_to_le32(typdatum->primary);
3042 } 2983 }
3043 BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); 2984 BUG_ON(items > ARRAY_SIZE(buf));
3044 rc = put_entry(buf, sizeof(u32), items, fp); 2985 rc = put_entry(buf, sizeof(u32), items, fp);
3045 if (rc) 2986 if (rc)
3046 return rc; 2987 return rc;
@@ -3069,7 +3010,7 @@ static int user_write(void *vkey, void *datum, void *ptr)
3069 buf[items++] = cpu_to_le32(usrdatum->value); 3010 buf[items++] = cpu_to_le32(usrdatum->value);
3070 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 3011 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
3071 buf[items++] = cpu_to_le32(usrdatum->bounds); 3012 buf[items++] = cpu_to_le32(usrdatum->bounds);
3072 BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); 3013 BUG_ON(items > ARRAY_SIZE(buf));
3073 rc = put_entry(buf, sizeof(u32), items, fp); 3014 rc = put_entry(buf, sizeof(u32), items, fp);
3074 if (rc) 3015 if (rc)
3075 return rc; 3016 return rc;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 4bca49414a40..2aa9d172dc7e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2277,7 +2277,7 @@ out:
2277} 2277}
2278 2278
2279/** 2279/**
2280 * security_genfs_sid - Obtain a SID for a file in a filesystem 2280 * __security_genfs_sid - Helper to obtain a SID for a file in a filesystem
2281 * @fstype: filesystem type 2281 * @fstype: filesystem type
2282 * @path: path from root of mount 2282 * @path: path from root of mount
2283 * @sclass: file security class 2283 * @sclass: file security class
@@ -2286,11 +2286,13 @@ out:
2286 * Obtain a SID to use for a file in a filesystem that 2286 * Obtain a SID to use for a file in a filesystem that
2287 * cannot support xattr or use a fixed labeling behavior like 2287 * cannot support xattr or use a fixed labeling behavior like
2288 * transition SIDs or task SIDs. 2288 * transition SIDs or task SIDs.
2289 *
2290 * The caller must acquire the policy_rwlock before calling this function.
2289 */ 2291 */
2290int security_genfs_sid(const char *fstype, 2292static inline int __security_genfs_sid(const char *fstype,
2291 char *path, 2293 char *path,
2292 u16 orig_sclass, 2294 u16 orig_sclass,
2293 u32 *sid) 2295 u32 *sid)
2294{ 2296{
2295 int len; 2297 int len;
2296 u16 sclass; 2298 u16 sclass;
@@ -2301,8 +2303,6 @@ int security_genfs_sid(const char *fstype,
2301 while (path[0] == '/' && path[1] == '/') 2303 while (path[0] == '/' && path[1] == '/')
2302 path++; 2304 path++;
2303 2305
2304 read_lock(&policy_rwlock);
2305
2306 sclass = unmap_class(orig_sclass); 2306 sclass = unmap_class(orig_sclass);
2307 *sid = SECINITSID_UNLABELED; 2307 *sid = SECINITSID_UNLABELED;
2308 2308
@@ -2336,11 +2336,33 @@ int security_genfs_sid(const char *fstype,
2336 *sid = c->sid[0]; 2336 *sid = c->sid[0];
2337 rc = 0; 2337 rc = 0;
2338out: 2338out:
2339 read_unlock(&policy_rwlock);
2340 return rc; 2339 return rc;
2341} 2340}
2342 2341
2343/** 2342/**
2343 * security_genfs_sid - Obtain a SID for a file in a filesystem
2344 * @fstype: filesystem type
2345 * @path: path from root of mount
2346 * @sclass: file security class
2347 * @sid: SID for path
2348 *
2349 * Acquire policy_rwlock before calling __security_genfs_sid() and release
2350 * it afterward.
2351 */
2352int security_genfs_sid(const char *fstype,
2353 char *path,
2354 u16 orig_sclass,
2355 u32 *sid)
2356{
2357 int retval;
2358
2359 read_lock(&policy_rwlock);
2360 retval = __security_genfs_sid(fstype, path, orig_sclass, sid);
2361 read_unlock(&policy_rwlock);
2362 return retval;
2363}
2364
2365/**
2344 * security_fs_use - Determine how to handle labeling for a filesystem. 2366 * security_fs_use - Determine how to handle labeling for a filesystem.
2345 * @sb: superblock in question 2367 * @sb: superblock in question
2346 */ 2368 */
@@ -2370,7 +2392,8 @@ int security_fs_use(struct super_block *sb)
2370 } 2392 }
2371 sbsec->sid = c->sid[0]; 2393 sbsec->sid = c->sid[0];
2372 } else { 2394 } else {
2373 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid); 2395 rc = __security_genfs_sid(fstype, "/", SECCLASS_DIR,
2396 &sbsec->sid);
2374 if (rc) { 2397 if (rc) {
2375 sbsec->behavior = SECURITY_FS_USE_NONE; 2398 sbsec->behavior = SECURITY_FS_USE_NONE;
2376 rc = 0; 2399 rc = 0;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index c062e9467b62..f97d0842e621 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -457,19 +457,16 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
457 457
458 sap->flags |= NETLBL_SECATTR_MLS_CAT; 458 sap->flags |= NETLBL_SECATTR_MLS_CAT;
459 sap->attr.mls.lvl = level; 459 sap->attr.mls.lvl = level;
460 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 460 sap->attr.mls.cat = NULL;
461 if (!sap->attr.mls.cat)
462 return -ENOMEM;
463 sap->attr.mls.cat->startbit = 0;
464 461
465 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 462 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
466 for (m = 0x80; m != 0; m >>= 1, cat++) { 463 for (m = 0x80; m != 0; m >>= 1, cat++) {
467 if ((m & *cp) == 0) 464 if ((m & *cp) == 0)
468 continue; 465 continue;
469 rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat, 466 rc = netlbl_catmap_setbit(&sap->attr.mls.cat,
470 cat, GFP_ATOMIC); 467 cat, GFP_ATOMIC);
471 if (rc < 0) { 468 if (rc < 0) {
472 netlbl_secattr_catmap_free(sap->attr.mls.cat); 469 netlbl_catmap_free(sap->attr.mls.cat);
473 return rc; 470 return rc;
474 } 471 }
475 } 472 }
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index f2c30801ce41..e6ab307ce86e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3209,9 +3209,9 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3209 break; 3209 break;
3210 } 3210 }
3211 for (acat = -1, kcat = -1; acat == kcat; ) { 3211 for (acat = -1, kcat = -1; acat == kcat; ) {
3212 acat = netlbl_secattr_catmap_walk( 3212 acat = netlbl_catmap_walk(sap->attr.mls.cat,
3213 sap->attr.mls.cat, acat + 1); 3213 acat + 1);
3214 kcat = netlbl_secattr_catmap_walk( 3214 kcat = netlbl_catmap_walk(
3215 skp->smk_netlabel.attr.mls.cat, 3215 skp->smk_netlabel.attr.mls.cat,
3216 kcat + 1); 3216 kcat + 1);
3217 if (acat < 0 || kcat < 0) 3217 if (acat < 0 || kcat < 0)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 32b248820840..3c720ff10591 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -787,7 +787,7 @@ static int cipso_seq_show(struct seq_file *s, void *v)
787 struct list_head *list = v; 787 struct list_head *list = v;
788 struct smack_known *skp = 788 struct smack_known *skp =
789 list_entry(list, struct smack_known, list); 789 list_entry(list, struct smack_known, list);
790 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 790 struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
791 char sep = '/'; 791 char sep = '/';
792 int i; 792 int i;
793 793
@@ -804,8 +804,8 @@ static int cipso_seq_show(struct seq_file *s, void *v)
804 804
805 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 805 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
806 806
807 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 807 for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
808 i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 808 i = netlbl_catmap_walk(cmp, i + 1)) {
809 seq_printf(s, "%c%d", sep, i); 809 seq_printf(s, "%c%d", sep, i);
810 sep = ','; 810 sep = ',';
811 } 811 }
@@ -926,7 +926,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
926 926
927 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); 927 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
928 if (rc >= 0) { 928 if (rc >= 0) {
929 netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat); 929 netlbl_catmap_free(skp->smk_netlabel.attr.mls.cat);
930 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; 930 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
931 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; 931 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
932 rc = count; 932 rc = count;
@@ -976,14 +976,14 @@ static int cipso2_seq_show(struct seq_file *s, void *v)
976 struct list_head *list = v; 976 struct list_head *list = v;
977 struct smack_known *skp = 977 struct smack_known *skp =
978 list_entry(list, struct smack_known, list); 978 list_entry(list, struct smack_known, list);
979 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 979 struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
980 char sep = '/'; 980 char sep = '/';
981 int i; 981 int i;
982 982
983 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 983 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
984 984
985 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 985 for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
986 i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 986 i = netlbl_catmap_walk(cmp, i + 1)) {
987 seq_printf(s, "%c%d", sep, i); 987 seq_printf(s, "%c%d", sep, i);
988 sep = ','; 988 sep = ',';
989 } 989 }