diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-05-16 21:12:46 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:33:39 -0400 |
commit | c3ef1500ec833890275172c7d063333404b64d60 (patch) | |
tree | 2453368e521a1f7a00098eef06afbedb8404503d /security/tomoyo/realpath.c | |
parent | 17fcfbd9d45b57f38d40e31f9d28db53f4af5c88 (diff) |
TOMOYO: Split files into some pieces.
security/tomoyo/common.c became too large to read.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r-- | security/tomoyo/realpath.c | 214 |
1 files changed, 4 insertions, 210 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 3ceb1724c92d..1fd685a94ad1 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -1,19 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * security/tomoyo/realpath.c | 2 | * security/tomoyo/realpath.c |
3 | * | 3 | * |
4 | * Get the canonicalized absolute pathnames. The basis for TOMOYO. | 4 | * Pathname calculation functions for TOMOYO. |
5 | * | ||
6 | * Copyright (C) 2005-2009 NTT DATA CORPORATION | ||
7 | * | ||
8 | * Version: 2.2.0 2009/04/01 | ||
9 | * | 5 | * |
6 | * Copyright (C) 2005-2010 NTT DATA CORPORATION | ||
10 | */ | 7 | */ |
11 | 8 | ||
12 | #include <linux/types.h> | 9 | #include <linux/types.h> |
13 | #include <linux/mount.h> | 10 | #include <linux/mount.h> |
14 | #include <linux/mnt_namespace.h> | 11 | #include <linux/mnt_namespace.h> |
15 | #include <linux/fs_struct.h> | 12 | #include <linux/fs_struct.h> |
16 | #include <linux/hash.h> | ||
17 | #include <linux/magic.h> | 13 | #include <linux/magic.h> |
18 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
19 | #include "common.h" | 15 | #include "common.h" |
@@ -123,7 +119,7 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname, | |||
123 | } | 119 | } |
124 | } | 120 | } |
125 | if (error) | 121 | if (error) |
126 | printk(KERN_WARNING "tomoyo_realpath: Pathname too long.\n"); | 122 | tomoyo_warn_oom(__func__); |
127 | return error; | 123 | return error; |
128 | } | 124 | } |
129 | 125 | ||
@@ -141,6 +137,7 @@ char *tomoyo_realpath_from_path(struct path *path) | |||
141 | { | 137 | { |
142 | char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_NOFS); | 138 | char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_NOFS); |
143 | 139 | ||
140 | BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN > PATH_MAX); | ||
144 | BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) | 141 | BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) |
145 | <= TOMOYO_MAX_PATHNAME_LEN - 1); | 142 | <= TOMOYO_MAX_PATHNAME_LEN - 1); |
146 | if (!buf) | 143 | if (!buf) |
@@ -189,206 +186,3 @@ char *tomoyo_realpath_nofollow(const char *pathname) | |||
189 | } | 186 | } |
190 | return NULL; | 187 | return NULL; |
191 | } | 188 | } |
192 | |||
193 | /* Memory allocated for non-string data. */ | ||
194 | static atomic_t tomoyo_policy_memory_size; | ||
195 | /* Quota for holding policy. */ | ||
196 | static unsigned int tomoyo_quota_for_policy; | ||
197 | |||
198 | /** | ||
199 | * tomoyo_memory_ok - Check memory quota. | ||
200 | * | ||
201 | * @ptr: Pointer to allocated memory. | ||
202 | * | ||
203 | * Returns true on success, false otherwise. | ||
204 | * | ||
205 | * Caller holds tomoyo_policy_lock. | ||
206 | * Memory pointed by @ptr will be zeroed on success. | ||
207 | */ | ||
208 | bool tomoyo_memory_ok(void *ptr) | ||
209 | { | ||
210 | int allocated_len = ptr ? ksize(ptr) : 0; | ||
211 | atomic_add(allocated_len, &tomoyo_policy_memory_size); | ||
212 | if (ptr && (!tomoyo_quota_for_policy || | ||
213 | atomic_read(&tomoyo_policy_memory_size) | ||
214 | <= tomoyo_quota_for_policy)) { | ||
215 | memset(ptr, 0, allocated_len); | ||
216 | return true; | ||
217 | } | ||
218 | printk(KERN_WARNING "ERROR: Out of memory " | ||
219 | "for tomoyo_alloc_element().\n"); | ||
220 | if (!tomoyo_policy_loaded) | ||
221 | panic("MAC Initialization failed.\n"); | ||
222 | return false; | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * tomoyo_commit_ok - Check memory quota. | ||
227 | * | ||
228 | * @data: Data to copy from. | ||
229 | * @size: Size in byte. | ||
230 | * | ||
231 | * Returns pointer to allocated memory on success, NULL otherwise. | ||
232 | */ | ||
233 | void *tomoyo_commit_ok(void *data, const unsigned int size) | ||
234 | { | ||
235 | void *ptr = kzalloc(size, GFP_NOFS); | ||
236 | if (tomoyo_memory_ok(ptr)) { | ||
237 | memmove(ptr, data, size); | ||
238 | memset(data, 0, size); | ||
239 | return ptr; | ||
240 | } | ||
241 | return NULL; | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * tomoyo_memory_free - Free memory for elements. | ||
246 | * | ||
247 | * @ptr: Pointer to allocated memory. | ||
248 | */ | ||
249 | void tomoyo_memory_free(void *ptr) | ||
250 | { | ||
251 | atomic_sub(ksize(ptr), &tomoyo_policy_memory_size); | ||
252 | kfree(ptr); | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * tomoyo_name_list is used for holding string data used by TOMOYO. | ||
257 | * Since same string data is likely used for multiple times (e.g. | ||
258 | * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of | ||
259 | * "const struct tomoyo_path_info *". | ||
260 | */ | ||
261 | struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; | ||
262 | |||
263 | /** | ||
264 | * tomoyo_get_name - Allocate permanent memory for string data. | ||
265 | * | ||
266 | * @name: The string to store into the permernent memory. | ||
267 | * | ||
268 | * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. | ||
269 | */ | ||
270 | const struct tomoyo_path_info *tomoyo_get_name(const char *name) | ||
271 | { | ||
272 | struct tomoyo_name_entry *ptr; | ||
273 | unsigned int hash; | ||
274 | int len; | ||
275 | int allocated_len; | ||
276 | struct list_head *head; | ||
277 | |||
278 | if (!name) | ||
279 | return NULL; | ||
280 | len = strlen(name) + 1; | ||
281 | hash = full_name_hash((const unsigned char *) name, len - 1); | ||
282 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; | ||
283 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | ||
284 | return NULL; | ||
285 | list_for_each_entry(ptr, head, list) { | ||
286 | if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) | ||
287 | continue; | ||
288 | atomic_inc(&ptr->users); | ||
289 | goto out; | ||
290 | } | ||
291 | ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS); | ||
292 | allocated_len = ptr ? ksize(ptr) : 0; | ||
293 | if (!ptr || (tomoyo_quota_for_policy && | ||
294 | atomic_read(&tomoyo_policy_memory_size) + allocated_len | ||
295 | > tomoyo_quota_for_policy)) { | ||
296 | kfree(ptr); | ||
297 | printk(KERN_WARNING "ERROR: Out of memory " | ||
298 | "for tomoyo_get_name().\n"); | ||
299 | if (!tomoyo_policy_loaded) | ||
300 | panic("MAC Initialization failed.\n"); | ||
301 | ptr = NULL; | ||
302 | goto out; | ||
303 | } | ||
304 | atomic_add(allocated_len, &tomoyo_policy_memory_size); | ||
305 | ptr->entry.name = ((char *) ptr) + sizeof(*ptr); | ||
306 | memmove((char *) ptr->entry.name, name, len); | ||
307 | atomic_set(&ptr->users, 1); | ||
308 | tomoyo_fill_path_info(&ptr->entry); | ||
309 | list_add_tail(&ptr->list, head); | ||
310 | out: | ||
311 | mutex_unlock(&tomoyo_policy_lock); | ||
312 | return ptr ? &ptr->entry : NULL; | ||
313 | } | ||
314 | |||
315 | /** | ||
316 | * tomoyo_realpath_init - Initialize realpath related code. | ||
317 | */ | ||
318 | void __init tomoyo_realpath_init(void) | ||
319 | { | ||
320 | int i; | ||
321 | |||
322 | BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN > PATH_MAX); | ||
323 | for (i = 0; i < TOMOYO_MAX_HASH; i++) | ||
324 | INIT_LIST_HEAD(&tomoyo_name_list[i]); | ||
325 | INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); | ||
326 | tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME); | ||
327 | /* | ||
328 | * tomoyo_read_lock() is not needed because this function is | ||
329 | * called before the first "delete" request. | ||
330 | */ | ||
331 | list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); | ||
332 | if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) | ||
333 | panic("Can't register tomoyo_kernel_domain"); | ||
334 | } | ||
335 | |||
336 | unsigned int tomoyo_quota_for_query; | ||
337 | unsigned int tomoyo_query_memory_size; | ||
338 | |||
339 | /** | ||
340 | * tomoyo_read_memory_counter - Check for memory usage in bytes. | ||
341 | * | ||
342 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
343 | * | ||
344 | * Returns memory usage. | ||
345 | */ | ||
346 | int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) | ||
347 | { | ||
348 | if (!head->read_eof) { | ||
349 | const unsigned int policy | ||
350 | = atomic_read(&tomoyo_policy_memory_size); | ||
351 | const unsigned int query = tomoyo_query_memory_size; | ||
352 | char buffer[64]; | ||
353 | |||
354 | memset(buffer, 0, sizeof(buffer)); | ||
355 | if (tomoyo_quota_for_policy) | ||
356 | snprintf(buffer, sizeof(buffer) - 1, | ||
357 | " (Quota: %10u)", | ||
358 | tomoyo_quota_for_policy); | ||
359 | else | ||
360 | buffer[0] = '\0'; | ||
361 | tomoyo_io_printf(head, "Policy: %10u%s\n", policy, | ||
362 | buffer); | ||
363 | if (tomoyo_quota_for_query) | ||
364 | snprintf(buffer, sizeof(buffer) - 1, | ||
365 | " (Quota: %10u)", | ||
366 | tomoyo_quota_for_query); | ||
367 | else | ||
368 | buffer[0] = '\0'; | ||
369 | tomoyo_io_printf(head, "Query lists: %10u%s\n", query, | ||
370 | buffer); | ||
371 | tomoyo_io_printf(head, "Total: %10u\n", policy + query); | ||
372 | head->read_eof = true; | ||
373 | } | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | /** | ||
378 | * tomoyo_write_memory_quota - Set memory quota. | ||
379 | * | ||
380 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
381 | * | ||
382 | * Returns 0. | ||
383 | */ | ||
384 | int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head) | ||
385 | { | ||
386 | char *data = head->write_buf; | ||
387 | unsigned int size; | ||
388 | |||
389 | if (sscanf(data, "Policy: %u", &size) == 1) | ||
390 | tomoyo_quota_for_policy = size; | ||
391 | else if (sscanf(data, "Query lists: %u", &size) == 1) | ||
392 | tomoyo_quota_for_query = size; | ||
393 | return 0; | ||
394 | } | ||