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 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull IMA fixes from James Morris:
"These three patches fix regressions in the IMA code in your current
tree.

The first fixes a couple of bugs in template_desc_init_fields(), and
the other two ensure that changes in this kernel don't break
userspace"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
ima: make a copy of template_fmt in template_desc_init_fields()
ima: do not send field length to userspace for digest of ima template
ima: do not include field length in template digest calc for ima template

+47 -18
+4 -2
security/integrity/ima/ima.h
··· 26 26 27 27 #include "../integrity.h" 28 28 29 - enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; 29 + enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN, 30 + IMA_SHOW_ASCII }; 30 31 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; 31 32 32 33 /* digest size for IMA, fits SHA1 or MD5 */ ··· 98 97 const char *op, struct inode *inode, 99 98 const unsigned char *filename); 100 99 int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); 101 - int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields, 100 + int ima_calc_field_array_hash(struct ima_field_data *field_data, 101 + struct ima_template_desc *desc, int num_fields, 102 102 struct ima_digest_data *hash); 103 103 int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); 104 104 void ima_add_violation(struct file *file, const unsigned char *filename,
+1
security/integrity/ima/ima_api.c
··· 94 94 /* this function uses default algo */ 95 95 hash.hdr.algo = HASH_ALGO_SHA1; 96 96 result = ima_calc_field_array_hash(&entry->template_data[0], 97 + entry->template_desc, 97 98 num_fields, &hash.hdr); 98 99 if (result < 0) { 99 100 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
+12 -5
security/integrity/ima/ima_crypto.c
··· 140 140 * Calculate the hash of template data 141 141 */ 142 142 static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data, 143 + struct ima_template_desc *td, 143 144 int num_fields, 144 145 struct ima_digest_data *hash, 145 146 struct crypto_shash *tfm) ··· 161 160 return rc; 162 161 163 162 for (i = 0; i < num_fields; i++) { 164 - rc = crypto_shash_update(&desc.shash, 165 - (const u8 *) &field_data[i].len, 166 - sizeof(field_data[i].len)); 163 + if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) { 164 + rc = crypto_shash_update(&desc.shash, 165 + (const u8 *) &field_data[i].len, 166 + sizeof(field_data[i].len)); 167 + if (rc) 168 + break; 169 + } 167 170 rc = crypto_shash_update(&desc.shash, field_data[i].data, 168 171 field_data[i].len); 169 172 if (rc) ··· 180 175 return rc; 181 176 } 182 177 183 - int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields, 178 + int ima_calc_field_array_hash(struct ima_field_data *field_data, 179 + struct ima_template_desc *desc, int num_fields, 184 180 struct ima_digest_data *hash) 185 181 { 186 182 struct crypto_shash *tfm; ··· 191 185 if (IS_ERR(tfm)) 192 186 return PTR_ERR(tfm); 193 187 194 - rc = ima_calc_field_array_hash_tfm(field_data, num_fields, hash, tfm); 188 + rc = ima_calc_field_array_hash_tfm(field_data, desc, num_fields, 189 + hash, tfm); 195 190 196 191 ima_free_tfm(tfm); 197 192
+11 -3
security/integrity/ima/ima_fs.c
··· 120 120 struct ima_template_entry *e; 121 121 int namelen; 122 122 u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX; 123 + bool is_ima_template = false; 123 124 int i; 124 125 125 126 /* get entry */ ··· 146 145 ima_putc(m, e->template_desc->name, namelen); 147 146 148 147 /* 5th: template length (except for 'ima' template) */ 149 - if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) 148 + if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) 149 + is_ima_template = true; 150 + 151 + if (!is_ima_template) 150 152 ima_putc(m, &e->template_data_len, 151 153 sizeof(e->template_data_len)); 152 154 153 155 /* 6th: template specific data */ 154 156 for (i = 0; i < e->template_desc->num_fields; i++) { 155 - e->template_desc->fields[i]->field_show(m, IMA_SHOW_BINARY, 156 - &e->template_data[i]); 157 + enum ima_show_type show = IMA_SHOW_BINARY; 158 + struct ima_template_field *field = e->template_desc->fields[i]; 159 + 160 + if (is_ima_template && strcmp(field->field_id, "d") == 0) 161 + show = IMA_SHOW_BINARY_NO_FIELD_LEN; 162 + field->field_show(m, show, &e->template_data[i]); 157 163 } 158 164 return 0; 159 165 }
+14 -7
security/integrity/ima/ima_template.c
··· 90 90 return NULL; 91 91 } 92 92 93 - static int template_fmt_size(char *template_fmt) 93 + static int template_fmt_size(const char *template_fmt) 94 94 { 95 95 char c; 96 96 int template_fmt_len = strlen(template_fmt); ··· 106 106 return j + 1; 107 107 } 108 108 109 - static int template_desc_init_fields(char *template_fmt, 109 + static int template_desc_init_fields(const char *template_fmt, 110 110 struct ima_template_field ***fields, 111 111 int *num_fields) 112 112 { 113 - char *c, *template_fmt_ptr = template_fmt; 113 + char *c, *template_fmt_copy; 114 114 int template_num_fields = template_fmt_size(template_fmt); 115 115 int i, result = 0; 116 116 117 117 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) 118 118 return -EINVAL; 119 119 120 + /* copying is needed as strsep() modifies the original buffer */ 121 + template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL); 122 + if (template_fmt_copy == NULL) 123 + return -ENOMEM; 124 + 120 125 *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL); 121 126 if (*fields == NULL) { 122 127 result = -ENOMEM; 123 128 goto out; 124 129 } 125 - for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && 130 + for (i = 0; (c = strsep(&template_fmt_copy, "|")) != NULL && 126 131 i < template_num_fields; i++) { 127 132 struct ima_template_field *f = lookup_template_field(c); 128 133 ··· 138 133 (*fields)[i] = f; 139 134 } 140 135 *num_fields = i; 141 - return 0; 142 136 out: 143 - kfree(*fields); 144 - *fields = NULL; 137 + if (result < 0) { 138 + kfree(*fields); 139 + *fields = NULL; 140 + } 141 + kfree(template_fmt_copy); 145 142 return result; 146 143 } 147 144
+5 -1
security/integrity/ima/ima_template_lib.c
··· 109 109 enum data_formats datafmt, 110 110 struct ima_field_data *field_data) 111 111 { 112 - ima_putc(m, &field_data->len, sizeof(u32)); 112 + if (show != IMA_SHOW_BINARY_NO_FIELD_LEN) 113 + ima_putc(m, &field_data->len, sizeof(u32)); 114 + 113 115 if (!field_data->len) 114 116 return; 117 + 115 118 ima_putc(m, field_data->data, field_data->len); 116 119 } 117 120 ··· 128 125 ima_show_template_data_ascii(m, show, datafmt, field_data); 129 126 break; 130 127 case IMA_SHOW_BINARY: 128 + case IMA_SHOW_BINARY_NO_FIELD_LEN: 131 129 ima_show_template_data_binary(m, show, datafmt, field_data); 132 130 break; 133 131 default: