aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/realpath.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-05-16 21:12:46 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:33:39 -0400
commitc3ef1500ec833890275172c7d063333404b64d60 (patch)
tree2453368e521a1f7a00098eef06afbedb8404503d /security/tomoyo/realpath.c
parent17fcfbd9d45b57f38d40e31f9d28db53f4af5c88 (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.c214
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. */
194static atomic_t tomoyo_policy_memory_size;
195/* Quota for holding policy. */
196static 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 */
208bool 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 */
233void *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 */
249void 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 */
261struct 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 */
270const 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 */
318void __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
336unsigned int tomoyo_quota_for_query;
337unsigned 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 */
346int 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 */
384int 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}