File Index
Files and directories
Sign in
FILE

ima_iint.c

File preview with syntax highlighting.

linux-6.19.14/security/integrity/ima/ima_iint.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) 2008 IBM Corporation
  4 *
  5 * Authors:
  6 * Mimi Zohar <zohar@us.ibm.com>
  7 *
  8 * File: ima_iint.c
  9 *	- implements the IMA hook: ima_inode_free
 10 *	- cache integrity information in the inode security blob
 11 */
 12#include <linux/slab.h>
 13
 14#include "ima.h"
 15
 16static struct kmem_cache *ima_iint_cache __ro_after_init;
 17
 18/**
 19 * ima_iint_find - Return the iint associated with an inode
 20 * @inode: Pointer to the inode
 21 *
 22 * Return the IMA integrity information (iint) associated with an inode, if the
 23 * inode was processed by IMA.
 24 *
 25 * Return: Found iint or NULL.
 26 */
 27struct ima_iint_cache *ima_iint_find(struct inode *inode)
 28{
 29	if (!IS_IMA(inode))
 30		return NULL;
 31
 32	return ima_inode_get_iint(inode);
 33}
 34
 35#define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH + 1)
 36
 37/*
 38 * It is not clear that IMA should be nested at all, but as long is it measures
 39 * files both on overlayfs and on underlying fs, we need to annotate the iint
 40 * mutex to avoid lockdep false positives related to IMA + overlayfs.
 41 * See ovl_lockdep_annotate_inode_mutex_key() for more details.
 42 */
 43static inline void ima_iint_lockdep_annotate(struct ima_iint_cache *iint,
 44					     struct inode *inode)
 45{
 46#ifdef CONFIG_LOCKDEP
 47	static struct lock_class_key ima_iint_mutex_key[IMA_MAX_NESTING];
 48
 49	int depth = inode->i_sb->s_stack_depth;
 50
 51	if (WARN_ON_ONCE(depth < 0 || depth >= IMA_MAX_NESTING))
 52		depth = 0;
 53
 54	lockdep_set_class(&iint->mutex, &ima_iint_mutex_key[depth]);
 55#endif
 56}
 57
 58static void ima_iint_init_always(struct ima_iint_cache *iint,
 59				 struct inode *inode)
 60{
 61	iint->ima_hash = NULL;
 62	iint->real_inode.version = 0;
 63	iint->flags = 0UL;
 64	iint->atomic_flags = 0UL;
 65	iint->ima_file_status = INTEGRITY_UNKNOWN;
 66	iint->ima_mmap_status = INTEGRITY_UNKNOWN;
 67	iint->ima_bprm_status = INTEGRITY_UNKNOWN;
 68	iint->ima_read_status = INTEGRITY_UNKNOWN;
 69	iint->ima_creds_status = INTEGRITY_UNKNOWN;
 70	iint->measured_pcrs = 0;
 71	mutex_init(&iint->mutex);
 72	ima_iint_lockdep_annotate(iint, inode);
 73}
 74
 75static void ima_iint_free(struct ima_iint_cache *iint)
 76{
 77	kfree(iint->ima_hash);
 78	mutex_destroy(&iint->mutex);
 79	kmem_cache_free(ima_iint_cache, iint);
 80}
 81
 82/**
 83 * ima_inode_get - Find or allocate an iint associated with an inode
 84 * @inode: Pointer to the inode
 85 *
 86 * Find an iint associated with an inode, and allocate a new one if not found.
 87 * Caller must lock i_mutex.
 88 *
 89 * Return: An iint on success, NULL on error.
 90 */
 91struct ima_iint_cache *ima_inode_get(struct inode *inode)
 92{
 93	struct ima_iint_cache *iint;
 94
 95	iint = ima_iint_find(inode);
 96	if (iint)
 97		return iint;
 98
 99	iint = kmem_cache_alloc(ima_iint_cache, GFP_NOFS);
100	if (!iint)
101		return NULL;
102
103	ima_iint_init_always(iint, inode);
104
105	inode->i_flags |= S_IMA;
106	ima_inode_set_iint(inode, iint);
107
108	return iint;
109}
110
111/**
112 * ima_inode_free_rcu - Called to free an inode via a RCU callback
113 * @inode_security: The inode->i_security pointer
114 *
115 * Free the IMA data associated with an inode.
116 */
117void ima_inode_free_rcu(void *inode_security)
118{
119	struct ima_iint_cache **iint_p = inode_security + ima_blob_sizes.lbs_inode;
120
121	/* *iint_p should be NULL if !IS_IMA(inode) */
122	if (*iint_p)
123		ima_iint_free(*iint_p);
124}
125
126static void ima_iint_init_once(void *foo)
127{
128	struct ima_iint_cache *iint = (struct ima_iint_cache *)foo;
129
130	memset(iint, 0, sizeof(*iint));
131}
132
133void __init ima_iintcache_init(void)
134{
135	ima_iint_cache =
136	    kmem_cache_create("ima_iint_cache", sizeof(struct ima_iint_cache),
137			      0, SLAB_PANIC, ima_iint_init_once);
138}
~/ Read-only file preview.