aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 23:36:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 23:36:37 -0500
commit67e2c3883828b39548cee2091b36656787775d95 (patch)
tree975a0f546a604beda30d4ede34f8e9cca9a88b71 /security/integrity
parent6ae840e7cc4be0be3aa40d9f67c35c75cfc67d83 (diff)
parentb2d1965dcea148100ffc4e7199470bf5fad13871 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris: "In terms of changes, there's general maintenance to the Smack, SELinux, and integrity code. The IMA code adds a new kconfig option, IMA_APPRAISE_SIGNED_INIT, which allows IMA appraisal to require signatures. Support for reading keys from rootfs before init is call is also added" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (23 commits) selinux: Remove security_ops extern security: smack: fix out-of-bounds access in smk_parse_smack() VFS: refactor vfs_read() ima: require signature based appraisal integrity: provide a hook to load keys when rootfs is ready ima: load x509 certificate from the kernel integrity: provide a function to load x509 certificate from the kernel integrity: define a new function integrity_read_file() Security: smack: replace kzalloc with kmem_cache for inode_smack Smack: Lock mode for the floor and hat labels ima: added support for new kernel cmdline parameter ima_template_fmt ima: allocate field pointers array on demand in template_desc_init_fields() ima: don't allocate a copy of template_fmt in template_desc_init_fields() ima: display template format in meas. list if template name length is zero ima: added error messages to template-related functions ima: use atomic bit operations to protect policy update interface ima: ignore empty and with whitespaces policy lines ima: no need to allocate entry for comment ima: report policy load status ima: use path names cache ...
Diffstat (limited to 'security/integrity')
-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 c5ee1a7c5e8a..f589c9a05da2 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 f92be1b14089..b8a27c5052d4 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 78d66dae15f4..686355fea7fd 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
@@ -414,7 +385,7 @@ static int ima_calc_file_hash_tfm(struct file *file,
414 while (offset < i_size) { 385 while (offset < i_size) {
415 int rbuf_len; 386 int rbuf_len;
416 387
417 rbuf_len = ima_kernel_read(file, offset, rbuf, PAGE_SIZE); 388 rbuf_len = integrity_kernel_read(file, offset, rbuf, PAGE_SIZE);
418 if (rbuf_len < 0) { 389 if (rbuf_len < 0) {
419 rc = rbuf_len; 390 rc = rbuf_len;
420 break; 391 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 9d1c2ebfe12a..0fc9519fefa9 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -120,6 +120,10 @@ struct integrity_iint_cache {
120 */ 120 */
121struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 121struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
122 122
123int integrity_kernel_read(struct file *file, loff_t offset,
124 char *addr, unsigned long count);
125int __init integrity_read_file(const char *path, char **data);
126
123#define INTEGRITY_KEYRING_EVM 0 127#define INTEGRITY_KEYRING_EVM 0
124#define INTEGRITY_KEYRING_MODULE 1 128#define INTEGRITY_KEYRING_MODULE 1
125#define INTEGRITY_KEYRING_IMA 2 129#define INTEGRITY_KEYRING_IMA 2
@@ -130,7 +134,8 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
130int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 134int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
131 const char *digest, int digestlen); 135 const char *digest, int digestlen);
132 136
133int integrity_init_keyring(const unsigned int id); 137int __init integrity_init_keyring(const unsigned int id);
138int __init integrity_load_x509(const unsigned int id, char *path);
134#else 139#else
135 140
136static inline int integrity_digsig_verify(const unsigned int id, 141static inline int integrity_digsig_verify(const unsigned int id,
@@ -144,6 +149,7 @@ static inline int integrity_init_keyring(const unsigned int id)
144{ 149{
145 return 0; 150 return 0;
146} 151}
152
147#endif /* CONFIG_INTEGRITY_SIGNATURE */ 153#endif /* CONFIG_INTEGRITY_SIGNATURE */
148 154
149#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS 155#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
@@ -157,6 +163,14 @@ static inline int asymmetric_verify(struct key *keyring, const char *sig,
157} 163}
158#endif 164#endif
159 165
166#ifdef CONFIG_IMA_LOAD_X509
167void __init ima_load_x509(void);
168#else
169static inline void ima_load_x509(void)
170{
171}
172#endif
173
160#ifdef CONFIG_INTEGRITY_AUDIT 174#ifdef CONFIG_INTEGRITY_AUDIT
161/* declarations */ 175/* declarations */
162void integrity_audit_msg(int audit_msgno, struct inode *inode, 176void integrity_audit_msg(int audit_msgno, struct inode *inode,
@@ -170,6 +184,3 @@ static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
170{ 184{
171} 185}
172#endif 186#endif
173
174/* set during initialization */
175extern int iint_initialized;