Commit 9353384e authored by Eric Paris's avatar Eric Paris Committed by Al Viro

ima: only insert at inode creation time

iints are supposed to be allocated when an inode is allocated (during
security_inode_alloc())  But we have code which will attempt to allocate
an iint during measurement calls.  If we couldn't allocate the iint and we
cared, we should have died during security_inode_alloc().  Not make the
code more complex and less efficient.
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent ec29ea54
...@@ -128,7 +128,6 @@ void ima_template_show(struct seq_file *m, void *e, ...@@ -128,7 +128,6 @@ void ima_template_show(struct seq_file *m, void *e,
*/ */
struct ima_iint_cache *ima_iint_insert(struct inode *inode); struct ima_iint_cache *ima_iint_insert(struct inode *inode);
struct ima_iint_cache *ima_iint_find_get(struct inode *inode); struct ima_iint_cache *ima_iint_find_get(struct inode *inode);
struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode);
void ima_iint_delete(struct inode *inode); void ima_iint_delete(struct inode *inode);
void iint_free(struct kref *kref); void iint_free(struct kref *kref);
void iint_rcu_free(struct rcu_head *rcu); void iint_rcu_free(struct rcu_head *rcu);
......
...@@ -45,22 +45,21 @@ struct ima_iint_cache *ima_iint_find_get(struct inode *inode) ...@@ -45,22 +45,21 @@ struct ima_iint_cache *ima_iint_find_get(struct inode *inode)
return iint; return iint;
} }
/* Allocate memory for the iint associated with the inode /**
* from the iint_cache slab, initialize the iint, and * ima_inode_alloc - allocate an iint associated with an inode
* insert it into the radix tree. * @inode: pointer to the inode
*
* On success return a pointer to the iint; on failure return NULL.
*/ */
struct ima_iint_cache *ima_iint_insert(struct inode *inode) int ima_inode_alloc(struct inode *inode)
{ {
struct ima_iint_cache *iint = NULL; struct ima_iint_cache *iint = NULL;
int rc = 0; int rc = 0;
if (!ima_initialized) if (!ima_initialized)
return iint; return 0;
iint = kmem_cache_alloc(iint_cache, GFP_NOFS); iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
if (!iint) if (!iint)
return iint; return -ENOMEM;
rc = radix_tree_preload(GFP_NOFS); rc = radix_tree_preload(GFP_NOFS);
if (rc < 0) if (rc < 0)
...@@ -70,63 +69,13 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode) ...@@ -70,63 +69,13 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode)
rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint);
spin_unlock(&ima_iint_lock); spin_unlock(&ima_iint_lock);
out: out:
if (rc < 0) { if (rc < 0)
kmem_cache_free(iint_cache, iint); kmem_cache_free(iint_cache, iint);
if (rc == -EEXIST) {
spin_lock(&ima_iint_lock);
iint = radix_tree_lookup(&ima_iint_store,
(unsigned long)inode);
spin_unlock(&ima_iint_lock);
} else
iint = NULL;
}
radix_tree_preload_end();
return iint;
}
/**
* ima_inode_alloc - allocate an iint associated with an inode
* @inode: pointer to the inode
*/
int ima_inode_alloc(struct inode *inode)
{
struct ima_iint_cache *iint;
if (!ima_initialized)
return 0;
iint = ima_iint_insert(inode);
if (!iint)
return -ENOMEM;
return 0;
}
/* ima_iint_find_insert_get - get the iint associated with an inode
*
* Most insertions are done at inode_alloc, except those allocated
* before late_initcall. When the iint does not exist, allocate it,
* initialize and insert it, and increment the iint refcount.
*
* (Can't initialize at security_initcall before any inodes are
* allocated, got to wait at least until proc_init.)
*
* Return the iint.
*/
struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode)
{
struct ima_iint_cache *iint = NULL;
iint = ima_iint_find_get(inode); radix_tree_preload_end();
if (iint)
return iint;
iint = ima_iint_insert(inode);
if (iint)
kref_get(&iint->refcount);
return iint; return rc;
} }
EXPORT_SYMBOL_GPL(ima_iint_find_insert_get);
/* iint_free - called when the iint refcount goes to zero */ /* iint_free - called when the iint refcount goes to zero */
void iint_free(struct kref *kref) void iint_free(struct kref *kref)
......
...@@ -161,7 +161,7 @@ int ima_path_check(struct path *path, int mask, int update_counts) ...@@ -161,7 +161,7 @@ int ima_path_check(struct path *path, int mask, int update_counts)
if (!ima_initialized || !S_ISREG(inode->i_mode)) if (!ima_initialized || !S_ISREG(inode->i_mode))
return 0; return 0;
iint = ima_iint_find_insert_get(inode); iint = ima_iint_find_get(inode);
if (!iint) if (!iint)
return 0; return 0;
...@@ -219,7 +219,7 @@ static int process_measurement(struct file *file, const unsigned char *filename, ...@@ -219,7 +219,7 @@ static int process_measurement(struct file *file, const unsigned char *filename,
if (!ima_initialized || !S_ISREG(inode->i_mode)) if (!ima_initialized || !S_ISREG(inode->i_mode))
return 0; return 0;
iint = ima_iint_find_insert_get(inode); iint = ima_iint_find_get(inode);
if (!iint) if (!iint)
return -ENOMEM; return -ENOMEM;
...@@ -255,7 +255,7 @@ void ima_counts_put(struct path *path, int mask) ...@@ -255,7 +255,7 @@ void ima_counts_put(struct path *path, int mask)
*/ */
if (!ima_initialized || !inode || !S_ISREG(inode->i_mode)) if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
return; return;
iint = ima_iint_find_insert_get(inode); iint = ima_iint_find_get(inode);
if (!iint) if (!iint)
return; return;
...@@ -286,7 +286,7 @@ void ima_counts_get(struct file *file) ...@@ -286,7 +286,7 @@ void ima_counts_get(struct file *file)
if (!ima_initialized || !S_ISREG(inode->i_mode)) if (!ima_initialized || !S_ISREG(inode->i_mode))
return; return;
iint = ima_iint_find_insert_get(inode); iint = ima_iint_find_get(inode);
if (!iint) if (!iint)
return; return;
mutex_lock(&iint->mutex); mutex_lock(&iint->mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment