aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima.h4
-rw-r--r--security/integrity/ima/ima_iint.c38
-rw-r--r--security/integrity/ima/ima_main.c7
3 files changed, 19 insertions, 30 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 27849e1656dc..ac79032bdf23 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -107,7 +107,6 @@ struct ima_iint_cache {
107 unsigned char flags; 107 unsigned char flags;
108 u8 digest[IMA_DIGEST_SIZE]; 108 u8 digest[IMA_DIGEST_SIZE];
109 struct mutex mutex; /* protects: version, flags, digest */ 109 struct mutex mutex; /* protects: version, flags, digest */
110 struct kref refcount; /* ima_iint_cache reference count */
111}; 110};
112 111
113/* LIM API function definitions */ 112/* LIM API function definitions */
@@ -125,8 +124,7 @@ void ima_template_show(struct seq_file *m, void *e,
125 * integrity data associated with an inode. 124 * integrity data associated with an inode.
126 */ 125 */
127struct ima_iint_cache *ima_iint_insert(struct inode *inode); 126struct ima_iint_cache *ima_iint_insert(struct inode *inode);
128struct ima_iint_cache *ima_iint_find_get(struct inode *inode); 127struct ima_iint_cache *ima_iint_find(struct inode *inode);
129void iint_free(struct kref *kref);
130 128
131/* IMA policy related functions */ 129/* IMA policy related functions */
132enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; 130enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index 0936a7197e47..969a1c1cb333 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -53,24 +53,26 @@ static struct ima_iint_cache *__ima_iint_find(struct inode *inode)
53} 53}
54 54
55/* 55/*
56 * ima_iint_find_get - return the iint associated with an inode 56 * ima_iint_find - return the iint associated with an inode
57 *
58 * ima_iint_find_get gets a reference to the iint. Caller must
59 * remember to put the iint reference.
60 */ 57 */
61struct ima_iint_cache *ima_iint_find_get(struct inode *inode) 58struct ima_iint_cache *ima_iint_find(struct inode *inode)
62{ 59{
63 struct ima_iint_cache *iint; 60 struct ima_iint_cache *iint;
64 61
65 spin_lock(&ima_iint_lock); 62 spin_lock(&ima_iint_lock);
66 iint = __ima_iint_find(inode); 63 iint = __ima_iint_find(inode);
67 if (iint)
68 kref_get(&iint->refcount);
69 spin_unlock(&ima_iint_lock); 64 spin_unlock(&ima_iint_lock);
70 65
71 return iint; 66 return iint;
72} 67}
73 68
69static void iint_free(struct ima_iint_cache *iint)
70{
71 iint->version = 0;
72 iint->flags = 0UL;
73 kmem_cache_free(iint_cache, iint);
74}
75
74/** 76/**
75 * ima_inode_alloc - allocate an iint associated with an inode 77 * ima_inode_alloc - allocate an iint associated with an inode
76 * @inode: pointer to the inode 78 * @inode: pointer to the inode
@@ -113,19 +115,9 @@ int ima_inode_alloc(struct inode *inode)
113 return 0; 115 return 0;
114out_err: 116out_err:
115 spin_unlock(&ima_iint_lock); 117 spin_unlock(&ima_iint_lock);
116 kref_put(&new_iint->refcount, iint_free); 118 iint_free(new_iint);
117 return rc;
118}
119 119
120/* iint_free - called when the iint refcount goes to zero */ 120 return rc;
121void iint_free(struct kref *kref)
122{
123 struct ima_iint_cache *iint = container_of(kref, struct ima_iint_cache,
124 refcount);
125 iint->version = 0;
126 iint->flags = 0UL;
127 kref_init(&iint->refcount);
128 kmem_cache_free(iint_cache, iint);
129} 121}
130 122
131/** 123/**
@@ -148,8 +140,11 @@ void ima_inode_free(struct inode *inode)
148 if (iint) 140 if (iint)
149 rb_erase(&iint->rb_node, &ima_iint_tree); 141 rb_erase(&iint->rb_node, &ima_iint_tree);
150 spin_unlock(&ima_iint_lock); 142 spin_unlock(&ima_iint_lock);
151 if (iint) 143
152 kref_put(&iint->refcount, iint_free); 144 if (!iint)
145 return;
146
147 iint_free(iint);
153} 148}
154 149
155static void init_once(void *foo) 150static void init_once(void *foo)
@@ -160,7 +155,6 @@ static void init_once(void *foo)
160 iint->version = 0; 155 iint->version = 0;
161 iint->flags = 0UL; 156 iint->flags = 0UL;
162 mutex_init(&iint->mutex); 157 mutex_init(&iint->mutex);
163 kref_init(&iint->refcount);
164} 158}
165 159
166static int __init ima_iintcache_init(void) 160static int __init ima_iintcache_init(void)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 5e3229c797fc..1dccafef7494 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -186,8 +186,6 @@ static void ima_file_free_iint(struct ima_iint_cache *iint, struct inode *inode,
186 186
187 spin_unlock(&inode->i_lock); 187 spin_unlock(&inode->i_lock);
188 mutex_unlock(&iint->mutex); 188 mutex_unlock(&iint->mutex);
189
190 kref_put(&iint->refcount, iint_free);
191} 189}
192 190
193static void ima_file_free_noiint(struct inode *inode, struct file *file) 191static void ima_file_free_noiint(struct inode *inode, struct file *file)
@@ -213,7 +211,7 @@ void ima_file_free(struct file *file)
213 211
214 if (!iint_initialized || !S_ISREG(inode->i_mode)) 212 if (!iint_initialized || !S_ISREG(inode->i_mode))
215 return; 213 return;
216 iint = ima_iint_find_get(inode); 214 iint = ima_iint_find(inode);
217 215
218 if (iint) 216 if (iint)
219 ima_file_free_iint(iint, inode, file); 217 ima_file_free_iint(iint, inode, file);
@@ -236,7 +234,7 @@ static int process_measurement(struct file *file, const unsigned char *filename,
236 if (rc != 0) 234 if (rc != 0)
237 return rc; 235 return rc;
238retry: 236retry:
239 iint = ima_iint_find_get(inode); 237 iint = ima_iint_find(inode);
240 if (!iint) { 238 if (!iint) {
241 rc = ima_inode_alloc(inode); 239 rc = ima_inode_alloc(inode);
242 if (!rc || rc == -EEXIST) 240 if (!rc || rc == -EEXIST)
@@ -255,7 +253,6 @@ retry:
255 ima_store_measurement(iint, file, filename); 253 ima_store_measurement(iint, file, filename);
256out: 254out:
257 mutex_unlock(&iint->mutex); 255 mutex_unlock(&iint->mutex);
258 kref_put(&iint->refcount, iint_free);
259 return rc; 256 return rc;
260} 257}
261 258