diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/integrity/ima/ima.h | 4 | ||||
-rw-r--r-- | security/integrity/ima/ima_iint.c | 38 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 7 |
3 files changed, 19 insertions, 30 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 27849e1656dc..ac79032bdf23 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -107,7 +107,6 @@ struct ima_iint_cache { | |||
107 | unsigned char flags; | 107 | unsigned char flags; |
108 | u8 digest[IMA_DIGEST_SIZE]; | 108 | u8 digest[IMA_DIGEST_SIZE]; |
109 | struct mutex mutex; /* protects: version, flags, digest */ | 109 | struct mutex mutex; /* protects: version, flags, digest */ |
110 | struct kref refcount; /* ima_iint_cache reference count */ | ||
111 | }; | 110 | }; |
112 | 111 | ||
113 | /* LIM API function definitions */ | 112 | /* LIM API function definitions */ |
@@ -125,8 +124,7 @@ void ima_template_show(struct seq_file *m, void *e, | |||
125 | * integrity data associated with an inode. | 124 | * integrity data associated with an inode. |
126 | */ | 125 | */ |
127 | struct ima_iint_cache *ima_iint_insert(struct inode *inode); | 126 | struct ima_iint_cache *ima_iint_insert(struct inode *inode); |
128 | struct ima_iint_cache *ima_iint_find_get(struct inode *inode); | 127 | struct ima_iint_cache *ima_iint_find(struct inode *inode); |
129 | void iint_free(struct kref *kref); | ||
130 | 128 | ||
131 | /* IMA policy related functions */ | 129 | /* IMA policy related functions */ |
132 | enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; | 130 | enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; |
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index 0936a7197e47..969a1c1cb333 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
@@ -53,24 +53,26 @@ static struct ima_iint_cache *__ima_iint_find(struct inode *inode) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * ima_iint_find_get - return the iint associated with an inode | 56 | * ima_iint_find - return the iint associated with an inode |
57 | * | ||
58 | * ima_iint_find_get gets a reference to the iint. Caller must | ||
59 | * remember to put the iint reference. | ||
60 | */ | 57 | */ |
61 | struct ima_iint_cache *ima_iint_find_get(struct inode *inode) | 58 | struct ima_iint_cache *ima_iint_find(struct inode *inode) |
62 | { | 59 | { |
63 | struct ima_iint_cache *iint; | 60 | struct ima_iint_cache *iint; |
64 | 61 | ||
65 | spin_lock(&ima_iint_lock); | 62 | spin_lock(&ima_iint_lock); |
66 | iint = __ima_iint_find(inode); | 63 | iint = __ima_iint_find(inode); |
67 | if (iint) | ||
68 | kref_get(&iint->refcount); | ||
69 | spin_unlock(&ima_iint_lock); | 64 | spin_unlock(&ima_iint_lock); |
70 | 65 | ||
71 | return iint; | 66 | return iint; |
72 | } | 67 | } |
73 | 68 | ||
69 | static void iint_free(struct ima_iint_cache *iint) | ||
70 | { | ||
71 | iint->version = 0; | ||
72 | iint->flags = 0UL; | ||
73 | kmem_cache_free(iint_cache, iint); | ||
74 | } | ||
75 | |||
74 | /** | 76 | /** |
75 | * ima_inode_alloc - allocate an iint associated with an inode | 77 | * ima_inode_alloc - allocate an iint associated with an inode |
76 | * @inode: pointer to the inode | 78 | * @inode: pointer to the inode |
@@ -113,19 +115,9 @@ int ima_inode_alloc(struct inode *inode) | |||
113 | return 0; | 115 | return 0; |
114 | out_err: | 116 | out_err: |
115 | spin_unlock(&ima_iint_lock); | 117 | spin_unlock(&ima_iint_lock); |
116 | kref_put(&new_iint->refcount, iint_free); | 118 | iint_free(new_iint); |
117 | return rc; | ||
118 | } | ||
119 | 119 | ||
120 | /* iint_free - called when the iint refcount goes to zero */ | 120 | return rc; |
121 | void iint_free(struct kref *kref) | ||
122 | { | ||
123 | struct ima_iint_cache *iint = container_of(kref, struct ima_iint_cache, | ||
124 | refcount); | ||
125 | iint->version = 0; | ||
126 | iint->flags = 0UL; | ||
127 | kref_init(&iint->refcount); | ||
128 | kmem_cache_free(iint_cache, iint); | ||
129 | } | 121 | } |
130 | 122 | ||
131 | /** | 123 | /** |
@@ -148,8 +140,11 @@ void ima_inode_free(struct inode *inode) | |||
148 | if (iint) | 140 | if (iint) |
149 | rb_erase(&iint->rb_node, &ima_iint_tree); | 141 | rb_erase(&iint->rb_node, &ima_iint_tree); |
150 | spin_unlock(&ima_iint_lock); | 142 | spin_unlock(&ima_iint_lock); |
151 | if (iint) | 143 | |
152 | kref_put(&iint->refcount, iint_free); | 144 | if (!iint) |
145 | return; | ||
146 | |||
147 | iint_free(iint); | ||
153 | } | 148 | } |
154 | 149 | ||
155 | static void init_once(void *foo) | 150 | static void init_once(void *foo) |
@@ -160,7 +155,6 @@ static void init_once(void *foo) | |||
160 | iint->version = 0; | 155 | iint->version = 0; |
161 | iint->flags = 0UL; | 156 | iint->flags = 0UL; |
162 | mutex_init(&iint->mutex); | 157 | mutex_init(&iint->mutex); |
163 | kref_init(&iint->refcount); | ||
164 | } | 158 | } |
165 | 159 | ||
166 | static int __init ima_iintcache_init(void) | 160 | static int __init ima_iintcache_init(void) |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 5e3229c797fc..1dccafef7494 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -186,8 +186,6 @@ static void ima_file_free_iint(struct ima_iint_cache *iint, struct inode *inode, | |||
186 | 186 | ||
187 | spin_unlock(&inode->i_lock); | 187 | spin_unlock(&inode->i_lock); |
188 | mutex_unlock(&iint->mutex); | 188 | mutex_unlock(&iint->mutex); |
189 | |||
190 | kref_put(&iint->refcount, iint_free); | ||
191 | } | 189 | } |
192 | 190 | ||
193 | static void ima_file_free_noiint(struct inode *inode, struct file *file) | 191 | static void ima_file_free_noiint(struct inode *inode, struct file *file) |
@@ -213,7 +211,7 @@ void ima_file_free(struct file *file) | |||
213 | 211 | ||
214 | if (!iint_initialized || !S_ISREG(inode->i_mode)) | 212 | if (!iint_initialized || !S_ISREG(inode->i_mode)) |
215 | return; | 213 | return; |
216 | iint = ima_iint_find_get(inode); | 214 | iint = ima_iint_find(inode); |
217 | 215 | ||
218 | if (iint) | 216 | if (iint) |
219 | ima_file_free_iint(iint, inode, file); | 217 | ima_file_free_iint(iint, inode, file); |
@@ -236,7 +234,7 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
236 | if (rc != 0) | 234 | if (rc != 0) |
237 | return rc; | 235 | return rc; |
238 | retry: | 236 | retry: |
239 | iint = ima_iint_find_get(inode); | 237 | iint = ima_iint_find(inode); |
240 | if (!iint) { | 238 | if (!iint) { |
241 | rc = ima_inode_alloc(inode); | 239 | rc = ima_inode_alloc(inode); |
242 | if (!rc || rc == -EEXIST) | 240 | if (!rc || rc == -EEXIST) |
@@ -255,7 +253,6 @@ retry: | |||
255 | ima_store_measurement(iint, file, filename); | 253 | ima_store_measurement(iint, file, filename); |
256 | out: | 254 | out: |
257 | mutex_unlock(&iint->mutex); | 255 | mutex_unlock(&iint->mutex); |
258 | kref_put(&iint->refcount, iint_free); | ||
259 | return rc; | 256 | return rc; |
260 | } | 257 | } |
261 | 258 | ||