aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 11:18:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 11:18:12 -0500
commit33673dcb372b5d8179c22127ca71deb5f3dc7016 (patch)
treed182e9dc6aa127375a92b5eb619d6cd2ddc23ce7 /security/integrity
parentfe9453a1dcb5fb146f9653267e78f4a558066f6f (diff)
parent5b2660326039a32b28766cb4c1a8b1bdcfadc375 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "This is basically a maintenance update for the TPM driver and EVM/IMA" Fix up conflicts in lib/digsig.c and security/integrity/ima/ima_main.c * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (45 commits) tpm/ibmvtpm: build only when IBM pseries is configured ima: digital signature verification using asymmetric keys ima: rename hash calculation functions ima: use new crypto_shash API instead of old crypto_hash ima: add policy support for file system uuid evm: add file system uuid to EVM hmac tpm_tis: check pnp_acpi_device return code char/tpm/tpm_i2c_stm_st33: drop temporary variable for return value char/tpm/tpm_i2c_stm_st33: remove dead assignment in tpm_st33_i2c_probe char/tpm/tpm_i2c_stm_st33: Remove __devexit attribute char/tpm/tpm_i2c_stm_st33: Don't use memcpy for one byte assignment tpm_i2c_stm_st33: removed unused variables/code TPM: Wait for TPM_ACCESS tpmRegValidSts to go high at startup tpm: Fix cancellation of TPM commands (interrupt mode) tpm: Fix cancellation of TPM commands (polling mode) tpm: Store TPM vendor ID TPM: Work around buggy TPMs that block during continue self test tpm_i2c_stm_st33: fix oops when i2c client is unavailable char/tpm: Use struct dev_pm_ops for power management TPM: STMicroelectronics ST33 I2C BUILD STUFF ...
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/Kconfig12
-rw-r--r--security/integrity/Makefile1
-rw-r--r--security/integrity/digsig.c11
-rw-r--r--security/integrity/digsig_asymmetric.c115
-rw-r--r--security/integrity/evm/Kconfig13
-rw-r--r--security/integrity/evm/evm.h2
-rw-r--r--security/integrity/evm/evm_crypto.c3
-rw-r--r--security/integrity/evm/evm_main.c10
-rw-r--r--security/integrity/evm/evm_secfs.c6
-rw-r--r--security/integrity/iint.c10
-rw-r--r--security/integrity/ima/ima.h21
-rw-r--r--security/integrity/ima/ima_api.c27
-rw-r--r--security/integrity/ima/ima_appraise.c92
-rw-r--r--security/integrity/ima/ima_crypto.c81
-rw-r--r--security/integrity/ima/ima_init.c3
-rw-r--r--security/integrity/ima/ima_main.c138
-rw-r--r--security/integrity/ima/ima_policy.c138
-rw-r--r--security/integrity/integrity.h62
18 files changed, 552 insertions, 193 deletions
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 5bd1cc1b4a54..4bb3a775a996 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -17,5 +17,17 @@ config INTEGRITY_SIGNATURE
17 This is useful for evm and module keyrings, when keys are 17 This is useful for evm and module keyrings, when keys are
18 usually only added from initramfs. 18 usually only added from initramfs.
19 19
20config INTEGRITY_ASYMMETRIC_KEYS
21 boolean "Enable asymmetric keys support"
22 depends on INTEGRITY_SIGNATURE
23 default n
24 select ASYMMETRIC_KEY_TYPE
25 select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
26 select PUBLIC_KEY_ALGO_RSA
27 select X509_CERTIFICATE_PARSER
28 help
29 This option enables digital signature verification using
30 asymmetric keys.
31
20source security/integrity/ima/Kconfig 32source security/integrity/ima/Kconfig
21source security/integrity/evm/Kconfig 33source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index d43799cc14f6..ebb6409b3fcb 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_INTEGRITY) += integrity.o 5obj-$(CONFIG_INTEGRITY) += integrity.o
6obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o 6obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
7obj-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
7 8
8integrity-y := iint.o 9integrity-y := iint.o
9 10
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 2dc167d7cde9..0b759e17a131 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -44,5 +44,14 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
44 } 44 }
45 } 45 }
46 46
47 return digsig_verify(keyring[id], sig, siglen, digest, digestlen); 47 switch (sig[0]) {
48 case 1:
49 return digsig_verify(keyring[id], sig, siglen,
50 digest, digestlen);
51 case 2:
52 return asymmetric_verify(keyring[id], sig, siglen,
53 digest, digestlen);
54 }
55
56 return -EOPNOTSUPP;
48} 57}
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
new file mode 100644
index 000000000000..b4754667659d
--- /dev/null
+++ b/security/integrity/digsig_asymmetric.c
@@ -0,0 +1,115 @@
1/*
2 * Copyright (C) 2013 Intel Corporation
3 *
4 * Author:
5 * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 */
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/err.h>
16#include <linux/key-type.h>
17#include <crypto/public_key.h>
18#include <keys/asymmetric-type.h>
19
20#include "integrity.h"
21
22/*
23 * signature format v2 - for using with asymmetric keys
24 */
25struct signature_v2_hdr {
26 uint8_t version; /* signature format version */
27 uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */
28 uint32_t keyid; /* IMA key identifier - not X509/PGP specific*/
29 uint16_t sig_size; /* signature size */
30 uint8_t sig[0]; /* signature payload */
31} __packed;
32
33/*
34 * Request an asymmetric key.
35 */
36static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
37{
38 struct key *key;
39 char name[12];
40
41 sprintf(name, "id:%x", keyid);
42
43 pr_debug("key search: \"%s\"\n", name);
44
45 if (keyring) {
46 /* search in specific keyring */
47 key_ref_t kref;
48 kref = keyring_search(make_key_ref(keyring, 1),
49 &key_type_asymmetric, name);
50 if (IS_ERR(kref))
51 key = ERR_CAST(kref);
52 else
53 key = key_ref_to_ptr(kref);
54 } else {
55 key = request_key(&key_type_asymmetric, name, NULL);
56 }
57
58 if (IS_ERR(key)) {
59 pr_warn("Request for unknown key '%s' err %ld\n",
60 name, PTR_ERR(key));
61 switch (PTR_ERR(key)) {
62 /* Hide some search errors */
63 case -EACCES:
64 case -ENOTDIR:
65 case -EAGAIN:
66 return ERR_PTR(-ENOKEY);
67 default:
68 return key;
69 }
70 }
71
72 pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key));
73
74 return key;
75}
76
77int asymmetric_verify(struct key *keyring, const char *sig,
78 int siglen, const char *data, int datalen)
79{
80 struct public_key_signature pks;
81 struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
82 struct key *key;
83 int ret = -ENOMEM;
84
85 if (siglen <= sizeof(*hdr))
86 return -EBADMSG;
87
88 siglen -= sizeof(*hdr);
89
90 if (siglen != __be16_to_cpu(hdr->sig_size))
91 return -EBADMSG;
92
93 if (hdr->hash_algo >= PKEY_HASH__LAST)
94 return -ENOPKG;
95
96 key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid));
97 if (IS_ERR(key))
98 return PTR_ERR(key);
99
100 memset(&pks, 0, sizeof(pks));
101
102 pks.pkey_hash_algo = hdr->hash_algo;
103 pks.digest = (u8 *)data;
104 pks.digest_size = datalen;
105 pks.nr_mpi = 1;
106 pks.rsa.s = mpi_read_raw_data(hdr->sig, siglen);
107
108 if (pks.rsa.s)
109 ret = verify_signature(key, &pks);
110
111 mpi_free(pks.rsa.s);
112 key_put(key);
113 pr_debug("%s() = %d\n", __func__, ret);
114 return ret;
115}
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig
index afbb59dd262d..fea9749c3756 100644
--- a/security/integrity/evm/Kconfig
+++ b/security/integrity/evm/Kconfig
@@ -11,3 +11,16 @@ config EVM
11 integrity attacks. 11 integrity attacks.
12 12
13 If you are unsure how to answer this question, answer N. 13 If you are unsure how to answer this question, answer N.
14
15config EVM_HMAC_VERSION
16 int "EVM HMAC version"
17 depends on EVM
18 default 2
19 help
20 This options adds EVM HMAC version support.
21 1 - original version
22 2 - add per filesystem unique identifier (UUID) (default)
23
24 WARNING: changing the HMAC calculation method or adding
25 additional info to the calculation, requires existing EVM
26 labeled file systems to be relabeled.
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index c885247ebcf7..30bd1ec0232e 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -24,6 +24,7 @@
24extern int evm_initialized; 24extern int evm_initialized;
25extern char *evm_hmac; 25extern char *evm_hmac;
26extern char *evm_hash; 26extern char *evm_hash;
27extern int evm_hmac_version;
27 28
28extern struct crypto_shash *hmac_tfm; 29extern struct crypto_shash *hmac_tfm;
29extern struct crypto_shash *hash_tfm; 30extern struct crypto_shash *hash_tfm;
@@ -45,6 +46,5 @@ extern int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
45extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr, 46extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
46 char *hmac_val); 47 char *hmac_val);
47extern int evm_init_secfs(void); 48extern int evm_init_secfs(void);
48extern void evm_cleanup_secfs(void);
49 49
50#endif 50#endif
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 7dd538ef5b83..3bab89eb21d6 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -110,6 +110,9 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
110 hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid); 110 hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
111 hmac_misc.mode = inode->i_mode; 111 hmac_misc.mode = inode->i_mode;
112 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc); 112 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc);
113 if (evm_hmac_version > 1)
114 crypto_shash_update(desc, inode->i_sb->s_uuid,
115 sizeof(inode->i_sb->s_uuid));
113 crypto_shash_final(desc, digest); 116 crypto_shash_final(desc, digest);
114} 117}
115 118
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index eb5484504f50..cdbde1762189 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -26,6 +26,7 @@ int evm_initialized;
26 26
27char *evm_hmac = "hmac(sha1)"; 27char *evm_hmac = "hmac(sha1)";
28char *evm_hash = "sha1"; 28char *evm_hash = "sha1";
29int evm_hmac_version = CONFIG_EVM_HMAC_VERSION;
29 30
30char *evm_config_xattrnames[] = { 31char *evm_config_xattrnames[] = {
31#ifdef CONFIG_SECURITY_SELINUX 32#ifdef CONFIG_SECURITY_SELINUX
@@ -427,15 +428,6 @@ err:
427 return error; 428 return error;
428} 429}
429 430
430static void __exit cleanup_evm(void)
431{
432 evm_cleanup_secfs();
433 if (hmac_tfm)
434 crypto_free_shash(hmac_tfm);
435 if (hash_tfm)
436 crypto_free_shash(hash_tfm);
437}
438
439/* 431/*
440 * evm_display_config - list the EVM protected security extended attributes 432 * evm_display_config - list the EVM protected security extended attributes
441 */ 433 */
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index ac7629950578..30f670ad6ac3 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -100,9 +100,3 @@ int __init evm_init_secfs(void)
100 error = -EFAULT; 100 error = -EFAULT;
101 return error; 101 return error;
102} 102}
103
104void __exit evm_cleanup_secfs(void)
105{
106 if (evm_init_tpm)
107 securityfs_remove(evm_init_tpm);
108}
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index d82a5a13d855..74522dbd10a6 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -72,7 +72,10 @@ static void iint_free(struct integrity_iint_cache *iint)
72{ 72{
73 iint->version = 0; 73 iint->version = 0;
74 iint->flags = 0UL; 74 iint->flags = 0UL;
75 iint->ima_status = INTEGRITY_UNKNOWN; 75 iint->ima_file_status = INTEGRITY_UNKNOWN;
76 iint->ima_mmap_status = INTEGRITY_UNKNOWN;
77 iint->ima_bprm_status = INTEGRITY_UNKNOWN;
78 iint->ima_module_status = INTEGRITY_UNKNOWN;
76 iint->evm_status = INTEGRITY_UNKNOWN; 79 iint->evm_status = INTEGRITY_UNKNOWN;
77 kmem_cache_free(iint_cache, iint); 80 kmem_cache_free(iint_cache, iint);
78} 81}
@@ -149,7 +152,10 @@ static void init_once(void *foo)
149 memset(iint, 0, sizeof *iint); 152 memset(iint, 0, sizeof *iint);
150 iint->version = 0; 153 iint->version = 0;
151 iint->flags = 0UL; 154 iint->flags = 0UL;
152 iint->ima_status = INTEGRITY_UNKNOWN; 155 iint->ima_file_status = INTEGRITY_UNKNOWN;
156 iint->ima_mmap_status = INTEGRITY_UNKNOWN;
157 iint->ima_bprm_status = INTEGRITY_UNKNOWN;
158 iint->ima_module_status = INTEGRITY_UNKNOWN;
153 iint->evm_status = INTEGRITY_UNKNOWN; 159 iint->evm_status = INTEGRITY_UNKNOWN;
154} 160}
155 161
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 079a85dc37b2..a41c9c18e5e0 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -84,11 +84,12 @@ void ima_fs_cleanup(void);
84int ima_inode_alloc(struct inode *inode); 84int ima_inode_alloc(struct inode *inode);
85int ima_add_template_entry(struct ima_template_entry *entry, int violation, 85int ima_add_template_entry(struct ima_template_entry *entry, int violation,
86 const char *op, struct inode *inode); 86 const char *op, struct inode *inode);
87int ima_calc_hash(struct file *file, char *digest); 87int ima_calc_file_hash(struct file *file, char *digest);
88int ima_calc_template_hash(int template_len, void *template, char *digest); 88int ima_calc_buffer_hash(const void *data, int len, char *digest);
89int ima_calc_boot_aggregate(char *digest); 89int ima_calc_boot_aggregate(char *digest);
90void ima_add_violation(struct inode *inode, const unsigned char *filename, 90void ima_add_violation(struct inode *inode, const unsigned char *filename,
91 const char *op, const char *cause); 91 const char *op, const char *cause);
92int ima_init_crypto(void);
92 93
93/* 94/*
94 * used to protect h_table and sha_table 95 * used to protect h_table and sha_table
@@ -119,6 +120,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
119int ima_store_template(struct ima_template_entry *entry, int violation, 120int ima_store_template(struct ima_template_entry *entry, int violation,
120 struct inode *inode); 121 struct inode *inode);
121void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); 122void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
123const char *ima_d_path(struct path *path, char **pathbuf);
122 124
123/* rbtree tree calls to lookup, insert, delete 125/* rbtree tree calls to lookup, insert, delete
124 * integrity data associated with an inode. 126 * integrity data associated with an inode.
@@ -127,7 +129,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
127struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 129struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
128 130
129/* IMA policy related functions */ 131/* IMA policy related functions */
130enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, MODULE_CHECK, POST_SETATTR }; 132enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, POST_SETATTR };
131 133
132int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 134int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
133 int flags); 135 int flags);
@@ -142,13 +144,16 @@ void ima_delete_rules(void);
142#define IMA_APPRAISE_MODULES 0x04 144#define IMA_APPRAISE_MODULES 0x04
143 145
144#ifdef CONFIG_IMA_APPRAISE 146#ifdef CONFIG_IMA_APPRAISE
145int ima_appraise_measurement(struct integrity_iint_cache *iint, 147int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
146 struct file *file, const unsigned char *filename); 148 struct file *file, const unsigned char *filename);
147int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); 149int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
148void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); 150void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
151enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
152 int func);
149 153
150#else 154#else
151static inline int ima_appraise_measurement(struct integrity_iint_cache *iint, 155static inline int ima_appraise_measurement(int func,
156 struct integrity_iint_cache *iint,
152 struct file *file, 157 struct file *file,
153 const unsigned char *filename) 158 const unsigned char *filename)
154{ 159{
@@ -165,6 +170,12 @@ static inline void ima_update_xattr(struct integrity_iint_cache *iint,
165 struct file *file) 170 struct file *file)
166{ 171{
167} 172}
173
174static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache
175 *iint, int func)
176{
177 return INTEGRITY_UNKNOWN;
178}
168#endif 179#endif
169 180
170/* LSM based policy rules require audit */ 181/* LSM based policy rules require audit */
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 0cea3db21657..d9030b29d84d 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -50,8 +50,8 @@ int ima_store_template(struct ima_template_entry *entry,
50 entry->template_len = sizeof(entry->template); 50 entry->template_len = sizeof(entry->template);
51 51
52 if (!violation) { 52 if (!violation) {
53 result = ima_calc_template_hash(entry->template_len, 53 result = ima_calc_buffer_hash(&entry->template,
54 &entry->template, 54 entry->template_len,
55 entry->digest); 55 entry->digest);
56 if (result < 0) { 56 if (result < 0) {
57 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, 57 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
@@ -100,12 +100,12 @@ err_out:
100 * ima_get_action - appraise & measure decision based on policy. 100 * ima_get_action - appraise & measure decision based on policy.
101 * @inode: pointer to inode to measure 101 * @inode: pointer to inode to measure
102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
103 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP, MODULE_CHECK) 103 * @function: calling function (FILE_CHECK, BPRM_CHECK, MMAP_CHECK, MODULE_CHECK)
104 * 104 *
105 * The policy is defined in terms of keypairs: 105 * The policy is defined in terms of keypairs:
106 * subj=, obj=, type=, func=, mask=, fsmagic= 106 * subj=, obj=, type=, func=, mask=, fsmagic=
107 * subj,obj, and type: are LSM specific. 107 * subj,obj, and type: are LSM specific.
108 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP | MODULE_CHECK 108 * func: FILE_CHECK | BPRM_CHECK | MMAP_CHECK | MODULE_CHECK
109 * mask: contains the permission mask 109 * mask: contains the permission mask
110 * fsmagic: hex value 110 * fsmagic: hex value
111 * 111 *
@@ -148,7 +148,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
148 u64 i_version = file->f_dentry->d_inode->i_version; 148 u64 i_version = file->f_dentry->d_inode->i_version;
149 149
150 iint->ima_xattr.type = IMA_XATTR_DIGEST; 150 iint->ima_xattr.type = IMA_XATTR_DIGEST;
151 result = ima_calc_hash(file, iint->ima_xattr.digest); 151 result = ima_calc_file_hash(file, iint->ima_xattr.digest);
152 if (!result) { 152 if (!result) {
153 iint->version = i_version; 153 iint->version = i_version;
154 iint->flags |= IMA_COLLECTED; 154 iint->flags |= IMA_COLLECTED;
@@ -237,3 +237,20 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
237 237
238 iint->flags |= IMA_AUDITED; 238 iint->flags |= IMA_AUDITED;
239} 239}
240
241const char *ima_d_path(struct path *path, char **pathbuf)
242{
243 char *pathname = NULL;
244
245 /* We will allow 11 spaces for ' (deleted)' to be appended */
246 *pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
247 if (*pathbuf) {
248 pathname = d_path(path, *pathbuf, PATH_MAX + 11);
249 if (IS_ERR(pathname)) {
250 kfree(*pathbuf);
251 *pathbuf = NULL;
252 pathname = NULL;
253 }
254 }
255 return pathname;
256}
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index bdc8ba1d1d27..2d4becab8918 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -42,12 +42,69 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
42 return ima_match_policy(inode, func, mask, IMA_APPRAISE); 42 return ima_match_policy(inode, func, mask, IMA_APPRAISE);
43} 43}
44 44
45static void ima_fix_xattr(struct dentry *dentry, 45static int ima_fix_xattr(struct dentry *dentry,
46 struct integrity_iint_cache *iint) 46 struct integrity_iint_cache *iint)
47{ 47{
48 iint->ima_xattr.type = IMA_XATTR_DIGEST; 48 iint->ima_xattr.type = IMA_XATTR_DIGEST;
49 __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, (u8 *)&iint->ima_xattr, 49 return __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
50 sizeof iint->ima_xattr, 0); 50 (u8 *)&iint->ima_xattr,
51 sizeof(iint->ima_xattr), 0);
52}
53
54/* Return specific func appraised cached result */
55enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
56 int func)
57{
58 switch(func) {
59 case MMAP_CHECK:
60 return iint->ima_mmap_status;
61 case BPRM_CHECK:
62 return iint->ima_bprm_status;
63 case MODULE_CHECK:
64 return iint->ima_module_status;
65 case FILE_CHECK:
66 default:
67 return iint->ima_file_status;
68 }
69}
70
71static void ima_set_cache_status(struct integrity_iint_cache *iint,
72 int func, enum integrity_status status)
73{
74 switch(func) {
75 case MMAP_CHECK:
76 iint->ima_mmap_status = status;
77 break;
78 case BPRM_CHECK:
79 iint->ima_bprm_status = status;
80 break;
81 case MODULE_CHECK:
82 iint->ima_module_status = status;
83 break;
84 case FILE_CHECK:
85 default:
86 iint->ima_file_status = status;
87 break;
88 }
89}
90
91static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
92{
93 switch(func) {
94 case MMAP_CHECK:
95 iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED);
96 break;
97 case BPRM_CHECK:
98 iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
99 break;
100 case MODULE_CHECK:
101 iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
102 break;
103 case FILE_CHECK:
104 default:
105 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
106 break;
107 }
51} 108}
52 109
53/* 110/*
@@ -58,7 +115,7 @@ static void ima_fix_xattr(struct dentry *dentry,
58 * 115 *
59 * Return 0 on success, error code otherwise 116 * Return 0 on success, error code otherwise
60 */ 117 */
61int ima_appraise_measurement(struct integrity_iint_cache *iint, 118int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
62 struct file *file, const unsigned char *filename) 119 struct file *file, const unsigned char *filename)
63{ 120{
64 struct dentry *dentry = file->f_dentry; 121 struct dentry *dentry = file->f_dentry;
@@ -74,9 +131,6 @@ int ima_appraise_measurement(struct integrity_iint_cache *iint,
74 if (!inode->i_op->getxattr) 131 if (!inode->i_op->getxattr)
75 return INTEGRITY_UNKNOWN; 132 return INTEGRITY_UNKNOWN;
76 133
77 if (iint->flags & IMA_APPRAISED)
78 return iint->ima_status;
79
80 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value, 134 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value,
81 0, GFP_NOFS); 135 0, GFP_NOFS);
82 if (rc <= 0) { 136 if (rc <= 0) {
@@ -98,19 +152,18 @@ int ima_appraise_measurement(struct integrity_iint_cache *iint,
98 cause = "invalid-HMAC"; 152 cause = "invalid-HMAC";
99 goto out; 153 goto out;
100 } 154 }
101
102 switch (xattr_value->type) { 155 switch (xattr_value->type) {
103 case IMA_XATTR_DIGEST: 156 case IMA_XATTR_DIGEST:
157 if (iint->flags & IMA_DIGSIG_REQUIRED) {
158 cause = "IMA signature required";
159 status = INTEGRITY_FAIL;
160 break;
161 }
104 rc = memcmp(xattr_value->digest, iint->ima_xattr.digest, 162 rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
105 IMA_DIGEST_SIZE); 163 IMA_DIGEST_SIZE);
106 if (rc) { 164 if (rc) {
107 cause = "invalid-hash"; 165 cause = "invalid-hash";
108 status = INTEGRITY_FAIL; 166 status = INTEGRITY_FAIL;
109 print_hex_dump_bytes("security.ima: ", DUMP_PREFIX_NONE,
110 xattr_value, sizeof(*xattr_value));
111 print_hex_dump_bytes("collected: ", DUMP_PREFIX_NONE,
112 (u8 *)&iint->ima_xattr,
113 sizeof iint->ima_xattr);
114 break; 167 break;
115 } 168 }
116 status = INTEGRITY_PASS; 169 status = INTEGRITY_PASS;
@@ -141,15 +194,15 @@ out:
141 if ((ima_appraise & IMA_APPRAISE_FIX) && 194 if ((ima_appraise & IMA_APPRAISE_FIX) &&
142 (!xattr_value || 195 (!xattr_value ||
143 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { 196 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
144 ima_fix_xattr(dentry, iint); 197 if (!ima_fix_xattr(dentry, iint))
145 status = INTEGRITY_PASS; 198 status = INTEGRITY_PASS;
146 } 199 }
147 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, 200 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
148 op, cause, rc, 0); 201 op, cause, rc, 0);
149 } else { 202 } else {
150 iint->flags |= IMA_APPRAISED; 203 ima_cache_flags(iint, func);
151 } 204 }
152 iint->ima_status = status; 205 ima_set_cache_status(iint, func, status);
153 kfree(xattr_value); 206 kfree(xattr_value);
154 return status; 207 return status;
155} 208}
@@ -195,10 +248,11 @@ void ima_inode_post_setattr(struct dentry *dentry)
195 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR); 248 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
196 iint = integrity_iint_find(inode); 249 iint = integrity_iint_find(inode);
197 if (iint) { 250 if (iint) {
251 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
252 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
253 IMA_ACTION_FLAGS);
198 if (must_appraise) 254 if (must_appraise)
199 iint->flags |= IMA_APPRAISE; 255 iint->flags |= IMA_APPRAISE;
200 else
201 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED);
202 } 256 }
203 if (!must_appraise) 257 if (!must_appraise)
204 rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA); 258 rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index b21ee5b5495a..b691e0f3830c 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -19,38 +19,41 @@
19#include <linux/scatterlist.h> 19#include <linux/scatterlist.h>
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <crypto/hash.h>
22#include "ima.h" 23#include "ima.h"
23 24
24static int init_desc(struct hash_desc *desc) 25static struct crypto_shash *ima_shash_tfm;
26
27int ima_init_crypto(void)
25{ 28{
26 int rc; 29 long rc;
27 30
28 desc->tfm = crypto_alloc_hash(ima_hash, 0, CRYPTO_ALG_ASYNC); 31 ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0);
29 if (IS_ERR(desc->tfm)) { 32 if (IS_ERR(ima_shash_tfm)) {
30 pr_info("IMA: failed to load %s transform: %ld\n", 33 rc = PTR_ERR(ima_shash_tfm);
31 ima_hash, PTR_ERR(desc->tfm)); 34 pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc);
32 rc = PTR_ERR(desc->tfm);
33 return rc; 35 return rc;
34 } 36 }
35 desc->flags = 0; 37 return 0;
36 rc = crypto_hash_init(desc);
37 if (rc)
38 crypto_free_hash(desc->tfm);
39 return rc;
40} 38}
41 39
42/* 40/*
43 * Calculate the MD5/SHA1 file digest 41 * Calculate the MD5/SHA1 file digest
44 */ 42 */
45int ima_calc_hash(struct file *file, char *digest) 43int ima_calc_file_hash(struct file *file, char *digest)
46{ 44{
47 struct hash_desc desc;
48 struct scatterlist sg[1];
49 loff_t i_size, offset = 0; 45 loff_t i_size, offset = 0;
50 char *rbuf; 46 char *rbuf;
51 int rc, read = 0; 47 int rc, read = 0;
48 struct {
49 struct shash_desc shash;
50 char ctx[crypto_shash_descsize(ima_shash_tfm)];
51 } desc;
52 52
53 rc = init_desc(&desc); 53 desc.shash.tfm = ima_shash_tfm;
54 desc.shash.flags = 0;
55
56 rc = crypto_shash_init(&desc.shash);
54 if (rc != 0) 57 if (rc != 0)
55 return rc; 58 return rc;
56 59
@@ -75,41 +78,34 @@ int ima_calc_hash(struct file *file, char *digest)
75 if (rbuf_len == 0) 78 if (rbuf_len == 0)
76 break; 79 break;
77 offset += rbuf_len; 80 offset += rbuf_len;
78 sg_init_one(sg, rbuf, rbuf_len);
79 81
80 rc = crypto_hash_update(&desc, sg, rbuf_len); 82 rc = crypto_shash_update(&desc.shash, rbuf, rbuf_len);
81 if (rc) 83 if (rc)
82 break; 84 break;
83 } 85 }
84 kfree(rbuf); 86 kfree(rbuf);
85 if (!rc) 87 if (!rc)
86 rc = crypto_hash_final(&desc, digest); 88 rc = crypto_shash_final(&desc.shash, digest);
87 if (read) 89 if (read)
88 file->f_mode &= ~FMODE_READ; 90 file->f_mode &= ~FMODE_READ;
89out: 91out:
90 crypto_free_hash(desc.tfm);
91 return rc; 92 return rc;
92} 93}
93 94
94/* 95/*
95 * Calculate the hash of a given template 96 * Calculate the hash of a given buffer
96 */ 97 */
97int ima_calc_template_hash(int template_len, void *template, char *digest) 98int ima_calc_buffer_hash(const void *data, int len, char *digest)
98{ 99{
99 struct hash_desc desc; 100 struct {
100 struct scatterlist sg[1]; 101 struct shash_desc shash;
101 int rc; 102 char ctx[crypto_shash_descsize(ima_shash_tfm)];
103 } desc;
102 104
103 rc = init_desc(&desc); 105 desc.shash.tfm = ima_shash_tfm;
104 if (rc != 0) 106 desc.shash.flags = 0;
105 return rc;
106 107
107 sg_init_one(sg, template, template_len); 108 return crypto_shash_digest(&desc.shash, data, len, digest);
108 rc = crypto_hash_update(&desc, sg, template_len);
109 if (!rc)
110 rc = crypto_hash_final(&desc, digest);
111 crypto_free_hash(desc.tfm);
112 return rc;
113} 109}
114 110
115static void __init ima_pcrread(int idx, u8 *pcr) 111static void __init ima_pcrread(int idx, u8 *pcr)
@@ -126,12 +122,17 @@ static void __init ima_pcrread(int idx, u8 *pcr)
126 */ 122 */
127int __init ima_calc_boot_aggregate(char *digest) 123int __init ima_calc_boot_aggregate(char *digest)
128{ 124{
129 struct hash_desc desc;
130 struct scatterlist sg;
131 u8 pcr_i[IMA_DIGEST_SIZE]; 125 u8 pcr_i[IMA_DIGEST_SIZE];
132 int rc, i; 126 int rc, i;
127 struct {
128 struct shash_desc shash;
129 char ctx[crypto_shash_descsize(ima_shash_tfm)];
130 } desc;
131
132 desc.shash.tfm = ima_shash_tfm;
133 desc.shash.flags = 0;
133 134
134 rc = init_desc(&desc); 135 rc = crypto_shash_init(&desc.shash);
135 if (rc != 0) 136 if (rc != 0)
136 return rc; 137 return rc;
137 138
@@ -139,11 +140,9 @@ int __init ima_calc_boot_aggregate(char *digest)
139 for (i = TPM_PCR0; i < TPM_PCR8; i++) { 140 for (i = TPM_PCR0; i < TPM_PCR8; i++) {
140 ima_pcrread(i, pcr_i); 141 ima_pcrread(i, pcr_i);
141 /* now accumulate with current aggregate */ 142 /* now accumulate with current aggregate */
142 sg_init_one(&sg, pcr_i, IMA_DIGEST_SIZE); 143 rc = crypto_shash_update(&desc.shash, pcr_i, IMA_DIGEST_SIZE);
143 rc = crypto_hash_update(&desc, &sg, IMA_DIGEST_SIZE);
144 } 144 }
145 if (!rc) 145 if (!rc)
146 crypto_hash_final(&desc, digest); 146 crypto_shash_final(&desc.shash, digest);
147 crypto_free_hash(desc.tfm);
148 return rc; 147 return rc;
149} 148}
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index b5dfd534f13d..162ea723db3d 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -85,6 +85,9 @@ int __init ima_init(void)
85 if (!ima_used_chip) 85 if (!ima_used_chip)
86 pr_info("IMA: No TPM chip found, activating TPM-bypass!\n"); 86 pr_info("IMA: No TPM chip found, activating TPM-bypass!\n");
87 87
88 rc = ima_init_crypto();
89 if (rc)
90 return rc;
88 ima_add_boot_aggregate(); /* boot aggregate must be first entry */ 91 ima_add_boot_aggregate(); /* boot aggregate must be first entry */
89 ima_init_policy(); 92 ima_init_policy();
90 93
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index dba965de90d3..5127afcc4b89 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -61,7 +61,8 @@ static void ima_rdwr_violation_check(struct file *file)
61 fmode_t mode = file->f_mode; 61 fmode_t mode = file->f_mode;
62 int must_measure; 62 int must_measure;
63 bool send_tomtou = false, send_writers = false; 63 bool send_tomtou = false, send_writers = false;
64 unsigned char *pathname = NULL, *pathbuf = NULL; 64 char *pathbuf = NULL;
65 const char *pathname;
65 66
66 if (!S_ISREG(inode->i_mode) || !ima_initialized) 67 if (!S_ISREG(inode->i_mode) || !ima_initialized)
67 return; 68 return;
@@ -86,22 +87,15 @@ out:
86 if (!send_tomtou && !send_writers) 87 if (!send_tomtou && !send_writers)
87 return; 88 return;
88 89
89 /* We will allow 11 spaces for ' (deleted)' to be appended */ 90 pathname = ima_d_path(&file->f_path, &pathbuf);
90 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); 91 if (!pathname || strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
91 if (pathbuf) { 92 pathname = dentry->d_name.name;
92 pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11); 93
93 if (IS_ERR(pathname))
94 pathname = NULL;
95 else if (strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
96 pathname = NULL;
97 }
98 if (send_tomtou) 94 if (send_tomtou)
99 ima_add_violation(inode, 95 ima_add_violation(inode, pathname,
100 !pathname ? dentry->d_name.name : pathname,
101 "invalid_pcr", "ToMToU"); 96 "invalid_pcr", "ToMToU");
102 if (send_writers) 97 if (send_writers)
103 ima_add_violation(inode, 98 ima_add_violation(inode, pathname,
104 !pathname ? dentry->d_name.name : pathname,
105 "invalid_pcr", "open_writers"); 99 "invalid_pcr", "open_writers");
106 kfree(pathbuf); 100 kfree(pathbuf);
107} 101}
@@ -145,25 +139,31 @@ void ima_file_free(struct file *file)
145 ima_check_last_writer(iint, inode, file); 139 ima_check_last_writer(iint, inode, file);
146} 140}
147 141
148static int process_measurement(struct file *file, const unsigned char *filename, 142static int process_measurement(struct file *file, const char *filename,
149 int mask, int function) 143 int mask, int function)
150{ 144{
151 struct inode *inode = file->f_dentry->d_inode; 145 struct inode *inode = file->f_dentry->d_inode;
152 struct integrity_iint_cache *iint; 146 struct integrity_iint_cache *iint;
153 unsigned char *pathname = NULL, *pathbuf = NULL; 147 char *pathbuf = NULL;
154 int rc = -ENOMEM, action, must_appraise; 148 const char *pathname = NULL;
149 int rc = -ENOMEM, action, must_appraise, _func;
155 150
156 if (!ima_initialized || !S_ISREG(inode->i_mode)) 151 if (!ima_initialized || !S_ISREG(inode->i_mode))
157 return 0; 152 return 0;
158 153
159 /* Determine if in appraise/audit/measurement policy, 154 /* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action
160 * returns IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT bitmask. */ 155 * bitmask based on the appraise/audit/measurement policy.
156 * Included is the appraise submask.
157 */
161 action = ima_get_action(inode, mask, function); 158 action = ima_get_action(inode, mask, function);
162 if (!action) 159 if (!action)
163 return 0; 160 return 0;
164 161
165 must_appraise = action & IMA_APPRAISE; 162 must_appraise = action & IMA_APPRAISE;
166 163
164 /* Is the appraise rule hook specific? */
165 _func = (action & IMA_FILE_APPRAISE) ? FILE_CHECK : function;
166
167 mutex_lock(&inode->i_mutex); 167 mutex_lock(&inode->i_mutex);
168 168
169 iint = integrity_inode_get(inode); 169 iint = integrity_inode_get(inode);
@@ -171,44 +171,45 @@ static int process_measurement(struct file *file, const unsigned char *filename,
171 goto out; 171 goto out;
172 172
173 /* Determine if already appraised/measured based on bitmask 173 /* Determine if already appraised/measured based on bitmask
174 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED, 174 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
175 * IMA_AUDIT, IMA_AUDITED) */ 175 * IMA_AUDIT, IMA_AUDITED)
176 */
176 iint->flags |= action; 177 iint->flags |= action;
178 action &= IMA_DO_MASK;
177 action &= ~((iint->flags & IMA_DONE_MASK) >> 1); 179 action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
178 180
179 /* Nothing to do, just return existing appraised status */ 181 /* Nothing to do, just return existing appraised status */
180 if (!action) { 182 if (!action) {
181 if (iint->flags & IMA_APPRAISED) 183 if (must_appraise)
182 rc = iint->ima_status; 184 rc = ima_get_cache_status(iint, _func);
183 goto out; 185 goto out_digsig;
184 } 186 }
185 187
186 rc = ima_collect_measurement(iint, file); 188 rc = ima_collect_measurement(iint, file);
187 if (rc != 0) 189 if (rc != 0)
188 goto out; 190 goto out_digsig;
191
192 if (function != BPRM_CHECK)
193 pathname = ima_d_path(&file->f_path, &pathbuf);
194
195 if (!pathname)
196 pathname = filename;
189 197
190 if (function != BPRM_CHECK) {
191 /* We will allow 11 spaces for ' (deleted)' to be appended */
192 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
193 if (pathbuf) {
194 pathname =
195 d_path(&file->f_path, pathbuf, PATH_MAX + 11);
196 if (IS_ERR(pathname))
197 pathname = NULL;
198 }
199 }
200 if (action & IMA_MEASURE) 198 if (action & IMA_MEASURE)
201 ima_store_measurement(iint, file, 199 ima_store_measurement(iint, file, pathname);
202 !pathname ? filename : pathname); 200 if (action & IMA_APPRAISE_SUBMASK)
203 if (action & IMA_APPRAISE) 201 rc = ima_appraise_measurement(_func, iint, file, pathname);
204 rc = ima_appraise_measurement(iint, file,
205 !pathname ? filename : pathname);
206 if (action & IMA_AUDIT) 202 if (action & IMA_AUDIT)
207 ima_audit_measurement(iint, !pathname ? filename : pathname); 203 ima_audit_measurement(iint, pathname);
208 kfree(pathbuf); 204 kfree(pathbuf);
205out_digsig:
206 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG))
207 rc = -EACCES;
209out: 208out:
210 mutex_unlock(&inode->i_mutex); 209 mutex_unlock(&inode->i_mutex);
211 return (rc && must_appraise) ? -EACCES : 0; 210 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
211 return -EACCES;
212 return 0;
212} 213}
213 214
214/** 215/**
@@ -219,19 +220,15 @@ out:
219 * Measure files being mmapped executable based on the ima_must_measure() 220 * Measure files being mmapped executable based on the ima_must_measure()
220 * policy decision. 221 * policy decision.
221 * 222 *
222 * Return 0 on success, an error code on failure. 223 * On success return 0. On integrity appraisal error, assuming the file
223 * (Based on the results of appraise_measurement().) 224 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
224 */ 225 */
225int ima_file_mmap(struct file *file, unsigned long prot) 226int ima_file_mmap(struct file *file, unsigned long prot)
226{ 227{
227 int rc = 0; 228 if (file && (prot & PROT_EXEC))
228 229 return process_measurement(file, file->f_dentry->d_name.name,
229 if (!file) 230 MAY_EXEC, MMAP_CHECK);
230 return 0; 231 return 0;
231 if (prot & PROT_EXEC)
232 rc = process_measurement(file, file->f_dentry->d_name.name,
233 MAY_EXEC, FILE_MMAP);
234 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
235} 232}
236 233
237/** 234/**
@@ -244,18 +241,15 @@ int ima_file_mmap(struct file *file, unsigned long prot)
244 * So we can be certain that what we verify and measure here is actually 241 * So we can be certain that what we verify and measure here is actually
245 * what is being executed. 242 * what is being executed.
246 * 243 *
247 * Return 0 on success, an error code on failure. 244 * On success return 0. On integrity appraisal error, assuming the file
248 * (Based on the results of appraise_measurement().) 245 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
249 */ 246 */
250int ima_bprm_check(struct linux_binprm *bprm) 247int ima_bprm_check(struct linux_binprm *bprm)
251{ 248{
252 int rc; 249 return process_measurement(bprm->file,
253
254 rc = process_measurement(bprm->file,
255 (strcmp(bprm->filename, bprm->interp) == 0) ? 250 (strcmp(bprm->filename, bprm->interp) == 0) ?
256 bprm->filename : bprm->interp, 251 bprm->filename : bprm->interp,
257 MAY_EXEC, BPRM_CHECK); 252 MAY_EXEC, BPRM_CHECK);
258 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
259} 253}
260 254
261/** 255/**
@@ -265,18 +259,15 @@ int ima_bprm_check(struct linux_binprm *bprm)
265 * 259 *
266 * Measure files based on the ima_must_measure() policy decision. 260 * Measure files based on the ima_must_measure() policy decision.
267 * 261 *
268 * Always return 0 and audit dentry_open failures. 262 * On success return 0. On integrity appraisal error, assuming the file
269 * (Return code will be based upon measurement appraisal.) 263 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
270 */ 264 */
271int ima_file_check(struct file *file, int mask) 265int ima_file_check(struct file *file, int mask)
272{ 266{
273 int rc;
274
275 ima_rdwr_violation_check(file); 267 ima_rdwr_violation_check(file);
276 rc = process_measurement(file, file->f_dentry->d_name.name, 268 return process_measurement(file, file->f_dentry->d_name.name,
277 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 269 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
278 FILE_CHECK); 270 FILE_CHECK);
279 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
280} 271}
281EXPORT_SYMBOL_GPL(ima_file_check); 272EXPORT_SYMBOL_GPL(ima_file_check);
282 273
@@ -286,23 +277,20 @@ EXPORT_SYMBOL_GPL(ima_file_check);
286 * 277 *
287 * Measure/appraise kernel modules based on policy. 278 * Measure/appraise kernel modules based on policy.
288 * 279 *
289 * Always return 0 and audit dentry_open failures. 280 * On success return 0. On integrity appraisal error, assuming the file
290 * Return code is based upon measurement appraisal. 281 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
291 */ 282 */
292int ima_module_check(struct file *file) 283int ima_module_check(struct file *file)
293{ 284{
294 int rc = 0;
295
296 if (!file) { 285 if (!file) {
297 if (ima_appraise & IMA_APPRAISE_MODULES) {
298#ifndef CONFIG_MODULE_SIG_FORCE 286#ifndef CONFIG_MODULE_SIG_FORCE
299 rc = -EACCES; /* INTEGRITY_UNKNOWN */ 287 if (ima_appraise & IMA_APPRAISE_MODULES)
288 return -EACCES; /* INTEGRITY_UNKNOWN */
300#endif 289#endif
301 } 290 return 0; /* We rely on module signature checking */
302 } else 291 }
303 rc = process_measurement(file, file->f_dentry->d_name.name, 292 return process_measurement(file, file->f_dentry->d_name.name,
304 MAY_EXEC, MODULE_CHECK); 293 MAY_EXEC, MODULE_CHECK);
305 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
306} 294}
307 295
308static int __init init_ima(void) 296static int __init init_ima(void)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 479fca940bb5..b27535a13a79 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -16,6 +16,7 @@
16#include <linux/magic.h> 16#include <linux/magic.h>
17#include <linux/parser.h> 17#include <linux/parser.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/genhd.h>
19 20
20#include "ima.h" 21#include "ima.h"
21 22
@@ -25,6 +26,7 @@
25#define IMA_FSMAGIC 0x0004 26#define IMA_FSMAGIC 0x0004
26#define IMA_UID 0x0008 27#define IMA_UID 0x0008
27#define IMA_FOWNER 0x0010 28#define IMA_FOWNER 0x0010
29#define IMA_FSUUID 0x0020
28 30
29#define UNKNOWN 0 31#define UNKNOWN 0
30#define MEASURE 0x0001 /* same as IMA_MEASURE */ 32#define MEASURE 0x0001 /* same as IMA_MEASURE */
@@ -45,10 +47,12 @@ struct ima_rule_entry {
45 enum ima_hooks func; 47 enum ima_hooks func;
46 int mask; 48 int mask;
47 unsigned long fsmagic; 49 unsigned long fsmagic;
50 u8 fsuuid[16];
48 kuid_t uid; 51 kuid_t uid;
49 kuid_t fowner; 52 kuid_t fowner;
50 struct { 53 struct {
51 void *rule; /* LSM file metadata specific */ 54 void *rule; /* LSM file metadata specific */
55 void *args_p; /* audit value */
52 int type; /* audit type */ 56 int type; /* audit type */
53 } lsm[MAX_LSM_RULES]; 57 } lsm[MAX_LSM_RULES];
54}; 58};
@@ -74,7 +78,7 @@ static struct ima_rule_entry default_rules[] = {
74 {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC}, 78 {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
75 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, 79 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
76 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, 80 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
77 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, 81 {.action = MEASURE,.func = MMAP_CHECK,.mask = MAY_EXEC,
78 .flags = IMA_FUNC | IMA_MASK}, 82 .flags = IMA_FUNC | IMA_MASK},
79 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, 83 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
80 .flags = IMA_FUNC | IMA_MASK}, 84 .flags = IMA_FUNC | IMA_MASK},
@@ -119,6 +123,35 @@ static int __init default_appraise_policy_setup(char *str)
119} 123}
120__setup("ima_appraise_tcb", default_appraise_policy_setup); 124__setup("ima_appraise_tcb", default_appraise_policy_setup);
121 125
126/*
127 * Although the IMA policy does not change, the LSM policy can be
128 * reloaded, leaving the IMA LSM based rules referring to the old,
129 * stale LSM policy.
130 *
131 * Update the IMA LSM based rules to reflect the reloaded LSM policy.
132 * We assume the rules still exist; and BUG_ON() if they don't.
133 */
134static void ima_lsm_update_rules(void)
135{
136 struct ima_rule_entry *entry, *tmp;
137 int result;
138 int i;
139
140 mutex_lock(&ima_rules_mutex);
141 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) {
142 for (i = 0; i < MAX_LSM_RULES; i++) {
143 if (!entry->lsm[i].rule)
144 continue;
145 result = security_filter_rule_init(entry->lsm[i].type,
146 Audit_equal,
147 entry->lsm[i].args_p,
148 &entry->lsm[i].rule);
149 BUG_ON(!entry->lsm[i].rule);
150 }
151 }
152 mutex_unlock(&ima_rules_mutex);
153}
154
122/** 155/**
123 * ima_match_rules - determine whether an inode matches the measure rule. 156 * ima_match_rules - determine whether an inode matches the measure rule.
124 * @rule: a pointer to a rule 157 * @rule: a pointer to a rule
@@ -142,6 +175,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
142 if ((rule->flags & IMA_FSMAGIC) 175 if ((rule->flags & IMA_FSMAGIC)
143 && rule->fsmagic != inode->i_sb->s_magic) 176 && rule->fsmagic != inode->i_sb->s_magic)
144 return false; 177 return false;
178 if ((rule->flags & IMA_FSUUID) &&
179 memcmp(rule->fsuuid, inode->i_sb->s_uuid, sizeof(rule->fsuuid)))
180 return false;
145 if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid)) 181 if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
146 return false; 182 return false;
147 if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid)) 183 if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
@@ -149,10 +185,11 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
149 for (i = 0; i < MAX_LSM_RULES; i++) { 185 for (i = 0; i < MAX_LSM_RULES; i++) {
150 int rc = 0; 186 int rc = 0;
151 u32 osid, sid; 187 u32 osid, sid;
188 int retried = 0;
152 189
153 if (!rule->lsm[i].rule) 190 if (!rule->lsm[i].rule)
154 continue; 191 continue;
155 192retry:
156 switch (i) { 193 switch (i) {
157 case LSM_OBJ_USER: 194 case LSM_OBJ_USER:
158 case LSM_OBJ_ROLE: 195 case LSM_OBJ_ROLE:
@@ -176,12 +213,39 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
176 default: 213 default:
177 break; 214 break;
178 } 215 }
216 if ((rc < 0) && (!retried)) {
217 retried = 1;
218 ima_lsm_update_rules();
219 goto retry;
220 }
179 if (!rc) 221 if (!rc)
180 return false; 222 return false;
181 } 223 }
182 return true; 224 return true;
183} 225}
184 226
227/*
228 * In addition to knowing that we need to appraise the file in general,
229 * we need to differentiate between calling hooks, for hook specific rules.
230 */
231static int get_subaction(struct ima_rule_entry *rule, int func)
232{
233 if (!(rule->flags & IMA_FUNC))
234 return IMA_FILE_APPRAISE;
235
236 switch(func) {
237 case MMAP_CHECK:
238 return IMA_MMAP_APPRAISE;
239 case BPRM_CHECK:
240 return IMA_BPRM_APPRAISE;
241 case MODULE_CHECK:
242 return IMA_MODULE_APPRAISE;
243 case FILE_CHECK:
244 default:
245 return IMA_FILE_APPRAISE;
246 }
247}
248
185/** 249/**
186 * ima_match_policy - decision based on LSM and other conditions 250 * ima_match_policy - decision based on LSM and other conditions
187 * @inode: pointer to an inode for which the policy decision is being made 251 * @inode: pointer to an inode for which the policy decision is being made
@@ -209,7 +273,12 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
209 if (!ima_match_rules(entry, inode, func, mask)) 273 if (!ima_match_rules(entry, inode, func, mask))
210 continue; 274 continue;
211 275
276 action |= entry->flags & IMA_ACTION_FLAGS;
277
212 action |= entry->action & IMA_DO_MASK; 278 action |= entry->action & IMA_DO_MASK;
279 if (entry->action & IMA_APPRAISE)
280 action |= get_subaction(entry, func);
281
213 if (entry->action & IMA_DO_MASK) 282 if (entry->action & IMA_DO_MASK)
214 actmask &= ~(entry->action | entry->action << 1); 283 actmask &= ~(entry->action | entry->action << 1);
215 else 284 else
@@ -282,7 +351,8 @@ enum {
282 Opt_audit, 351 Opt_audit,
283 Opt_obj_user, Opt_obj_role, Opt_obj_type, 352 Opt_obj_user, Opt_obj_role, Opt_obj_type,
284 Opt_subj_user, Opt_subj_role, Opt_subj_type, 353 Opt_subj_user, Opt_subj_role, Opt_subj_type,
285 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner 354 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
355 Opt_appraise_type, Opt_fsuuid
286}; 356};
287 357
288static match_table_t policy_tokens = { 358static match_table_t policy_tokens = {
@@ -300,25 +370,35 @@ static match_table_t policy_tokens = {
300 {Opt_func, "func=%s"}, 370 {Opt_func, "func=%s"},
301 {Opt_mask, "mask=%s"}, 371 {Opt_mask, "mask=%s"},
302 {Opt_fsmagic, "fsmagic=%s"}, 372 {Opt_fsmagic, "fsmagic=%s"},
373 {Opt_fsuuid, "fsuuid=%s"},
303 {Opt_uid, "uid=%s"}, 374 {Opt_uid, "uid=%s"},
304 {Opt_fowner, "fowner=%s"}, 375 {Opt_fowner, "fowner=%s"},
376 {Opt_appraise_type, "appraise_type=%s"},
305 {Opt_err, NULL} 377 {Opt_err, NULL}
306}; 378};
307 379
308static int ima_lsm_rule_init(struct ima_rule_entry *entry, 380static int ima_lsm_rule_init(struct ima_rule_entry *entry,
309 char *args, int lsm_rule, int audit_type) 381 substring_t *args, int lsm_rule, int audit_type)
310{ 382{
311 int result; 383 int result;
312 384
313 if (entry->lsm[lsm_rule].rule) 385 if (entry->lsm[lsm_rule].rule)
314 return -EINVAL; 386 return -EINVAL;
315 387
388 entry->lsm[lsm_rule].args_p = match_strdup(args);
389 if (!entry->lsm[lsm_rule].args_p)
390 return -ENOMEM;
391
316 entry->lsm[lsm_rule].type = audit_type; 392 entry->lsm[lsm_rule].type = audit_type;
317 result = security_filter_rule_init(entry->lsm[lsm_rule].type, 393 result = security_filter_rule_init(entry->lsm[lsm_rule].type,
318 Audit_equal, args, 394 Audit_equal,
395 entry->lsm[lsm_rule].args_p,
319 &entry->lsm[lsm_rule].rule); 396 &entry->lsm[lsm_rule].rule);
320 if (!entry->lsm[lsm_rule].rule) 397 if (!entry->lsm[lsm_rule].rule) {
398 kfree(entry->lsm[lsm_rule].args_p);
321 return -EINVAL; 399 return -EINVAL;
400 }
401
322 return result; 402 return result;
323} 403}
324 404
@@ -404,8 +484,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
404 entry->func = FILE_CHECK; 484 entry->func = FILE_CHECK;
405 else if (strcmp(args[0].from, "MODULE_CHECK") == 0) 485 else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
406 entry->func = MODULE_CHECK; 486 entry->func = MODULE_CHECK;
407 else if (strcmp(args[0].from, "FILE_MMAP") == 0) 487 else if ((strcmp(args[0].from, "FILE_MMAP") == 0)
408 entry->func = FILE_MMAP; 488 || (strcmp(args[0].from, "MMAP_CHECK") == 0))
489 entry->func = MMAP_CHECK;
409 else if (strcmp(args[0].from, "BPRM_CHECK") == 0) 490 else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
410 entry->func = BPRM_CHECK; 491 entry->func = BPRM_CHECK;
411 else 492 else
@@ -445,6 +526,19 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
445 if (!result) 526 if (!result)
446 entry->flags |= IMA_FSMAGIC; 527 entry->flags |= IMA_FSMAGIC;
447 break; 528 break;
529 case Opt_fsuuid:
530 ima_log_string(ab, "fsuuid", args[0].from);
531
532 if (memchr_inv(entry->fsuuid, 0x00,
533 sizeof(entry->fsuuid))) {
534 result = -EINVAL;
535 break;
536 }
537
538 part_pack_uuid(args[0].from, entry->fsuuid);
539 entry->flags |= IMA_FSUUID;
540 result = 0;
541 break;
448 case Opt_uid: 542 case Opt_uid:
449 ima_log_string(ab, "uid", args[0].from); 543 ima_log_string(ab, "uid", args[0].from);
450 544
@@ -481,40 +575,52 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
481 break; 575 break;
482 case Opt_obj_user: 576 case Opt_obj_user:
483 ima_log_string(ab, "obj_user", args[0].from); 577 ima_log_string(ab, "obj_user", args[0].from);
484 result = ima_lsm_rule_init(entry, args[0].from, 578 result = ima_lsm_rule_init(entry, args,
485 LSM_OBJ_USER, 579 LSM_OBJ_USER,
486 AUDIT_OBJ_USER); 580 AUDIT_OBJ_USER);
487 break; 581 break;
488 case Opt_obj_role: 582 case Opt_obj_role:
489 ima_log_string(ab, "obj_role", args[0].from); 583 ima_log_string(ab, "obj_role", args[0].from);
490 result = ima_lsm_rule_init(entry, args[0].from, 584 result = ima_lsm_rule_init(entry, args,
491 LSM_OBJ_ROLE, 585 LSM_OBJ_ROLE,
492 AUDIT_OBJ_ROLE); 586 AUDIT_OBJ_ROLE);
493 break; 587 break;
494 case Opt_obj_type: 588 case Opt_obj_type:
495 ima_log_string(ab, "obj_type", args[0].from); 589 ima_log_string(ab, "obj_type", args[0].from);
496 result = ima_lsm_rule_init(entry, args[0].from, 590 result = ima_lsm_rule_init(entry, args,
497 LSM_OBJ_TYPE, 591 LSM_OBJ_TYPE,
498 AUDIT_OBJ_TYPE); 592 AUDIT_OBJ_TYPE);
499 break; 593 break;
500 case Opt_subj_user: 594 case Opt_subj_user:
501 ima_log_string(ab, "subj_user", args[0].from); 595 ima_log_string(ab, "subj_user", args[0].from);
502 result = ima_lsm_rule_init(entry, args[0].from, 596 result = ima_lsm_rule_init(entry, args,
503 LSM_SUBJ_USER, 597 LSM_SUBJ_USER,
504 AUDIT_SUBJ_USER); 598 AUDIT_SUBJ_USER);
505 break; 599 break;
506 case Opt_subj_role: 600 case Opt_subj_role:
507 ima_log_string(ab, "subj_role", args[0].from); 601 ima_log_string(ab, "subj_role", args[0].from);
508 result = ima_lsm_rule_init(entry, args[0].from, 602 result = ima_lsm_rule_init(entry, args,
509 LSM_SUBJ_ROLE, 603 LSM_SUBJ_ROLE,
510 AUDIT_SUBJ_ROLE); 604 AUDIT_SUBJ_ROLE);
511 break; 605 break;
512 case Opt_subj_type: 606 case Opt_subj_type:
513 ima_log_string(ab, "subj_type", args[0].from); 607 ima_log_string(ab, "subj_type", args[0].from);
514 result = ima_lsm_rule_init(entry, args[0].from, 608 result = ima_lsm_rule_init(entry, args,
515 LSM_SUBJ_TYPE, 609 LSM_SUBJ_TYPE,
516 AUDIT_SUBJ_TYPE); 610 AUDIT_SUBJ_TYPE);
517 break; 611 break;
612 case Opt_appraise_type:
613 if (entry->action != APPRAISE) {
614 result = -EINVAL;
615 break;
616 }
617
618 ima_log_string(ab, "appraise_type", args[0].from);
619 if ((strcmp(args[0].from, "imasig")) == 0)
620 entry->flags |= IMA_DIGSIG_REQUIRED;
621 else
622 result = -EINVAL;
623 break;
518 case Opt_err: 624 case Opt_err:
519 ima_log_string(ab, "UNKNOWN", p); 625 ima_log_string(ab, "UNKNOWN", p);
520 result = -EINVAL; 626 result = -EINVAL;
@@ -590,9 +696,13 @@ ssize_t ima_parse_add_rule(char *rule)
590void ima_delete_rules(void) 696void ima_delete_rules(void)
591{ 697{
592 struct ima_rule_entry *entry, *tmp; 698 struct ima_rule_entry *entry, *tmp;
699 int i;
593 700
594 mutex_lock(&ima_rules_mutex); 701 mutex_lock(&ima_rules_mutex);
595 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) { 702 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) {
703 for (i = 0; i < MAX_LSM_RULES; i++)
704 kfree(entry->lsm[i].args_p);
705
596 list_del(&entry->list); 706 list_del(&entry->list);
597 kfree(entry); 707 kfree(entry);
598 } 708 }
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index e9db763a875e..84c37c4db914 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -14,23 +14,41 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/integrity.h> 15#include <linux/integrity.h>
16#include <crypto/sha.h> 16#include <crypto/sha.h>
17#include <linux/key.h>
17 18
18/* iint action cache flags */ 19/* iint action cache flags */
19#define IMA_MEASURE 0x0001 20#define IMA_MEASURE 0x00000001
20#define IMA_MEASURED 0x0002 21#define IMA_MEASURED 0x00000002
21#define IMA_APPRAISE 0x0004 22#define IMA_APPRAISE 0x00000004
22#define IMA_APPRAISED 0x0008 23#define IMA_APPRAISED 0x00000008
23/*#define IMA_COLLECT 0x0010 do not use this flag */ 24/*#define IMA_COLLECT 0x00000010 do not use this flag */
24#define IMA_COLLECTED 0x0020 25#define IMA_COLLECTED 0x00000020
25#define IMA_AUDIT 0x0040 26#define IMA_AUDIT 0x00000040
26#define IMA_AUDITED 0x0080 27#define IMA_AUDITED 0x00000080
27 28
28/* iint cache flags */ 29/* iint cache flags */
29#define IMA_DIGSIG 0x0100 30#define IMA_ACTION_FLAGS 0xff000000
31#define IMA_DIGSIG 0x01000000
32#define IMA_DIGSIG_REQUIRED 0x02000000
30 33
31#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT) 34#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
32#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED \ 35 IMA_APPRAISE_SUBMASK)
33 | IMA_COLLECTED) 36#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED | \
37 IMA_COLLECTED | IMA_APPRAISED_SUBMASK)
38
39/* iint subaction appraise cache flags */
40#define IMA_FILE_APPRAISE 0x00000100
41#define IMA_FILE_APPRAISED 0x00000200
42#define IMA_MMAP_APPRAISE 0x00000400
43#define IMA_MMAP_APPRAISED 0x00000800
44#define IMA_BPRM_APPRAISE 0x00001000
45#define IMA_BPRM_APPRAISED 0x00002000
46#define IMA_MODULE_APPRAISE 0x00004000
47#define IMA_MODULE_APPRAISED 0x00008000
48#define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
49 IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE)
50#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
51 IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED)
34 52
35enum evm_ima_xattr_type { 53enum evm_ima_xattr_type {
36 IMA_XATTR_DIGEST = 0x01, 54 IMA_XATTR_DIGEST = 0x01,
@@ -48,10 +66,13 @@ struct integrity_iint_cache {
48 struct rb_node rb_node; /* rooted in integrity_iint_tree */ 66 struct rb_node rb_node; /* rooted in integrity_iint_tree */
49 struct inode *inode; /* back pointer to inode in question */ 67 struct inode *inode; /* back pointer to inode in question */
50 u64 version; /* track inode changes */ 68 u64 version; /* track inode changes */
51 unsigned short flags; 69 unsigned long flags;
52 struct evm_ima_xattr_data ima_xattr; 70 struct evm_ima_xattr_data ima_xattr;
53 enum integrity_status ima_status; 71 enum integrity_status ima_file_status:4;
54 enum integrity_status evm_status; 72 enum integrity_status ima_mmap_status:4;
73 enum integrity_status ima_bprm_status:4;
74 enum integrity_status ima_module_status:4;
75 enum integrity_status evm_status:4;
55}; 76};
56 77
57/* rbtree tree calls to lookup, insert, delete 78/* rbtree tree calls to lookup, insert, delete
@@ -81,5 +102,16 @@ static inline int integrity_digsig_verify(const unsigned int id,
81 102
82#endif /* CONFIG_INTEGRITY_SIGNATURE */ 103#endif /* CONFIG_INTEGRITY_SIGNATURE */
83 104
105#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
106int asymmetric_verify(struct key *keyring, const char *sig,
107 int siglen, const char *data, int datalen);
108#else
109static inline int asymmetric_verify(struct key *keyring, const char *sig,
110 int siglen, const char *data, int datalen)
111{
112 return -EOPNOTSUPP;
113}
114#endif
115
84/* set during initialization */ 116/* set during initialization */
85extern int iint_initialized; 117extern int iint_initialized;