diff options
Diffstat (limited to 'security/integrity/ima/ima_iint.c')
-rw-r--r-- | security/integrity/ima/ima_iint.c | 79 |
1 files changed, 12 insertions, 67 deletions
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index a4e2b1dac94..fa592ff1ac1 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <linux/radix-tree.h> | 19 | #include <linux/radix-tree.h> |
20 | #include "ima.h" | 20 | #include "ima.h" |
21 | 21 | ||
22 | #define ima_iint_delete ima_inode_free | ||
23 | |||
24 | RADIX_TREE(ima_iint_store, GFP_ATOMIC); | 22 | RADIX_TREE(ima_iint_store, GFP_ATOMIC); |
25 | DEFINE_SPINLOCK(ima_iint_lock); | 23 | DEFINE_SPINLOCK(ima_iint_lock); |
26 | 24 | ||
@@ -45,22 +43,21 @@ out: | |||
45 | return iint; | 43 | return iint; |
46 | } | 44 | } |
47 | 45 | ||
48 | /* Allocate memory for the iint associated with the inode | 46 | /** |
49 | * from the iint_cache slab, initialize the iint, and | 47 | * ima_inode_alloc - allocate an iint associated with an inode |
50 | * insert it into the radix tree. | 48 | * @inode: pointer to the inode |
51 | * | ||
52 | * On success return a pointer to the iint; on failure return NULL. | ||
53 | */ | 49 | */ |
54 | struct ima_iint_cache *ima_iint_insert(struct inode *inode) | 50 | int ima_inode_alloc(struct inode *inode) |
55 | { | 51 | { |
56 | struct ima_iint_cache *iint = NULL; | 52 | struct ima_iint_cache *iint = NULL; |
57 | int rc = 0; | 53 | int rc = 0; |
58 | 54 | ||
59 | if (!ima_initialized) | 55 | if (!ima_initialized) |
60 | return iint; | 56 | return 0; |
57 | |||
61 | iint = kmem_cache_alloc(iint_cache, GFP_NOFS); | 58 | iint = kmem_cache_alloc(iint_cache, GFP_NOFS); |
62 | if (!iint) | 59 | if (!iint) |
63 | return iint; | 60 | return -ENOMEM; |
64 | 61 | ||
65 | rc = radix_tree_preload(GFP_NOFS); | 62 | rc = radix_tree_preload(GFP_NOFS); |
66 | if (rc < 0) | 63 | if (rc < 0) |
@@ -70,65 +67,13 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode) | |||
70 | rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); | 67 | rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); |
71 | spin_unlock(&ima_iint_lock); | 68 | spin_unlock(&ima_iint_lock); |
72 | out: | 69 | out: |
73 | if (rc < 0) { | 70 | if (rc < 0) |
74 | kmem_cache_free(iint_cache, iint); | 71 | 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 | * Return 0 on success, 1 on failure. | ||
92 | */ | ||
93 | int ima_inode_alloc(struct inode *inode) | ||
94 | { | ||
95 | struct ima_iint_cache *iint; | ||
96 | |||
97 | if (!ima_initialized) | ||
98 | return 0; | ||
99 | |||
100 | iint = ima_iint_insert(inode); | ||
101 | if (!iint) | ||
102 | return 1; | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | /* ima_iint_find_insert_get - get the iint associated with an inode | ||
107 | * | ||
108 | * Most insertions are done at inode_alloc, except those allocated | ||
109 | * before late_initcall. When the iint does not exist, allocate it, | ||
110 | * initialize and insert it, and increment the iint refcount. | ||
111 | * | ||
112 | * (Can't initialize at security_initcall before any inodes are | ||
113 | * allocated, got to wait at least until proc_init.) | ||
114 | * | ||
115 | * Return the iint. | ||
116 | */ | ||
117 | struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode) | ||
118 | { | ||
119 | struct ima_iint_cache *iint = NULL; | ||
120 | 72 | ||
121 | iint = ima_iint_find_get(inode); | 73 | radix_tree_preload_end(); |
122 | if (iint) | ||
123 | return iint; | ||
124 | |||
125 | iint = ima_iint_insert(inode); | ||
126 | if (iint) | ||
127 | kref_get(&iint->refcount); | ||
128 | 74 | ||
129 | return iint; | 75 | return rc; |
130 | } | 76 | } |
131 | EXPORT_SYMBOL_GPL(ima_iint_find_insert_get); | ||
132 | 77 | ||
133 | /* iint_free - called when the iint refcount goes to zero */ | 78 | /* iint_free - called when the iint refcount goes to zero */ |
134 | void iint_free(struct kref *kref) | 79 | void iint_free(struct kref *kref) |
@@ -164,12 +109,12 @@ void iint_rcu_free(struct rcu_head *rcu_head) | |||
164 | } | 109 | } |
165 | 110 | ||
166 | /** | 111 | /** |
167 | * ima_iint_delete - called on integrity_inode_free | 112 | * ima_inode_free - called on security_inode_free |
168 | * @inode: pointer to the inode | 113 | * @inode: pointer to the inode |
169 | * | 114 | * |
170 | * Free the integrity information(iint) associated with an inode. | 115 | * Free the integrity information(iint) associated with an inode. |
171 | */ | 116 | */ |
172 | void ima_iint_delete(struct inode *inode) | 117 | void ima_inode_free(struct inode *inode) |
173 | { | 118 | { |
174 | struct ima_iint_cache *iint; | 119 | struct ima_iint_cache *iint; |
175 | 120 | ||