diff options
author | Eric Paris <eparis@redhat.com> | 2009-12-04 15:47:52 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-12-16 12:16:46 -0500 |
commit | 9353384ec8128cb443463016bbabb44ca857ff52 (patch) | |
tree | 411ff22e85868aea1575d8b133187def3b0e0498 /security/integrity/ima/ima_iint.c | |
parent | ec29ea544b1ce204ba3575ba05fccf3069d00c3f (diff) |
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: Eric Paris <eparis@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security/integrity/ima/ima_iint.c')
-rw-r--r-- | security/integrity/ima/ima_iint.c | 71 |
1 files changed, 10 insertions, 61 deletions
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index 4a53f396d42..2f6ab5258b1 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
@@ -45,22 +45,21 @@ out: | |||
45 | return iint; | 45 | return iint; |
46 | } | 46 | } |
47 | 47 | ||
48 | /* Allocate memory for the iint associated with the inode | 48 | /** |
49 | * from the iint_cache slab, initialize the iint, and | 49 | * ima_inode_alloc - allocate an iint associated with an inode |
50 | * insert it into the radix tree. | 50 | * @inode: pointer to the inode |
51 | * | ||
52 | * On success return a pointer to the iint; on failure return NULL. | ||
53 | */ | 51 | */ |
54 | struct ima_iint_cache *ima_iint_insert(struct inode *inode) | 52 | int ima_inode_alloc(struct inode *inode) |
55 | { | 53 | { |
56 | struct ima_iint_cache *iint = NULL; | 54 | struct ima_iint_cache *iint = NULL; |
57 | int rc = 0; | 55 | int rc = 0; |
58 | 56 | ||
59 | if (!ima_initialized) | 57 | if (!ima_initialized) |
60 | return iint; | 58 | return 0; |
59 | |||
61 | iint = kmem_cache_alloc(iint_cache, GFP_NOFS); | 60 | iint = kmem_cache_alloc(iint_cache, GFP_NOFS); |
62 | if (!iint) | 61 | if (!iint) |
63 | return iint; | 62 | return -ENOMEM; |
64 | 63 | ||
65 | rc = radix_tree_preload(GFP_NOFS); | 64 | rc = radix_tree_preload(GFP_NOFS); |
66 | if (rc < 0) | 65 | if (rc < 0) |
@@ -70,63 +69,13 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode) | |||
70 | rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); | 69 | rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); |
71 | spin_unlock(&ima_iint_lock); | 70 | spin_unlock(&ima_iint_lock); |
72 | out: | 71 | out: |
73 | if (rc < 0) { | 72 | if (rc < 0) |
74 | kmem_cache_free(iint_cache, iint); | 73 | kmem_cache_free(iint_cache, iint); |
75 | if (rc == -EEXIST) { | ||
76 | spin_lock(&ima_iint_lock); | ||
77 | iint = radix_tree_lookup(&ima_iint_store, | ||
78 | (unsigned long)inode); | ||
79 | spin_unlock(&ima_iint_lock); | ||
80 | } else | ||
81 | iint = NULL; | ||
82 | } | ||
83 | radix_tree_preload_end(); | ||
84 | return iint; | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * ima_inode_alloc - allocate an iint associated with an inode | ||
89 | * @inode: pointer to the inode | ||
90 | */ | ||
91 | int ima_inode_alloc(struct inode *inode) | ||
92 | { | ||
93 | struct ima_iint_cache *iint; | ||
94 | |||
95 | if (!ima_initialized) | ||
96 | return 0; | ||
97 | |||
98 | iint = ima_iint_insert(inode); | ||
99 | if (!iint) | ||
100 | return -ENOMEM; | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | /* ima_iint_find_insert_get - get the iint associated with an inode | ||
105 | * | ||
106 | * Most insertions are done at inode_alloc, except those allocated | ||
107 | * before late_initcall. When the iint does not exist, allocate it, | ||
108 | * initialize and insert it, and increment the iint refcount. | ||
109 | * | ||
110 | * (Can't initialize at security_initcall before any inodes are | ||
111 | * allocated, got to wait at least until proc_init.) | ||
112 | * | ||
113 | * Return the iint. | ||
114 | */ | ||
115 | struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode) | ||
116 | { | ||
117 | struct ima_iint_cache *iint = NULL; | ||
118 | 74 | ||
119 | iint = ima_iint_find_get(inode); | 75 | radix_tree_preload_end(); |
120 | if (iint) | ||
121 | return iint; | ||
122 | |||
123 | iint = ima_iint_insert(inode); | ||
124 | if (iint) | ||
125 | kref_get(&iint->refcount); | ||
126 | 76 | ||
127 | return iint; | 77 | return rc; |
128 | } | 78 | } |
129 | EXPORT_SYMBOL_GPL(ima_iint_find_insert_get); | ||
130 | 79 | ||
131 | /* iint_free - called when the iint refcount goes to zero */ | 80 | /* iint_free - called when the iint refcount goes to zero */ |
132 | void iint_free(struct kref *kref) | 81 | void iint_free(struct kref *kref) |