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

Merge tag 'integrity-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity

Pull integrity updates from Mimi Zohar:
"The main changes are extending the TPM 2.0 PCR banks with bank
specific file hashes, calculating the "boot_aggregate" based on other
TPM PCR banks, using the default IMA hash algorithm, instead of SHA1,
as the basis for the cache hash table key, and preventing the mprotect
syscall to circumvent an IMA mmap appraise policy rule.

- In preparation for extending TPM 2.0 PCR banks with bank specific
digests, commit 0b6cf6b97b7e ("tpm: pass an array of
tpm_extend_digest structures to tpm_pcr_extend()") modified
tpm_pcr_extend(). The original SHA1 file digests were
padded/truncated, before being extended into the other TPM PCR
banks. This pull request calculates and extends the TPM PCR banks
with bank specific file hashes completing the above change.

- The "boot_aggregate", the first IMA measurement list record, is the
"trusted boot" link between the pre-boot environment and the
running OS. With TPM 2.0, the "boot_aggregate" record is not
limited to being based on the SHA1 TPM PCR bank, but can be
calculated based on any enabled bank, assuming the hash algorithm
is also enabled in the kernel.

Other changes include the following and five other bug fixes/code
clean up:

- supporting both a SHA1 and a larger "boot_aggregate" digest in a
custom template format containing both the the SHA1 ('d') and
larger digests ('d-ng') fields.

- Initial hash table key fix, but additional changes would be good"

* tag 'integrity-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
ima: Directly free *entry in ima_alloc_init_template() if digests is NULL
ima: Call ima_calc_boot_aggregate() in ima_eventdigest_init()
ima: Directly assign the ima_default_policy pointer to ima_rules
ima: verify mprotect change is consistent with mmap policy
evm: Fix possible memory leak in evm_calc_hmac_or_hash()
ima: Set again build_ima_appraise variable
ima: Remove redundant policy rule set in add_rules()
ima: Fix ima digest hash table key calculation
ima: Use ima_hash_algo for collision detection in the measurement list
ima: Calculate and extend PCR with digests in ima_template_entry
ima: Allocate and initialize tfm for each PCR bank
ima: Switch to dynamically allocated buffer for template digests
ima: Store template digest directly in ima_template_entry
ima: Evaluate error in init_ima()
ima: Switch to ima_hash_algo for boot aggregate

+396 -86
+7
include/linux/ima.h
··· 18 18 extern void ima_post_create_tmpfile(struct inode *inode); 19 19 extern void ima_file_free(struct file *file); 20 20 extern int ima_file_mmap(struct file *file, unsigned long prot); 21 + extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot); 21 22 extern int ima_load_data(enum kernel_load_data_id id); 22 23 extern int ima_read_file(struct file *file, enum kernel_read_file_id id); 23 24 extern int ima_post_read_file(struct file *file, void *buf, loff_t size, ··· 67 66 } 68 67 69 68 static inline int ima_file_mmap(struct file *file, unsigned long prot) 69 + { 70 + return 0; 71 + } 72 + 73 + static inline int ima_file_mprotect(struct vm_area_struct *vma, 74 + unsigned long prot) 70 75 { 71 76 return 0; 72 77 }
+1 -1
security/integrity/evm/evm_crypto.c
··· 241 241 242 242 /* Portable EVM signatures must include an IMA hash */ 243 243 if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present) 244 - return -EPERM; 244 + error = -EPERM; 245 245 out: 246 246 kfree(xattr_value); 247 247 kfree(desc);
+13 -7
security/integrity/ima/ima.h
··· 36 36 #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE 37 37 #define IMA_EVENT_NAME_LEN_MAX 255 38 38 39 - #define IMA_HASH_BITS 9 39 + #define IMA_HASH_BITS 10 40 40 #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) 41 41 42 42 #define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16 ··· 45 45 #define IMA_TEMPLATE_IMA_NAME "ima" 46 46 #define IMA_TEMPLATE_IMA_FMT "d|n" 47 47 48 + #define NR_BANKS(chip) ((chip != NULL) ? chip->nr_allocated_banks : 0) 49 + 48 50 /* current content of the policy */ 49 51 extern int ima_policy_flag; 50 52 51 53 /* set during initialization */ 52 54 extern int ima_hash_algo; 55 + extern int ima_sha1_idx __ro_after_init; 56 + extern int ima_hash_algo_idx __ro_after_init; 57 + extern int ima_extra_slots __ro_after_init; 53 58 extern int ima_appraise; 54 59 extern struct tpm_chip *ima_tpm_chip; 60 + extern const char boot_aggregate_name[]; 55 61 56 62 /* IMA event related data */ 57 63 struct ima_event_data { ··· 98 92 99 93 struct ima_template_entry { 100 94 int pcr; 101 - u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ 95 + struct tpm_digest *digests; 102 96 struct ima_template_desc *template_desc; /* template descriptor */ 103 97 u32 template_data_len; 104 98 struct ima_field_data template_data[0]; /* template related data */ ··· 144 138 int ima_calc_buffer_hash(const void *buf, loff_t len, 145 139 struct ima_digest_data *hash); 146 140 int ima_calc_field_array_hash(struct ima_field_data *field_data, 147 - struct ima_template_desc *desc, int num_fields, 148 - struct ima_digest_data *hash); 149 - int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); 141 + struct ima_template_entry *entry); 142 + int ima_calc_boot_aggregate(struct ima_digest_data *hash); 150 143 void ima_add_violation(struct file *file, const unsigned char *filename, 151 144 struct integrity_iint_cache *iint, 152 145 const char *op, const char *cause); ··· 180 175 }; 181 176 extern struct ima_h_table ima_htable; 182 177 183 - static inline unsigned long ima_hash_key(u8 *digest) 178 + static inline unsigned int ima_hash_key(u8 *digest) 184 179 { 185 - return hash_long(*digest, IMA_HASH_BITS); 180 + /* there is no point in taking a hash of part of a digest */ 181 + return (digest[0] | digest[1] << 8) % IMA_MEASURE_HTABLE_SIZE; 186 182 } 187 183 188 184 #define __ima_hooks(hook) \
+12 -11
security/integrity/ima/ima_api.c
··· 27 27 for (i = 0; i < entry->template_desc->num_fields; i++) 28 28 kfree(entry->template_data[i].data); 29 29 30 + kfree(entry->digests); 30 31 kfree(entry); 31 32 } 32 33 ··· 39 38 struct ima_template_desc *desc) 40 39 { 41 40 struct ima_template_desc *template_desc; 41 + struct tpm_digest *digests; 42 42 int i, result = 0; 43 43 44 44 if (desc) ··· 52 50 if (!*entry) 53 51 return -ENOMEM; 54 52 53 + digests = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots, 54 + sizeof(*digests), GFP_NOFS); 55 + if (!digests) { 56 + kfree(*entry); 57 + *entry = NULL; 58 + return -ENOMEM; 59 + } 60 + 61 + (*entry)->digests = digests; 55 62 (*entry)->template_desc = template_desc; 56 63 for (i = 0; i < template_desc->num_fields; i++) { 57 64 const struct ima_template_field *field = ··· 107 96 static const char audit_cause[] = "hashing_error"; 108 97 char *template_name = entry->template_desc->name; 109 98 int result; 110 - struct { 111 - struct ima_digest_data hdr; 112 - char digest[TPM_DIGEST_SIZE]; 113 - } hash; 114 99 115 100 if (!violation) { 116 - int num_fields = entry->template_desc->num_fields; 117 - 118 - /* this function uses default algo */ 119 - hash.hdr.algo = HASH_ALGO_SHA1; 120 101 result = ima_calc_field_array_hash(&entry->template_data[0], 121 - entry->template_desc, 122 - num_fields, &hash.hdr); 102 + entry); 123 103 if (result < 0) { 124 104 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, 125 105 template_name, op, 126 106 audit_cause, result, 0); 127 107 return result; 128 108 } 129 - memcpy(entry->digest, hash.hdr.digest, hash.hdr.length); 130 109 } 131 110 entry->pcr = pcr; 132 111 result = ima_add_template_entry(entry, violation, op, inode, filename);
+214 -38
security/integrity/ima/ima_crypto.c
··· 57 57 static struct crypto_shash *ima_shash_tfm; 58 58 static struct crypto_ahash *ima_ahash_tfm; 59 59 60 - int __init ima_init_crypto(void) 60 + struct ima_algo_desc { 61 + struct crypto_shash *tfm; 62 + enum hash_algo algo; 63 + }; 64 + 65 + int ima_sha1_idx __ro_after_init; 66 + int ima_hash_algo_idx __ro_after_init; 67 + /* 68 + * Additional number of slots reserved, as needed, for SHA1 69 + * and IMA default algo. 70 + */ 71 + int ima_extra_slots __ro_after_init; 72 + 73 + static struct ima_algo_desc *ima_algo_array; 74 + 75 + static int __init ima_init_ima_crypto(void) 61 76 { 62 77 long rc; 63 78 ··· 91 76 static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo) 92 77 { 93 78 struct crypto_shash *tfm = ima_shash_tfm; 94 - int rc; 79 + int rc, i; 95 80 96 81 if (algo < 0 || algo >= HASH_ALGO__LAST) 97 82 algo = ima_hash_algo; 98 83 99 - if (algo != ima_hash_algo) { 100 - tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0); 101 - if (IS_ERR(tfm)) { 102 - rc = PTR_ERR(tfm); 103 - pr_err("Can not allocate %s (reason: %d)\n", 104 - hash_algo_name[algo], rc); 105 - } 84 + if (algo == ima_hash_algo) 85 + return tfm; 86 + 87 + for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) 88 + if (ima_algo_array[i].tfm && ima_algo_array[i].algo == algo) 89 + return ima_algo_array[i].tfm; 90 + 91 + tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0); 92 + if (IS_ERR(tfm)) { 93 + rc = PTR_ERR(tfm); 94 + pr_err("Can not allocate %s (reason: %d)\n", 95 + hash_algo_name[algo], rc); 106 96 } 107 97 return tfm; 108 98 } 109 99 100 + int __init ima_init_crypto(void) 101 + { 102 + enum hash_algo algo; 103 + long rc; 104 + int i; 105 + 106 + rc = ima_init_ima_crypto(); 107 + if (rc) 108 + return rc; 109 + 110 + ima_sha1_idx = -1; 111 + ima_hash_algo_idx = -1; 112 + 113 + for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) { 114 + algo = ima_tpm_chip->allocated_banks[i].crypto_id; 115 + if (algo == HASH_ALGO_SHA1) 116 + ima_sha1_idx = i; 117 + 118 + if (algo == ima_hash_algo) 119 + ima_hash_algo_idx = i; 120 + } 121 + 122 + if (ima_sha1_idx < 0) { 123 + ima_sha1_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++; 124 + if (ima_hash_algo == HASH_ALGO_SHA1) 125 + ima_hash_algo_idx = ima_sha1_idx; 126 + } 127 + 128 + if (ima_hash_algo_idx < 0) 129 + ima_hash_algo_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++; 130 + 131 + ima_algo_array = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots, 132 + sizeof(*ima_algo_array), GFP_KERNEL); 133 + if (!ima_algo_array) { 134 + rc = -ENOMEM; 135 + goto out; 136 + } 137 + 138 + for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) { 139 + algo = ima_tpm_chip->allocated_banks[i].crypto_id; 140 + ima_algo_array[i].algo = algo; 141 + 142 + /* unknown TPM algorithm */ 143 + if (algo == HASH_ALGO__LAST) 144 + continue; 145 + 146 + if (algo == ima_hash_algo) { 147 + ima_algo_array[i].tfm = ima_shash_tfm; 148 + continue; 149 + } 150 + 151 + ima_algo_array[i].tfm = ima_alloc_tfm(algo); 152 + if (IS_ERR(ima_algo_array[i].tfm)) { 153 + if (algo == HASH_ALGO_SHA1) { 154 + rc = PTR_ERR(ima_algo_array[i].tfm); 155 + ima_algo_array[i].tfm = NULL; 156 + goto out_array; 157 + } 158 + 159 + ima_algo_array[i].tfm = NULL; 160 + } 161 + } 162 + 163 + if (ima_sha1_idx >= NR_BANKS(ima_tpm_chip)) { 164 + if (ima_hash_algo == HASH_ALGO_SHA1) { 165 + ima_algo_array[ima_sha1_idx].tfm = ima_shash_tfm; 166 + } else { 167 + ima_algo_array[ima_sha1_idx].tfm = 168 + ima_alloc_tfm(HASH_ALGO_SHA1); 169 + if (IS_ERR(ima_algo_array[ima_sha1_idx].tfm)) { 170 + rc = PTR_ERR(ima_algo_array[ima_sha1_idx].tfm); 171 + goto out_array; 172 + } 173 + } 174 + 175 + ima_algo_array[ima_sha1_idx].algo = HASH_ALGO_SHA1; 176 + } 177 + 178 + if (ima_hash_algo_idx >= NR_BANKS(ima_tpm_chip) && 179 + ima_hash_algo_idx != ima_sha1_idx) { 180 + ima_algo_array[ima_hash_algo_idx].tfm = ima_shash_tfm; 181 + ima_algo_array[ima_hash_algo_idx].algo = ima_hash_algo; 182 + } 183 + 184 + return 0; 185 + out_array: 186 + for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) { 187 + if (!ima_algo_array[i].tfm || 188 + ima_algo_array[i].tfm == ima_shash_tfm) 189 + continue; 190 + 191 + crypto_free_shash(ima_algo_array[i].tfm); 192 + } 193 + out: 194 + crypto_free_shash(ima_shash_tfm); 195 + return rc; 196 + } 197 + 110 198 static void ima_free_tfm(struct crypto_shash *tfm) 111 199 { 112 - if (tfm != ima_shash_tfm) 113 - crypto_free_shash(tfm); 200 + int i; 201 + 202 + if (tfm == ima_shash_tfm) 203 + return; 204 + 205 + for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) 206 + if (ima_algo_array[i].tfm == tfm) 207 + return; 208 + 209 + crypto_free_shash(tfm); 114 210 } 115 211 116 212 /** ··· 590 464 * Calculate the hash of template data 591 465 */ 592 466 static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data, 593 - struct ima_template_desc *td, 594 - int num_fields, 595 - struct ima_digest_data *hash, 596 - struct crypto_shash *tfm) 467 + struct ima_template_entry *entry, 468 + int tfm_idx) 597 469 { 598 - SHASH_DESC_ON_STACK(shash, tfm); 470 + SHASH_DESC_ON_STACK(shash, ima_algo_array[tfm_idx].tfm); 471 + struct ima_template_desc *td = entry->template_desc; 472 + int num_fields = entry->template_desc->num_fields; 599 473 int rc, i; 600 474 601 - shash->tfm = tfm; 602 - 603 - hash->length = crypto_shash_digestsize(tfm); 475 + shash->tfm = ima_algo_array[tfm_idx].tfm; 604 476 605 477 rc = crypto_shash_init(shash); 606 478 if (rc != 0) ··· 628 504 } 629 505 630 506 if (!rc) 631 - rc = crypto_shash_final(shash, hash->digest); 507 + rc = crypto_shash_final(shash, entry->digests[tfm_idx].digest); 632 508 633 509 return rc; 634 510 } 635 511 636 512 int ima_calc_field_array_hash(struct ima_field_data *field_data, 637 - struct ima_template_desc *desc, int num_fields, 638 - struct ima_digest_data *hash) 513 + struct ima_template_entry *entry) 639 514 { 640 - struct crypto_shash *tfm; 641 - int rc; 515 + u16 alg_id; 516 + int rc, i; 642 517 643 - tfm = ima_alloc_tfm(hash->algo); 644 - if (IS_ERR(tfm)) 645 - return PTR_ERR(tfm); 518 + rc = ima_calc_field_array_hash_tfm(field_data, entry, ima_sha1_idx); 519 + if (rc) 520 + return rc; 646 521 647 - rc = ima_calc_field_array_hash_tfm(field_data, desc, num_fields, 648 - hash, tfm); 522 + entry->digests[ima_sha1_idx].alg_id = TPM_ALG_SHA1; 649 523 650 - ima_free_tfm(tfm); 524 + for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) { 525 + if (i == ima_sha1_idx) 526 + continue; 651 527 528 + if (i < NR_BANKS(ima_tpm_chip)) { 529 + alg_id = ima_tpm_chip->allocated_banks[i].alg_id; 530 + entry->digests[i].alg_id = alg_id; 531 + } 532 + 533 + /* for unmapped TPM algorithms digest is still a padded SHA1 */ 534 + if (!ima_algo_array[i].tfm) { 535 + memcpy(entry->digests[i].digest, 536 + entry->digests[ima_sha1_idx].digest, 537 + TPM_DIGEST_SIZE); 538 + continue; 539 + } 540 + 541 + rc = ima_calc_field_array_hash_tfm(field_data, entry, i); 542 + if (rc) 543 + return rc; 544 + } 652 545 return rc; 653 546 } 654 547 ··· 796 655 } 797 656 798 657 /* 799 - * Calculate the boot aggregate hash 658 + * The boot_aggregate is a cumulative hash over TPM registers 0 - 7. With 659 + * TPM 1.2 the boot_aggregate was based on reading the SHA1 PCRs, but with 660 + * TPM 2.0 hash agility, TPM chips could support multiple TPM PCR banks, 661 + * allowing firmware to configure and enable different banks. 662 + * 663 + * Knowing which TPM bank is read to calculate the boot_aggregate digest 664 + * needs to be conveyed to a verifier. For this reason, use the same 665 + * hash algorithm for reading the TPM PCRs as for calculating the boot 666 + * aggregate digest as stored in the measurement list. 800 667 */ 801 - static int __init ima_calc_boot_aggregate_tfm(char *digest, 802 - struct crypto_shash *tfm) 668 + static int ima_calc_boot_aggregate_tfm(char *digest, u16 alg_id, 669 + struct crypto_shash *tfm) 803 670 { 804 - struct tpm_digest d = { .alg_id = TPM_ALG_SHA1, .digest = {0} }; 671 + struct tpm_digest d = { .alg_id = alg_id, .digest = {0} }; 805 672 int rc; 806 673 u32 i; 807 674 SHASH_DESC_ON_STACK(shash, tfm); 808 675 809 676 shash->tfm = tfm; 677 + 678 + pr_devel("calculating the boot-aggregate based on TPM bank: %04x\n", 679 + d.alg_id); 810 680 811 681 rc = crypto_shash_init(shash); 812 682 if (rc != 0) ··· 827 675 for (i = TPM_PCR0; i < TPM_PCR8; i++) { 828 676 ima_pcrread(i, &d); 829 677 /* now accumulate with current aggregate */ 830 - rc = crypto_shash_update(shash, d.digest, TPM_DIGEST_SIZE); 678 + rc = crypto_shash_update(shash, d.digest, 679 + crypto_shash_digestsize(tfm)); 831 680 } 832 681 if (!rc) 833 682 crypto_shash_final(shash, digest); 834 683 return rc; 835 684 } 836 685 837 - int __init ima_calc_boot_aggregate(struct ima_digest_data *hash) 686 + int ima_calc_boot_aggregate(struct ima_digest_data *hash) 838 687 { 839 688 struct crypto_shash *tfm; 840 - int rc; 689 + u16 crypto_id, alg_id; 690 + int rc, i, bank_idx = -1; 691 + 692 + for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) { 693 + crypto_id = ima_tpm_chip->allocated_banks[i].crypto_id; 694 + if (crypto_id == hash->algo) { 695 + bank_idx = i; 696 + break; 697 + } 698 + 699 + if (crypto_id == HASH_ALGO_SHA256) 700 + bank_idx = i; 701 + 702 + if (bank_idx == -1 && crypto_id == HASH_ALGO_SHA1) 703 + bank_idx = i; 704 + } 705 + 706 + if (bank_idx == -1) { 707 + pr_err("No suitable TPM algorithm for boot aggregate\n"); 708 + return 0; 709 + } 710 + 711 + hash->algo = ima_tpm_chip->allocated_banks[bank_idx].crypto_id; 841 712 842 713 tfm = ima_alloc_tfm(hash->algo); 843 714 if (IS_ERR(tfm)) 844 715 return PTR_ERR(tfm); 845 716 846 717 hash->length = crypto_shash_digestsize(tfm); 847 - rc = ima_calc_boot_aggregate_tfm(hash->digest, tfm); 718 + alg_id = ima_tpm_chip->allocated_banks[bank_idx].alg_id; 719 + rc = ima_calc_boot_aggregate_tfm(hash->digest, alg_id, tfm); 848 720 849 721 ima_free_tfm(tfm); 850 722
+2 -2
security/integrity/ima/ima_fs.c
··· 150 150 ima_putc(m, &pcr, sizeof(e->pcr)); 151 151 152 152 /* 2nd: template digest */ 153 - ima_putc(m, e->digest, TPM_DIGEST_SIZE); 153 + ima_putc(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE); 154 154 155 155 /* 3rd: template name size */ 156 156 namelen = !ima_canonical_fmt ? strlen(template_name) : ··· 233 233 seq_printf(m, "%2d ", e->pcr); 234 234 235 235 /* 2nd: SHA1 template hash */ 236 - ima_print_digest(m, e->digest, TPM_DIGEST_SIZE); 236 + ima_print_digest(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE); 237 237 238 238 /* 3th: template name */ 239 239 seq_printf(m, " %s", template_name);
+17 -5
security/integrity/ima/ima_init.c
··· 19 19 #include "ima.h" 20 20 21 21 /* name for boot aggregate entry */ 22 - static const char boot_aggregate_name[] = "boot_aggregate"; 22 + const char boot_aggregate_name[] = "boot_aggregate"; 23 23 struct tpm_chip *ima_tpm_chip; 24 24 25 25 /* Add the boot aggregate to the IMA measurement list and extend 26 26 * the PCR register. 27 27 * 28 - * Calculate the boot aggregate, a SHA1 over tpm registers 0-7, 28 + * Calculate the boot aggregate, a hash over tpm registers 0-7, 29 29 * assuming a TPM chip exists, and zeroes if the TPM chip does not 30 30 * exist. Add the boot aggregate measurement to the measurement 31 31 * list and extend the PCR register. ··· 49 49 int violation = 0; 50 50 struct { 51 51 struct ima_digest_data hdr; 52 - char digest[TPM_DIGEST_SIZE]; 52 + char digest[TPM_MAX_DIGEST_SIZE]; 53 53 } hash; 54 54 55 55 memset(iint, 0, sizeof(*iint)); 56 56 memset(&hash, 0, sizeof(hash)); 57 57 iint->ima_hash = &hash.hdr; 58 - iint->ima_hash->algo = HASH_ALGO_SHA1; 59 - iint->ima_hash->length = SHA1_DIGEST_SIZE; 58 + iint->ima_hash->algo = ima_hash_algo; 59 + iint->ima_hash->length = hash_digest_size[ima_hash_algo]; 60 60 61 + /* 62 + * With TPM 2.0 hash agility, TPM chips could support multiple TPM 63 + * PCR banks, allowing firmware to configure and enable different 64 + * banks. The SHA1 bank is not necessarily enabled. 65 + * 66 + * Use the same hash algorithm for reading the TPM PCRs as for 67 + * calculating the boot aggregate digest. Preference is given to 68 + * the configured IMA default hash algorithm. Otherwise, use the 69 + * TCG required banks - SHA256 for TPM 2.0, SHA1 for TPM 1.2. 70 + * Ultimately select SHA1 also for TPM 2.0 if the SHA256 PCR bank 71 + * is not found. 72 + */ 61 73 if (ima_tpm_chip) { 62 74 result = ima_calc_boot_aggregate(&hash.hdr); 63 75 if (result < 0) {
+54
security/integrity/ima/ima_main.c
··· 394 394 } 395 395 396 396 /** 397 + * ima_file_mprotect - based on policy, limit mprotect change 398 + * @prot: contains the protection that will be applied by the kernel. 399 + * 400 + * Files can be mmap'ed read/write and later changed to execute to circumvent 401 + * IMA's mmap appraisal policy rules. Due to locking issues (mmap semaphore 402 + * would be taken before i_mutex), files can not be measured or appraised at 403 + * this point. Eliminate this integrity gap by denying the mprotect 404 + * PROT_EXECUTE change, if an mmap appraise policy rule exists. 405 + * 406 + * On mprotect change success, return 0. On failure, return -EACESS. 407 + */ 408 + int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) 409 + { 410 + struct ima_template_desc *template; 411 + struct file *file = vma->vm_file; 412 + char filename[NAME_MAX]; 413 + char *pathbuf = NULL; 414 + const char *pathname = NULL; 415 + struct inode *inode; 416 + int result = 0; 417 + int action; 418 + u32 secid; 419 + int pcr; 420 + 421 + /* Is mprotect making an mmap'ed file executable? */ 422 + if (!vma->vm_file || !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC)) 423 + return 0; 424 + 425 + security_task_getsecid(current, &secid); 426 + inode = file_inode(vma->vm_file); 427 + action = ima_get_action(inode, current_cred(), secid, MAY_EXEC, 428 + MMAP_CHECK, &pcr, &template, 0); 429 + 430 + /* Is the mmap'ed file in policy? */ 431 + if (!(action & (IMA_MEASURE | IMA_APPRAISE_SUBMASK))) 432 + return 0; 433 + 434 + if (action & IMA_APPRAISE_SUBMASK) 435 + result = -EPERM; 436 + 437 + file = vma->vm_file; 438 + pathname = ima_d_path(&file->f_path, &pathbuf, filename); 439 + integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, pathname, 440 + "collect_data", "failed-mprotect", result, 0); 441 + if (pathbuf) 442 + __putname(pathbuf); 443 + 444 + return result; 445 + } 446 + 447 + /** 397 448 * ima_bprm_check - based on policy, collect/store measurement. 398 449 * @bprm: contains the linux_binprm structure 399 450 * ··· 842 791 hash_setup(CONFIG_IMA_DEFAULT_HASH); 843 792 error = ima_init(); 844 793 } 794 + 795 + if (error) 796 + return error; 845 797 846 798 error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier); 847 799 if (error)
+7 -5
security/integrity/ima/ima_policy.c
··· 204 204 static LIST_HEAD(ima_default_rules); 205 205 static LIST_HEAD(ima_policy_rules); 206 206 static LIST_HEAD(ima_temp_rules); 207 - static struct list_head *ima_rules; 207 + static struct list_head *ima_rules = &ima_default_rules; 208 208 209 209 /* Pre-allocated buffer used for matching keyrings. */ 210 210 static char *ima_keyrings; ··· 644 644 list_add_tail(&entry->list, &ima_policy_rules); 645 645 } 646 646 if (entries[i].action == APPRAISE) { 647 - temp_ima_appraise |= ima_appraise_flag(entries[i].func); 648 - if (entries[i].func == POLICY_CHECK) 649 - temp_ima_appraise |= IMA_APPRAISE_POLICY; 647 + if (entries != build_appraise_rules) 648 + temp_ima_appraise |= 649 + ima_appraise_flag(entries[i].func); 650 + else 651 + build_ima_appraise |= 652 + ima_appraise_flag(entries[i].func); 650 653 } 651 654 } 652 655 } ··· 768 765 ARRAY_SIZE(default_appraise_rules), 769 766 IMA_DEFAULT_POLICY); 770 767 771 - ima_rules = &ima_default_rules; 772 768 ima_update_policy_flag(); 773 769 } 774 770
+22 -14
security/integrity/ima/ima_queue.c
··· 55 55 key = ima_hash_key(digest_value); 56 56 rcu_read_lock(); 57 57 hlist_for_each_entry_rcu(qe, &ima_htable.queue[key], hnext) { 58 - rc = memcmp(qe->entry->digest, digest_value, TPM_DIGEST_SIZE); 58 + rc = memcmp(qe->entry->digests[ima_hash_algo_idx].digest, 59 + digest_value, hash_digest_size[ima_hash_algo]); 59 60 if ((rc == 0) && (qe->entry->pcr == pcr)) { 60 61 ret = qe; 61 62 break; ··· 76 75 int size = 0; 77 76 78 77 size += sizeof(u32); /* pcr */ 79 - size += sizeof(entry->digest); 78 + size += TPM_DIGEST_SIZE; 80 79 size += sizeof(int); /* template name size field */ 81 80 size += strlen(entry->template_desc->name); 82 81 size += sizeof(entry->template_data_len); ··· 108 107 109 108 atomic_long_inc(&ima_htable.len); 110 109 if (update_htable) { 111 - key = ima_hash_key(entry->digest); 110 + key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest); 112 111 hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]); 113 112 } 114 113 ··· 135 134 return binary_runtime_size + sizeof(struct ima_kexec_hdr); 136 135 }; 137 136 138 - static int ima_pcr_extend(const u8 *hash, int pcr) 137 + static int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr) 139 138 { 140 139 int result = 0; 141 - int i; 142 140 143 141 if (!ima_tpm_chip) 144 142 return result; 145 143 146 - for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) 147 - memcpy(digests[i].digest, hash, TPM_DIGEST_SIZE); 148 - 149 - result = tpm_pcr_extend(ima_tpm_chip, pcr, digests); 144 + result = tpm_pcr_extend(ima_tpm_chip, pcr, digests_arg); 150 145 if (result != 0) 151 146 pr_err("Error Communicating to TPM chip, result: %d\n", result); 152 147 return result; ··· 160 163 const char *op, struct inode *inode, 161 164 const unsigned char *filename) 162 165 { 163 - u8 digest[TPM_DIGEST_SIZE]; 166 + u8 *digest = entry->digests[ima_hash_algo_idx].digest; 167 + struct tpm_digest *digests_arg = entry->digests; 164 168 const char *audit_cause = "hash_added"; 165 169 char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX]; 166 170 int audit_info = 1; ··· 169 171 170 172 mutex_lock(&ima_extend_list_mutex); 171 173 if (!violation) { 172 - memcpy(digest, entry->digest, sizeof(digest)); 173 174 if (ima_lookup_digest_entry(digest, entry->pcr)) { 174 175 audit_cause = "hash_exists"; 175 176 result = -EEXIST; ··· 184 187 } 185 188 186 189 if (violation) /* invalidate pcr */ 187 - memset(digest, 0xff, sizeof(digest)); 190 + digests_arg = digests; 188 191 189 - tpmresult = ima_pcr_extend(digest, entry->pcr); 192 + tpmresult = ima_pcr_extend(digests_arg, entry->pcr); 190 193 if (tpmresult != 0) { 191 194 snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)", 192 195 tpmresult); ··· 212 215 213 216 int __init ima_init_digests(void) 214 217 { 218 + u16 digest_size; 219 + u16 crypto_id; 215 220 int i; 216 221 217 222 if (!ima_tpm_chip) ··· 224 225 if (!digests) 225 226 return -ENOMEM; 226 227 227 - for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) 228 + for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) { 228 229 digests[i].alg_id = ima_tpm_chip->allocated_banks[i].alg_id; 230 + digest_size = ima_tpm_chip->allocated_banks[i].digest_size; 231 + crypto_id = ima_tpm_chip->allocated_banks[i].crypto_id; 232 + 233 + /* for unmapped TPM algorithms digest is still a padded SHA1 */ 234 + if (crypto_id == HASH_ALGO__LAST) 235 + digest_size = SHA1_DIGEST_SIZE; 236 + 237 + memset(digests[i].digest, 0xff, digest_size); 238 + } 229 239 230 240 return 0; 231 241 }
+23 -2
security/integrity/ima/ima_template.c
··· 301 301 int template_data_size, 302 302 struct ima_template_entry **entry) 303 303 { 304 + struct tpm_digest *digests; 304 305 int ret = 0; 305 306 int i; 306 307 ··· 310 309 if (!*entry) 311 310 return -ENOMEM; 312 311 312 + digests = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots, 313 + sizeof(*digests), GFP_NOFS); 314 + if (!digests) { 315 + kfree(*entry); 316 + return -ENOMEM; 317 + } 318 + 319 + (*entry)->digests = digests; 320 + 313 321 ret = ima_parse_buf(template_data, template_data + template_data_size, 314 322 NULL, template_desc->num_fields, 315 323 (*entry)->template_data, NULL, NULL, 316 324 ENFORCE_FIELDS | ENFORCE_BUFEND, "template data"); 317 325 if (ret < 0) { 326 + kfree((*entry)->digests); 318 327 kfree(*entry); 319 328 return ret; 320 329 } ··· 357 346 int ima_restore_measurement_list(loff_t size, void *buf) 358 347 { 359 348 char template_name[MAX_TEMPLATE_NAME_LEN]; 349 + unsigned char zero[TPM_DIGEST_SIZE] = { 0 }; 360 350 361 351 struct ima_kexec_hdr *khdr = buf; 362 352 struct ima_field_data hdr[HDR__LAST] = { ··· 457 445 if (ret < 0) 458 446 break; 459 447 460 - memcpy(entry->digest, hdr[HDR_DIGEST].data, 461 - hdr[HDR_DIGEST].len); 448 + if (memcmp(hdr[HDR_DIGEST].data, zero, sizeof(zero))) { 449 + ret = ima_calc_field_array_hash( 450 + &entry->template_data[0], 451 + entry); 452 + if (ret < 0) { 453 + pr_err("cannot calculate template digest\n"); 454 + ret = -EINVAL; 455 + break; 456 + } 457 + } 458 + 462 459 entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR].data) : 463 460 le32_to_cpu(*(hdr[HDR_PCR].data)); 464 461 ret = ima_restore_measurement_entry(entry);
+18
security/integrity/ima/ima_template_lib.c
··· 286 286 goto out; 287 287 } 288 288 289 + if ((const char *)event_data->filename == boot_aggregate_name) { 290 + if (ima_tpm_chip) { 291 + hash.hdr.algo = HASH_ALGO_SHA1; 292 + result = ima_calc_boot_aggregate(&hash.hdr); 293 + 294 + /* algo can change depending on available PCR banks */ 295 + if (!result && hash.hdr.algo != HASH_ALGO_SHA1) 296 + result = -EINVAL; 297 + 298 + if (result < 0) 299 + memset(&hash, 0, sizeof(hash)); 300 + } 301 + 302 + cur_digest = hash.hdr.digest; 303 + cur_digestsize = hash_digest_size[HASH_ALGO_SHA1]; 304 + goto out; 305 + } 306 + 289 307 if (!event_data->file) /* missing info to re-calculate the digest */ 290 308 return -EINVAL; 291 309
+6 -1
security/security.c
··· 1517 1517 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, 1518 1518 unsigned long prot) 1519 1519 { 1520 - return call_int_hook(file_mprotect, 0, vma, reqprot, prot); 1520 + int ret; 1521 + 1522 + ret = call_int_hook(file_mprotect, 0, vma, reqprot, prot); 1523 + if (ret) 1524 + return ret; 1525 + return ima_file_mprotect(vma, prot); 1521 1526 } 1522 1527 1523 1528 int security_file_lock(struct file *file, unsigned int cmd)