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 ---