diff options
author | Dmitry Kasatkin <dmitry.kasatkin@intel.com> | 2011-10-19 05:04:40 -0400 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2012-09-07 14:57:45 -0400 |
commit | bf2276d10ce58ff44ab8857266a6718024496af6 (patch) | |
tree | 7be39c026fd30856248f68c964d0f1e2ae703c25 /security | |
parent | 07f6a79415d7d502ee0c7d02ace6594a7be7429a (diff) |
ima: allocating iint improvements
With IMA-appraisal's removal of the iint mutex and taking the i_mutex
instead, allocating the iint becomes a lot simplier, as we don't need
to be concerned with two processes racing to allocate the iint. This
patch cleans up and improves performance for allocating the iint.
- removed redundant double i_mutex locking
- combined iint allocation with tree search
Changelog v2:
- removed the rwlock/read_lock changes from this patch
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Diffstat (limited to 'security')
-rw-r--r-- | security/integrity/iint.c | 45 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 13 |
2 files changed, 23 insertions, 35 deletions
diff --git a/security/integrity/iint.c b/security/integrity/iint.c index e600986aa49f..c91a436e13ac 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c | |||
@@ -80,24 +80,26 @@ static void iint_free(struct integrity_iint_cache *iint) | |||
80 | } | 80 | } |
81 | 81 | ||
82 | /** | 82 | /** |
83 | * integrity_inode_alloc - allocate an iint associated with an inode | 83 | * integrity_inode_get - find or allocate an iint associated with an inode |
84 | * @inode: pointer to the inode | 84 | * @inode: pointer to the inode |
85 | * @return: allocated iint | ||
86 | * | ||
87 | * Caller must lock i_mutex | ||
85 | */ | 88 | */ |
86 | int integrity_inode_alloc(struct inode *inode) | 89 | struct integrity_iint_cache *integrity_inode_get(struct inode *inode) |
87 | { | 90 | { |
88 | struct rb_node **p; | 91 | struct rb_node **p; |
89 | struct rb_node *new_node, *parent = NULL; | 92 | struct rb_node *node, *parent = NULL; |
90 | struct integrity_iint_cache *new_iint, *test_iint; | 93 | struct integrity_iint_cache *iint, *test_iint; |
91 | int rc; | ||
92 | 94 | ||
93 | new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS); | 95 | iint = integrity_iint_find(inode); |
94 | if (!new_iint) | 96 | if (iint) |
95 | return -ENOMEM; | 97 | return iint; |
96 | 98 | ||
97 | new_iint->inode = inode; | 99 | iint = kmem_cache_alloc(iint_cache, GFP_NOFS); |
98 | new_node = &new_iint->rb_node; | 100 | if (!iint) |
101 | return NULL; | ||
99 | 102 | ||
100 | mutex_lock(&inode->i_mutex); /* i_flags */ | ||
101 | spin_lock(&integrity_iint_lock); | 103 | spin_lock(&integrity_iint_lock); |
102 | 104 | ||
103 | p = &integrity_iint_tree.rb_node; | 105 | p = &integrity_iint_tree.rb_node; |
@@ -105,29 +107,20 @@ int integrity_inode_alloc(struct inode *inode) | |||
105 | parent = *p; | 107 | parent = *p; |
106 | test_iint = rb_entry(parent, struct integrity_iint_cache, | 108 | test_iint = rb_entry(parent, struct integrity_iint_cache, |
107 | rb_node); | 109 | rb_node); |
108 | rc = -EEXIST; | ||
109 | if (inode < test_iint->inode) | 110 | if (inode < test_iint->inode) |
110 | p = &(*p)->rb_left; | 111 | p = &(*p)->rb_left; |
111 | else if (inode > test_iint->inode) | ||
112 | p = &(*p)->rb_right; | ||
113 | else | 112 | else |
114 | goto out_err; | 113 | p = &(*p)->rb_right; |
115 | } | 114 | } |
116 | 115 | ||
116 | iint->inode = inode; | ||
117 | node = &iint->rb_node; | ||
117 | inode->i_flags |= S_IMA; | 118 | inode->i_flags |= S_IMA; |
118 | rb_link_node(new_node, parent, p); | 119 | rb_link_node(node, parent, p); |
119 | rb_insert_color(new_node, &integrity_iint_tree); | 120 | rb_insert_color(node, &integrity_iint_tree); |
120 | 121 | ||
121 | spin_unlock(&integrity_iint_lock); | 122 | spin_unlock(&integrity_iint_lock); |
122 | mutex_unlock(&inode->i_mutex); /* i_flags */ | 123 | return iint; |
123 | |||
124 | return 0; | ||
125 | out_err: | ||
126 | spin_unlock(&integrity_iint_lock); | ||
127 | mutex_unlock(&inode->i_mutex); /* i_flags */ | ||
128 | iint_free(new_iint); | ||
129 | |||
130 | return rc; | ||
131 | } | 124 | } |
132 | 125 | ||
133 | /** | 126 | /** |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 6eb28d47e74b..df6521296051 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -162,19 +162,14 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
162 | if (!action) | 162 | if (!action) |
163 | return 0; | 163 | return 0; |
164 | 164 | ||
165 | retry: | ||
166 | iint = integrity_iint_find(inode); | ||
167 | if (!iint) { | ||
168 | rc = integrity_inode_alloc(inode); | ||
169 | if (!rc || rc == -EEXIST) | ||
170 | goto retry; | ||
171 | return rc; | ||
172 | } | ||
173 | |||
174 | must_appraise = action & IMA_APPRAISE; | 165 | must_appraise = action & IMA_APPRAISE; |
175 | 166 | ||
176 | mutex_lock(&inode->i_mutex); | 167 | mutex_lock(&inode->i_mutex); |
177 | 168 | ||
169 | iint = integrity_inode_get(inode); | ||
170 | if (!iint) | ||
171 | goto out; | ||
172 | |||
178 | /* Determine if already appraised/measured based on bitmask | 173 | /* Determine if already appraised/measured based on bitmask |
179 | * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED) */ | 174 | * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED) */ |
180 | iint->flags |= action; | 175 | iint->flags |= action; |