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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'serge-next-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux-security

Pull more security layer updates from Serge Hallyn:
"A few more commits had previously failed to make it through
security-next into linux-next but this week made it into linux-next.
At least commit "ima: introduce ima_kernel_read()" was deemed critical
by Mimi to make this merge window.

This is a temporary tree just for this request. Mimi has pointed me
to some previous threads about keeping maintainer trees at the
previous release, which I'll certainly do for anything long-term,
after talking with James"

* 'serge-next-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux-security:
ima: introduce ima_kernel_read()
evm: prohibit userspace writing 'security.evm' HMAC value
ima: check inode integrity cache in violation check
ima: prevent unnecessary policy checking
evm: provide option to protect additional SMACK xattrs
evm: replace HMAC version with attribute mask
ima: prevent new digsig xattr from being replaced

+116 -30
+36 -10
security/integrity/evm/Kconfig
··· 12 12 13 13 If you are unsure how to answer this question, answer N. 14 14 15 - config EVM_HMAC_VERSION 16 - int "EVM HMAC version" 17 - depends on EVM 18 - default 2 19 - help 20 - This options adds EVM HMAC version support. 21 - 1 - original version 22 - 2 - add per filesystem unique identifier (UUID) (default) 15 + if EVM 23 16 24 - WARNING: changing the HMAC calculation method or adding 17 + menu "EVM options" 18 + 19 + config EVM_ATTR_FSUUID 20 + bool "FSUUID (version 2)" 21 + default y 22 + depends on EVM 23 + help 24 + Include filesystem UUID for HMAC calculation. 25 + 26 + Default value is 'selected', which is former version 2. 27 + if 'not selected', it is former version 1 28 + 29 + WARNING: changing the HMAC calculation method or adding 25 30 additional info to the calculation, requires existing EVM 26 - labeled file systems to be relabeled. 31 + labeled file systems to be relabeled. 32 + 33 + config EVM_EXTRA_SMACK_XATTRS 34 + bool "Additional SMACK xattrs" 35 + depends on EVM && SECURITY_SMACK 36 + default n 37 + help 38 + Include additional SMACK xattrs for HMAC calculation. 39 + 40 + In addition to the original security xattrs (eg. security.selinux, 41 + security.SMACK64, security.capability, and security.ima) included 42 + in the HMAC calculation, enabling this option includes newly defined 43 + Smack xattrs: security.SMACK64EXEC, security.SMACK64TRANSMUTE and 44 + security.SMACK64MMAP. 45 + 46 + WARNING: changing the HMAC calculation method or adding 47 + additional info to the calculation, requires existing EVM 48 + labeled file systems to be relabeled. 49 + 50 + endmenu 51 + 52 + endif
+4 -1
security/integrity/evm/evm.h
··· 24 24 extern int evm_initialized; 25 25 extern char *evm_hmac; 26 26 extern char *evm_hash; 27 - extern int evm_hmac_version; 27 + 28 + #define EVM_ATTR_FSUUID 0x0001 29 + 30 + extern int evm_hmac_attrs; 28 31 29 32 extern struct crypto_shash *hmac_tfm; 30 33 extern struct crypto_shash *hash_tfm;
+1 -1
security/integrity/evm/evm_crypto.c
··· 112 112 hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid); 113 113 hmac_misc.mode = inode->i_mode; 114 114 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc)); 115 - if (evm_hmac_version > 1) 115 + if (evm_hmac_attrs & EVM_ATTR_FSUUID) 116 116 crypto_shash_update(desc, inode->i_sb->s_uuid, 117 117 sizeof(inode->i_sb->s_uuid)); 118 118 crypto_shash_final(desc, digest);
+26 -3
security/integrity/evm/evm_main.c
··· 32 32 }; 33 33 char *evm_hmac = "hmac(sha1)"; 34 34 char *evm_hash = "sha1"; 35 - int evm_hmac_version = CONFIG_EVM_HMAC_VERSION; 35 + int evm_hmac_attrs; 36 36 37 37 char *evm_config_xattrnames[] = { 38 38 #ifdef CONFIG_SECURITY_SELINUX ··· 40 40 #endif 41 41 #ifdef CONFIG_SECURITY_SMACK 42 42 XATTR_NAME_SMACK, 43 + #ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS 44 + XATTR_NAME_SMACKEXEC, 45 + XATTR_NAME_SMACKTRANSMUTE, 46 + XATTR_NAME_SMACKMMAP, 47 + #endif 43 48 #endif 44 49 #ifdef CONFIG_IMA_APPRAISE 45 50 XATTR_NAME_IMA, ··· 61 56 return 0; 62 57 } 63 58 __setup("evm=", evm_set_fixmode); 59 + 60 + static void __init evm_init_config(void) 61 + { 62 + #ifdef CONFIG_EVM_ATTR_FSUUID 63 + evm_hmac_attrs |= EVM_ATTR_FSUUID; 64 + #endif 65 + pr_info("HMAC attrs: 0x%x\n", evm_hmac_attrs); 66 + } 64 67 65 68 static int evm_find_protected_xattrs(struct dentry *dentry) 66 69 { ··· 300 287 * @xattr_value: pointer to the new extended attribute value 301 288 * @xattr_value_len: pointer to the new extended attribute value length 302 289 * 303 - * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that 304 - * the current value is valid. 290 + * Before allowing the 'security.evm' protected xattr to be updated, 291 + * verify the existing value is valid. As only the kernel should have 292 + * access to the EVM encrypted key needed to calculate the HMAC, prevent 293 + * userspace from writing HMAC value. Writing 'security.evm' requires 294 + * requires CAP_SYS_ADMIN privileges. 305 295 */ 306 296 int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name, 307 297 const void *xattr_value, size_t xattr_value_len) 308 298 { 299 + const struct evm_ima_xattr_data *xattr_data = xattr_value; 300 + 301 + if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0) 302 + && (xattr_data->type == EVM_XATTR_HMAC)) 303 + return -EPERM; 309 304 return evm_protect_xattr(dentry, xattr_name, xattr_value, 310 305 xattr_value_len); 311 306 } ··· 452 431 static int __init init_evm(void) 453 432 { 454 433 int error; 434 + 435 + evm_init_config(); 455 436 456 437 error = evm_init_secfs(); 457 438 if (error < 0) {
+7 -3
security/integrity/ima/ima_appraise.c
··· 341 341 return 0; 342 342 } 343 343 344 - static void ima_reset_appraise_flags(struct inode *inode) 344 + static void ima_reset_appraise_flags(struct inode *inode, int digsig) 345 345 { 346 346 struct integrity_iint_cache *iint; 347 347 ··· 353 353 return; 354 354 355 355 iint->flags &= ~IMA_DONE_MASK; 356 + if (digsig) 357 + iint->flags |= IMA_DIGSIG; 356 358 return; 357 359 } 358 360 359 361 int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, 360 362 const void *xattr_value, size_t xattr_value_len) 361 363 { 364 + const struct evm_ima_xattr_data *xvalue = xattr_value; 362 365 int result; 363 366 364 367 result = ima_protect_xattr(dentry, xattr_name, xattr_value, 365 368 xattr_value_len); 366 369 if (result == 1) { 367 - ima_reset_appraise_flags(dentry->d_inode); 370 + ima_reset_appraise_flags(dentry->d_inode, 371 + (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); 368 372 result = 0; 369 373 } 370 374 return result; ··· 380 376 381 377 result = ima_protect_xattr(dentry, xattr_name, NULL, 0); 382 378 if (result == 1) { 383 - ima_reset_appraise_flags(dentry->d_inode); 379 + ima_reset_appraise_flags(dentry->d_inode, 0); 384 380 result = 0; 385 381 } 386 382 return result;
+31 -1
security/integrity/ima/ima_crypto.c
··· 27 27 28 28 static struct crypto_shash *ima_shash_tfm; 29 29 30 + /** 31 + * ima_kernel_read - read file content 32 + * 33 + * This is a function for reading file content instead of kernel_read(). 34 + * It does not perform locking checks to ensure it cannot be blocked. 35 + * It does not perform security checks because it is irrelevant for IMA. 36 + * 37 + */ 38 + static int ima_kernel_read(struct file *file, loff_t offset, 39 + char *addr, unsigned long count) 40 + { 41 + mm_segment_t old_fs; 42 + char __user *buf = addr; 43 + ssize_t ret; 44 + 45 + if (!(file->f_mode & FMODE_READ)) 46 + return -EBADF; 47 + if (!file->f_op->read && !file->f_op->aio_read) 48 + return -EINVAL; 49 + 50 + old_fs = get_fs(); 51 + set_fs(get_ds()); 52 + if (file->f_op->read) 53 + ret = file->f_op->read(file, buf, count, &offset); 54 + else 55 + ret = do_sync_read(file, buf, count, &offset); 56 + set_fs(old_fs); 57 + return ret; 58 + } 59 + 30 60 int ima_init_crypto(void) 31 61 { 32 62 long rc; ··· 134 104 while (offset < i_size) { 135 105 int rbuf_len; 136 106 137 - rbuf_len = kernel_read(file, offset, rbuf, PAGE_SIZE); 107 + rbuf_len = ima_kernel_read(file, offset, rbuf, PAGE_SIZE); 138 108 if (rbuf_len < 0) { 139 109 rc = rbuf_len; 140 110 break;
+11 -11
security/integrity/ima/ima_main.c
··· 81 81 { 82 82 struct inode *inode = file_inode(file); 83 83 fmode_t mode = file->f_mode; 84 - int must_measure; 85 84 bool send_tomtou = false, send_writers = false; 86 85 char *pathbuf = NULL; 87 86 const char *pathname; ··· 91 92 mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */ 92 93 93 94 if (mode & FMODE_WRITE) { 94 - if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) 95 - send_tomtou = true; 96 - goto out; 95 + if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) { 96 + struct integrity_iint_cache *iint; 97 + iint = integrity_iint_find(inode); 98 + /* IMA_MEASURE is set from reader side */ 99 + if (iint && (iint->flags & IMA_MEASURE)) 100 + send_tomtou = true; 101 + } 102 + } else { 103 + if ((atomic_read(&inode->i_writecount) > 0) && 104 + ima_must_measure(inode, MAY_READ, FILE_CHECK)) 105 + send_writers = true; 97 106 } 98 107 99 - must_measure = ima_must_measure(inode, MAY_READ, FILE_CHECK); 100 - if (!must_measure) 101 - goto out; 102 - 103 - if (atomic_read(&inode->i_writecount) > 0) 104 - send_writers = true; 105 - out: 106 108 mutex_unlock(&inode->i_mutex); 107 109 108 110 if (!send_tomtou && !send_writers)