aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/realpath.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-02-10 19:43:54 -0500
committerJames Morris <jmorris@namei.org>2010-02-14 17:00:24 -0500
commit847b173ea3d6f50936823d07f2245059bf44713b (patch)
treeb53c6d0536af73a078bcff0375f9f4d837f79bba /security/tomoyo/realpath.c
parentec8e6a4e062e2edebef91e930c20572c9f4c0dda (diff)
TOMOYO: Add garbage collector.
This patch adds garbage collector support to TOMOYO. Elements are protected by "struct srcu_struct tomoyo_ss". Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r--security/tomoyo/realpath.c86
1 files changed, 40 insertions, 46 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 9557168b3767..c00df45c7ede 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -205,9 +205,9 @@ char *tomoyo_realpath_nofollow(const char *pathname)
205} 205}
206 206
207/* Memory allocated for non-string data. */ 207/* Memory allocated for non-string data. */
208static unsigned int tomoyo_allocated_memory_for_elements; 208static atomic_t tomoyo_policy_memory_size;
209/* Quota for holding non-string data. */ 209/* Quota for holding policy. */
210static unsigned int tomoyo_quota_for_elements; 210static unsigned int tomoyo_quota_for_policy;
211 211
212/** 212/**
213 * tomoyo_memory_ok - Check memory quota. 213 * tomoyo_memory_ok - Check memory quota.
@@ -222,26 +222,30 @@ static unsigned int tomoyo_quota_for_elements;
222bool tomoyo_memory_ok(void *ptr) 222bool tomoyo_memory_ok(void *ptr)
223{ 223{
224 int allocated_len = ptr ? ksize(ptr) : 0; 224 int allocated_len = ptr ? ksize(ptr) : 0;
225 bool result = false; 225 atomic_add(allocated_len, &tomoyo_policy_memory_size);
226 if (!ptr || (tomoyo_quota_for_elements && 226 if (ptr && (!tomoyo_quota_for_policy ||
227 tomoyo_allocated_memory_for_elements 227 atomic_read(&tomoyo_policy_memory_size)
228 + allocated_len > tomoyo_quota_for_elements)) { 228 <= tomoyo_quota_for_policy)) {
229 printk(KERN_WARNING "ERROR: Out of memory "
230 "for tomoyo_alloc_element().\n");
231 if (!tomoyo_policy_loaded)
232 panic("MAC Initialization failed.\n");
233 } else {
234 result = true;
235 tomoyo_allocated_memory_for_elements += allocated_len;
236 memset(ptr, 0, allocated_len); 229 memset(ptr, 0, allocated_len);
230 return true;
237 } 231 }
238 return result; 232 printk(KERN_WARNING "ERROR: Out of memory "
233 "for tomoyo_alloc_element().\n");
234 if (!tomoyo_policy_loaded)
235 panic("MAC Initialization failed.\n");
236 return false;
239} 237}
240 238
241/* Memory allocated for string data in bytes. */ 239/**
242static unsigned int tomoyo_allocated_memory_for_savename; 240 * tomoyo_memory_free - Free memory for elements.
243/* Quota for holding string data in bytes. */ 241 *
244static unsigned int tomoyo_quota_for_savename; 242 * @ptr: Pointer to allocated memory.
243 */
244void tomoyo_memory_free(void *ptr)
245{
246 atomic_sub(ksize(ptr), &tomoyo_policy_memory_size);
247 kfree(ptr);
248}
245 249
246/* 250/*
247 * tomoyo_name_list is used for holding string data used by TOMOYO. 251 * tomoyo_name_list is used for holding string data used by TOMOYO.
@@ -249,7 +253,9 @@ static unsigned int tomoyo_quota_for_savename;
249 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of 253 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
250 * "const struct tomoyo_path_info *". 254 * "const struct tomoyo_path_info *".
251 */ 255 */
252static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 256struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
257/* Lock for protecting tomoyo_name_list . */
258DEFINE_MUTEX(tomoyo_name_list_lock);
253 259
254/** 260/**
255 * tomoyo_get_name - Allocate permanent memory for string data. 261 * tomoyo_get_name - Allocate permanent memory for string data.
@@ -260,7 +266,6 @@ static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
260 */ 266 */
261const struct tomoyo_path_info *tomoyo_get_name(const char *name) 267const struct tomoyo_path_info *tomoyo_get_name(const char *name)
262{ 268{
263 static DEFINE_MUTEX(lock);
264 struct tomoyo_name_entry *ptr; 269 struct tomoyo_name_entry *ptr;
265 unsigned int hash; 270 unsigned int hash;
266 int len; 271 int len;
@@ -272,7 +277,7 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
272 len = strlen(name) + 1; 277 len = strlen(name) + 1;
273 hash = full_name_hash((const unsigned char *) name, len - 1); 278 hash = full_name_hash((const unsigned char *) name, len - 1);
274 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 279 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
275 mutex_lock(&lock); 280 mutex_lock(&tomoyo_name_list_lock);
276 list_for_each_entry(ptr, head, list) { 281 list_for_each_entry(ptr, head, list) {
277 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 282 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
278 continue; 283 continue;
@@ -281,9 +286,9 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
281 } 286 }
282 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); 287 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
283 allocated_len = ptr ? ksize(ptr) : 0; 288 allocated_len = ptr ? ksize(ptr) : 0;
284 if (!ptr || (tomoyo_quota_for_savename && 289 if (!ptr || (tomoyo_quota_for_policy &&
285 tomoyo_allocated_memory_for_savename + allocated_len 290 atomic_read(&tomoyo_policy_memory_size) + allocated_len
286 > tomoyo_quota_for_savename)) { 291 > tomoyo_quota_for_policy)) {
287 kfree(ptr); 292 kfree(ptr);
288 printk(KERN_WARNING "ERROR: Out of memory " 293 printk(KERN_WARNING "ERROR: Out of memory "
289 "for tomoyo_get_name().\n"); 294 "for tomoyo_get_name().\n");
@@ -292,14 +297,14 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
292 ptr = NULL; 297 ptr = NULL;
293 goto out; 298 goto out;
294 } 299 }
295 tomoyo_allocated_memory_for_savename += allocated_len; 300 atomic_add(allocated_len, &tomoyo_policy_memory_size);
296 ptr->entry.name = ((char *) ptr) + sizeof(*ptr); 301 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
297 memmove((char *) ptr->entry.name, name, len); 302 memmove((char *) ptr->entry.name, name, len);
298 atomic_set(&ptr->users, 1); 303 atomic_set(&ptr->users, 1);
299 tomoyo_fill_path_info(&ptr->entry); 304 tomoyo_fill_path_info(&ptr->entry);
300 list_add_tail(&ptr->list, head); 305 list_add_tail(&ptr->list, head);
301 out: 306 out:
302 mutex_unlock(&lock); 307 mutex_unlock(&tomoyo_name_list_lock);
303 return ptr ? &ptr->entry : NULL; 308 return ptr ? &ptr->entry : NULL;
304} 309}
305 310
@@ -334,28 +339,19 @@ void __init tomoyo_realpath_init(void)
334int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) 339int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
335{ 340{
336 if (!head->read_eof) { 341 if (!head->read_eof) {
337 const unsigned int shared 342 const unsigned int policy
338 = tomoyo_allocated_memory_for_savename; 343 = atomic_read(&tomoyo_policy_memory_size);
339 const unsigned int private
340 = tomoyo_allocated_memory_for_elements;
341 char buffer[64]; 344 char buffer[64];
342 345
343 memset(buffer, 0, sizeof(buffer)); 346 memset(buffer, 0, sizeof(buffer));
344 if (tomoyo_quota_for_savename) 347 if (tomoyo_quota_for_policy)
345 snprintf(buffer, sizeof(buffer) - 1,
346 " (Quota: %10u)",
347 tomoyo_quota_for_savename);
348 else
349 buffer[0] = '\0';
350 tomoyo_io_printf(head, "Shared: %10u%s\n", shared, buffer);
351 if (tomoyo_quota_for_elements)
352 snprintf(buffer, sizeof(buffer) - 1, 348 snprintf(buffer, sizeof(buffer) - 1,
353 " (Quota: %10u)", 349 " (Quota: %10u)",
354 tomoyo_quota_for_elements); 350 tomoyo_quota_for_policy);
355 else 351 else
356 buffer[0] = '\0'; 352 buffer[0] = '\0';
357 tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer); 353 tomoyo_io_printf(head, "Policy: %10u%s\n", policy, buffer);
358 tomoyo_io_printf(head, "Total: %10u\n", shared + private); 354 tomoyo_io_printf(head, "Total: %10u\n", policy);
359 head->read_eof = true; 355 head->read_eof = true;
360 } 356 }
361 return 0; 357 return 0;
@@ -373,9 +369,7 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
373 char *data = head->write_buf; 369 char *data = head->write_buf;
374 unsigned int size; 370 unsigned int size;
375 371
376 if (sscanf(data, "Shared: %u", &size) == 1) 372 if (sscanf(data, "Policy: %u", &size) == 1)
377 tomoyo_quota_for_savename = size; 373 tomoyo_quota_for_policy = size;
378 else if (sscanf(data, "Private: %u", &size) == 1)
379 tomoyo_quota_for_elements = size;
380 return 0; 374 return 0;
381} 375}