diff options
Diffstat (limited to 'security/integrity/ima/ima_main.c')
-rw-r--r-- | security/integrity/ima/ima_main.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 101c512564ec..b85e61bcf246 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -249,7 +249,11 @@ void ima_counts_put(struct path *path, int mask) | |||
249 | struct inode *inode = path->dentry->d_inode; | 249 | struct inode *inode = path->dentry->d_inode; |
250 | struct ima_iint_cache *iint; | 250 | struct ima_iint_cache *iint; |
251 | 251 | ||
252 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 252 | /* The inode may already have been freed, freeing the iint |
253 | * with it. Verify the inode is not NULL before dereferencing | ||
254 | * it. | ||
255 | */ | ||
256 | if (!ima_initialized || !inode || !S_ISREG(inode->i_mode)) | ||
253 | return; | 257 | return; |
254 | iint = ima_iint_find_insert_get(inode); | 258 | iint = ima_iint_find_insert_get(inode); |
255 | if (!iint) | 259 | if (!iint) |
@@ -262,6 +266,8 @@ void ima_counts_put(struct path *path, int mask) | |||
262 | else if (mask & (MAY_READ | MAY_EXEC)) | 266 | else if (mask & (MAY_READ | MAY_EXEC)) |
263 | iint->readcount--; | 267 | iint->readcount--; |
264 | mutex_unlock(&iint->mutex); | 268 | mutex_unlock(&iint->mutex); |
269 | |||
270 | kref_put(&iint->refcount, iint_free); | ||
265 | } | 271 | } |
266 | 272 | ||
267 | /* | 273 | /* |
@@ -291,6 +297,8 @@ void ima_counts_get(struct file *file) | |||
291 | if (file->f_mode & FMODE_WRITE) | 297 | if (file->f_mode & FMODE_WRITE) |
292 | iint->writecount++; | 298 | iint->writecount++; |
293 | mutex_unlock(&iint->mutex); | 299 | mutex_unlock(&iint->mutex); |
300 | |||
301 | kref_put(&iint->refcount, iint_free); | ||
294 | } | 302 | } |
295 | EXPORT_SYMBOL_GPL(ima_counts_get); | 303 | EXPORT_SYMBOL_GPL(ima_counts_get); |
296 | 304 | ||