@@ -141,41 +141,70 @@ void ima_counts_get(struct file *file)
141
141
/*
142
142
* Decrement ima counts
143
143
*/
144
- static void ima_dec_counts (struct ima_iint_cache * iint , struct inode * inode ,
145
- struct file * file )
144
+ static void ima_dec_counts (struct inode * inode , struct file * file )
146
145
{
147
146
mode_t mode = file -> f_mode ;
148
- bool dump = false;
149
147
150
- BUG_ON (!mutex_is_locked (& iint -> mutex ));
151
148
assert_spin_locked (& inode -> i_lock );
152
149
153
150
if ((mode & (FMODE_READ | FMODE_WRITE )) == FMODE_READ ) {
154
- if (unlikely (inode -> i_readcount == 0 ))
155
- dump = true;
151
+ if (unlikely (inode -> i_readcount == 0 )) {
152
+ if (!ima_limit_imbalance (file )) {
153
+ printk (KERN_INFO "%s: open/free imbalance (r:%u)\n" ,
154
+ __func__ , inode -> i_readcount );
155
+ dump_stack ();
156
+ }
157
+ return ;
158
+ }
156
159
inode -> i_readcount -- ;
157
160
}
158
- if (mode & FMODE_WRITE ) {
159
- if (atomic_read (& inode -> i_writecount ) <= 0 )
160
- dump = true;
161
- if (atomic_read (& inode -> i_writecount ) == 1 &&
162
- iint -> version != inode -> i_version )
163
- iint -> flags &= ~IMA_MEASURED ;
164
- }
161
+ }
165
162
166
- if (dump && !ima_limit_imbalance (file )) {
167
- printk (KERN_INFO "%s: open/free imbalance (r:%u)\n" ,
168
- __func__ , inode -> i_readcount );
169
- dump_stack ();
170
- }
163
+ static void ima_check_last_writer (struct ima_iint_cache * iint ,
164
+ struct inode * inode ,
165
+ struct file * file )
166
+ {
167
+ mode_t mode = file -> f_mode ;
168
+
169
+ BUG_ON (!mutex_is_locked (& iint -> mutex ));
170
+ assert_spin_locked (& inode -> i_lock );
171
+
172
+ if (mode & FMODE_WRITE &&
173
+ atomic_read (& inode -> i_writecount ) == 1 &&
174
+ iint -> version != inode -> i_version )
175
+ iint -> flags &= ~IMA_MEASURED ;
176
+ }
177
+
178
+ static void ima_file_free_iint (struct ima_iint_cache * iint , struct inode * inode ,
179
+ struct file * file )
180
+ {
181
+ mutex_lock (& iint -> mutex );
182
+ spin_lock (& inode -> i_lock );
183
+
184
+ ima_dec_counts (inode , file );
185
+ ima_check_last_writer (iint , inode , file );
186
+
187
+ spin_unlock (& inode -> i_lock );
188
+ mutex_unlock (& iint -> mutex );
189
+
190
+ kref_put (& iint -> refcount , iint_free );
191
+ }
192
+
193
+ static void ima_file_free_noiint (struct inode * inode , struct file * file )
194
+ {
195
+ spin_lock (& inode -> i_lock );
196
+
197
+ ima_dec_counts (inode , file );
198
+
199
+ spin_unlock (& inode -> i_lock );
171
200
}
172
201
173
202
/**
174
203
* ima_file_free - called on __fput()
175
204
* @file: pointer to file structure being freed
176
205
*
177
206
* Flag files that changed, based on i_version;
178
- * and decrement the iint readcount/writecount .
207
+ * and decrement the i_readcount .
179
208
*/
180
209
void ima_file_free (struct file * file )
181
210
{
@@ -185,17 +214,12 @@ void ima_file_free(struct file *file)
185
214
if (!iint_initialized || !S_ISREG (inode -> i_mode ))
186
215
return ;
187
216
iint = ima_iint_find_get (inode );
188
- if (!iint )
189
- return ;
190
217
191
- mutex_lock ( & iint -> mutex );
192
- spin_lock ( & inode -> i_lock );
193
-
194
- ima_dec_counts ( iint , inode , file );
218
+ if ( iint )
219
+ ima_file_free_iint ( iint , inode , file );
220
+ else
221
+ ima_file_free_noiint ( inode , file );
195
222
196
- spin_unlock (& inode -> i_lock );
197
- mutex_unlock (& iint -> mutex );
198
- kref_put (& iint -> refcount , iint_free );
199
223
}
200
224
201
225
static int process_measurement (struct file * file , const unsigned char * filename ,
@@ -207,11 +231,21 @@ static int process_measurement(struct file *file, const unsigned char *filename,
207
231
208
232
if (!ima_initialized || !S_ISREG (inode -> i_mode ))
209
233
return 0 ;
234
+
235
+ rc = ima_must_measure (NULL , inode , mask , function );
236
+ if (rc != 0 )
237
+ return rc ;
238
+ retry :
210
239
iint = ima_iint_find_get (inode );
211
- if (!iint )
212
- return - ENOMEM ;
240
+ if (!iint ) {
241
+ rc = ima_inode_alloc (inode );
242
+ if (!rc || rc == - EEXIST )
243
+ goto retry ;
244
+ return rc ;
245
+ }
213
246
214
247
mutex_lock (& iint -> mutex );
248
+
215
249
rc = ima_must_measure (iint , inode , mask , function );
216
250
if (rc != 0 )
217
251
goto out ;
0 commit comments