aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-11-19 05:36:07 -0500
committerJames Morris <james.l.morris@oracle.com>2014-11-19 05:36:07 -0500
commita6aacbde406eeb6f8fc218b2c6172825f5e73fcf (patch)
treeb79e1a17c38090915085f0dbb501a0970cb79b28 /security
parentb10778a00d40b3d9fdaaf5891e802794781ff71c (diff)
parent6fb5032ebb1c5b852461d64ee33829081de8ca61 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next
Diffstat (limited to 'security')
-rw-r--r--security/integrity/digsig.c38
-rw-r--r--security/integrity/evm/evm_main.c11
-rw-r--r--security/integrity/iint.c88
-rw-r--r--security/integrity/ima/Kconfig25
-rw-r--r--security/integrity/ima/ima_api.c7
-rw-r--r--security/integrity/ima/ima_crypto.c35
-rw-r--r--security/integrity/ima/ima_fs.c37
-rw-r--r--security/integrity/ima/ima_init.c17
-rw-r--r--security/integrity/ima/ima_main.c5
-rw-r--r--security/integrity/ima/ima_policy.c42
-rw-r--r--security/integrity/ima/ima_template.c103
-rw-r--r--security/integrity/integrity.h19
12 files changed, 308 insertions, 119 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 8d4fbff8b87c..5e3bd72b299a 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -14,7 +14,7 @@
14 14
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/rbtree.h> 17#include <linux/slab.h>
18#include <linux/cred.h> 18#include <linux/cred.h>
19#include <linux/key-type.h> 19#include <linux/key-type.h>
20#include <linux/digsig.h> 20#include <linux/digsig.h>
@@ -63,7 +63,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
63 return -EOPNOTSUPP; 63 return -EOPNOTSUPP;
64} 64}
65 65
66int integrity_init_keyring(const unsigned int id) 66int __init integrity_init_keyring(const unsigned int id)
67{ 67{
68 const struct cred *cred = current_cred(); 68 const struct cred *cred = current_cred();
69 int err = 0; 69 int err = 0;
@@ -84,3 +84,37 @@ int integrity_init_keyring(const unsigned int id)
84 } 84 }
85 return err; 85 return err;
86} 86}
87
88int __init integrity_load_x509(const unsigned int id, char *path)
89{
90 key_ref_t key;
91 char *data;
92 int rc;
93
94 if (!keyring[id])
95 return -EINVAL;
96
97 rc = integrity_read_file(path, &data);
98 if (rc < 0)
99 return rc;
100
101 key = key_create_or_update(make_key_ref(keyring[id], 1),
102 "asymmetric",
103 NULL,
104 data,
105 rc,
106 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
107 KEY_USR_VIEW | KEY_USR_READ),
108 KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_TRUSTED);
109 if (IS_ERR(key)) {
110 rc = PTR_ERR(key);
111 pr_err("Problem loading X.509 certificate (%d): %s\n",
112 rc, path);
113 } else {
114 pr_notice("Loaded X.509 cert '%s': %s\n",
115 key_ref_to_ptr(key)->description, path);
116 key_ref_put(key);
117 }
118 kfree(data);
119 return 0;
120}
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 9685af330de5..b392fe614738 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -162,9 +162,14 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
162 (const char *)xattr_data, xattr_len, 162 (const char *)xattr_data, xattr_len,
163 calc.digest, sizeof(calc.digest)); 163 calc.digest, sizeof(calc.digest));
164 if (!rc) { 164 if (!rc) {
165 /* we probably want to replace rsa with hmac here */ 165 /* Replace RSA with HMAC if not mounted readonly and
166 evm_update_evmxattr(dentry, xattr_name, xattr_value, 166 * not immutable
167 xattr_value_len); 167 */
168 if (!IS_RDONLY(dentry->d_inode) &&
169 !IS_IMMUTABLE(dentry->d_inode))
170 evm_update_evmxattr(dentry, xattr_name,
171 xattr_value,
172 xattr_value_len);
168 } 173 }
169 break; 174 break;
170 default: 175 default:
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index a521edf4cbd6..dbb6d141c3db 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -19,14 +19,14 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21#include <linux/rbtree.h> 21#include <linux/rbtree.h>
22#include <linux/file.h>
23#include <linux/uaccess.h>
22#include "integrity.h" 24#include "integrity.h"
23 25
24static struct rb_root integrity_iint_tree = RB_ROOT; 26static struct rb_root integrity_iint_tree = RB_ROOT;
25static DEFINE_RWLOCK(integrity_iint_lock); 27static DEFINE_RWLOCK(integrity_iint_lock);
26static struct kmem_cache *iint_cache __read_mostly; 28static struct kmem_cache *iint_cache __read_mostly;
27 29
28int iint_initialized;
29
30/* 30/*
31 * __integrity_iint_find - return the iint associated with an inode 31 * __integrity_iint_find - return the iint associated with an inode
32 */ 32 */
@@ -166,7 +166,89 @@ static int __init integrity_iintcache_init(void)
166 iint_cache = 166 iint_cache =
167 kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache), 167 kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
168 0, SLAB_PANIC, init_once); 168 0, SLAB_PANIC, init_once);
169 iint_initialized = 1;
170 return 0; 169 return 0;
171} 170}
172security_initcall(integrity_iintcache_init); 171security_initcall(integrity_iintcache_init);
172
173
174/*
175 * integrity_kernel_read - read data from the file
176 *
177 * This is a function for reading file content instead of kernel_read().
178 * It does not perform locking checks to ensure it cannot be blocked.
179 * It does not perform security checks because it is irrelevant for IMA.
180 *
181 */
182int integrity_kernel_read(struct file *file, loff_t offset,
183 char *addr, unsigned long count)
184{
185 mm_segment_t old_fs;
186 char __user *buf = (char __user *)addr;
187 ssize_t ret;
188
189 if (!(file->f_mode & FMODE_READ))
190 return -EBADF;
191
192 old_fs = get_fs();
193 set_fs(get_ds());
194 ret = __vfs_read(file, buf, count, &offset);
195 set_fs(old_fs);
196
197 return ret;
198}
199
200/*
201 * integrity_read_file - read entire file content into the buffer
202 *
203 * This is function opens a file, allocates the buffer of required
204 * size, read entire file content to the buffer and closes the file
205 *
206 * It is used only by init code.
207 *
208 */
209int __init integrity_read_file(const char *path, char **data)
210{
211 struct file *file;
212 loff_t size;
213 char *buf;
214 int rc = -EINVAL;
215
216 file = filp_open(path, O_RDONLY, 0);
217 if (IS_ERR(file)) {
218 rc = PTR_ERR(file);
219 pr_err("Unable to open file: %s (%d)", path, rc);
220 return rc;
221 }
222
223 size = i_size_read(file_inode(file));
224 if (size <= 0)
225 goto out;
226
227 buf = kmalloc(size, GFP_KERNEL);
228 if (!buf) {
229 rc = -ENOMEM;
230 goto out;
231 }
232
233 rc = integrity_kernel_read(file, 0, buf, size);
234 if (rc < 0)
235 kfree(buf);
236 else if (rc != size)
237 rc = -EIO;
238 else
239 *data = buf;
240out:
241 fput(file);
242 return rc;
243}
244
245/*
246 * integrity_load_keys - load integrity keys hook
247 *
248 * Hooks is called from init/main.c:kernel_init_freeable()
249 * when rootfs is ready
250 */
251void __init integrity_load_keys(void)
252{
253 ima_load_x509();
254}
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index e099875643c5..b80a93ec1ccc 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -131,3 +131,28 @@ config IMA_TRUSTED_KEYRING
131 help 131 help
132 This option requires that all keys added to the .ima 132 This option requires that all keys added to the .ima
133 keyring be signed by a key on the system trusted keyring. 133 keyring be signed by a key on the system trusted keyring.
134
135config IMA_LOAD_X509
136 bool "Load X509 certificate onto the '.ima' trusted keyring"
137 depends on IMA_TRUSTED_KEYRING
138 default n
139 help
140 File signature verification is based on the public keys
141 loaded on the .ima trusted keyring. These public keys are
142 X509 certificates signed by a trusted key on the
143 .system keyring. This option enables X509 certificate
144 loading from the kernel onto the '.ima' trusted keyring.
145
146config IMA_X509_PATH
147 string "IMA X509 certificate path"
148 depends on IMA_LOAD_X509
149 default "/etc/keys/x509_ima.der"
150 help
151 This option defines IMA X509 certificate path.
152
153config IMA_APPRAISE_SIGNED_INIT
154 bool "Require signed user-space initialization"
155 depends on IMA_LOAD_X509
156 default n
157 help
158 This option requires user-space init to be signed.
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 86885979918c..b0dc922d8be3 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -173,8 +173,7 @@ int ima_get_action(struct inode *inode, int mask, int function)
173{ 173{
174 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE; 174 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
175 175
176 if (!ima_appraise) 176 flags &= ima_policy_flag;
177 flags &= ~IMA_APPRAISE;
178 177
179 return ima_match_policy(inode, function, mask, flags); 178 return ima_match_policy(inode, function, mask, flags);
180} 179}
@@ -325,11 +324,11 @@ const char *ima_d_path(struct path *path, char **pathbuf)
325{ 324{
326 char *pathname = NULL; 325 char *pathname = NULL;
327 326
328 *pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); 327 *pathbuf = __getname();
329 if (*pathbuf) { 328 if (*pathbuf) {
330 pathname = d_absolute_path(path, *pathbuf, PATH_MAX); 329 pathname = d_absolute_path(path, *pathbuf, PATH_MAX);
331 if (IS_ERR(pathname)) { 330 if (IS_ERR(pathname)) {
332 kfree(*pathbuf); 331 __putname(*pathbuf);
333 *pathbuf = NULL; 332 *pathbuf = NULL;
334 pathname = NULL; 333 pathname = NULL;
335 } 334 }
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index d34e7dfc1118..5df4d960d4dc 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -67,36 +67,6 @@ MODULE_PARM_DESC(ahash_bufsize, "Maximum ahash buffer size");
67static struct crypto_shash *ima_shash_tfm; 67static struct crypto_shash *ima_shash_tfm;
68static struct crypto_ahash *ima_ahash_tfm; 68static struct crypto_ahash *ima_ahash_tfm;
69 69
70/**
71 * ima_kernel_read - read file content
72 *
73 * This is a function for reading file content instead of kernel_read().
74 * It does not perform locking checks to ensure it cannot be blocked.
75 * It does not perform security checks because it is irrelevant for IMA.
76 *
77 */
78static int ima_kernel_read(struct file *file, loff_t offset,
79 char *addr, unsigned long count)
80{
81 mm_segment_t old_fs;
82 char __user *buf = addr;
83 ssize_t ret = -EINVAL;
84
85 if (!(file->f_mode & FMODE_READ))
86 return -EBADF;
87
88 old_fs = get_fs();
89 set_fs(get_ds());
90 if (file->f_op->read)
91 ret = file->f_op->read(file, buf, count, &offset);
92 else if (file->f_op->aio_read)
93 ret = do_sync_read(file, buf, count, &offset);
94 else if (file->f_op->read_iter)
95 ret = new_sync_read(file, buf, count, &offset);
96 set_fs(old_fs);
97 return ret;
98}
99
100int __init ima_init_crypto(void) 70int __init ima_init_crypto(void)
101{ 71{
102 long rc; 72 long rc;
@@ -324,7 +294,8 @@ static int ima_calc_file_hash_atfm(struct file *file,
324 } 294 }
325 /* read buffer */ 295 /* read buffer */
326 rbuf_len = min_t(loff_t, i_size - offset, rbuf_size[active]); 296 rbuf_len = min_t(loff_t, i_size - offset, rbuf_size[active]);
327 rc = ima_kernel_read(file, offset, rbuf[active], rbuf_len); 297 rc = integrity_kernel_read(file, offset, rbuf[active],
298 rbuf_len);
328 if (rc != rbuf_len) 299 if (rc != rbuf_len)
329 goto out3; 300 goto out3;
330 301
@@ -417,7 +388,7 @@ static int ima_calc_file_hash_tfm(struct file *file,
417 while (offset < i_size) { 388 while (offset < i_size) {
418 int rbuf_len; 389 int rbuf_len;
419 390
420 rbuf_len = ima_kernel_read(file, offset, rbuf, PAGE_SIZE); 391 rbuf_len = integrity_kernel_read(file, offset, rbuf, PAGE_SIZE);
421 if (rbuf_len < 0) { 392 if (rbuf_len < 0) {
422 rc = rbuf_len; 393 rc = rbuf_len;
423 break; 394 break;
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index da92fcc08d15..461215e5fd31 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -118,6 +118,7 @@ static int ima_measurements_show(struct seq_file *m, void *v)
118 /* the list never shrinks, so we don't need a lock here */ 118 /* the list never shrinks, so we don't need a lock here */
119 struct ima_queue_entry *qe = v; 119 struct ima_queue_entry *qe = v;
120 struct ima_template_entry *e; 120 struct ima_template_entry *e;
121 char *template_name;
121 int namelen; 122 int namelen;
122 u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX; 123 u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX;
123 bool is_ima_template = false; 124 bool is_ima_template = false;
@@ -128,6 +129,9 @@ static int ima_measurements_show(struct seq_file *m, void *v)
128 if (e == NULL) 129 if (e == NULL)
129 return -1; 130 return -1;
130 131
132 template_name = (e->template_desc->name[0] != '\0') ?
133 e->template_desc->name : e->template_desc->fmt;
134
131 /* 135 /*
132 * 1st: PCRIndex 136 * 1st: PCRIndex
133 * PCR used is always the same (config option) in 137 * PCR used is always the same (config option) in
@@ -139,14 +143,14 @@ static int ima_measurements_show(struct seq_file *m, void *v)
139 ima_putc(m, e->digest, TPM_DIGEST_SIZE); 143 ima_putc(m, e->digest, TPM_DIGEST_SIZE);
140 144
141 /* 3rd: template name size */ 145 /* 3rd: template name size */
142 namelen = strlen(e->template_desc->name); 146 namelen = strlen(template_name);
143 ima_putc(m, &namelen, sizeof(namelen)); 147 ima_putc(m, &namelen, sizeof(namelen));
144 148
145 /* 4th: template name */ 149 /* 4th: template name */
146 ima_putc(m, e->template_desc->name, namelen); 150 ima_putc(m, template_name, namelen);
147 151
148 /* 5th: template length (except for 'ima' template) */ 152 /* 5th: template length (except for 'ima' template) */
149 if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) 153 if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0)
150 is_ima_template = true; 154 is_ima_template = true;
151 155
152 if (!is_ima_template) 156 if (!is_ima_template)
@@ -200,6 +204,7 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
200 /* the list never shrinks, so we don't need a lock here */ 204 /* the list never shrinks, so we don't need a lock here */
201 struct ima_queue_entry *qe = v; 205 struct ima_queue_entry *qe = v;
202 struct ima_template_entry *e; 206 struct ima_template_entry *e;
207 char *template_name;
203 int i; 208 int i;
204 209
205 /* get entry */ 210 /* get entry */
@@ -207,6 +212,9 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
207 if (e == NULL) 212 if (e == NULL)
208 return -1; 213 return -1;
209 214
215 template_name = (e->template_desc->name[0] != '\0') ?
216 e->template_desc->name : e->template_desc->fmt;
217
210 /* 1st: PCR used (config option) */ 218 /* 1st: PCR used (config option) */
211 seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX); 219 seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX);
212 220
@@ -214,7 +222,7 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
214 ima_print_digest(m, e->digest, TPM_DIGEST_SIZE); 222 ima_print_digest(m, e->digest, TPM_DIGEST_SIZE);
215 223
216 /* 3th: template name */ 224 /* 3th: template name */
217 seq_printf(m, " %s", e->template_desc->name); 225 seq_printf(m, " %s", template_name);
218 226
219 /* 4th: template specific data */ 227 /* 4th: template specific data */
220 for (i = 0; i < e->template_desc->num_fields; i++) { 228 for (i = 0; i < e->template_desc->num_fields; i++) {
@@ -288,7 +296,12 @@ static struct dentry *runtime_measurements_count;
288static struct dentry *violations; 296static struct dentry *violations;
289static struct dentry *ima_policy; 297static struct dentry *ima_policy;
290 298
291static atomic_t policy_opencount = ATOMIC_INIT(1); 299enum ima_fs_flags {
300 IMA_FS_BUSY,
301};
302
303static unsigned long ima_fs_flags;
304
292/* 305/*
293 * ima_open_policy: sequentialize access to the policy file 306 * ima_open_policy: sequentialize access to the policy file
294 */ 307 */
@@ -297,9 +310,9 @@ static int ima_open_policy(struct inode *inode, struct file *filp)
297 /* No point in being allowed to open it if you aren't going to write */ 310 /* No point in being allowed to open it if you aren't going to write */
298 if (!(filp->f_flags & O_WRONLY)) 311 if (!(filp->f_flags & O_WRONLY))
299 return -EACCES; 312 return -EACCES;
300 if (atomic_dec_and_test(&policy_opencount)) 313 if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
301 return 0; 314 return -EBUSY;
302 return -EBUSY; 315 return 0;
303} 316}
304 317
305/* 318/*
@@ -311,10 +324,16 @@ static int ima_open_policy(struct inode *inode, struct file *filp)
311 */ 324 */
312static int ima_release_policy(struct inode *inode, struct file *file) 325static int ima_release_policy(struct inode *inode, struct file *file)
313{ 326{
327 const char *cause = valid_policy ? "completed" : "failed";
328
329 pr_info("IMA: policy update %s\n", cause);
330 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
331 "policy_update", cause, !valid_policy, 0);
332
314 if (!valid_policy) { 333 if (!valid_policy) {
315 ima_delete_rules(); 334 ima_delete_rules();
316 valid_policy = 1; 335 valid_policy = 1;
317 atomic_set(&policy_opencount, 1); 336 clear_bit(IMA_FS_BUSY, &ima_fs_flags);
318 return 0; 337 return 0;
319 } 338 }
320 ima_update_policy(); 339 ima_update_policy();
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 9164fc8cac84..5e4c29d174ee 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -24,6 +24,12 @@
24#include <crypto/hash_info.h> 24#include <crypto/hash_info.h>
25#include "ima.h" 25#include "ima.h"
26 26
27#ifdef CONFIG_IMA_X509_PATH
28#define IMA_X509_PATH CONFIG_IMA_X509_PATH
29#else
30#define IMA_X509_PATH "/etc/keys/x509_ima.der"
31#endif
32
27/* name for boot aggregate entry */ 33/* name for boot aggregate entry */
28static const char *boot_aggregate_name = "boot_aggregate"; 34static const char *boot_aggregate_name = "boot_aggregate";
29int ima_used_chip; 35int ima_used_chip;
@@ -91,6 +97,17 @@ err_out:
91 return result; 97 return result;
92} 98}
93 99
100#ifdef CONFIG_IMA_LOAD_X509
101void __init ima_load_x509(void)
102{
103 int unset_flags = ima_policy_flag & IMA_APPRAISE;
104
105 ima_policy_flag &= ~unset_flags;
106 integrity_load_x509(INTEGRITY_KEYRING_IMA, IMA_X509_PATH);
107 ima_policy_flag |= unset_flags;
108}
109#endif
110
94int __init ima_init(void) 111int __init ima_init(void)
95{ 112{
96 u8 pcr_i[TPM_DIGEST_SIZE]; 113 u8 pcr_i[TPM_DIGEST_SIZE];
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 62f59eca32d3..eeee00dce729 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -143,7 +143,7 @@ void ima_file_free(struct file *file)
143 struct inode *inode = file_inode(file); 143 struct inode *inode = file_inode(file);
144 struct integrity_iint_cache *iint; 144 struct integrity_iint_cache *iint;
145 145
146 if (!iint_initialized || !S_ISREG(inode->i_mode)) 146 if (!ima_policy_flag || !S_ISREG(inode->i_mode))
147 return; 147 return;
148 148
149 iint = integrity_iint_find(inode); 149 iint = integrity_iint_find(inode);
@@ -246,7 +246,8 @@ out_digsig:
246 rc = -EACCES; 246 rc = -EACCES;
247 kfree(xattr_value); 247 kfree(xattr_value);
248out_free: 248out_free:
249 kfree(pathbuf); 249 if (pathbuf)
250 __putname(pathbuf);
250out: 251out:
251 mutex_unlock(&inode->i_mutex); 252 mutex_unlock(&inode->i_mutex);
252 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) 253 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index cdc620b2152f..d1eefb9d65fb 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -100,7 +100,13 @@ static struct ima_rule_entry default_appraise_rules[] = {
100 {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, 100 {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC},
101 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 101 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
102 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 102 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
103#ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT
103 {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER}, 104 {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER},
105#else
106 /* force signature */
107 {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID,
108 .flags = IMA_FOWNER | IMA_DIGSIG_REQUIRED},
109#endif
104}; 110};
105 111
106static LIST_HEAD(ima_default_rules); 112static LIST_HEAD(ima_default_rules);
@@ -356,19 +362,8 @@ void __init ima_init_policy(void)
356 */ 362 */
357void ima_update_policy(void) 363void ima_update_policy(void)
358{ 364{
359 static const char op[] = "policy_update"; 365 ima_rules = &ima_policy_rules;
360 const char *cause = "already-exists"; 366 ima_update_policy_flag();
361 int result = 1;
362 int audit_info = 0;
363
364 if (ima_rules == &ima_default_rules) {
365 ima_rules = &ima_policy_rules;
366 ima_update_policy_flag();
367 cause = "complete";
368 result = 0;
369 }
370 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
371 NULL, op, cause, result, audit_info);
372} 367}
373 368
374enum { 369enum {
@@ -686,13 +681,12 @@ ssize_t ima_parse_add_rule(char *rule)
686 ssize_t result, len; 681 ssize_t result, len;
687 int audit_info = 0; 682 int audit_info = 0;
688 683
689 /* Prevent installed policy from changing */ 684 p = strsep(&rule, "\n");
690 if (ima_rules != &ima_default_rules) { 685 len = strlen(p) + 1;
691 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 686 p += strspn(p, " \t");
692 NULL, op, "already-exists", 687
693 -EACCES, audit_info); 688 if (*p == '#' || *p == '\0')
694 return -EACCES; 689 return len;
695 }
696 690
697 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 691 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
698 if (!entry) { 692 if (!entry) {
@@ -703,14 +697,6 @@ ssize_t ima_parse_add_rule(char *rule)
703 697
704 INIT_LIST_HEAD(&entry->list); 698 INIT_LIST_HEAD(&entry->list);
705 699
706 p = strsep(&rule, "\n");
707 len = strlen(p) + 1;
708
709 if (*p == '#') {
710 kfree(entry);
711 return len;
712 }
713
714 result = ima_parse_rule(p, entry); 700 result = ima_parse_rule(p, entry);
715 if (result) { 701 if (result) {
716 kfree(entry); 702 kfree(entry);
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index e854862c9337..0b7404ebfa80 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -24,6 +24,7 @@ static struct ima_template_desc defined_templates[] = {
24 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, 24 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
25 {.name = "ima-ng", .fmt = "d-ng|n-ng"}, 25 {.name = "ima-ng", .fmt = "d-ng|n-ng"},
26 {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, 26 {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"},
27 {.name = "", .fmt = ""}, /* placeholder for a custom format */
27}; 28};
28 29
29static struct ima_template_field supported_fields[] = { 30static struct ima_template_field supported_fields[] = {
@@ -41,19 +42,28 @@ static struct ima_template_field supported_fields[] = {
41 42
42static struct ima_template_desc *ima_template; 43static struct ima_template_desc *ima_template;
43static struct ima_template_desc *lookup_template_desc(const char *name); 44static struct ima_template_desc *lookup_template_desc(const char *name);
45static int template_desc_init_fields(const char *template_fmt,
46 struct ima_template_field ***fields,
47 int *num_fields);
44 48
45static int __init ima_template_setup(char *str) 49static int __init ima_template_setup(char *str)
46{ 50{
47 struct ima_template_desc *template_desc; 51 struct ima_template_desc *template_desc;
48 int template_len = strlen(str); 52 int template_len = strlen(str);
49 53
54 if (ima_template)
55 return 1;
56
50 /* 57 /*
51 * Verify that a template with the supplied name exists. 58 * Verify that a template with the supplied name exists.
52 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. 59 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
53 */ 60 */
54 template_desc = lookup_template_desc(str); 61 template_desc = lookup_template_desc(str);
55 if (!template_desc) 62 if (!template_desc) {
63 pr_err("template %s not found, using %s\n",
64 str, CONFIG_IMA_DEFAULT_TEMPLATE);
56 return 1; 65 return 1;
66 }
57 67
58 /* 68 /*
59 * Verify whether the current hash algorithm is supported 69 * Verify whether the current hash algorithm is supported
@@ -70,6 +80,25 @@ static int __init ima_template_setup(char *str)
70} 80}
71__setup("ima_template=", ima_template_setup); 81__setup("ima_template=", ima_template_setup);
72 82
83static int __init ima_template_fmt_setup(char *str)
84{
85 int num_templates = ARRAY_SIZE(defined_templates);
86
87 if (ima_template)
88 return 1;
89
90 if (template_desc_init_fields(str, NULL, NULL) < 0) {
91 pr_err("format string '%s' not valid, using template %s\n",
92 str, CONFIG_IMA_DEFAULT_TEMPLATE);
93 return 1;
94 }
95
96 defined_templates[num_templates - 1].fmt = str;
97 ima_template = defined_templates + num_templates - 1;
98 return 1;
99}
100__setup("ima_template_fmt=", ima_template_fmt_setup);
101
73static struct ima_template_desc *lookup_template_desc(const char *name) 102static struct ima_template_desc *lookup_template_desc(const char *name)
74{ 103{
75 int i; 104 int i;
@@ -113,43 +142,46 @@ static int template_desc_init_fields(const char *template_fmt,
113 struct ima_template_field ***fields, 142 struct ima_template_field ***fields,
114 int *num_fields) 143 int *num_fields)
115{ 144{
116 char *c, *template_fmt_copy, *template_fmt_ptr; 145 const char *template_fmt_ptr;
146 struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX];
117 int template_num_fields = template_fmt_size(template_fmt); 147 int template_num_fields = template_fmt_size(template_fmt);
118 int i, result = 0; 148 int i, len;
119 149
120 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) 150 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) {
151 pr_err("format string '%s' contains too many fields\n",
152 template_fmt);
121 return -EINVAL; 153 return -EINVAL;
122
123 /* copying is needed as strsep() modifies the original buffer */
124 template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
125 if (template_fmt_copy == NULL)
126 return -ENOMEM;
127
128 *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
129 if (*fields == NULL) {
130 result = -ENOMEM;
131 goto out;
132 } 154 }
133 155
134 template_fmt_ptr = template_fmt_copy; 156 for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields;
135 for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && 157 i++, template_fmt_ptr += len + 1) {
136 i < template_num_fields; i++) { 158 char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1];
137 struct ima_template_field *f = lookup_template_field(c); 159
160 len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr;
161 if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) {
162 pr_err("Invalid field with length %d\n", len);
163 return -EINVAL;
164 }
138 165
139 if (!f) { 166 memcpy(tmp_field_id, template_fmt_ptr, len);
140 result = -ENOENT; 167 tmp_field_id[len] = '\0';
141 goto out; 168 found_fields[i] = lookup_template_field(tmp_field_id);
169 if (!found_fields[i]) {
170 pr_err("field '%s' not found\n", tmp_field_id);
171 return -ENOENT;
142 } 172 }
143 (*fields)[i] = f;
144 } 173 }
145 *num_fields = i; 174
146out: 175 if (fields && num_fields) {
147 if (result < 0) { 176 *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
148 kfree(*fields); 177 if (*fields == NULL)
149 *fields = NULL; 178 return -ENOMEM;
179
180 memcpy(*fields, found_fields, i * sizeof(*fields));
181 *num_fields = i;
150 } 182 }
151 kfree(template_fmt_copy); 183
152 return result; 184 return 0;
153} 185}
154 186
155struct ima_template_desc *ima_template_desc_current(void) 187struct ima_template_desc *ima_template_desc_current(void)
@@ -163,8 +195,15 @@ struct ima_template_desc *ima_template_desc_current(void)
163int __init ima_init_template(void) 195int __init ima_init_template(void)
164{ 196{
165 struct ima_template_desc *template = ima_template_desc_current(); 197 struct ima_template_desc *template = ima_template_desc_current();
198 int result;
199
200 result = template_desc_init_fields(template->fmt,
201 &(template->fields),
202 &(template->num_fields));
203 if (result < 0)
204 pr_err("template %s init failed, result: %d\n",
205 (strlen(template->name) ?
206 template->name : template->fmt), result);
166 207
167 return template_desc_init_fields(template->fmt, 208 return result;
168 &(template->fields),
169 &(template->num_fields));
170} 209}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index c0379d13dbe1..caa1f6ca72e9 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -119,6 +119,10 @@ struct integrity_iint_cache {
119 */ 119 */
120struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 120struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
121 121
122int integrity_kernel_read(struct file *file, loff_t offset,
123 char *addr, unsigned long count);
124int __init integrity_read_file(const char *path, char **data);
125
122#define INTEGRITY_KEYRING_EVM 0 126#define INTEGRITY_KEYRING_EVM 0
123#define INTEGRITY_KEYRING_MODULE 1 127#define INTEGRITY_KEYRING_MODULE 1
124#define INTEGRITY_KEYRING_IMA 2 128#define INTEGRITY_KEYRING_IMA 2
@@ -129,7 +133,8 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
129int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 133int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
130 const char *digest, int digestlen); 134 const char *digest, int digestlen);
131 135
132int integrity_init_keyring(const unsigned int id); 136int __init integrity_init_keyring(const unsigned int id);
137int __init integrity_load_x509(const unsigned int id, char *path);
133#else 138#else
134 139
135static inline int integrity_digsig_verify(const unsigned int id, 140static inline int integrity_digsig_verify(const unsigned int id,
@@ -143,6 +148,7 @@ static inline int integrity_init_keyring(const unsigned int id)
143{ 148{
144 return 0; 149 return 0;
145} 150}
151
146#endif /* CONFIG_INTEGRITY_SIGNATURE */ 152#endif /* CONFIG_INTEGRITY_SIGNATURE */
147 153
148#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS 154#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
@@ -156,6 +162,14 @@ static inline int asymmetric_verify(struct key *keyring, const char *sig,
156} 162}
157#endif 163#endif
158 164
165#ifdef CONFIG_IMA_LOAD_X509
166void __init ima_load_x509(void);
167#else
168static inline void ima_load_x509(void)
169{
170}
171#endif
172
159#ifdef CONFIG_INTEGRITY_AUDIT 173#ifdef CONFIG_INTEGRITY_AUDIT
160/* declarations */ 174/* declarations */
161void integrity_audit_msg(int audit_msgno, struct inode *inode, 175void integrity_audit_msg(int audit_msgno, struct inode *inode,
@@ -169,6 +183,3 @@ static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
169{ 183{
170} 184}
171#endif 185#endif
172
173/* set during initialization */
174extern int iint_initialized;