ima_api.c (0ea5c948cb64bab5bc7a5516774eb8536f05aa0d) | ima_api.c (4de2f084fbff41113d9adec3c9e15ab12bf05e21) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2008 IBM Corporation 4 * 5 * Author: Mimi Zohar <zohar@us.ibm.com> 6 * 7 * File: ima_api.c 8 * Implements must_appraise_or_measure, collect_measurement, --- 117 unchanged lines hidden (view full) --- 126/* 127 * ima_add_violation - add violation to measurement list. 128 * 129 * Violations are flagged in the measurement list with zero hash values. 130 * By extending the PCR with 0xFF's instead of with zeroes, the PCR 131 * value is invalidated. 132 */ 133void ima_add_violation(struct file *file, const unsigned char *filename, | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2008 IBM Corporation 4 * 5 * Author: Mimi Zohar <zohar@us.ibm.com> 6 * 7 * File: ima_api.c 8 * Implements must_appraise_or_measure, collect_measurement, --- 117 unchanged lines hidden (view full) --- 126/* 127 * ima_add_violation - add violation to measurement list. 128 * 129 * Violations are flagged in the measurement list with zero hash values. 130 * By extending the PCR with 0xFF's instead of with zeroes, the PCR 131 * value is invalidated. 132 */ 133void ima_add_violation(struct file *file, const unsigned char *filename, |
134 struct integrity_iint_cache *iint, 135 const char *op, const char *cause) | 134 struct ima_iint_cache *iint, const char *op, 135 const char *cause) |
136{ 137 struct ima_template_entry *entry; 138 struct inode *inode = file_inode(file); 139 struct ima_event_data event_data = { .iint = iint, 140 .file = file, 141 .filename = filename, 142 .violation = cause }; 143 int violation = 1; --- 52 unchanged lines hidden (view full) --- 196 197 flags &= ima_policy_flag; 198 199 return ima_match_policy(idmap, inode, cred, secid, func, mask, 200 flags, pcr, template_desc, func_data, 201 allowed_algos); 202} 203 | 136{ 137 struct ima_template_entry *entry; 138 struct inode *inode = file_inode(file); 139 struct ima_event_data event_data = { .iint = iint, 140 .file = file, 141 .filename = filename, 142 .violation = cause }; 143 int violation = 1; --- 52 unchanged lines hidden (view full) --- 196 197 flags &= ima_policy_flag; 198 199 return ima_match_policy(idmap, inode, cred, secid, func, mask, 200 flags, pcr, template_desc, func_data, 201 allowed_algos); 202} 203 |
204static bool ima_get_verity_digest(struct integrity_iint_cache *iint, | 204static bool ima_get_verity_digest(struct ima_iint_cache *iint, 205 struct inode *inode, |
205 struct ima_max_digest_data *hash) 206{ 207 enum hash_algo alg; 208 int digest_len; 209 210 /* 211 * On failure, 'measure' policy rules will result in a file data 212 * hash containing 0's. 213 */ | 206 struct ima_max_digest_data *hash) 207{ 208 enum hash_algo alg; 209 int digest_len; 210 211 /* 212 * On failure, 'measure' policy rules will result in a file data 213 * hash containing 0's. 214 */ |
214 digest_len = fsverity_get_digest(iint->inode, hash->digest, NULL, &alg); | 215 digest_len = fsverity_get_digest(inode, hash->digest, NULL, &alg); |
215 if (digest_len == 0) 216 return false; 217 218 /* 219 * Unlike in the case of actually calculating the file hash, in 220 * the fsverity case regardless of the hash algorithm, return 221 * the verity digest to be included in the measurement list. A 222 * mismatch between the verity algorithm and the xattr signature --- 9 unchanged lines hidden (view full) --- 232 * 233 * Calculate the file hash, if it doesn't already exist, 234 * storing the measurement and i_version in the iint. 235 * 236 * Must be called with iint->mutex held. 237 * 238 * Return 0 on success, error code otherwise 239 */ | 216 if (digest_len == 0) 217 return false; 218 219 /* 220 * Unlike in the case of actually calculating the file hash, in 221 * the fsverity case regardless of the hash algorithm, return 222 * the verity digest to be included in the measurement list. A 223 * mismatch between the verity algorithm and the xattr signature --- 9 unchanged lines hidden (view full) --- 233 * 234 * Calculate the file hash, if it doesn't already exist, 235 * storing the measurement and i_version in the iint. 236 * 237 * Must be called with iint->mutex held. 238 * 239 * Return 0 on success, error code otherwise 240 */ |
240int ima_collect_measurement(struct integrity_iint_cache *iint, 241 struct file *file, void *buf, loff_t size, 242 enum hash_algo algo, struct modsig *modsig) | 241int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file, 242 void *buf, loff_t size, enum hash_algo algo, 243 struct modsig *modsig) |
243{ 244 const char *audit_cause = "failed"; 245 struct inode *inode = file_inode(file); 246 struct inode *real_inode = d_real_inode(file_dentry(file)); 247 const char *filename = file->f_path.dentry->d_name.name; 248 struct ima_max_digest_data hash; 249 struct kstat stat; 250 int result = 0; --- 24 unchanged lines hidden (view full) --- 275 i_version = stat.change_cookie; 276 hash.hdr.algo = algo; 277 hash.hdr.length = hash_digest_size[algo]; 278 279 /* Initialize hash digest to 0's in case of failure */ 280 memset(&hash.digest, 0, sizeof(hash.digest)); 281 282 if (iint->flags & IMA_VERITY_REQUIRED) { | 244{ 245 const char *audit_cause = "failed"; 246 struct inode *inode = file_inode(file); 247 struct inode *real_inode = d_real_inode(file_dentry(file)); 248 const char *filename = file->f_path.dentry->d_name.name; 249 struct ima_max_digest_data hash; 250 struct kstat stat; 251 int result = 0; --- 24 unchanged lines hidden (view full) --- 276 i_version = stat.change_cookie; 277 hash.hdr.algo = algo; 278 hash.hdr.length = hash_digest_size[algo]; 279 280 /* Initialize hash digest to 0's in case of failure */ 281 memset(&hash.digest, 0, sizeof(hash.digest)); 282 283 if (iint->flags & IMA_VERITY_REQUIRED) { |
283 if (!ima_get_verity_digest(iint, &hash)) { | 284 if (!ima_get_verity_digest(iint, inode, &hash)) { |
284 audit_cause = "no-verity-digest"; 285 result = -ENODATA; 286 } 287 } else if (buf) { 288 result = ima_calc_buffer_hash(buf, size, &hash.hdr); 289 } else { 290 result = ima_calc_file_hash(file, &hash.hdr); 291 } --- 41 unchanged lines hidden (view full) --- 333 * but the measurement could already exist: 334 * - multiple copies of the same file on either the same or 335 * different filesystems. 336 * - the inode was previously flushed as well as the iint info, 337 * containing the hashing info. 338 * 339 * Must be called with iint->mutex held. 340 */ | 285 audit_cause = "no-verity-digest"; 286 result = -ENODATA; 287 } 288 } else if (buf) { 289 result = ima_calc_buffer_hash(buf, size, &hash.hdr); 290 } else { 291 result = ima_calc_file_hash(file, &hash.hdr); 292 } --- 41 unchanged lines hidden (view full) --- 334 * but the measurement could already exist: 335 * - multiple copies of the same file on either the same or 336 * different filesystems. 337 * - the inode was previously flushed as well as the iint info, 338 * containing the hashing info. 339 * 340 * Must be called with iint->mutex held. 341 */ |
341void ima_store_measurement(struct integrity_iint_cache *iint, 342 struct file *file, const unsigned char *filename, | 342void ima_store_measurement(struct ima_iint_cache *iint, struct file *file, 343 const unsigned char *filename, |
343 struct evm_ima_xattr_data *xattr_value, 344 int xattr_len, const struct modsig *modsig, int pcr, 345 struct ima_template_desc *template_desc) 346{ 347 static const char op[] = "add_template_measure"; 348 static const char audit_cause[] = "ENOMEM"; 349 int result = -ENOMEM; 350 struct inode *inode = file_inode(file); --- 26 unchanged lines hidden (view full) --- 377 if ((!result || result == -EEXIST) && !(file->f_flags & O_DIRECT)) { 378 iint->flags |= IMA_MEASURED; 379 iint->measured_pcrs |= (0x1 << pcr); 380 } 381 if (result < 0) 382 ima_free_template_entry(entry); 383} 384 | 344 struct evm_ima_xattr_data *xattr_value, 345 int xattr_len, const struct modsig *modsig, int pcr, 346 struct ima_template_desc *template_desc) 347{ 348 static const char op[] = "add_template_measure"; 349 static const char audit_cause[] = "ENOMEM"; 350 int result = -ENOMEM; 351 struct inode *inode = file_inode(file); --- 26 unchanged lines hidden (view full) --- 378 if ((!result || result == -EEXIST) && !(file->f_flags & O_DIRECT)) { 379 iint->flags |= IMA_MEASURED; 380 iint->measured_pcrs |= (0x1 << pcr); 381 } 382 if (result < 0) 383 ima_free_template_entry(entry); 384} 385 |
385void ima_audit_measurement(struct integrity_iint_cache *iint, | 386void ima_audit_measurement(struct ima_iint_cache *iint, |
386 const unsigned char *filename) 387{ 388 struct audit_buffer *ab; 389 char *hash; 390 const char *algo_name = hash_algo_name[iint->ima_hash->algo]; 391 int i; 392 393 if (iint->flags & IMA_AUDITED) --- 59 unchanged lines hidden --- | 387 const unsigned char *filename) 388{ 389 struct audit_buffer *ab; 390 char *hash; 391 const char *algo_name = hash_algo_name[iint->ima_hash->algo]; 392 int i; 393 394 if (iint->flags & IMA_AUDITED) --- 59 unchanged lines hidden --- |