Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next

+356 -141
+4
Documentation/kernel-parameters.txt
··· 1330 1330 Formats: { "ima" | "ima-ng" } 1331 1331 Default: "ima-ng" 1332 1332 1333 + ima_template_fmt= 1334 + [IMA] Define a custom template format. 1335 + Format: { "field1|...|fieldN" } 1336 + 1333 1337 ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage 1334 1338 Format: <min_file_size> 1335 1339 Set the minimal file size for using asynchronous hash.
+14 -15
Documentation/security/IMA-templates.txt
··· 27 27 a new data type, developers define the field identifier and implement 28 28 two functions, init() and show(), respectively to generate and display 29 29 measurement entries. Defining a new template descriptor requires 30 - specifying the template format, a string of field identifiers separated 31 - by the '|' character. While in the current implementation it is possible 32 - to define new template descriptors only by adding their definition in the 33 - template specific code (ima_template.c), in a future version it will be 34 - possible to register a new template on a running kernel by supplying to IMA 35 - the desired format string. In this version, IMA initializes at boot time 36 - all defined template descriptors by translating the format into an array 37 - of template fields structures taken from the set of the supported ones. 30 + specifying the template format (a string of field identifiers separated 31 + by the '|' character) through the 'ima_template_fmt' kernel command line 32 + parameter. At boot time, IMA initializes the chosen template descriptor 33 + by translating the format into an array of template fields structures taken 34 + from the set of the supported ones. 38 35 39 36 After the initialization step, IMA will call ima_alloc_init_template() 40 37 (new function defined within the patches for the new template management 41 38 mechanism) to generate a new measurement entry by using the template 42 39 descriptor chosen through the kernel configuration or through the newly 43 - introduced 'ima_template=' kernel command line parameter. It is during this 44 - phase that the advantages of the new architecture are clearly shown: 45 - the latter function will not contain specific code to handle a given template 46 - but, instead, it simply calls the init() method of the template fields 47 - associated to the chosen template descriptor and store the result (pointer 48 - to allocated data and data length) in the measurement entry structure. 40 + introduced 'ima_template' and 'ima_template_fmt' kernel command line parameters. 41 + It is during this phase that the advantages of the new architecture are 42 + clearly shown: the latter function will not contain specific code to handle 43 + a given template but, instead, it simply calls the init() method of the template 44 + fields associated to the chosen template descriptor and store the result 45 + (pointer to allocated data and data length) in the measurement entry structure. 49 46 50 47 The same mechanism is employed to display measurements entries. 51 48 The functions ima[_ascii]_measurements_show() retrieve, for each entry, ··· 83 86 - select a template descriptor among those supported in the kernel 84 87 configuration ('ima-ng' is the default choice); 85 88 - specify a template descriptor name from the kernel command line through 86 - the 'ima_template=' parameter. 89 + the 'ima_template=' parameter; 90 + - register a new template descriptor with custom format through the kernel 91 + command line parameter 'ima_template_fmt='.
+18 -6
fs/read_write.c
··· 412 412 413 413 EXPORT_SYMBOL(new_sync_read); 414 414 415 + ssize_t __vfs_read(struct file *file, char __user *buf, size_t count, 416 + loff_t *pos) 417 + { 418 + ssize_t ret; 419 + 420 + if (file->f_op->read) 421 + ret = file->f_op->read(file, buf, count, pos); 422 + else if (file->f_op->aio_read) 423 + ret = do_sync_read(file, buf, count, pos); 424 + else if (file->f_op->read_iter) 425 + ret = new_sync_read(file, buf, count, pos); 426 + else 427 + ret = -EINVAL; 428 + 429 + return ret; 430 + } 431 + 415 432 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) 416 433 { 417 434 ssize_t ret; ··· 443 426 ret = rw_verify_area(READ, file, pos, count); 444 427 if (ret >= 0) { 445 428 count = ret; 446 - if (file->f_op->read) 447 - ret = file->f_op->read(file, buf, count, pos); 448 - else if (file->f_op->aio_read) 449 - ret = do_sync_read(file, buf, count, pos); 450 - else 451 - ret = new_sync_read(file, buf, count, pos); 429 + ret = __vfs_read(file, buf, count, pos); 452 430 if (ret > 0) { 453 431 fsnotify_access(file); 454 432 add_rchar(current, ret);
+1
include/linux/fs.h
··· 1553 1553 struct iovec *fast_pointer, 1554 1554 struct iovec **ret_pointer); 1555 1555 1556 + extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); 1556 1557 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); 1557 1558 extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); 1558 1559 extern ssize_t vfs_readv(struct file *, const struct iovec __user *,
+6
include/linux/integrity.h
··· 24 24 #ifdef CONFIG_INTEGRITY 25 25 extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode); 26 26 extern void integrity_inode_free(struct inode *inode); 27 + extern void __init integrity_load_keys(void); 27 28 28 29 #else 29 30 static inline struct integrity_iint_cache * ··· 37 36 { 38 37 return; 39 38 } 39 + 40 + static inline void integrity_load_keys(void) 41 + { 42 + } 40 43 #endif /* CONFIG_INTEGRITY */ 44 + 41 45 #endif /* _LINUX_INTEGRITY_H */
+5 -1
init/main.c
··· 78 78 #include <linux/context_tracking.h> 79 79 #include <linux/random.h> 80 80 #include <linux/list.h> 81 + #include <linux/integrity.h> 81 82 82 83 #include <asm/io.h> 83 84 #include <asm/bugs.h> ··· 1028 1027 * Ok, we have completed the initial bootup, and 1029 1028 * we're essentially up and running. Get rid of the 1030 1029 * initmem segments and start the user-mode stuff.. 1030 + * 1031 + * rootfs is available now, try loading the public keys 1032 + * and default modules 1031 1033 */ 1032 1034 1033 - /* rootfs is available now, try loading default modules */ 1035 + integrity_load_keys(); 1034 1036 load_default_modules(); 1035 1037 }
+36 -2
security/integrity/digsig.c
··· 14 14 15 15 #include <linux/err.h> 16 16 #include <linux/sched.h> 17 - #include <linux/rbtree.h> 17 + #include <linux/slab.h> 18 18 #include <linux/cred.h> 19 19 #include <linux/key-type.h> 20 20 #include <linux/digsig.h> ··· 63 63 return -EOPNOTSUPP; 64 64 } 65 65 66 - int integrity_init_keyring(const unsigned int id) 66 + int __init integrity_init_keyring(const unsigned int id) 67 67 { 68 68 const struct cred *cred = current_cred(); 69 69 int err = 0; ··· 83 83 keyring[id] = NULL; 84 84 } 85 85 return err; 86 + } 87 + 88 + int __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; 86 120 }
+8 -3
security/integrity/evm/evm_main.c
··· 162 162 (const char *)xattr_data, xattr_len, 163 163 calc.digest, sizeof(calc.digest)); 164 164 if (!rc) { 165 - /* we probably want to replace rsa with hmac here */ 166 - evm_update_evmxattr(dentry, xattr_name, xattr_value, 167 - xattr_value_len); 165 + /* Replace RSA with HMAC if not mounted readonly and 166 + * not immutable 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 174 break; 170 175 default:
+85 -3
security/integrity/iint.c
··· 19 19 #include <linux/module.h> 20 20 #include <linux/spinlock.h> 21 21 #include <linux/rbtree.h> 22 + #include <linux/file.h> 23 + #include <linux/uaccess.h> 22 24 #include "integrity.h" 23 25 24 26 static struct rb_root integrity_iint_tree = RB_ROOT; 25 27 static DEFINE_RWLOCK(integrity_iint_lock); 26 28 static struct kmem_cache *iint_cache __read_mostly; 27 - 28 - int iint_initialized; 29 29 30 30 /* 31 31 * __integrity_iint_find - return the iint associated with an inode ··· 166 166 iint_cache = 167 167 kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache), 168 168 0, SLAB_PANIC, init_once); 169 - iint_initialized = 1; 170 169 return 0; 171 170 } 172 171 security_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 + */ 182 + int 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 + */ 209 + int __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; 240 + out: 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 + */ 251 + void __init integrity_load_keys(void) 252 + { 253 + ima_load_x509(); 254 + }
+25
security/integrity/ima/Kconfig
··· 131 131 help 132 132 This option requires that all keys added to the .ima 133 133 keyring be signed by a key on the system trusted keyring. 134 + 135 + config 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 + 146 + config 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 + 153 + config 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.
+3 -4
security/integrity/ima/ima_api.c
··· 173 173 { 174 174 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE; 175 175 176 - if (!ima_appraise) 177 - flags &= ~IMA_APPRAISE; 176 + flags &= ima_policy_flag; 178 177 179 178 return ima_match_policy(inode, function, mask, flags); 180 179 } ··· 324 325 { 325 326 char *pathname = NULL; 326 327 327 - *pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); 328 + *pathbuf = __getname(); 328 329 if (*pathbuf) { 329 330 pathname = d_absolute_path(path, *pathbuf, PATH_MAX); 330 331 if (IS_ERR(pathname)) { 331 - kfree(*pathbuf); 332 + __putname(*pathbuf); 332 333 *pathbuf = NULL; 333 334 pathname = NULL; 334 335 }
+3 -32
security/integrity/ima/ima_crypto.c
··· 67 67 static struct crypto_shash *ima_shash_tfm; 68 68 static 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 - */ 78 - static 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 - 100 70 int __init ima_init_crypto(void) 101 71 { 102 72 long rc; ··· 294 324 } 295 325 /* read buffer */ 296 326 rbuf_len = min_t(loff_t, i_size - offset, rbuf_size[active]); 297 - rc = ima_kernel_read(file, offset, rbuf[active], rbuf_len); 327 + rc = integrity_kernel_read(file, offset, rbuf[active], 328 + rbuf_len); 298 329 if (rc != rbuf_len) 299 330 goto out3; 300 331 ··· 388 417 while (offset < i_size) { 389 418 int rbuf_len; 390 419 391 - rbuf_len = ima_kernel_read(file, offset, rbuf, PAGE_SIZE); 420 + rbuf_len = integrity_kernel_read(file, offset, rbuf, PAGE_SIZE); 392 421 if (rbuf_len < 0) { 393 422 rc = rbuf_len; 394 423 break;
+28 -9
security/integrity/ima/ima_fs.c
··· 118 118 /* the list never shrinks, so we don't need a lock here */ 119 119 struct ima_queue_entry *qe = v; 120 120 struct ima_template_entry *e; 121 + char *template_name; 121 122 int namelen; 122 123 u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX; 123 124 bool is_ima_template = false; ··· 128 127 e = qe->entry; 129 128 if (e == NULL) 130 129 return -1; 130 + 131 + template_name = (e->template_desc->name[0] != '\0') ? 132 + e->template_desc->name : e->template_desc->fmt; 131 133 132 134 /* 133 135 * 1st: PCRIndex ··· 143 139 ima_putc(m, e->digest, TPM_DIGEST_SIZE); 144 140 145 141 /* 3rd: template name size */ 146 - namelen = strlen(e->template_desc->name); 142 + namelen = strlen(template_name); 147 143 ima_putc(m, &namelen, sizeof(namelen)); 148 144 149 145 /* 4th: template name */ 150 - ima_putc(m, e->template_desc->name, namelen); 146 + ima_putc(m, template_name, namelen); 151 147 152 148 /* 5th: template length (except for 'ima' template) */ 153 - if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) 149 + if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0) 154 150 is_ima_template = true; 155 151 156 152 if (!is_ima_template) ··· 204 200 /* the list never shrinks, so we don't need a lock here */ 205 201 struct ima_queue_entry *qe = v; 206 202 struct ima_template_entry *e; 203 + char *template_name; 207 204 int i; 208 205 209 206 /* get entry */ 210 207 e = qe->entry; 211 208 if (e == NULL) 212 209 return -1; 210 + 211 + template_name = (e->template_desc->name[0] != '\0') ? 212 + e->template_desc->name : e->template_desc->fmt; 213 213 214 214 /* 1st: PCR used (config option) */ 215 215 seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX); ··· 222 214 ima_print_digest(m, e->digest, TPM_DIGEST_SIZE); 223 215 224 216 /* 3th: template name */ 225 - seq_printf(m, " %s", e->template_desc->name); 217 + seq_printf(m, " %s", template_name); 226 218 227 219 /* 4th: template specific data */ 228 220 for (i = 0; i < e->template_desc->num_fields; i++) { ··· 296 288 static struct dentry *violations; 297 289 static struct dentry *ima_policy; 298 290 299 - static atomic_t policy_opencount = ATOMIC_INIT(1); 291 + enum ima_fs_flags { 292 + IMA_FS_BUSY, 293 + }; 294 + 295 + static unsigned long ima_fs_flags; 296 + 300 297 /* 301 298 * ima_open_policy: sequentialize access to the policy file 302 299 */ ··· 310 297 /* No point in being allowed to open it if you aren't going to write */ 311 298 if (!(filp->f_flags & O_WRONLY)) 312 299 return -EACCES; 313 - if (atomic_dec_and_test(&policy_opencount)) 314 - return 0; 315 - return -EBUSY; 300 + if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags)) 301 + return -EBUSY; 302 + return 0; 316 303 } 317 304 318 305 /* ··· 324 311 */ 325 312 static int ima_release_policy(struct inode *inode, struct file *file) 326 313 { 314 + const char *cause = valid_policy ? "completed" : "failed"; 315 + 316 + pr_info("IMA: policy update %s\n", cause); 317 + integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, 318 + "policy_update", cause, !valid_policy, 0); 319 + 327 320 if (!valid_policy) { 328 321 ima_delete_rules(); 329 322 valid_policy = 1; 330 - atomic_set(&policy_opencount, 1); 323 + clear_bit(IMA_FS_BUSY, &ima_fs_flags); 331 324 return 0; 332 325 } 333 326 ima_update_policy();
+17
security/integrity/ima/ima_init.c
··· 24 24 #include <crypto/hash_info.h> 25 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 33 /* name for boot aggregate entry */ 28 34 static const char *boot_aggregate_name = "boot_aggregate"; 29 35 int ima_used_chip; ··· 96 90 audit_cause, result, 0); 97 91 return result; 98 92 } 93 + 94 + #ifdef CONFIG_IMA_LOAD_X509 95 + void __init ima_load_x509(void) 96 + { 97 + int unset_flags = ima_policy_flag & IMA_APPRAISE; 98 + 99 + ima_policy_flag &= ~unset_flags; 100 + integrity_load_x509(INTEGRITY_KEYRING_IMA, IMA_X509_PATH); 101 + ima_policy_flag |= unset_flags; 102 + } 103 + #endif 99 104 100 105 int __init ima_init(void) 101 106 {
+3 -2
security/integrity/ima/ima_main.c
··· 143 143 struct inode *inode = file_inode(file); 144 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 147 return; 148 148 149 149 iint = integrity_iint_find(inode); ··· 246 246 rc = -EACCES; 247 247 kfree(xattr_value); 248 248 out_free: 249 - kfree(pathbuf); 249 + if (pathbuf) 250 + __putname(pathbuf); 250 251 out: 251 252 mutex_unlock(&inode->i_mutex); 252 253 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
+14 -28
security/integrity/ima/ima_policy.c
··· 100 100 {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, 101 101 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 102 102 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 103 + #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT 103 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 106 112 static LIST_HEAD(ima_default_rules); ··· 362 356 */ 363 357 void ima_update_policy(void) 364 358 { 365 - static const char op[] = "policy_update"; 366 - const char *cause = "already-exists"; 367 - int result = 1; 368 - int audit_info = 0; 369 - 370 - if (ima_rules == &ima_default_rules) { 371 - ima_rules = &ima_policy_rules; 372 - ima_update_policy_flag(); 373 - cause = "complete"; 374 - result = 0; 375 - } 376 - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 377 - NULL, op, cause, result, audit_info); 359 + ima_rules = &ima_policy_rules; 360 + ima_update_policy_flag(); 378 361 } 379 362 380 363 enum { ··· 681 686 ssize_t result, len; 682 687 int audit_info = 0; 683 688 684 - /* Prevent installed policy from changing */ 685 - if (ima_rules != &ima_default_rules) { 686 - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 687 - NULL, op, "already-exists", 688 - -EACCES, audit_info); 689 - return -EACCES; 690 - } 689 + p = strsep(&rule, "\n"); 690 + len = strlen(p) + 1; 691 + p += strspn(p, " \t"); 692 + 693 + if (*p == '#' || *p == '\0') 694 + return len; 691 695 692 696 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 693 697 if (!entry) { ··· 696 702 } 697 703 698 704 INIT_LIST_HEAD(&entry->list); 699 - 700 - p = strsep(&rule, "\n"); 701 - len = strlen(p) + 1; 702 - 703 - if (*p == '#') { 704 - kfree(entry); 705 - return len; 706 - } 707 705 708 706 result = ima_parse_rule(p, entry); 709 707 if (result) {
+71 -32
security/integrity/ima/ima_template.c
··· 24 24 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, 25 25 {.name = "ima-ng", .fmt = "d-ng|n-ng"}, 26 26 {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, 27 + {.name = "", .fmt = ""}, /* placeholder for a custom format */ 27 28 }; 28 29 29 30 static struct ima_template_field supported_fields[] = { ··· 42 41 43 42 static struct ima_template_desc *ima_template; 44 43 static struct ima_template_desc *lookup_template_desc(const char *name); 44 + static int template_desc_init_fields(const char *template_fmt, 45 + struct ima_template_field ***fields, 46 + int *num_fields); 45 47 46 48 static int __init ima_template_setup(char *str) 47 49 { 48 50 struct ima_template_desc *template_desc; 49 51 int template_len = strlen(str); 50 52 53 + if (ima_template) 54 + return 1; 55 + 51 56 /* 52 57 * Verify that a template with the supplied name exists. 53 58 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. 54 59 */ 55 60 template_desc = lookup_template_desc(str); 56 - if (!template_desc) 61 + if (!template_desc) { 62 + pr_err("template %s not found, using %s\n", 63 + str, CONFIG_IMA_DEFAULT_TEMPLATE); 57 64 return 1; 65 + } 58 66 59 67 /* 60 68 * Verify whether the current hash algorithm is supported ··· 79 69 return 1; 80 70 } 81 71 __setup("ima_template=", ima_template_setup); 72 + 73 + static int __init ima_template_fmt_setup(char *str) 74 + { 75 + int num_templates = ARRAY_SIZE(defined_templates); 76 + 77 + if (ima_template) 78 + return 1; 79 + 80 + if (template_desc_init_fields(str, NULL, NULL) < 0) { 81 + pr_err("format string '%s' not valid, using template %s\n", 82 + str, CONFIG_IMA_DEFAULT_TEMPLATE); 83 + return 1; 84 + } 85 + 86 + defined_templates[num_templates - 1].fmt = str; 87 + ima_template = defined_templates + num_templates - 1; 88 + return 1; 89 + } 90 + __setup("ima_template_fmt=", ima_template_fmt_setup); 82 91 83 92 static struct ima_template_desc *lookup_template_desc(const char *name) 84 93 { ··· 142 113 struct ima_template_field ***fields, 143 114 int *num_fields) 144 115 { 145 - char *c, *template_fmt_copy, *template_fmt_ptr; 116 + const char *template_fmt_ptr; 117 + struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX]; 146 118 int template_num_fields = template_fmt_size(template_fmt); 147 - int i, result = 0; 119 + int i, len; 148 120 149 - if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) 121 + if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) { 122 + pr_err("format string '%s' contains too many fields\n", 123 + template_fmt); 150 124 return -EINVAL; 151 - 152 - /* copying is needed as strsep() modifies the original buffer */ 153 - template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL); 154 - if (template_fmt_copy == NULL) 155 - return -ENOMEM; 156 - 157 - *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL); 158 - if (*fields == NULL) { 159 - result = -ENOMEM; 160 - goto out; 161 125 } 162 126 163 - template_fmt_ptr = template_fmt_copy; 164 - for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && 165 - i < template_num_fields; i++) { 166 - struct ima_template_field *f = lookup_template_field(c); 127 + for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields; 128 + i++, template_fmt_ptr += len + 1) { 129 + char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1]; 167 130 168 - if (!f) { 169 - result = -ENOENT; 170 - goto out; 131 + len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr; 132 + if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) { 133 + pr_err("Invalid field with length %d\n", len); 134 + return -EINVAL; 171 135 } 172 - (*fields)[i] = f; 136 + 137 + memcpy(tmp_field_id, template_fmt_ptr, len); 138 + tmp_field_id[len] = '\0'; 139 + found_fields[i] = lookup_template_field(tmp_field_id); 140 + if (!found_fields[i]) { 141 + pr_err("field '%s' not found\n", tmp_field_id); 142 + return -ENOENT; 143 + } 173 144 } 174 - *num_fields = i; 175 - out: 176 - if (result < 0) { 177 - kfree(*fields); 178 - *fields = NULL; 145 + 146 + if (fields && num_fields) { 147 + *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL); 148 + if (*fields == NULL) 149 + return -ENOMEM; 150 + 151 + memcpy(*fields, found_fields, i * sizeof(*fields)); 152 + *num_fields = i; 179 153 } 180 - kfree(template_fmt_copy); 181 - return result; 154 + 155 + return 0; 182 156 } 183 157 184 158 struct ima_template_desc *ima_template_desc_current(void) ··· 195 163 int __init ima_init_template(void) 196 164 { 197 165 struct ima_template_desc *template = ima_template_desc_current(); 166 + int result; 198 167 199 - return template_desc_init_fields(template->fmt, 200 - &(template->fields), 201 - &(template->num_fields)); 168 + result = template_desc_init_fields(template->fmt, 169 + &(template->fields), 170 + &(template->num_fields)); 171 + if (result < 0) 172 + pr_err("template %s init failed, result: %d\n", 173 + (strlen(template->name) ? 174 + template->name : template->fmt), result); 175 + 176 + return result; 202 177 }
+15 -4
security/integrity/integrity.h
··· 119 119 */ 120 120 struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 121 121 122 + int integrity_kernel_read(struct file *file, loff_t offset, 123 + char *addr, unsigned long count); 124 + int __init integrity_read_file(const char *path, char **data); 125 + 122 126 #define INTEGRITY_KEYRING_EVM 0 123 127 #define INTEGRITY_KEYRING_MODULE 1 124 128 #define INTEGRITY_KEYRING_IMA 2 ··· 133 129 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 134 130 const char *digest, int digestlen); 135 131 136 - int integrity_init_keyring(const unsigned int id); 132 + int __init integrity_init_keyring(const unsigned int id); 133 + int __init integrity_load_x509(const unsigned int id, char *path); 137 134 #else 138 135 139 136 static inline int integrity_digsig_verify(const unsigned int id, ··· 148 143 { 149 144 return 0; 150 145 } 146 + 151 147 #endif /* CONFIG_INTEGRITY_SIGNATURE */ 152 148 153 149 #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS ··· 159 153 int siglen, const char *data, int datalen) 160 154 { 161 155 return -EOPNOTSUPP; 156 + } 157 + #endif 158 + 159 + #ifdef CONFIG_IMA_LOAD_X509 160 + void __init ima_load_x509(void); 161 + #else 162 + static inline void ima_load_x509(void) 163 + { 162 164 } 163 165 #endif 164 166 ··· 183 169 { 184 170 } 185 171 #endif 186 - 187 - /* set during initialization */ 188 - extern int iint_initialized;