aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-12-04 15:48:00 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-16 12:16:46 -0500
commite0d5bd2aec4e69e720ee86958503923cafb45be5 (patch)
tree07ad4c96ad5c680f8a6b1f8152269af23944dc5d /security/integrity
parent9353384ec8128cb443463016bbabb44ca857ff52 (diff)
IMA: clean up the IMA counts updating code
We currently have a lot of duplicated code around ima file counts. Clean that all up. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/ima/ima.h1
-rw-r--r--security/integrity/ima/ima_main.c118
2 files changed, 70 insertions, 49 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 349aabc83297..268ef57b9142 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -97,7 +97,6 @@ static inline unsigned long ima_hash_key(u8 *digest)
97 97
98/* iint cache flags */ 98/* iint cache flags */
99#define IMA_MEASURED 1 99#define IMA_MEASURED 1
100#define IMA_IINT_DUMP_STACK 512
101 100
102/* integrity data associated with an inode */ 101/* integrity data associated with an inode */
103struct ima_iint_cache { 102struct ima_iint_cache {
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 96fafc01e2c7..e041233b4d2a 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -13,8 +13,8 @@
13 * License. 13 * License.
14 * 14 *
15 * File: ima_main.c 15 * File: ima_main.c
16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap, 16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
17 * and ima_path_check. 17 * and ima_path_check.
18 */ 18 */
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/file.h> 20#include <linux/file.h>
@@ -35,6 +35,69 @@ static int __init hash_setup(char *str)
35} 35}
36__setup("ima_hash=", hash_setup); 36__setup("ima_hash=", hash_setup);
37 37
38/*
39 * Update the counts given an fmode_t
40 */
41static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
42{
43 BUG_ON(!mutex_is_locked(&iint->mutex));
44
45 iint->opencount++;
46 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
47 iint->readcount++;
48 if (mode & FMODE_WRITE)
49 iint->writecount++;
50}
51
52/*
53 * Update the counts given open flags instead of fmode
54 */
55static void ima_inc_counts_flags(struct ima_iint_cache *iint, int flags)
56{
57 ima_inc_counts(iint, (__force fmode_t)((flags+1) & O_ACCMODE));
58}
59
60/*
61 * Decrement ima counts
62 */
63static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
64 fmode_t mode)
65{
66 BUG_ON(!mutex_is_locked(&iint->mutex));
67
68 iint->opencount--;
69 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
70 iint->readcount--;
71 if (mode & FMODE_WRITE) {
72 iint->writecount--;
73 if (iint->writecount == 0) {
74 if (iint->version != inode->i_version)
75 iint->flags &= ~IMA_MEASURED;
76 }
77 }
78
79 if ((iint->opencount < 0) ||
80 (iint->readcount < 0) ||
81 (iint->writecount < 0)) {
82 static int dumped;
83
84 if (dumped)
85 return;
86 dumped = 1;
87
88 printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n",
89 __FUNCTION__, iint->readcount, iint->writecount,
90 iint->opencount);
91 dump_stack();
92 }
93}
94
95static void ima_dec_counts_flags(struct ima_iint_cache *iint,
96 struct inode *inode, int flags)
97{
98 ima_dec_counts(iint, inode, (__force fmode_t)((flags+1) & O_ACCMODE));
99}
100
38/** 101/**
39 * ima_file_free - called on __fput() 102 * ima_file_free - called on __fput()
40 * @file: pointer to file structure being freed 103 * @file: pointer to file structure being freed
@@ -54,29 +117,7 @@ void ima_file_free(struct file *file)
54 return; 117 return;
55 118
56 mutex_lock(&iint->mutex); 119 mutex_lock(&iint->mutex);
57 if (iint->opencount <= 0) { 120 ima_dec_counts(iint, inode, file->f_mode);
58 printk(KERN_INFO
59 "%s: %s open/free imbalance (r:%ld w:%ld o:%ld f:%ld)\n",
60 __FUNCTION__, file->f_dentry->d_name.name,
61 iint->readcount, iint->writecount,
62 iint->opencount, atomic_long_read(&file->f_count));
63 if (!(iint->flags & IMA_IINT_DUMP_STACK)) {
64 dump_stack();
65 iint->flags |= IMA_IINT_DUMP_STACK;
66 }
67 }
68 iint->opencount--;
69
70 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
71 iint->readcount--;
72
73 if (file->f_mode & FMODE_WRITE) {
74 iint->writecount--;
75 if (iint->writecount == 0) {
76 if (iint->version != inode->i_version)
77 iint->flags &= ~IMA_MEASURED;
78 }
79 }
80 mutex_unlock(&iint->mutex); 121 mutex_unlock(&iint->mutex);
81 kref_put(&iint->refcount, iint_free); 122 kref_put(&iint->refcount, iint_free);
82} 123}
@@ -116,8 +157,7 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
116{ 157{
117 int rc = 0; 158 int rc = 0;
118 159
119 iint->opencount++; 160 ima_inc_counts(iint, file->f_mode);
120 iint->readcount++;
121 161
122 rc = ima_collect_measurement(iint, file); 162 rc = ima_collect_measurement(iint, file);
123 if (!rc) 163 if (!rc)
@@ -125,15 +165,6 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
125 return rc; 165 return rc;
126} 166}
127 167
128static void ima_update_counts(struct ima_iint_cache *iint, int mask)
129{
130 iint->opencount++;
131 if ((mask & MAY_WRITE) || (mask == 0))
132 iint->writecount++;
133 else if (mask & (MAY_READ | MAY_EXEC))
134 iint->readcount++;
135}
136
137/** 168/**
138 * ima_path_check - based on policy, collect/store measurement. 169 * ima_path_check - based on policy, collect/store measurement.
139 * @path: contains a pointer to the path to be measured 170 * @path: contains a pointer to the path to be measured
@@ -167,7 +198,7 @@ int ima_path_check(struct path *path, int mask, int update_counts)
167 198
168 mutex_lock(&iint->mutex); 199 mutex_lock(&iint->mutex);
169 if (update_counts) 200 if (update_counts)
170 ima_update_counts(iint, mask); 201 ima_inc_counts_flags(iint, mask);
171 202
172 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK); 203 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
173 if (rc < 0) 204 if (rc < 0)
@@ -260,11 +291,7 @@ void ima_counts_put(struct path *path, int mask)
260 return; 291 return;
261 292
262 mutex_lock(&iint->mutex); 293 mutex_lock(&iint->mutex);
263 iint->opencount--; 294 ima_dec_counts_flags(iint, inode, mask);
264 if ((mask & MAY_WRITE) || (mask == 0))
265 iint->writecount--;
266 else if (mask & (MAY_READ | MAY_EXEC))
267 iint->readcount--;
268 mutex_unlock(&iint->mutex); 295 mutex_unlock(&iint->mutex);
269 296
270 kref_put(&iint->refcount, iint_free); 297 kref_put(&iint->refcount, iint_free);
@@ -290,12 +317,7 @@ void ima_counts_get(struct file *file)
290 if (!iint) 317 if (!iint)
291 return; 318 return;
292 mutex_lock(&iint->mutex); 319 mutex_lock(&iint->mutex);
293 iint->opencount++; 320 ima_inc_counts(iint, file->f_mode);
294 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
295 iint->readcount++;
296
297 if (file->f_mode & FMODE_WRITE)
298 iint->writecount++;
299 mutex_unlock(&iint->mutex); 321 mutex_unlock(&iint->mutex);
300 322
301 kref_put(&iint->refcount, iint_free); 323 kref_put(&iint->refcount, iint_free);