aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /security/integrity
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/Kconfig21
-rw-r--r--security/integrity/Makefile13
-rw-r--r--security/integrity/digsig.c48
-rw-r--r--security/integrity/evm/Kconfig13
-rw-r--r--security/integrity/evm/Makefile7
-rw-r--r--security/integrity/evm/evm.h50
-rw-r--r--security/integrity/evm/evm_crypto.c257
-rw-r--r--security/integrity/evm/evm_main.c455
-rw-r--r--security/integrity/evm/evm_posix_acl.c26
-rw-r--r--security/integrity/evm/evm_secfs.c108
-rw-r--r--security/integrity/iint.c164
-rw-r--r--security/integrity/ima/Kconfig24
-rw-r--r--security/integrity/ima/Makefile4
-rw-r--r--security/integrity/ima/ima.h79
-rw-r--r--security/integrity/ima/ima_api.c101
-rw-r--r--security/integrity/ima/ima_appraise.c263
-rw-r--r--security/integrity/ima/ima_audit.c18
-rw-r--r--security/integrity/ima/ima_crypto.c8
-rw-r--r--security/integrity/ima/ima_fs.c13
-rw-r--r--security/integrity/ima/ima_init.c5
-rw-r--r--security/integrity/ima/ima_main.c179
-rw-r--r--security/integrity/ima/ima_policy.c221
-rw-r--r--security/integrity/integrity.h85
23 files changed, 181 insertions, 1981 deletions
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
deleted file mode 100644
index 5bd1cc1b4a5..00000000000
--- a/security/integrity/Kconfig
+++ /dev/null
@@ -1,21 +0,0 @@
1#
2config INTEGRITY
3 def_bool y
4 depends on IMA || EVM
5
6config INTEGRITY_SIGNATURE
7 boolean "Digital signature verification using multiple keyrings"
8 depends on INTEGRITY && KEYS
9 default n
10 select SIGNATURE
11 help
12 This option enables digital signature verification support
13 using multiple keyrings. It defines separate keyrings for each
14 of the different use cases - evm, ima, and modules.
15 Different keyrings improves search performance, but also allow
16 to "lock" certain keyring to prevent adding new keys.
17 This is useful for evm and module keyrings, when keys are
18 usually only added from initramfs.
19
20source security/integrity/ima/Kconfig
21source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
deleted file mode 100644
index d43799cc14f..00000000000
--- a/security/integrity/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
1#
2# Makefile for caching inode integrity data (iint)
3#
4
5obj-$(CONFIG_INTEGRITY) += integrity.o
6obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
7
8integrity-y := iint.o
9
10subdir-$(CONFIG_IMA) += ima
11obj-$(CONFIG_IMA) += ima/built-in.o
12subdir-$(CONFIG_EVM) += evm
13obj-$(CONFIG_EVM) += evm/built-in.o
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
deleted file mode 100644
index 2dc167d7cde..00000000000
--- a/security/integrity/digsig.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * Copyright (C) 2011 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/rbtree.h>
17#include <linux/key-type.h>
18#include <linux/digsig.h>
19
20#include "integrity.h"
21
22static struct key *keyring[INTEGRITY_KEYRING_MAX];
23
24static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
25 "_evm",
26 "_module",
27 "_ima",
28};
29
30int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
31 const char *digest, int digestlen)
32{
33 if (id >= INTEGRITY_KEYRING_MAX)
34 return -EINVAL;
35
36 if (!keyring[id]) {
37 keyring[id] =
38 request_key(&key_type_keyring, keyring_name[id], NULL);
39 if (IS_ERR(keyring[id])) {
40 int err = PTR_ERR(keyring[id]);
41 pr_err("no %s keyring: %d\n", keyring_name[id], err);
42 keyring[id] = NULL;
43 return err;
44 }
45 }
46
47 return digsig_verify(keyring[id], sig, siglen, digest, digestlen);
48}
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig
deleted file mode 100644
index afbb59dd262..00000000000
--- a/security/integrity/evm/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
1config EVM
2 boolean "EVM support"
3 depends on SECURITY && KEYS && (TRUSTED_KEYS=y || TRUSTED_KEYS=n)
4 select CRYPTO_HMAC
5 select CRYPTO_MD5
6 select CRYPTO_SHA1
7 select ENCRYPTED_KEYS
8 default n
9 help
10 EVM protects a file's security extended attributes against
11 integrity attacks.
12
13 If you are unsure how to answer this question, answer N.
diff --git a/security/integrity/evm/Makefile b/security/integrity/evm/Makefile
deleted file mode 100644
index 7393c415a06..00000000000
--- a/security/integrity/evm/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
1#
2# Makefile for building the Extended Verification Module(EVM)
3#
4obj-$(CONFIG_EVM) += evm.o
5
6evm-y := evm_main.o evm_crypto.o evm_secfs.o
7evm-$(CONFIG_FS_POSIX_ACL) += evm_posix_acl.o
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
deleted file mode 100644
index c885247ebcf..00000000000
--- a/security/integrity/evm/evm.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm.h
13 *
14 */
15
16#ifndef __INTEGRITY_EVM_H
17#define __INTEGRITY_EVM_H
18
19#include <linux/xattr.h>
20#include <linux/security.h>
21
22#include "../integrity.h"
23
24extern int evm_initialized;
25extern char *evm_hmac;
26extern char *evm_hash;
27
28extern struct crypto_shash *hmac_tfm;
29extern struct crypto_shash *hash_tfm;
30
31/* List of EVM protected security xattrs */
32extern char *evm_config_xattrnames[];
33
34extern int evm_init_key(void);
35extern int evm_update_evmxattr(struct dentry *dentry,
36 const char *req_xattr_name,
37 const char *req_xattr_value,
38 size_t req_xattr_value_len);
39extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
40 const char *req_xattr_value,
41 size_t req_xattr_value_len, char *digest);
42extern int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
43 const char *req_xattr_value,
44 size_t req_xattr_value_len, char *digest);
45extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
46 char *hmac_val);
47extern int evm_init_secfs(void);
48extern void evm_cleanup_secfs(void);
49
50#endif
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
deleted file mode 100644
index dfb26918699..00000000000
--- a/security/integrity/evm/evm_crypto.c
+++ /dev/null
@@ -1,257 +0,0 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm_crypto.c
13 * Using root's kernel master key (kmk), calculate the HMAC
14 */
15
16#include <linux/module.h>
17#include <linux/crypto.h>
18#include <linux/xattr.h>
19#include <keys/encrypted-type.h>
20#include <crypto/hash.h>
21#include "evm.h"
22
23#define EVMKEY "evm-key"
24#define MAX_KEY_SIZE 128
25static unsigned char evmkey[MAX_KEY_SIZE];
26static int evmkey_len = MAX_KEY_SIZE;
27
28struct crypto_shash *hmac_tfm;
29struct crypto_shash *hash_tfm;
30
31static DEFINE_MUTEX(mutex);
32
33static struct shash_desc *init_desc(char type)
34{
35 long rc;
36 char *algo;
37 struct crypto_shash **tfm;
38 struct shash_desc *desc;
39
40 if (type == EVM_XATTR_HMAC) {
41 tfm = &hmac_tfm;
42 algo = evm_hmac;
43 } else {
44 tfm = &hash_tfm;
45 algo = evm_hash;
46 }
47
48 if (*tfm == NULL) {
49 mutex_lock(&mutex);
50 if (*tfm)
51 goto out;
52 *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC);
53 if (IS_ERR(*tfm)) {
54 rc = PTR_ERR(*tfm);
55 pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
56 *tfm = NULL;
57 mutex_unlock(&mutex);
58 return ERR_PTR(rc);
59 }
60 if (type == EVM_XATTR_HMAC) {
61 rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len);
62 if (rc) {
63 crypto_free_shash(*tfm);
64 *tfm = NULL;
65 mutex_unlock(&mutex);
66 return ERR_PTR(rc);
67 }
68 }
69out:
70 mutex_unlock(&mutex);
71 }
72
73 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm),
74 GFP_KERNEL);
75 if (!desc)
76 return ERR_PTR(-ENOMEM);
77
78 desc->tfm = *tfm;
79 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
80
81 rc = crypto_shash_init(desc);
82 if (rc) {
83 kfree(desc);
84 return ERR_PTR(rc);
85 }
86 return desc;
87}
88
89/* Protect against 'cutting & pasting' security.evm xattr, include inode
90 * specific info.
91 *
92 * (Additional directory/file metadata needs to be added for more complete
93 * protection.)
94 */
95static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
96 char *digest)
97{
98 struct h_misc {
99 unsigned long ino;
100 __u32 generation;
101 uid_t uid;
102 gid_t gid;
103 umode_t mode;
104 } hmac_misc;
105
106 memset(&hmac_misc, 0, sizeof hmac_misc);
107 hmac_misc.ino = inode->i_ino;
108 hmac_misc.generation = inode->i_generation;
109 hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
110 hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
111 hmac_misc.mode = inode->i_mode;
112 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc);
113 crypto_shash_final(desc, digest);
114}
115
116/*
117 * Calculate the HMAC value across the set of protected security xattrs.
118 *
119 * Instead of retrieving the requested xattr, for performance, calculate
120 * the hmac using the requested xattr value. Don't alloc/free memory for
121 * each xattr, but attempt to re-use the previously allocated memory.
122 */
123static int evm_calc_hmac_or_hash(struct dentry *dentry,
124 const char *req_xattr_name,
125 const char *req_xattr_value,
126 size_t req_xattr_value_len,
127 char type, char *digest)
128{
129 struct inode *inode = dentry->d_inode;
130 struct shash_desc *desc;
131 char **xattrname;
132 size_t xattr_size = 0;
133 char *xattr_value = NULL;
134 int error;
135 int size;
136
137 if (!inode->i_op || !inode->i_op->getxattr)
138 return -EOPNOTSUPP;
139 desc = init_desc(type);
140 if (IS_ERR(desc))
141 return PTR_ERR(desc);
142
143 error = -ENODATA;
144 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
145 if ((req_xattr_name && req_xattr_value)
146 && !strcmp(*xattrname, req_xattr_name)) {
147 error = 0;
148 crypto_shash_update(desc, (const u8 *)req_xattr_value,
149 req_xattr_value_len);
150 continue;
151 }
152 size = vfs_getxattr_alloc(dentry, *xattrname,
153 &xattr_value, xattr_size, GFP_NOFS);
154 if (size == -ENOMEM) {
155 error = -ENOMEM;
156 goto out;
157 }
158 if (size < 0)
159 continue;
160
161 error = 0;
162 xattr_size = size;
163 crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size);
164 }
165 hmac_add_misc(desc, inode, digest);
166
167out:
168 kfree(xattr_value);
169 kfree(desc);
170 return error;
171}
172
173int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
174 const char *req_xattr_value, size_t req_xattr_value_len,
175 char *digest)
176{
177 return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
178 req_xattr_value_len, EVM_XATTR_HMAC, digest);
179}
180
181int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
182 const char *req_xattr_value, size_t req_xattr_value_len,
183 char *digest)
184{
185 return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
186 req_xattr_value_len, IMA_XATTR_DIGEST, digest);
187}
188
189/*
190 * Calculate the hmac and update security.evm xattr
191 *
192 * Expects to be called with i_mutex locked.
193 */
194int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
195 const char *xattr_value, size_t xattr_value_len)
196{
197 struct inode *inode = dentry->d_inode;
198 struct evm_ima_xattr_data xattr_data;
199 int rc = 0;
200
201 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
202 xattr_value_len, xattr_data.digest);
203 if (rc == 0) {
204 xattr_data.type = EVM_XATTR_HMAC;
205 rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
206 &xattr_data,
207 sizeof(xattr_data), 0);
208 }
209 else if (rc == -ENODATA)
210 rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
211 return rc;
212}
213
214int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
215 char *hmac_val)
216{
217 struct shash_desc *desc;
218
219 desc = init_desc(EVM_XATTR_HMAC);
220 if (IS_ERR(desc)) {
221 printk(KERN_INFO "init_desc failed\n");
222 return PTR_ERR(desc);
223 }
224
225 crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len);
226 hmac_add_misc(desc, inode, hmac_val);
227 kfree(desc);
228 return 0;
229}
230
231/*
232 * Get the key from the TPM for the SHA1-HMAC
233 */
234int evm_init_key(void)
235{
236 struct key *evm_key;
237 struct encrypted_key_payload *ekp;
238 int rc = 0;
239
240 evm_key = request_key(&key_type_encrypted, EVMKEY, NULL);
241 if (IS_ERR(evm_key))
242 return -ENOENT;
243
244 down_read(&evm_key->sem);
245 ekp = evm_key->payload.data;
246 if (ekp->decrypted_datalen > MAX_KEY_SIZE) {
247 rc = -EINVAL;
248 goto out;
249 }
250 memcpy(evmkey, ekp->decrypted_data, ekp->decrypted_datalen);
251out:
252 /* burn the original key contents */
253 memset(ekp->decrypted_data, 0, ekp->decrypted_datalen);
254 up_read(&evm_key->sem);
255 key_put(evm_key);
256 return rc;
257}
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
deleted file mode 100644
index eb5484504f5..00000000000
--- a/security/integrity/evm/evm_main.c
+++ /dev/null
@@ -1,455 +0,0 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm_main.c
13 * implements evm_inode_setxattr, evm_inode_post_setxattr,
14 * evm_inode_removexattr, and evm_verifyxattr
15 */
16
17#include <linux/module.h>
18#include <linux/crypto.h>
19#include <linux/xattr.h>
20#include <linux/integrity.h>
21#include <linux/evm.h>
22#include <crypto/hash.h>
23#include "evm.h"
24
25int evm_initialized;
26
27char *evm_hmac = "hmac(sha1)";
28char *evm_hash = "sha1";
29
30char *evm_config_xattrnames[] = {
31#ifdef CONFIG_SECURITY_SELINUX
32 XATTR_NAME_SELINUX,
33#endif
34#ifdef CONFIG_SECURITY_SMACK
35 XATTR_NAME_SMACK,
36#endif
37#ifdef CONFIG_IMA_APPRAISE
38 XATTR_NAME_IMA,
39#endif
40 XATTR_NAME_CAPS,
41 NULL
42};
43
44static int evm_fixmode;
45static int __init evm_set_fixmode(char *str)
46{
47 if (strncmp(str, "fix", 3) == 0)
48 evm_fixmode = 1;
49 return 0;
50}
51__setup("evm=", evm_set_fixmode);
52
53static int evm_find_protected_xattrs(struct dentry *dentry)
54{
55 struct inode *inode = dentry->d_inode;
56 char **xattr;
57 int error;
58 int count = 0;
59
60 if (!inode->i_op || !inode->i_op->getxattr)
61 return -EOPNOTSUPP;
62
63 for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
64 error = inode->i_op->getxattr(dentry, *xattr, NULL, 0);
65 if (error < 0) {
66 if (error == -ENODATA)
67 continue;
68 return error;
69 }
70 count++;
71 }
72
73 return count;
74}
75
76/*
77 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
78 *
79 * Compute the HMAC on the dentry's protected set of extended attributes
80 * and compare it against the stored security.evm xattr.
81 *
82 * For performance:
83 * - use the previoulsy retrieved xattr value and length to calculate the
84 * HMAC.)
85 * - cache the verification result in the iint, when available.
86 *
87 * Returns integrity status
88 */
89static enum integrity_status evm_verify_hmac(struct dentry *dentry,
90 const char *xattr_name,
91 char *xattr_value,
92 size_t xattr_value_len,
93 struct integrity_iint_cache *iint)
94{
95 struct evm_ima_xattr_data *xattr_data = NULL;
96 struct evm_ima_xattr_data calc;
97 enum integrity_status evm_status = INTEGRITY_PASS;
98 int rc, xattr_len;
99
100 if (iint && iint->evm_status == INTEGRITY_PASS)
101 return iint->evm_status;
102
103 /* if status is not PASS, try to check again - against -ENOMEM */
104
105 /* first need to know the sig type */
106 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0,
107 GFP_NOFS);
108 if (rc <= 0) {
109 if (rc == 0)
110 evm_status = INTEGRITY_FAIL; /* empty */
111 else if (rc == -ENODATA) {
112 rc = evm_find_protected_xattrs(dentry);
113 if (rc > 0)
114 evm_status = INTEGRITY_NOLABEL;
115 else if (rc == 0)
116 evm_status = INTEGRITY_NOXATTRS; /* new file */
117 }
118 goto out;
119 }
120
121 xattr_len = rc - 1;
122
123 /* check value type */
124 switch (xattr_data->type) {
125 case EVM_XATTR_HMAC:
126 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
127 xattr_value_len, calc.digest);
128 if (rc)
129 break;
130 rc = memcmp(xattr_data->digest, calc.digest,
131 sizeof(calc.digest));
132 if (rc)
133 rc = -EINVAL;
134 break;
135 case EVM_IMA_XATTR_DIGSIG:
136 rc = evm_calc_hash(dentry, xattr_name, xattr_value,
137 xattr_value_len, calc.digest);
138 if (rc)
139 break;
140 rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
141 xattr_data->digest, xattr_len,
142 calc.digest, sizeof(calc.digest));
143 if (!rc) {
144 /* we probably want to replace rsa with hmac here */
145 evm_update_evmxattr(dentry, xattr_name, xattr_value,
146 xattr_value_len);
147 }
148 break;
149 default:
150 rc = -EINVAL;
151 break;
152 }
153
154 if (rc)
155 evm_status = (rc == -ENODATA) ?
156 INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
157out:
158 if (iint)
159 iint->evm_status = evm_status;
160 kfree(xattr_data);
161 return evm_status;
162}
163
164static int evm_protected_xattr(const char *req_xattr_name)
165{
166 char **xattrname;
167 int namelen;
168 int found = 0;
169
170 namelen = strlen(req_xattr_name);
171 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
172 if ((strlen(*xattrname) == namelen)
173 && (strncmp(req_xattr_name, *xattrname, namelen) == 0)) {
174 found = 1;
175 break;
176 }
177 if (strncmp(req_xattr_name,
178 *xattrname + XATTR_SECURITY_PREFIX_LEN,
179 strlen(req_xattr_name)) == 0) {
180 found = 1;
181 break;
182 }
183 }
184 return found;
185}
186
187/**
188 * evm_verifyxattr - verify the integrity of the requested xattr
189 * @dentry: object of the verify xattr
190 * @xattr_name: requested xattr
191 * @xattr_value: requested xattr value
192 * @xattr_value_len: requested xattr value length
193 *
194 * Calculate the HMAC for the given dentry and verify it against the stored
195 * security.evm xattr. For performance, use the xattr value and length
196 * previously retrieved to calculate the HMAC.
197 *
198 * Returns the xattr integrity status.
199 *
200 * This function requires the caller to lock the inode's i_mutex before it
201 * is executed.
202 */
203enum integrity_status evm_verifyxattr(struct dentry *dentry,
204 const char *xattr_name,
205 void *xattr_value, size_t xattr_value_len,
206 struct integrity_iint_cache *iint)
207{
208 if (!evm_initialized || !evm_protected_xattr(xattr_name))
209 return INTEGRITY_UNKNOWN;
210
211 if (!iint) {
212 iint = integrity_iint_find(dentry->d_inode);
213 if (!iint)
214 return INTEGRITY_UNKNOWN;
215 }
216 return evm_verify_hmac(dentry, xattr_name, xattr_value,
217 xattr_value_len, iint);
218}
219EXPORT_SYMBOL_GPL(evm_verifyxattr);
220
221/*
222 * evm_verify_current_integrity - verify the dentry's metadata integrity
223 * @dentry: pointer to the affected dentry
224 *
225 * Verify and return the dentry's metadata integrity. The exceptions are
226 * before EVM is initialized or in 'fix' mode.
227 */
228static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
229{
230 struct inode *inode = dentry->d_inode;
231
232 if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode)
233 return 0;
234 return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
235}
236
237/*
238 * evm_protect_xattr - protect the EVM extended attribute
239 *
240 * Prevent security.evm from being modified or removed without the
241 * necessary permissions or when the existing value is invalid.
242 *
243 * The posix xattr acls are 'system' prefixed, which normally would not
244 * affect security.evm. An interesting side affect of writing posix xattr
245 * acls is their modifying of the i_mode, which is included in security.evm.
246 * For posix xattr acls only, permit security.evm, even if it currently
247 * doesn't exist, to be updated.
248 */
249static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
250 const void *xattr_value, size_t xattr_value_len)
251{
252 enum integrity_status evm_status;
253
254 if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
255 if (!capable(CAP_SYS_ADMIN))
256 return -EPERM;
257 } else if (!evm_protected_xattr(xattr_name)) {
258 if (!posix_xattr_acl(xattr_name))
259 return 0;
260 evm_status = evm_verify_current_integrity(dentry);
261 if ((evm_status == INTEGRITY_PASS) ||
262 (evm_status == INTEGRITY_NOXATTRS))
263 return 0;
264 return -EPERM;
265 }
266 evm_status = evm_verify_current_integrity(dentry);
267 return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
268}
269
270/**
271 * evm_inode_setxattr - protect the EVM extended attribute
272 * @dentry: pointer to the affected dentry
273 * @xattr_name: pointer to the affected extended attribute name
274 * @xattr_value: pointer to the new extended attribute value
275 * @xattr_value_len: pointer to the new extended attribute value length
276 *
277 * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
278 * the current value is valid.
279 */
280int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
281 const void *xattr_value, size_t xattr_value_len)
282{
283 return evm_protect_xattr(dentry, xattr_name, xattr_value,
284 xattr_value_len);
285}
286
287/**
288 * evm_inode_removexattr - protect the EVM extended attribute
289 * @dentry: pointer to the affected dentry
290 * @xattr_name: pointer to the affected extended attribute name
291 *
292 * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
293 * the current value is valid.
294 */
295int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name)
296{
297 return evm_protect_xattr(dentry, xattr_name, NULL, 0);
298}
299
300/**
301 * evm_inode_post_setxattr - update 'security.evm' to reflect the changes
302 * @dentry: pointer to the affected dentry
303 * @xattr_name: pointer to the affected extended attribute name
304 * @xattr_value: pointer to the new extended attribute value
305 * @xattr_value_len: pointer to the new extended attribute value length
306 *
307 * Update the HMAC stored in 'security.evm' to reflect the change.
308 *
309 * No need to take the i_mutex lock here, as this function is called from
310 * __vfs_setxattr_noperm(). The caller of which has taken the inode's
311 * i_mutex lock.
312 */
313void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
314 const void *xattr_value, size_t xattr_value_len)
315{
316 if (!evm_initialized || (!evm_protected_xattr(xattr_name)
317 && !posix_xattr_acl(xattr_name)))
318 return;
319
320 evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
321 return;
322}
323
324/**
325 * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
326 * @dentry: pointer to the affected dentry
327 * @xattr_name: pointer to the affected extended attribute name
328 *
329 * Update the HMAC stored in 'security.evm' to reflect removal of the xattr.
330 */
331void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
332{
333 struct inode *inode = dentry->d_inode;
334
335 if (!evm_initialized || !evm_protected_xattr(xattr_name))
336 return;
337
338 mutex_lock(&inode->i_mutex);
339 evm_update_evmxattr(dentry, xattr_name, NULL, 0);
340 mutex_unlock(&inode->i_mutex);
341 return;
342}
343
344/**
345 * evm_inode_setattr - prevent updating an invalid EVM extended attribute
346 * @dentry: pointer to the affected dentry
347 */
348int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
349{
350 unsigned int ia_valid = attr->ia_valid;
351 enum integrity_status evm_status;
352
353 if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
354 return 0;
355 evm_status = evm_verify_current_integrity(dentry);
356 if ((evm_status == INTEGRITY_PASS) ||
357 (evm_status == INTEGRITY_NOXATTRS))
358 return 0;
359 return -EPERM;
360}
361
362/**
363 * evm_inode_post_setattr - update 'security.evm' after modifying metadata
364 * @dentry: pointer to the affected dentry
365 * @ia_valid: for the UID and GID status
366 *
367 * For now, update the HMAC stored in 'security.evm' to reflect UID/GID
368 * changes.
369 *
370 * This function is called from notify_change(), which expects the caller
371 * to lock the inode's i_mutex.
372 */
373void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
374{
375 if (!evm_initialized)
376 return;
377
378 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
379 evm_update_evmxattr(dentry, NULL, NULL, 0);
380 return;
381}
382
383/*
384 * evm_inode_init_security - initializes security.evm
385 */
386int evm_inode_init_security(struct inode *inode,
387 const struct xattr *lsm_xattr,
388 struct xattr *evm_xattr)
389{
390 struct evm_ima_xattr_data *xattr_data;
391 int rc;
392
393 if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name))
394 return 0;
395
396 xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
397 if (!xattr_data)
398 return -ENOMEM;
399
400 xattr_data->type = EVM_XATTR_HMAC;
401 rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
402 if (rc < 0)
403 goto out;
404
405 evm_xattr->value = xattr_data;
406 evm_xattr->value_len = sizeof(*xattr_data);
407 evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS);
408 return 0;
409out:
410 kfree(xattr_data);
411 return rc;
412}
413EXPORT_SYMBOL_GPL(evm_inode_init_security);
414
415static int __init init_evm(void)
416{
417 int error;
418
419 error = evm_init_secfs();
420 if (error < 0) {
421 printk(KERN_INFO "EVM: Error registering secfs\n");
422 goto err;
423 }
424
425 return 0;
426err:
427 return error;
428}
429
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/*
440 * evm_display_config - list the EVM protected security extended attributes
441 */
442static int __init evm_display_config(void)
443{
444 char **xattrname;
445
446 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++)
447 printk(KERN_INFO "EVM: %s\n", *xattrname);
448 return 0;
449}
450
451pure_initcall(evm_display_config);
452late_initcall(init_evm);
453
454MODULE_DESCRIPTION("Extended Verification Module");
455MODULE_LICENSE("GPL");
diff --git a/security/integrity/evm/evm_posix_acl.c b/security/integrity/evm/evm_posix_acl.c
deleted file mode 100644
index b1753e98bf9..00000000000
--- a/security/integrity/evm/evm_posix_acl.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * Copyright (C) 2011 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.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#include <linux/module.h>
13#include <linux/xattr.h>
14
15int posix_xattr_acl(char *xattr)
16{
17 int xattr_len = strlen(xattr);
18
19 if ((strlen(XATTR_NAME_POSIX_ACL_ACCESS) == xattr_len)
20 && (strncmp(XATTR_NAME_POSIX_ACL_ACCESS, xattr, xattr_len) == 0))
21 return 1;
22 if ((strlen(XATTR_NAME_POSIX_ACL_DEFAULT) == xattr_len)
23 && (strncmp(XATTR_NAME_POSIX_ACL_DEFAULT, xattr, xattr_len) == 0))
24 return 1;
25 return 0;
26}
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
deleted file mode 100644
index ac762995057..00000000000
--- a/security/integrity/evm/evm_secfs.c
+++ /dev/null
@@ -1,108 +0,0 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.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 * File: evm_secfs.c
12 * - Used to signal when key is on keyring
13 * - Get the key and enable EVM
14 */
15
16#include <linux/uaccess.h>
17#include <linux/module.h>
18#include "evm.h"
19
20static struct dentry *evm_init_tpm;
21
22/**
23 * evm_read_key - read() for <securityfs>/evm
24 *
25 * @filp: file pointer, not actually used
26 * @buf: where to put the result
27 * @count: maximum to send along
28 * @ppos: where to start
29 *
30 * Returns number of bytes read or error code, as appropriate
31 */
32static ssize_t evm_read_key(struct file *filp, char __user *buf,
33 size_t count, loff_t *ppos)
34{
35 char temp[80];
36 ssize_t rc;
37
38 if (*ppos != 0)
39 return 0;
40
41 sprintf(temp, "%d", evm_initialized);
42 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
43
44 return rc;
45}
46
47/**
48 * evm_write_key - write() for <securityfs>/evm
49 * @file: file pointer, not actually used
50 * @buf: where to get the data from
51 * @count: bytes sent
52 * @ppos: where to start
53 *
54 * Used to signal that key is on the kernel key ring.
55 * - get the integrity hmac key from the kernel key ring
56 * - create list of hmac protected extended attributes
57 * Returns number of bytes written or error code, as appropriate
58 */
59static ssize_t evm_write_key(struct file *file, const char __user *buf,
60 size_t count, loff_t *ppos)
61{
62 char temp[80];
63 int i, error;
64
65 if (!capable(CAP_SYS_ADMIN) || evm_initialized)
66 return -EPERM;
67
68 if (count >= sizeof(temp) || count == 0)
69 return -EINVAL;
70
71 if (copy_from_user(temp, buf, count) != 0)
72 return -EFAULT;
73
74 temp[count] = '\0';
75
76 if ((sscanf(temp, "%d", &i) != 1) || (i != 1))
77 return -EINVAL;
78
79 error = evm_init_key();
80 if (!error) {
81 evm_initialized = 1;
82 pr_info("EVM: initialized\n");
83 } else
84 pr_err("EVM: initialization failed\n");
85 return count;
86}
87
88static const struct file_operations evm_key_ops = {
89 .read = evm_read_key,
90 .write = evm_write_key,
91};
92
93int __init evm_init_secfs(void)
94{
95 int error = 0;
96
97 evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP,
98 NULL, NULL, &evm_key_ops);
99 if (!evm_init_tpm || IS_ERR(evm_init_tpm))
100 error = -EFAULT;
101 return error;
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
deleted file mode 100644
index d82a5a13d85..00000000000
--- a/security/integrity/iint.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * Copyright (C) 2008 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: integrity_iint.c
13 * - implements the integrity hooks: integrity_inode_alloc,
14 * integrity_inode_free
15 * - cache integrity information associated with an inode
16 * using a rbtree tree.
17 */
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/spinlock.h>
21#include <linux/rbtree.h>
22#include "integrity.h"
23
24static struct rb_root integrity_iint_tree = RB_ROOT;
25static DEFINE_RWLOCK(integrity_iint_lock);
26static struct kmem_cache *iint_cache __read_mostly;
27
28int iint_initialized;
29
30/*
31 * __integrity_iint_find - return the iint associated with an inode
32 */
33static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
34{
35 struct integrity_iint_cache *iint;
36 struct rb_node *n = integrity_iint_tree.rb_node;
37
38 while (n) {
39 iint = rb_entry(n, struct integrity_iint_cache, rb_node);
40
41 if (inode < iint->inode)
42 n = n->rb_left;
43 else if (inode > iint->inode)
44 n = n->rb_right;
45 else
46 break;
47 }
48 if (!n)
49 return NULL;
50
51 return iint;
52}
53
54/*
55 * integrity_iint_find - return the iint associated with an inode
56 */
57struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
58{
59 struct integrity_iint_cache *iint;
60
61 if (!IS_IMA(inode))
62 return NULL;
63
64 read_lock(&integrity_iint_lock);
65 iint = __integrity_iint_find(inode);
66 read_unlock(&integrity_iint_lock);
67
68 return iint;
69}
70
71static void iint_free(struct integrity_iint_cache *iint)
72{
73 iint->version = 0;
74 iint->flags = 0UL;
75 iint->ima_status = INTEGRITY_UNKNOWN;
76 iint->evm_status = INTEGRITY_UNKNOWN;
77 kmem_cache_free(iint_cache, iint);
78}
79
80/**
81 * integrity_inode_get - find or allocate an iint associated with an inode
82 * @inode: pointer to the inode
83 * @return: allocated iint
84 *
85 * Caller must lock i_mutex
86 */
87struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
88{
89 struct rb_node **p;
90 struct rb_node *node, *parent = NULL;
91 struct integrity_iint_cache *iint, *test_iint;
92
93 iint = integrity_iint_find(inode);
94 if (iint)
95 return iint;
96
97 iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
98 if (!iint)
99 return NULL;
100
101 write_lock(&integrity_iint_lock);
102
103 p = &integrity_iint_tree.rb_node;
104 while (*p) {
105 parent = *p;
106 test_iint = rb_entry(parent, struct integrity_iint_cache,
107 rb_node);
108 if (inode < test_iint->inode)
109 p = &(*p)->rb_left;
110 else
111 p = &(*p)->rb_right;
112 }
113
114 iint->inode = inode;
115 node = &iint->rb_node;
116 inode->i_flags |= S_IMA;
117 rb_link_node(node, parent, p);
118 rb_insert_color(node, &integrity_iint_tree);
119
120 write_unlock(&integrity_iint_lock);
121 return iint;
122}
123
124/**
125 * integrity_inode_free - called on security_inode_free
126 * @inode: pointer to the inode
127 *
128 * Free the integrity information(iint) associated with an inode.
129 */
130void integrity_inode_free(struct inode *inode)
131{
132 struct integrity_iint_cache *iint;
133
134 if (!IS_IMA(inode))
135 return;
136
137 write_lock(&integrity_iint_lock);
138 iint = __integrity_iint_find(inode);
139 rb_erase(&iint->rb_node, &integrity_iint_tree);
140 write_unlock(&integrity_iint_lock);
141
142 iint_free(iint);
143}
144
145static void init_once(void *foo)
146{
147 struct integrity_iint_cache *iint = foo;
148
149 memset(iint, 0, sizeof *iint);
150 iint->version = 0;
151 iint->flags = 0UL;
152 iint->ima_status = INTEGRITY_UNKNOWN;
153 iint->evm_status = INTEGRITY_UNKNOWN;
154}
155
156static int __init integrity_iintcache_init(void)
157{
158 iint_cache =
159 kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
160 0, SLAB_PANIC, init_once);
161 iint_initialized = 1;
162 return 0;
163}
164security_initcall(integrity_iintcache_init);
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index d232c73647a..b6ecfd4d8d7 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -3,15 +3,13 @@
3config IMA 3config IMA
4 bool "Integrity Measurement Architecture(IMA)" 4 bool "Integrity Measurement Architecture(IMA)"
5 depends on SECURITY 5 depends on SECURITY
6 select INTEGRITY
7 select SECURITYFS 6 select SECURITYFS
8 select CRYPTO 7 select CRYPTO
9 select CRYPTO_HMAC 8 select CRYPTO_HMAC
10 select CRYPTO_MD5 9 select CRYPTO_MD5
11 select CRYPTO_SHA1 10 select CRYPTO_SHA1
12 select TCG_TPM if HAS_IOMEM && !UML 11 select TCG_TPM if !S390
13 select TCG_TIS if TCG_TPM && X86 12 select TCG_TIS if TCG_TPM
14 select TCG_IBMVTPM if TCG_TPM && PPC64
15 help 13 help
16 The Trusted Computing Group(TCG) runtime Integrity 14 The Trusted Computing Group(TCG) runtime Integrity
17 Measurement Architecture(IMA) maintains a list of hash 15 Measurement Architecture(IMA) maintains a list of hash
@@ -39,9 +37,8 @@ config IMA_MEASURE_PCR_IDX
39 measurement list. If unsure, use the default 10. 37 measurement list. If unsure, use the default 10.
40 38
41config IMA_AUDIT 39config IMA_AUDIT
42 bool "Enables auditing support" 40 bool
43 depends on IMA 41 depends on IMA
44 depends on AUDIT
45 default y 42 default y
46 help 43 help
47 This option adds a kernel parameter 'ima_audit', which 44 This option adds a kernel parameter 'ima_audit', which
@@ -56,18 +53,3 @@ config IMA_LSM_RULES
56 default y 53 default y
57 help 54 help
58 Disabling this option will disregard LSM based policy rules. 55 Disabling this option will disregard LSM based policy rules.
59
60config IMA_APPRAISE
61 bool "Appraise integrity measurements"
62 depends on IMA
63 default n
64 help
65 This option enables local measurement integrity appraisal.
66 It requires the system to be labeled with a security extended
67 attribute containing the file hash measurement. To protect
68 the security extended attributes from offline attack, enable
69 and configure EVM.
70
71 For more information on integrity appraisal refer to:
72 <http://linux-ima.sourceforge.net>
73 If unsure, say N.
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 3f2ca6bdc38..787c4cb916c 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -6,6 +6,4 @@
6obj-$(CONFIG_IMA) += ima.o 6obj-$(CONFIG_IMA) += ima.o
7 7
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o 9 ima_policy.o ima_iint.o ima_audit.o
10ima-$(CONFIG_IMA_AUDIT) += ima_audit.o
11ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 079a85dc37b..08408bd7146 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -24,23 +24,21 @@
24#include <linux/tpm.h> 24#include <linux/tpm.h>
25#include <linux/audit.h> 25#include <linux/audit.h>
26 26
27#include "../integrity.h"
28
29enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; 27enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
30enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; 28enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
31 29
32/* digest size for IMA, fits SHA1 or MD5 */ 30/* digest size for IMA, fits SHA1 or MD5 */
33#define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE 31#define IMA_DIGEST_SIZE 20
34#define IMA_EVENT_NAME_LEN_MAX 255 32#define IMA_EVENT_NAME_LEN_MAX 255
35 33
36#define IMA_HASH_BITS 9 34#define IMA_HASH_BITS 9
37#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) 35#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
38 36
39/* set during initialization */ 37/* set during initialization */
38extern int iint_initialized;
40extern int ima_initialized; 39extern int ima_initialized;
41extern int ima_used_chip; 40extern int ima_used_chip;
42extern char *ima_hash; 41extern char *ima_hash;
43extern int ima_appraise;
44 42
45/* IMA inode template definition */ 43/* IMA inode template definition */
46struct ima_template_data { 44struct ima_template_data {
@@ -62,19 +60,10 @@ struct ima_queue_entry {
62}; 60};
63extern struct list_head ima_measurements; /* list of all measurements */ 61extern struct list_head ima_measurements; /* list of all measurements */
64 62
65#ifdef CONFIG_IMA_AUDIT
66/* declarations */ 63/* declarations */
67void integrity_audit_msg(int audit_msgno, struct inode *inode, 64void integrity_audit_msg(int audit_msgno, struct inode *inode,
68 const unsigned char *fname, const char *op, 65 const unsigned char *fname, const char *op,
69 const char *cause, int result, int info); 66 const char *cause, int result, int info);
70#else
71static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
72 const unsigned char *fname,
73 const char *op, const char *cause,
74 int result, int info)
75{
76}
77#endif
78 67
79/* Internal IMA function definitions */ 68/* Internal IMA function definitions */
80int ima_init(void); 69int ima_init(void);
@@ -107,66 +96,44 @@ static inline unsigned long ima_hash_key(u8 *digest)
107 return hash_long(*digest, IMA_HASH_BITS); 96 return hash_long(*digest, IMA_HASH_BITS);
108} 97}
109 98
99/* iint cache flags */
100#define IMA_MEASURED 0x01
101
102/* integrity data associated with an inode */
103struct ima_iint_cache {
104 struct rb_node rb_node; /* rooted in ima_iint_tree */
105 struct inode *inode; /* back pointer to inode in question */
106 u64 version; /* track inode changes */
107 unsigned char flags;
108 u8 digest[IMA_DIGEST_SIZE];
109 struct mutex mutex; /* protects: version, flags, digest */
110};
111
110/* LIM API function definitions */ 112/* LIM API function definitions */
111int ima_get_action(struct inode *inode, int mask, int function);
112int ima_must_measure(struct inode *inode, int mask, int function); 113int ima_must_measure(struct inode *inode, int mask, int function);
113int ima_collect_measurement(struct integrity_iint_cache *iint, 114int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file);
114 struct file *file); 115void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
115void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
116 const unsigned char *filename);
117void ima_audit_measurement(struct integrity_iint_cache *iint,
118 const unsigned char *filename); 116 const unsigned char *filename);
119int ima_store_template(struct ima_template_entry *entry, int violation, 117int ima_store_template(struct ima_template_entry *entry, int violation,
120 struct inode *inode); 118 struct inode *inode);
121void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); 119void ima_template_show(struct seq_file *m, void *e,
120 enum ima_show_type show);
122 121
123/* rbtree tree calls to lookup, insert, delete 122/* rbtree tree calls to lookup, insert, delete
124 * integrity data associated with an inode. 123 * integrity data associated with an inode.
125 */ 124 */
126struct integrity_iint_cache *integrity_iint_insert(struct inode *inode); 125struct ima_iint_cache *ima_iint_insert(struct inode *inode);
127struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 126struct ima_iint_cache *ima_iint_find(struct inode *inode);
128 127
129/* IMA policy related functions */ 128/* IMA policy related functions */
130enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, MODULE_CHECK, POST_SETATTR }; 129enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
131 130
132int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 131int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
133 int flags);
134void ima_init_policy(void); 132void ima_init_policy(void);
135void ima_update_policy(void); 133void ima_update_policy(void);
136ssize_t ima_parse_add_rule(char *); 134ssize_t ima_parse_add_rule(char *);
137void ima_delete_rules(void); 135void ima_delete_rules(void);
138 136
139/* Appraise integrity measurements */
140#define IMA_APPRAISE_ENFORCE 0x01
141#define IMA_APPRAISE_FIX 0x02
142#define IMA_APPRAISE_MODULES 0x04
143
144#ifdef CONFIG_IMA_APPRAISE
145int ima_appraise_measurement(struct integrity_iint_cache *iint,
146 struct file *file, const unsigned char *filename);
147int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
148void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
149
150#else
151static inline int ima_appraise_measurement(struct integrity_iint_cache *iint,
152 struct file *file,
153 const unsigned char *filename)
154{
155 return INTEGRITY_UNKNOWN;
156}
157
158static inline int ima_must_appraise(struct inode *inode, int mask,
159 enum ima_hooks func)
160{
161 return 0;
162}
163
164static inline void ima_update_xattr(struct integrity_iint_cache *iint,
165 struct file *file)
166{
167}
168#endif
169
170/* LSM based policy rules require audit */ 137/* LSM based policy rules require audit */
171#ifdef CONFIG_IMA_LSM_RULES 138#ifdef CONFIG_IMA_LSM_RULES
172 139
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 0cea3db2165..5335605571f 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -9,17 +9,13 @@
9 * License. 9 * License.
10 * 10 *
11 * File: ima_api.c 11 * File: ima_api.c
12 * Implements must_appraise_or_measure, collect_measurement, 12 * Implements must_measure, collect_measurement, store_measurement,
13 * appraise_measurement, store_measurement and store_template. 13 * and store_template.
14 */ 14 */
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/file.h>
18#include <linux/fs.h>
19#include <linux/xattr.h>
20#include <linux/evm.h>
21#include "ima.h"
22 17
18#include "ima.h"
23static const char *IMA_TEMPLATE_NAME = "ima"; 19static const char *IMA_TEMPLATE_NAME = "ima";
24 20
25/* 21/*
@@ -97,34 +93,27 @@ err_out:
97} 93}
98 94
99/** 95/**
100 * ima_get_action - appraise & measure decision based on policy. 96 * ima_must_measure - measure decision based on policy.
101 * @inode: pointer to inode to measure 97 * @inode: pointer to inode to measure
102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 98 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
103 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP, MODULE_CHECK) 99 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
104 * 100 *
105 * The policy is defined in terms of keypairs: 101 * The policy is defined in terms of keypairs:
106 * subj=, obj=, type=, func=, mask=, fsmagic= 102 * subj=, obj=, type=, func=, mask=, fsmagic=
107 * subj,obj, and type: are LSM specific. 103 * subj,obj, and type: are LSM specific.
108 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP | MODULE_CHECK 104 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP
109 * mask: contains the permission mask 105 * mask: contains the permission mask
110 * fsmagic: hex value 106 * fsmagic: hex value
111 * 107 *
112 * Returns IMA_MEASURE, IMA_APPRAISE mask. 108 * Return 0 to measure. For matching a DONT_MEASURE policy, no policy,
113 * 109 * or other error, return an error code.
114 */ 110*/
115int ima_get_action(struct inode *inode, int mask, int function)
116{
117 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
118
119 if (!ima_appraise)
120 flags &= ~IMA_APPRAISE;
121
122 return ima_match_policy(inode, function, mask, flags);
123}
124
125int ima_must_measure(struct inode *inode, int mask, int function) 111int ima_must_measure(struct inode *inode, int mask, int function)
126{ 112{
127 return ima_match_policy(inode, function, mask, IMA_MEASURE); 113 int must_measure;
114
115 must_measure = ima_match_policy(inode, function, mask);
116 return must_measure ? 0 : -EACCES;
128} 117}
129 118
130/* 119/*
@@ -137,27 +126,18 @@ int ima_must_measure(struct inode *inode, int mask, int function)
137 * 126 *
138 * Return 0 on success, error code otherwise 127 * Return 0 on success, error code otherwise
139 */ 128 */
140int ima_collect_measurement(struct integrity_iint_cache *iint, 129int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file)
141 struct file *file)
142{ 130{
143 struct inode *inode = file->f_dentry->d_inode; 131 int result = -EEXIST;
144 const char *filename = file->f_dentry->d_name.name;
145 int result = 0;
146 132
147 if (!(iint->flags & IMA_COLLECTED)) { 133 if (!(iint->flags & IMA_MEASURED)) {
148 u64 i_version = file->f_dentry->d_inode->i_version; 134 u64 i_version = file->f_dentry->d_inode->i_version;
149 135
150 iint->ima_xattr.type = IMA_XATTR_DIGEST; 136 memset(iint->digest, 0, IMA_DIGEST_SIZE);
151 result = ima_calc_hash(file, iint->ima_xattr.digest); 137 result = ima_calc_hash(file, iint->digest);
152 if (!result) { 138 if (!result)
153 iint->version = i_version; 139 iint->version = i_version;
154 iint->flags |= IMA_COLLECTED;
155 }
156 } 140 }
157 if (result)
158 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
159 filename, "collect_data", "failed",
160 result, 0);
161 return result; 141 return result;
162} 142}
163 143
@@ -176,8 +156,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
176 * 156 *
177 * Must be called with iint->mutex held. 157 * Must be called with iint->mutex held.
178 */ 158 */
179void ima_store_measurement(struct integrity_iint_cache *iint, 159void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
180 struct file *file, const unsigned char *filename) 160 const unsigned char *filename)
181{ 161{
182 const char *op = "add_template_measure"; 162 const char *op = "add_template_measure";
183 const char *audit_cause = "ENOMEM"; 163 const char *audit_cause = "ENOMEM";
@@ -186,9 +166,6 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
186 struct ima_template_entry *entry; 166 struct ima_template_entry *entry;
187 int violation = 0; 167 int violation = 0;
188 168
189 if (iint->flags & IMA_MEASURED)
190 return;
191
192 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 169 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
193 if (!entry) { 170 if (!entry) {
194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 171 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
@@ -196,10 +173,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
196 return; 173 return;
197 } 174 }
198 memset(&entry->template, 0, sizeof(entry->template)); 175 memset(&entry->template, 0, sizeof(entry->template));
199 memcpy(entry->template.digest, iint->ima_xattr.digest, IMA_DIGEST_SIZE); 176 memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE);
200 strcpy(entry->template.file_name, 177 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
201 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
202 file->f_dentry->d_name.name : filename);
203 178
204 result = ima_store_template(entry, violation, inode); 179 result = ima_store_template(entry, violation, inode);
205 if (!result || result == -EEXIST) 180 if (!result || result == -EEXIST)
@@ -207,33 +182,3 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
207 if (result < 0) 182 if (result < 0)
208 kfree(entry); 183 kfree(entry);
209} 184}
210
211void ima_audit_measurement(struct integrity_iint_cache *iint,
212 const unsigned char *filename)
213{
214 struct audit_buffer *ab;
215 char hash[(IMA_DIGEST_SIZE * 2) + 1];
216 int i;
217
218 if (iint->flags & IMA_AUDITED)
219 return;
220
221 for (i = 0; i < IMA_DIGEST_SIZE; i++)
222 hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]);
223 hash[i * 2] = '\0';
224
225 ab = audit_log_start(current->audit_context, GFP_KERNEL,
226 AUDIT_INTEGRITY_RULE);
227 if (!ab)
228 return;
229
230 audit_log_format(ab, "file=");
231 audit_log_untrustedstring(ab, filename);
232 audit_log_format(ab, " hash=");
233 audit_log_untrustedstring(ab, hash);
234
235 audit_log_task_info(ab, current);
236 audit_log_end(ab);
237
238 iint->flags |= IMA_AUDITED;
239}
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
deleted file mode 100644
index bdc8ba1d1d2..00000000000
--- a/security/integrity/ima/ima_appraise.c
+++ /dev/null
@@ -1,263 +0,0 @@
1/*
2 * Copyright (C) 2011 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.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#include <linux/module.h>
12#include <linux/file.h>
13#include <linux/fs.h>
14#include <linux/xattr.h>
15#include <linux/magic.h>
16#include <linux/ima.h>
17#include <linux/evm.h>
18
19#include "ima.h"
20
21static int __init default_appraise_setup(char *str)
22{
23 if (strncmp(str, "off", 3) == 0)
24 ima_appraise = 0;
25 else if (strncmp(str, "fix", 3) == 0)
26 ima_appraise = IMA_APPRAISE_FIX;
27 return 1;
28}
29
30__setup("ima_appraise=", default_appraise_setup);
31
32/*
33 * ima_must_appraise - set appraise flag
34 *
35 * Return 1 to appraise
36 */
37int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
38{
39 if (!ima_appraise)
40 return 0;
41
42 return ima_match_policy(inode, func, mask, IMA_APPRAISE);
43}
44
45static void ima_fix_xattr(struct dentry *dentry,
46 struct integrity_iint_cache *iint)
47{
48 iint->ima_xattr.type = IMA_XATTR_DIGEST;
49 __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, (u8 *)&iint->ima_xattr,
50 sizeof iint->ima_xattr, 0);
51}
52
53/*
54 * ima_appraise_measurement - appraise file measurement
55 *
56 * Call evm_verifyxattr() to verify the integrity of 'security.ima'.
57 * Assuming success, compare the xattr hash with the collected measurement.
58 *
59 * Return 0 on success, error code otherwise
60 */
61int ima_appraise_measurement(struct integrity_iint_cache *iint,
62 struct file *file, const unsigned char *filename)
63{
64 struct dentry *dentry = file->f_dentry;
65 struct inode *inode = dentry->d_inode;
66 struct evm_ima_xattr_data *xattr_value = NULL;
67 enum integrity_status status = INTEGRITY_UNKNOWN;
68 const char *op = "appraise_data";
69 char *cause = "unknown";
70 int rc;
71
72 if (!ima_appraise)
73 return 0;
74 if (!inode->i_op->getxattr)
75 return INTEGRITY_UNKNOWN;
76
77 if (iint->flags & IMA_APPRAISED)
78 return iint->ima_status;
79
80 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value,
81 0, GFP_NOFS);
82 if (rc <= 0) {
83 if (rc && rc != -ENODATA)
84 goto out;
85
86 cause = "missing-hash";
87 status =
88 (inode->i_size == 0) ? INTEGRITY_PASS : INTEGRITY_NOLABEL;
89 goto out;
90 }
91
92 status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint);
93 if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) {
94 if ((status == INTEGRITY_NOLABEL)
95 || (status == INTEGRITY_NOXATTRS))
96 cause = "missing-HMAC";
97 else if (status == INTEGRITY_FAIL)
98 cause = "invalid-HMAC";
99 goto out;
100 }
101
102 switch (xattr_value->type) {
103 case IMA_XATTR_DIGEST:
104 rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
105 IMA_DIGEST_SIZE);
106 if (rc) {
107 cause = "invalid-hash";
108 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;
115 }
116 status = INTEGRITY_PASS;
117 break;
118 case EVM_IMA_XATTR_DIGSIG:
119 iint->flags |= IMA_DIGSIG;
120 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
121 xattr_value->digest, rc - 1,
122 iint->ima_xattr.digest,
123 IMA_DIGEST_SIZE);
124 if (rc == -EOPNOTSUPP) {
125 status = INTEGRITY_UNKNOWN;
126 } else if (rc) {
127 cause = "invalid-signature";
128 status = INTEGRITY_FAIL;
129 } else {
130 status = INTEGRITY_PASS;
131 }
132 break;
133 default:
134 status = INTEGRITY_UNKNOWN;
135 cause = "unknown-ima-data";
136 break;
137 }
138
139out:
140 if (status != INTEGRITY_PASS) {
141 if ((ima_appraise & IMA_APPRAISE_FIX) &&
142 (!xattr_value ||
143 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
144 ima_fix_xattr(dentry, iint);
145 status = INTEGRITY_PASS;
146 }
147 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
148 op, cause, rc, 0);
149 } else {
150 iint->flags |= IMA_APPRAISED;
151 }
152 iint->ima_status = status;
153 kfree(xattr_value);
154 return status;
155}
156
157/*
158 * ima_update_xattr - update 'security.ima' hash value
159 */
160void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
161{
162 struct dentry *dentry = file->f_dentry;
163 int rc = 0;
164
165 /* do not collect and update hash for digital signatures */
166 if (iint->flags & IMA_DIGSIG)
167 return;
168
169 rc = ima_collect_measurement(iint, file);
170 if (rc < 0)
171 return;
172
173 ima_fix_xattr(dentry, iint);
174}
175
176/**
177 * ima_inode_post_setattr - reflect file metadata changes
178 * @dentry: pointer to the affected dentry
179 *
180 * Changes to a dentry's metadata might result in needing to appraise.
181 *
182 * This function is called from notify_change(), which expects the caller
183 * to lock the inode's i_mutex.
184 */
185void ima_inode_post_setattr(struct dentry *dentry)
186{
187 struct inode *inode = dentry->d_inode;
188 struct integrity_iint_cache *iint;
189 int must_appraise, rc;
190
191 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode)
192 || !inode->i_op->removexattr)
193 return;
194
195 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
196 iint = integrity_iint_find(inode);
197 if (iint) {
198 if (must_appraise)
199 iint->flags |= IMA_APPRAISE;
200 else
201 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED);
202 }
203 if (!must_appraise)
204 rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);
205 return;
206}
207
208/*
209 * ima_protect_xattr - protect 'security.ima'
210 *
211 * Ensure that not just anyone can modify or remove 'security.ima'.
212 */
213static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
214 const void *xattr_value, size_t xattr_value_len)
215{
216 if (strcmp(xattr_name, XATTR_NAME_IMA) == 0) {
217 if (!capable(CAP_SYS_ADMIN))
218 return -EPERM;
219 return 1;
220 }
221 return 0;
222}
223
224static void ima_reset_appraise_flags(struct inode *inode)
225{
226 struct integrity_iint_cache *iint;
227
228 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode))
229 return;
230
231 iint = integrity_iint_find(inode);
232 if (!iint)
233 return;
234
235 iint->flags &= ~IMA_DONE_MASK;
236 return;
237}
238
239int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
240 const void *xattr_value, size_t xattr_value_len)
241{
242 int result;
243
244 result = ima_protect_xattr(dentry, xattr_name, xattr_value,
245 xattr_value_len);
246 if (result == 1) {
247 ima_reset_appraise_flags(dentry->d_inode);
248 result = 0;
249 }
250 return result;
251}
252
253int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
254{
255 int result;
256
257 result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
258 if (result == 1) {
259 ima_reset_appraise_flags(dentry->d_inode);
260 result = 0;
261 }
262 return result;
263}
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index c586faae8fd..c5c5a72c30b 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -17,6 +17,8 @@
17 17
18static int ima_audit; 18static int ima_audit;
19 19
20#ifdef CONFIG_IMA_AUDIT
21
20/* ima_audit_setup - enable informational auditing messages */ 22/* ima_audit_setup - enable informational auditing messages */
21static int __init ima_audit_setup(char *str) 23static int __init ima_audit_setup(char *str)
22{ 24{
@@ -27,6 +29,7 @@ static int __init ima_audit_setup(char *str)
27 return 1; 29 return 1;
28} 30}
29__setup("ima_audit=", ima_audit_setup); 31__setup("ima_audit=", ima_audit_setup);
32#endif
30 33
31void integrity_audit_msg(int audit_msgno, struct inode *inode, 34void integrity_audit_msg(int audit_msgno, struct inode *inode,
32 const unsigned char *fname, const char *op, 35 const unsigned char *fname, const char *op,
@@ -39,9 +42,8 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
39 42
40 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); 43 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
41 audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", 44 audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u",
42 current->pid, 45 current->pid, current_cred()->uid,
43 from_kuid(&init_user_ns, current_cred()->uid), 46 audit_get_loginuid(current),
44 from_kuid(&init_user_ns, audit_get_loginuid(current)),
45 audit_get_sessionid(current)); 47 audit_get_sessionid(current));
46 audit_log_task_context(ab); 48 audit_log_task_context(ab);
47 audit_log_format(ab, " op="); 49 audit_log_format(ab, " op=");
@@ -54,11 +56,9 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
54 audit_log_format(ab, " name="); 56 audit_log_format(ab, " name=");
55 audit_log_untrustedstring(ab, fname); 57 audit_log_untrustedstring(ab, fname);
56 } 58 }
57 if (inode) { 59 if (inode)
58 audit_log_format(ab, " dev="); 60 audit_log_format(ab, " dev=%s ino=%lu",
59 audit_log_untrustedstring(ab, inode->i_sb->s_id); 61 inode->i_sb->s_id, inode->i_ino);
60 audit_log_format(ab, " ino=%lu", inode->i_ino); 62 audit_log_format(ab, " res=%d", !result ? 0 : 1);
61 }
62 audit_log_format(ab, " res=%d", !result);
63 audit_log_end(ab); 63 audit_log_end(ab);
64} 64}
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index b21ee5b5495..9b3ade7468b 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -48,7 +48,7 @@ int ima_calc_hash(struct file *file, char *digest)
48 struct scatterlist sg[1]; 48 struct scatterlist sg[1];
49 loff_t i_size, offset = 0; 49 loff_t i_size, offset = 0;
50 char *rbuf; 50 char *rbuf;
51 int rc, read = 0; 51 int rc;
52 52
53 rc = init_desc(&desc); 53 rc = init_desc(&desc);
54 if (rc != 0) 54 if (rc != 0)
@@ -59,10 +59,6 @@ int ima_calc_hash(struct file *file, char *digest)
59 rc = -ENOMEM; 59 rc = -ENOMEM;
60 goto out; 60 goto out;
61 } 61 }
62 if (!(file->f_mode & FMODE_READ)) {
63 file->f_mode |= FMODE_READ;
64 read = 1;
65 }
66 i_size = i_size_read(file->f_dentry->d_inode); 62 i_size = i_size_read(file->f_dentry->d_inode);
67 while (offset < i_size) { 63 while (offset < i_size) {
68 int rbuf_len; 64 int rbuf_len;
@@ -84,8 +80,6 @@ int ima_calc_hash(struct file *file, char *digest)
84 kfree(rbuf); 80 kfree(rbuf);
85 if (!rc) 81 if (!rc)
86 rc = crypto_hash_final(&desc, digest); 82 rc = crypto_hash_final(&desc, digest);
87 if (read)
88 file->f_mode &= ~FMODE_READ;
89out: 83out:
90 crypto_free_hash(desc.tfm); 84 crypto_free_hash(desc.tfm);
91 return rc; 85 return rc;
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 38477c9c341..ef21b96a0b4 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -287,7 +287,7 @@ static atomic_t policy_opencount = ATOMIC_INIT(1);
287/* 287/*
288 * ima_open_policy: sequentialize access to the policy file 288 * ima_open_policy: sequentialize access to the policy file
289 */ 289 */
290static int ima_open_policy(struct inode * inode, struct file * filp) 290int ima_open_policy(struct inode * inode, struct file * filp)
291{ 291{
292 /* No point in being allowed to open it if you aren't going to write */ 292 /* No point in being allowed to open it if you aren't going to write */
293 if (!(filp->f_flags & O_WRONLY)) 293 if (!(filp->f_flags & O_WRONLY))
@@ -367,7 +367,6 @@ int __init ima_fs_init(void)
367 367
368 return 0; 368 return 0;
369out: 369out:
370 securityfs_remove(violations);
371 securityfs_remove(runtime_measurements_count); 370 securityfs_remove(runtime_measurements_count);
372 securityfs_remove(ascii_runtime_measurements); 371 securityfs_remove(ascii_runtime_measurements);
373 securityfs_remove(binary_runtime_measurements); 372 securityfs_remove(binary_runtime_measurements);
@@ -375,3 +374,13 @@ out:
375 securityfs_remove(ima_policy); 374 securityfs_remove(ima_policy);
376 return -1; 375 return -1;
377} 376}
377
378void __exit ima_fs_cleanup(void)
379{
380 securityfs_remove(violations);
381 securityfs_remove(runtime_measurements_count);
382 securityfs_remove(ascii_runtime_measurements);
383 securityfs_remove(binary_runtime_measurements);
384 securityfs_remove(ima_dir);
385 securityfs_remove(ima_policy);
386}
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index b5dfd534f13..17f1f060306 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -90,3 +90,8 @@ int __init ima_init(void)
90 90
91 return ima_fs_init(); 91 return ima_fs_init();
92} 92}
93
94void __exit ima_cleanup(void)
95{
96 ima_fs_cleanup();
97}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index dba965de90d..26b46ff7466 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -22,19 +22,11 @@
22#include <linux/mount.h> 22#include <linux/mount.h>
23#include <linux/mman.h> 23#include <linux/mman.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/xattr.h>
26#include <linux/ima.h>
27 25
28#include "ima.h" 26#include "ima.h"
29 27
30int ima_initialized; 28int ima_initialized;
31 29
32#ifdef CONFIG_IMA_APPRAISE
33int ima_appraise = IMA_APPRAISE_ENFORCE;
34#else
35int ima_appraise;
36#endif
37
38char *ima_hash = "sha1"; 30char *ima_hash = "sha1";
39static int __init hash_setup(char *str) 31static int __init hash_setup(char *str)
40{ 32{
@@ -59,9 +51,8 @@ static void ima_rdwr_violation_check(struct file *file)
59 struct dentry *dentry = file->f_path.dentry; 51 struct dentry *dentry = file->f_path.dentry;
60 struct inode *inode = dentry->d_inode; 52 struct inode *inode = dentry->d_inode;
61 fmode_t mode = file->f_mode; 53 fmode_t mode = file->f_mode;
62 int must_measure; 54 int rc;
63 bool send_tomtou = false, send_writers = false; 55 bool send_tomtou = false, send_writers = false;
64 unsigned char *pathname = NULL, *pathbuf = NULL;
65 56
66 if (!S_ISREG(inode->i_mode) || !ima_initialized) 57 if (!S_ISREG(inode->i_mode) || !ima_initialized)
67 return; 58 return;
@@ -74,8 +65,8 @@ static void ima_rdwr_violation_check(struct file *file)
74 goto out; 65 goto out;
75 } 66 }
76 67
77 must_measure = ima_must_measure(inode, MAY_READ, FILE_CHECK); 68 rc = ima_must_measure(inode, MAY_READ, FILE_CHECK);
78 if (!must_measure) 69 if (rc < 0)
79 goto out; 70 goto out;
80 71
81 if (atomic_read(&inode->i_writecount) > 0) 72 if (atomic_read(&inode->i_writecount) > 0)
@@ -83,45 +74,26 @@ static void ima_rdwr_violation_check(struct file *file)
83out: 74out:
84 mutex_unlock(&inode->i_mutex); 75 mutex_unlock(&inode->i_mutex);
85 76
86 if (!send_tomtou && !send_writers)
87 return;
88
89 /* We will allow 11 spaces for ' (deleted)' to be appended */
90 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
91 if (pathbuf) {
92 pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11);
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) 77 if (send_tomtou)
99 ima_add_violation(inode, 78 ima_add_violation(inode, dentry->d_name.name, "invalid_pcr",
100 !pathname ? dentry->d_name.name : pathname, 79 "ToMToU");
101 "invalid_pcr", "ToMToU");
102 if (send_writers) 80 if (send_writers)
103 ima_add_violation(inode, 81 ima_add_violation(inode, dentry->d_name.name, "invalid_pcr",
104 !pathname ? dentry->d_name.name : pathname, 82 "open_writers");
105 "invalid_pcr", "open_writers");
106 kfree(pathbuf);
107} 83}
108 84
109static void ima_check_last_writer(struct integrity_iint_cache *iint, 85static void ima_check_last_writer(struct ima_iint_cache *iint,
110 struct inode *inode, struct file *file) 86 struct inode *inode,
87 struct file *file)
111{ 88{
112 fmode_t mode = file->f_mode; 89 fmode_t mode = file->f_mode;
113 90
114 if (!(mode & FMODE_WRITE)) 91 mutex_lock(&iint->mutex);
115 return; 92 if (mode & FMODE_WRITE &&
116 93 atomic_read(&inode->i_writecount) == 1 &&
117 mutex_lock(&inode->i_mutex); 94 iint->version != inode->i_version)
118 if (atomic_read(&inode->i_writecount) == 1 && 95 iint->flags &= ~IMA_MEASURED;
119 iint->version != inode->i_version) { 96 mutex_unlock(&iint->mutex);
120 iint->flags &= ~IMA_DONE_MASK;
121 if (iint->flags & IMA_APPRAISE)
122 ima_update_xattr(iint, file);
123 }
124 mutex_unlock(&inode->i_mutex);
125} 97}
126 98
127/** 99/**
@@ -133,12 +105,12 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
133void ima_file_free(struct file *file) 105void ima_file_free(struct file *file)
134{ 106{
135 struct inode *inode = file->f_dentry->d_inode; 107 struct inode *inode = file->f_dentry->d_inode;
136 struct integrity_iint_cache *iint; 108 struct ima_iint_cache *iint;
137 109
138 if (!iint_initialized || !S_ISREG(inode->i_mode)) 110 if (!iint_initialized || !S_ISREG(inode->i_mode))
139 return; 111 return;
140 112
141 iint = integrity_iint_find(inode); 113 iint = ima_iint_find(inode);
142 if (!iint) 114 if (!iint)
143 return; 115 return;
144 116
@@ -149,66 +121,36 @@ static int process_measurement(struct file *file, const unsigned char *filename,
149 int mask, int function) 121 int mask, int function)
150{ 122{
151 struct inode *inode = file->f_dentry->d_inode; 123 struct inode *inode = file->f_dentry->d_inode;
152 struct integrity_iint_cache *iint; 124 struct ima_iint_cache *iint;
153 unsigned char *pathname = NULL, *pathbuf = NULL; 125 int rc = 0;
154 int rc = -ENOMEM, action, must_appraise;
155 126
156 if (!ima_initialized || !S_ISREG(inode->i_mode)) 127 if (!ima_initialized || !S_ISREG(inode->i_mode))
157 return 0; 128 return 0;
158 129
159 /* Determine if in appraise/audit/measurement policy, 130 rc = ima_must_measure(inode, mask, function);
160 * returns IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT bitmask. */ 131 if (rc != 0)
161 action = ima_get_action(inode, mask, function); 132 return rc;
162 if (!action) 133retry:
163 return 0; 134 iint = ima_iint_find(inode);
164 135 if (!iint) {
165 must_appraise = action & IMA_APPRAISE; 136 rc = ima_inode_alloc(inode);
166 137 if (!rc || rc == -EEXIST)
167 mutex_lock(&inode->i_mutex); 138 goto retry;
168 139 return rc;
169 iint = integrity_inode_get(inode);
170 if (!iint)
171 goto out;
172
173 /* Determine if already appraised/measured based on bitmask
174 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED,
175 * IMA_AUDIT, IMA_AUDITED) */
176 iint->flags |= action;
177 action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
178
179 /* Nothing to do, just return existing appraised status */
180 if (!action) {
181 if (iint->flags & IMA_APPRAISED)
182 rc = iint->ima_status;
183 goto out;
184 } 140 }
185 141
186 rc = ima_collect_measurement(iint, file); 142 mutex_lock(&iint->mutex);
143
144 rc = iint->flags & IMA_MEASURED ? 1 : 0;
187 if (rc != 0) 145 if (rc != 0)
188 goto out; 146 goto out;
189 147
190 if (function != BPRM_CHECK) { 148 rc = ima_collect_measurement(iint, file);
191 /* We will allow 11 spaces for ' (deleted)' to be appended */ 149 if (!rc)
192 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); 150 ima_store_measurement(iint, file, filename);
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)
201 ima_store_measurement(iint, file,
202 !pathname ? filename : pathname);
203 if (action & IMA_APPRAISE)
204 rc = ima_appraise_measurement(iint, file,
205 !pathname ? filename : pathname);
206 if (action & IMA_AUDIT)
207 ima_audit_measurement(iint, !pathname ? filename : pathname);
208 kfree(pathbuf);
209out: 151out:
210 mutex_unlock(&inode->i_mutex); 152 mutex_unlock(&iint->mutex);
211 return (rc && must_appraise) ? -EACCES : 0; 153 return rc;
212} 154}
213 155
214/** 156/**
@@ -224,14 +166,14 @@ out:
224 */ 166 */
225int ima_file_mmap(struct file *file, unsigned long prot) 167int ima_file_mmap(struct file *file, unsigned long prot)
226{ 168{
227 int rc = 0; 169 int rc;
228 170
229 if (!file) 171 if (!file)
230 return 0; 172 return 0;
231 if (prot & PROT_EXEC) 173 if (prot & PROT_EXEC)
232 rc = process_measurement(file, file->f_dentry->d_name.name, 174 rc = process_measurement(file, file->f_dentry->d_name.name,
233 MAY_EXEC, FILE_MMAP); 175 MAY_EXEC, FILE_MMAP);
234 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; 176 return 0;
235} 177}
236 178
237/** 179/**
@@ -251,11 +193,9 @@ int ima_bprm_check(struct linux_binprm *bprm)
251{ 193{
252 int rc; 194 int rc;
253 195
254 rc = process_measurement(bprm->file, 196 rc = process_measurement(bprm->file, bprm->filename,
255 (strcmp(bprm->filename, bprm->interp) == 0) ?
256 bprm->filename : bprm->interp,
257 MAY_EXEC, BPRM_CHECK); 197 MAY_EXEC, BPRM_CHECK);
258 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; 198 return 0;
259} 199}
260 200
261/** 201/**
@@ -276,45 +216,24 @@ int ima_file_check(struct file *file, int mask)
276 rc = process_measurement(file, file->f_dentry->d_name.name, 216 rc = process_measurement(file, file->f_dentry->d_name.name,
277 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 217 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
278 FILE_CHECK); 218 FILE_CHECK);
279 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; 219 return 0;
280} 220}
281EXPORT_SYMBOL_GPL(ima_file_check); 221EXPORT_SYMBOL_GPL(ima_file_check);
282 222
283/**
284 * ima_module_check - based on policy, collect/store/appraise measurement.
285 * @file: pointer to the file to be measured/appraised
286 *
287 * Measure/appraise kernel modules based on policy.
288 *
289 * Always return 0 and audit dentry_open failures.
290 * Return code is based upon measurement appraisal.
291 */
292int ima_module_check(struct file *file)
293{
294 int rc = 0;
295
296 if (!file) {
297 if (ima_appraise & IMA_APPRAISE_MODULES) {
298#ifndef CONFIG_MODULE_SIG_FORCE
299 rc = -EACCES; /* INTEGRITY_UNKNOWN */
300#endif
301 }
302 } else
303 rc = process_measurement(file, file->f_dentry->d_name.name,
304 MAY_EXEC, MODULE_CHECK);
305 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
306}
307
308static int __init init_ima(void) 223static int __init init_ima(void)
309{ 224{
310 int error; 225 int error;
311 226
312 error = ima_init(); 227 error = ima_init();
313 if (!error) 228 ima_initialized = 1;
314 ima_initialized = 1;
315 return error; 229 return error;
316} 230}
317 231
232static void __exit cleanup_ima(void)
233{
234 ima_cleanup();
235}
236
318late_initcall(init_ima); /* Start IMA after the TPM is available */ 237late_initcall(init_ima); /* Start IMA after the TPM is available */
319 238
320MODULE_DESCRIPTION("Integrity Measurement Architecture"); 239MODULE_DESCRIPTION("Integrity Measurement Architecture");
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 479fca940bb..d661afbe474 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -24,29 +24,22 @@
24#define IMA_MASK 0x0002 24#define IMA_MASK 0x0002
25#define IMA_FSMAGIC 0x0004 25#define IMA_FSMAGIC 0x0004
26#define IMA_UID 0x0008 26#define IMA_UID 0x0008
27#define IMA_FOWNER 0x0010
28 27
29#define UNKNOWN 0 28enum ima_action { UNKNOWN = -1, DONT_MEASURE = 0, MEASURE };
30#define MEASURE 0x0001 /* same as IMA_MEASURE */
31#define DONT_MEASURE 0x0002
32#define APPRAISE 0x0004 /* same as IMA_APPRAISE */
33#define DONT_APPRAISE 0x0008
34#define AUDIT 0x0040
35 29
36#define MAX_LSM_RULES 6 30#define MAX_LSM_RULES 6
37enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, 31enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
38 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE 32 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
39}; 33};
40 34
41struct ima_rule_entry { 35struct ima_measure_rule_entry {
42 struct list_head list; 36 struct list_head list;
43 int action; 37 enum ima_action action;
44 unsigned int flags; 38 unsigned int flags;
45 enum ima_hooks func; 39 enum ima_hooks func;
46 int mask; 40 int mask;
47 unsigned long fsmagic; 41 unsigned long fsmagic;
48 kuid_t uid; 42 uid_t uid;
49 kuid_t fowner;
50 struct { 43 struct {
51 void *rule; /* LSM file metadata specific */ 44 void *rule; /* LSM file metadata specific */
52 int type; /* audit type */ 45 int type; /* audit type */
@@ -55,7 +48,7 @@ struct ima_rule_entry {
55 48
56/* 49/*
57 * Without LSM specific knowledge, the default policy can only be 50 * Without LSM specific knowledge, the default policy can only be
58 * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner 51 * written in terms of .action, .func, .mask, .fsmagic, and .uid
59 */ 52 */
60 53
61/* 54/*
@@ -64,60 +57,34 @@ struct ima_rule_entry {
64 * normal users can easily run the machine out of memory simply building 57 * normal users can easily run the machine out of memory simply building
65 * and running executables. 58 * and running executables.
66 */ 59 */
67static struct ima_rule_entry default_rules[] = { 60static struct ima_measure_rule_entry default_rules[] = {
68 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, 61 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
69 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 62 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
70 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 63 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
71 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, 64 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
72 {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
73 {.action = DONT_MEASURE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
74 {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
75 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, 65 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
76 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, 66 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
77 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, 67 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
78 .flags = IMA_FUNC | IMA_MASK}, 68 .flags = IMA_FUNC | IMA_MASK},
79 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, 69 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
80 .flags = IMA_FUNC | IMA_MASK}, 70 .flags = IMA_FUNC | IMA_MASK},
81 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID, 71 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = 0,
82 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 72 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
83 {.action = MEASURE,.func = MODULE_CHECK, .flags = IMA_FUNC},
84}; 73};
85 74
86static struct ima_rule_entry default_appraise_rules[] = { 75static LIST_HEAD(measure_default_rules);
87 {.action = DONT_APPRAISE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, 76static LIST_HEAD(measure_policy_rules);
88 {.action = DONT_APPRAISE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 77static struct list_head *ima_measure;
89 {.action = DONT_APPRAISE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
90 {.action = DONT_APPRAISE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
91 {.action = DONT_APPRAISE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
92 {.action = DONT_APPRAISE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
93 {.action = DONT_APPRAISE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
94 {.action = DONT_APPRAISE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
95 {.action = DONT_APPRAISE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
96 {.action = DONT_APPRAISE,.fsmagic = CGROUP_SUPER_MAGIC,.flags = IMA_FSMAGIC},
97 {.action = APPRAISE,.fowner = GLOBAL_ROOT_UID,.flags = IMA_FOWNER},
98};
99
100static LIST_HEAD(ima_default_rules);
101static LIST_HEAD(ima_policy_rules);
102static struct list_head *ima_rules;
103 78
104static DEFINE_MUTEX(ima_rules_mutex); 79static DEFINE_MUTEX(ima_measure_mutex);
105 80
106static bool ima_use_tcb __initdata; 81static bool ima_use_tcb __initdata;
107static int __init default_measure_policy_setup(char *str) 82static int __init default_policy_setup(char *str)
108{ 83{
109 ima_use_tcb = 1; 84 ima_use_tcb = 1;
110 return 1; 85 return 1;
111} 86}
112__setup("ima_tcb", default_measure_policy_setup); 87__setup("ima_tcb", default_policy_setup);
113
114static bool ima_use_appraise_tcb __initdata;
115static int __init default_appraise_policy_setup(char *str)
116{
117 ima_use_appraise_tcb = 1;
118 return 1;
119}
120__setup("ima_appraise_tcb", default_appraise_policy_setup);
121 88
122/** 89/**
123 * ima_match_rules - determine whether an inode matches the measure rule. 90 * ima_match_rules - determine whether an inode matches the measure rule.
@@ -128,11 +95,10 @@ __setup("ima_appraise_tcb", default_appraise_policy_setup);
128 * 95 *
129 * Returns true on rule match, false on failure. 96 * Returns true on rule match, false on failure.
130 */ 97 */
131static bool ima_match_rules(struct ima_rule_entry *rule, 98static bool ima_match_rules(struct ima_measure_rule_entry *rule,
132 struct inode *inode, enum ima_hooks func, int mask) 99 struct inode *inode, enum ima_hooks func, int mask)
133{ 100{
134 struct task_struct *tsk = current; 101 struct task_struct *tsk = current;
135 const struct cred *cred = current_cred();
136 int i; 102 int i;
137 103
138 if ((rule->flags & IMA_FUNC) && rule->func != func) 104 if ((rule->flags & IMA_FUNC) && rule->func != func)
@@ -142,9 +108,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
142 if ((rule->flags & IMA_FSMAGIC) 108 if ((rule->flags & IMA_FSMAGIC)
143 && rule->fsmagic != inode->i_sb->s_magic) 109 && rule->fsmagic != inode->i_sb->s_magic)
144 return false; 110 return false;
145 if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid)) 111 if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid)
146 return false;
147 if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
148 return false; 112 return false;
149 for (i = 0; i < MAX_LSM_RULES; i++) { 113 for (i = 0; i < MAX_LSM_RULES; i++) {
150 int rc = 0; 114 int rc = 0;
@@ -195,61 +159,39 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
195 * as elements in the list are never deleted, nor does the list 159 * as elements in the list are never deleted, nor does the list
196 * change.) 160 * change.)
197 */ 161 */
198int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 162int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask)
199 int flags)
200{ 163{
201 struct ima_rule_entry *entry; 164 struct ima_measure_rule_entry *entry;
202 int action = 0, actmask = flags | (flags << 1);
203
204 list_for_each_entry(entry, ima_rules, list) {
205
206 if (!(entry->action & actmask))
207 continue;
208
209 if (!ima_match_rules(entry, inode, func, mask))
210 continue;
211 165
212 action |= entry->action & IMA_DO_MASK; 166 list_for_each_entry(entry, ima_measure, list) {
213 if (entry->action & IMA_DO_MASK) 167 bool rc;
214 actmask &= ~(entry->action | entry->action << 1);
215 else
216 actmask &= ~(entry->action | entry->action >> 1);
217 168
218 if (!actmask) 169 rc = ima_match_rules(entry, inode, func, mask);
219 break; 170 if (rc)
171 return entry->action;
220 } 172 }
221 173 return 0;
222 return action;
223} 174}
224 175
225/** 176/**
226 * ima_init_policy - initialize the default measure rules. 177 * ima_init_policy - initialize the default measure rules.
227 * 178 *
228 * ima_rules points to either the ima_default_rules or the 179 * ima_measure points to either the measure_default_rules or the
229 * the new ima_policy_rules. 180 * the new measure_policy_rules.
230 */ 181 */
231void __init ima_init_policy(void) 182void __init ima_init_policy(void)
232{ 183{
233 int i, measure_entries, appraise_entries; 184 int i, entries;
234 185
235 /* if !ima_use_tcb set entries = 0 so we load NO default rules */ 186 /* if !ima_use_tcb set entries = 0 so we load NO default rules */
236 measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0; 187 if (ima_use_tcb)
237 appraise_entries = ima_use_appraise_tcb ? 188 entries = ARRAY_SIZE(default_rules);
238 ARRAY_SIZE(default_appraise_rules) : 0; 189 else
239 190 entries = 0;
240 for (i = 0; i < measure_entries + appraise_entries; i++) { 191
241 if (i < measure_entries) 192 for (i = 0; i < entries; i++)
242 list_add_tail(&default_rules[i].list, 193 list_add_tail(&default_rules[i].list, &measure_default_rules);
243 &ima_default_rules); 194 ima_measure = &measure_default_rules;
244 else {
245 int j = i - measure_entries;
246
247 list_add_tail(&default_appraise_rules[j].list,
248 &ima_default_rules);
249 }
250 }
251
252 ima_rules = &ima_default_rules;
253} 195}
254 196
255/** 197/**
@@ -266,8 +208,8 @@ void ima_update_policy(void)
266 int result = 1; 208 int result = 1;
267 int audit_info = 0; 209 int audit_info = 0;
268 210
269 if (ima_rules == &ima_default_rules) { 211 if (ima_measure == &measure_default_rules) {
270 ima_rules = &ima_policy_rules; 212 ima_measure = &measure_policy_rules;
271 cause = "complete"; 213 cause = "complete";
272 result = 0; 214 result = 0;
273 } 215 }
@@ -278,19 +220,14 @@ void ima_update_policy(void)
278enum { 220enum {
279 Opt_err = -1, 221 Opt_err = -1,
280 Opt_measure = 1, Opt_dont_measure, 222 Opt_measure = 1, Opt_dont_measure,
281 Opt_appraise, Opt_dont_appraise,
282 Opt_audit,
283 Opt_obj_user, Opt_obj_role, Opt_obj_type, 223 Opt_obj_user, Opt_obj_role, Opt_obj_type,
284 Opt_subj_user, Opt_subj_role, Opt_subj_type, 224 Opt_subj_user, Opt_subj_role, Opt_subj_type,
285 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner 225 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid
286}; 226};
287 227
288static match_table_t policy_tokens = { 228static match_table_t policy_tokens = {
289 {Opt_measure, "measure"}, 229 {Opt_measure, "measure"},
290 {Opt_dont_measure, "dont_measure"}, 230 {Opt_dont_measure, "dont_measure"},
291 {Opt_appraise, "appraise"},
292 {Opt_dont_appraise, "dont_appraise"},
293 {Opt_audit, "audit"},
294 {Opt_obj_user, "obj_user=%s"}, 231 {Opt_obj_user, "obj_user=%s"},
295 {Opt_obj_role, "obj_role=%s"}, 232 {Opt_obj_role, "obj_role=%s"},
296 {Opt_obj_type, "obj_type=%s"}, 233 {Opt_obj_type, "obj_type=%s"},
@@ -301,11 +238,10 @@ static match_table_t policy_tokens = {
301 {Opt_mask, "mask=%s"}, 238 {Opt_mask, "mask=%s"},
302 {Opt_fsmagic, "fsmagic=%s"}, 239 {Opt_fsmagic, "fsmagic=%s"},
303 {Opt_uid, "uid=%s"}, 240 {Opt_uid, "uid=%s"},
304 {Opt_fowner, "fowner=%s"},
305 {Opt_err, NULL} 241 {Opt_err, NULL}
306}; 242};
307 243
308static int ima_lsm_rule_init(struct ima_rule_entry *entry, 244static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
309 char *args, int lsm_rule, int audit_type) 245 char *args, int lsm_rule, int audit_type)
310{ 246{
311 int result; 247 int result;
@@ -329,7 +265,7 @@ static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
329 audit_log_format(ab, " "); 265 audit_log_format(ab, " ");
330} 266}
331 267
332static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) 268static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
333{ 269{
334 struct audit_buffer *ab; 270 struct audit_buffer *ab;
335 char *p; 271 char *p;
@@ -337,8 +273,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
337 273
338 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); 274 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
339 275
340 entry->uid = INVALID_UID; 276 entry->uid = -1;
341 entry->fowner = INVALID_UID;
342 entry->action = UNKNOWN; 277 entry->action = UNKNOWN;
343 while ((p = strsep(&rule, " \t")) != NULL) { 278 while ((p = strsep(&rule, " \t")) != NULL) {
344 substring_t args[MAX_OPT_ARGS]; 279 substring_t args[MAX_OPT_ARGS];
@@ -367,43 +302,17 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
367 302
368 entry->action = DONT_MEASURE; 303 entry->action = DONT_MEASURE;
369 break; 304 break;
370 case Opt_appraise:
371 ima_log_string(ab, "action", "appraise");
372
373 if (entry->action != UNKNOWN)
374 result = -EINVAL;
375
376 entry->action = APPRAISE;
377 break;
378 case Opt_dont_appraise:
379 ima_log_string(ab, "action", "dont_appraise");
380
381 if (entry->action != UNKNOWN)
382 result = -EINVAL;
383
384 entry->action = DONT_APPRAISE;
385 break;
386 case Opt_audit:
387 ima_log_string(ab, "action", "audit");
388
389 if (entry->action != UNKNOWN)
390 result = -EINVAL;
391
392 entry->action = AUDIT;
393 break;
394 case Opt_func: 305 case Opt_func:
395 ima_log_string(ab, "func", args[0].from); 306 ima_log_string(ab, "func", args[0].from);
396 307
397 if (entry->func) 308 if (entry->func)
398 result = -EINVAL; 309 result = -EINVAL;
399 310
400 if (strcmp(args[0].from, "FILE_CHECK") == 0) 311 if (strcmp(args[0].from, "FILE_CHECK") == 0)
401 entry->func = FILE_CHECK; 312 entry->func = FILE_CHECK;
402 /* PATH_CHECK is for backwards compat */ 313 /* PATH_CHECK is for backwards compat */
403 else if (strcmp(args[0].from, "PATH_CHECK") == 0) 314 else if (strcmp(args[0].from, "PATH_CHECK") == 0)
404 entry->func = FILE_CHECK; 315 entry->func = FILE_CHECK;
405 else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
406 entry->func = MODULE_CHECK;
407 else if (strcmp(args[0].from, "FILE_MMAP") == 0) 316 else if (strcmp(args[0].from, "FILE_MMAP") == 0)
408 entry->func = FILE_MMAP; 317 entry->func = FILE_MMAP;
409 else if (strcmp(args[0].from, "BPRM_CHECK") == 0) 318 else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
@@ -448,37 +357,20 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
448 case Opt_uid: 357 case Opt_uid:
449 ima_log_string(ab, "uid", args[0].from); 358 ima_log_string(ab, "uid", args[0].from);
450 359
451 if (uid_valid(entry->uid)) { 360 if (entry->uid != -1) {
452 result = -EINVAL; 361 result = -EINVAL;
453 break; 362 break;
454 } 363 }
455 364
456 result = strict_strtoul(args[0].from, 10, &lnum); 365 result = strict_strtoul(args[0].from, 10, &lnum);
457 if (!result) { 366 if (!result) {
458 entry->uid = make_kuid(current_user_ns(), (uid_t)lnum); 367 entry->uid = (uid_t) lnum;
459 if (!uid_valid(entry->uid) || (((uid_t)lnum) != lnum)) 368 if (entry->uid != lnum)
460 result = -EINVAL; 369 result = -EINVAL;
461 else 370 else
462 entry->flags |= IMA_UID; 371 entry->flags |= IMA_UID;
463 } 372 }
464 break; 373 break;
465 case Opt_fowner:
466 ima_log_string(ab, "fowner", args[0].from);
467
468 if (uid_valid(entry->fowner)) {
469 result = -EINVAL;
470 break;
471 }
472
473 result = strict_strtoul(args[0].from, 10, &lnum);
474 if (!result) {
475 entry->fowner = make_kuid(current_user_ns(), (uid_t)lnum);
476 if (!uid_valid(entry->fowner) || (((uid_t)lnum) != lnum))
477 result = -EINVAL;
478 else
479 entry->flags |= IMA_FOWNER;
480 }
481 break;
482 case Opt_obj_user: 374 case Opt_obj_user:
483 ima_log_string(ab, "obj_user", args[0].from); 375 ima_log_string(ab, "obj_user", args[0].from);
484 result = ima_lsm_rule_init(entry, args[0].from, 376 result = ima_lsm_rule_init(entry, args[0].from,
@@ -523,15 +415,14 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
523 } 415 }
524 if (!result && (entry->action == UNKNOWN)) 416 if (!result && (entry->action == UNKNOWN))
525 result = -EINVAL; 417 result = -EINVAL;
526 else if (entry->func == MODULE_CHECK) 418
527 ima_appraise |= IMA_APPRAISE_MODULES; 419 audit_log_format(ab, "res=%d", !!result);
528 audit_log_format(ab, "res=%d", !result);
529 audit_log_end(ab); 420 audit_log_end(ab);
530 return result; 421 return result;
531} 422}
532 423
533/** 424/**
534 * ima_parse_add_rule - add a rule to ima_policy_rules 425 * ima_parse_add_rule - add a rule to measure_policy_rules
535 * @rule - ima measurement policy rule 426 * @rule - ima measurement policy rule
536 * 427 *
537 * Uses a mutex to protect the policy list from multiple concurrent writers. 428 * Uses a mutex to protect the policy list from multiple concurrent writers.
@@ -541,12 +432,12 @@ ssize_t ima_parse_add_rule(char *rule)
541{ 432{
542 const char *op = "update_policy"; 433 const char *op = "update_policy";
543 char *p; 434 char *p;
544 struct ima_rule_entry *entry; 435 struct ima_measure_rule_entry *entry;
545 ssize_t result, len; 436 ssize_t result, len;
546 int audit_info = 0; 437 int audit_info = 0;
547 438
548 /* Prevent installed policy from changing */ 439 /* Prevent installed policy from changing */
549 if (ima_rules != &ima_default_rules) { 440 if (ima_measure != &measure_default_rules) {
550 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 441 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
551 NULL, op, "already exists", 442 NULL, op, "already exists",
552 -EACCES, audit_info); 443 -EACCES, audit_info);
@@ -579,9 +470,9 @@ ssize_t ima_parse_add_rule(char *rule)
579 return result; 470 return result;
580 } 471 }
581 472
582 mutex_lock(&ima_rules_mutex); 473 mutex_lock(&ima_measure_mutex);
583 list_add_tail(&entry->list, &ima_policy_rules); 474 list_add_tail(&entry->list, &measure_policy_rules);
584 mutex_unlock(&ima_rules_mutex); 475 mutex_unlock(&ima_measure_mutex);
585 476
586 return len; 477 return len;
587} 478}
@@ -589,12 +480,12 @@ ssize_t ima_parse_add_rule(char *rule)
589/* ima_delete_rules called to cleanup invalid policy */ 480/* ima_delete_rules called to cleanup invalid policy */
590void ima_delete_rules(void) 481void ima_delete_rules(void)
591{ 482{
592 struct ima_rule_entry *entry, *tmp; 483 struct ima_measure_rule_entry *entry, *tmp;
593 484
594 mutex_lock(&ima_rules_mutex); 485 mutex_lock(&ima_measure_mutex);
595 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) { 486 list_for_each_entry_safe(entry, tmp, &measure_policy_rules, list) {
596 list_del(&entry->list); 487 list_del(&entry->list);
597 kfree(entry); 488 kfree(entry);
598 } 489 }
599 mutex_unlock(&ima_rules_mutex); 490 mutex_unlock(&ima_measure_mutex);
600} 491}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
deleted file mode 100644
index e9db763a875..00000000000
--- a/security/integrity/integrity.h
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * Copyright (C) 2009-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 */
13
14#include <linux/types.h>
15#include <linux/integrity.h>
16#include <crypto/sha.h>
17
18/* iint action cache flags */
19#define IMA_MEASURE 0x0001
20#define IMA_MEASURED 0x0002
21#define IMA_APPRAISE 0x0004
22#define IMA_APPRAISED 0x0008
23/*#define IMA_COLLECT 0x0010 do not use this flag */
24#define IMA_COLLECTED 0x0020
25#define IMA_AUDIT 0x0040
26#define IMA_AUDITED 0x0080
27
28/* iint cache flags */
29#define IMA_DIGSIG 0x0100
30
31#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT)
32#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED \
33 | IMA_COLLECTED)
34
35enum evm_ima_xattr_type {
36 IMA_XATTR_DIGEST = 0x01,
37 EVM_XATTR_HMAC,
38 EVM_IMA_XATTR_DIGSIG,
39};
40
41struct evm_ima_xattr_data {
42 u8 type;
43 u8 digest[SHA1_DIGEST_SIZE];
44} __attribute__((packed));
45
46/* integrity data associated with an inode */
47struct integrity_iint_cache {
48 struct rb_node rb_node; /* rooted in integrity_iint_tree */
49 struct inode *inode; /* back pointer to inode in question */
50 u64 version; /* track inode changes */
51 unsigned short flags;
52 struct evm_ima_xattr_data ima_xattr;
53 enum integrity_status ima_status;
54 enum integrity_status evm_status;
55};
56
57/* rbtree tree calls to lookup, insert, delete
58 * integrity data associated with an inode.
59 */
60struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
61struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
62
63#define INTEGRITY_KEYRING_EVM 0
64#define INTEGRITY_KEYRING_MODULE 1
65#define INTEGRITY_KEYRING_IMA 2
66#define INTEGRITY_KEYRING_MAX 3
67
68#ifdef CONFIG_INTEGRITY_SIGNATURE
69
70int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
71 const char *digest, int digestlen);
72
73#else
74
75static inline int integrity_digsig_verify(const unsigned int id,
76 const char *sig, int siglen,
77 const char *digest, int digestlen)
78{
79 return -EOPNOTSUPP;
80}
81
82#endif /* CONFIG_INTEGRITY_SIGNATURE */
83
84/* set during initialization */
85extern int iint_initialized;