~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/integrity/ima/ima_iint.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 
 16 static 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  */
 27 struct 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  */
 43 static 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 
 58 static 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 
 75 static 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  */
 91 struct 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  */
117 void 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 
126 static 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 
133 void __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 }
139 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php