aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/common.c426
-rw-r--r--security/tomoyo/common.h28
-rw-r--r--security/tomoyo/domain.c47
-rw-r--r--security/tomoyo/file.c140
-rw-r--r--security/tomoyo/mount.c24
-rw-r--r--security/tomoyo/realpath.c19
6 files changed, 564 insertions, 120 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 0c6f9a5c37a5..ee46aaa3566f 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -74,6 +74,8 @@ static int tomoyo_read_control(struct file *file, char __user *buffer,
74/* Write operation for /sys/kernel/security/tomoyo/ interface. */ 74/* Write operation for /sys/kernel/security/tomoyo/ interface. */
75static int tomoyo_write_control(struct file *file, const char __user *buffer, 75static int tomoyo_write_control(struct file *file, const char __user *buffer,
76 const int buffer_len); 76 const int buffer_len);
77/* Check whether the domain has too many ACL entries to hold. */
78static bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
77 79
78/** 80/**
79 * tomoyo_parse_name_union - Parse a tomoyo_name_union. 81 * tomoyo_parse_name_union - Parse a tomoyo_name_union.
@@ -1031,7 +1033,7 @@ bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
1031 * 1033 *
1032 * Caller holds tomoyo_read_lock(). 1034 * Caller holds tomoyo_read_lock().
1033 */ 1035 */
1034bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r) 1036static bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
1035{ 1037{
1036 unsigned int count = 0; 1038 unsigned int count = 0;
1037 struct tomoyo_domain_info *domain = r->domain; 1039 struct tomoyo_domain_info *domain = r->domain;
@@ -1531,6 +1533,24 @@ static int tomoyo_delete_domain(char *domainname)
1531} 1533}
1532 1534
1533/** 1535/**
1536 * tomoyo_write_domain_policy2 - Write domain policy.
1537 *
1538 * @head: Pointer to "struct tomoyo_io_buffer".
1539 *
1540 * Returns 0 on success, negative value otherwise.
1541 *
1542 * Caller holds tomoyo_read_lock().
1543 */
1544static int tomoyo_write_domain_policy2(char *data,
1545 struct tomoyo_domain_info *domain,
1546 const bool is_delete)
1547{
1548 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_MOUNT))
1549 return tomoyo_write_mount_policy(data, domain, is_delete);
1550 return tomoyo_write_file_policy(data, domain, is_delete);
1551}
1552
1553/**
1534 * tomoyo_write_domain_policy - Write domain policy. 1554 * tomoyo_write_domain_policy - Write domain policy.
1535 * 1555 *
1536 * @head: Pointer to "struct tomoyo_io_buffer". 1556 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1580,9 +1600,7 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1580 domain->ignore_global_allow_read = !is_delete; 1600 domain->ignore_global_allow_read = !is_delete;
1581 return 0; 1601 return 0;
1582 } 1602 }
1583 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_MOUNT)) 1603 return tomoyo_write_domain_policy2(data, domain, is_delete);
1584 return tomoyo_write_mount_policy(data, domain, is_delete);
1585 return tomoyo_write_file_policy(data, domain, is_delete);
1586} 1604}
1587 1605
1588/** 1606/**
@@ -2186,6 +2204,357 @@ void tomoyo_load_policy(const char *filename)
2186} 2204}
2187 2205
2188/** 2206/**
2207 * tomoyo_print_header - Get header line of audit log.
2208 *
2209 * @r: Pointer to "struct tomoyo_request_info".
2210 *
2211 * Returns string representation.
2212 *
2213 * This function uses kmalloc(), so caller must kfree() if this function
2214 * didn't return NULL.
2215 */
2216static char *tomoyo_print_header(struct tomoyo_request_info *r)
2217{
2218 static const char *tomoyo_mode_4[4] = {
2219 "disabled", "learning", "permissive", "enforcing"
2220 };
2221 struct timeval tv;
2222 const pid_t gpid = task_pid_nr(current);
2223 static const int tomoyo_buffer_len = 4096;
2224 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
2225 if (!buffer)
2226 return NULL;
2227 do_gettimeofday(&tv);
2228 snprintf(buffer, tomoyo_buffer_len - 1,
2229 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
2230 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
2231 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
2232 tv.tv_sec, r->profile, tomoyo_mode_4[r->mode], gpid,
2233 (pid_t) sys_getpid(), (pid_t) sys_getppid(),
2234 current_uid(), current_gid(), current_euid(),
2235 current_egid(), current_suid(), current_sgid(),
2236 current_fsuid(), current_fsgid());
2237 return buffer;
2238}
2239
2240/**
2241 * tomoyo_init_audit_log - Allocate buffer for audit logs.
2242 *
2243 * @len: Required size.
2244 * @r: Pointer to "struct tomoyo_request_info".
2245 *
2246 * Returns pointer to allocated memory.
2247 *
2248 * The @len is updated to add the header lines' size on success.
2249 *
2250 * This function uses kzalloc(), so caller must kfree() if this function
2251 * didn't return NULL.
2252 */
2253static char *tomoyo_init_audit_log(int *len, struct tomoyo_request_info *r)
2254{
2255 char *buf = NULL;
2256 const char *header;
2257 const char *domainname;
2258 if (!r->domain)
2259 r->domain = tomoyo_domain();
2260 domainname = r->domain->domainname->name;
2261 header = tomoyo_print_header(r);
2262 if (!header)
2263 return NULL;
2264 *len += strlen(domainname) + strlen(header) + 10;
2265 buf = kzalloc(*len, GFP_NOFS);
2266 if (buf)
2267 snprintf(buf, (*len) - 1, "%s\n%s\n", header, domainname);
2268 kfree(header);
2269 return buf;
2270}
2271
2272/* Wait queue for tomoyo_query_list. */
2273static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait);
2274
2275/* Lock for manipulating tomoyo_query_list. */
2276static DEFINE_SPINLOCK(tomoyo_query_list_lock);
2277
2278/* Structure for query. */
2279struct tomoyo_query_entry {
2280 struct list_head list;
2281 char *query;
2282 int query_len;
2283 unsigned int serial;
2284 int timer;
2285 int answer;
2286};
2287
2288/* The list for "struct tomoyo_query_entry". */
2289static LIST_HEAD(tomoyo_query_list);
2290
2291/*
2292 * Number of "struct file" referring /sys/kernel/security/tomoyo/query
2293 * interface.
2294 */
2295static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
2296
2297/**
2298 * tomoyo_supervisor - Ask for the supervisor's decision.
2299 *
2300 * @r: Pointer to "struct tomoyo_request_info".
2301 * @fmt: The printf()'s format string, followed by parameters.
2302 *
2303 * Returns 0 if the supervisor decided to permit the access request which
2304 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
2305 * supervisor decided to retry the access request which violated the policy in
2306 * enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise.
2307 */
2308int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
2309{
2310 va_list args;
2311 int error = -EPERM;
2312 int pos;
2313 int len;
2314 static unsigned int tomoyo_serial;
2315 struct tomoyo_query_entry *tomoyo_query_entry = NULL;
2316 bool quota_exceeded = false;
2317 char *header;
2318 switch (r->mode) {
2319 char *buffer;
2320 case TOMOYO_CONFIG_LEARNING:
2321 if (!tomoyo_domain_quota_is_ok(r))
2322 return 0;
2323 va_start(args, fmt);
2324 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;
2325 va_end(args);
2326 buffer = kmalloc(len, GFP_NOFS);
2327 if (!buffer)
2328 return 0;
2329 va_start(args, fmt);
2330 vsnprintf(buffer, len - 1, fmt, args);
2331 va_end(args);
2332 tomoyo_normalize_line(buffer);
2333 tomoyo_write_domain_policy2(buffer, r->domain, false);
2334 kfree(buffer);
2335 /* fall through */
2336 case TOMOYO_CONFIG_PERMISSIVE:
2337 return 0;
2338 }
2339 if (!r->domain)
2340 r->domain = tomoyo_domain();
2341 if (!atomic_read(&tomoyo_query_observers))
2342 return -EPERM;
2343 va_start(args, fmt);
2344 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
2345 va_end(args);
2346 header = tomoyo_init_audit_log(&len, r);
2347 if (!header)
2348 goto out;
2349 tomoyo_query_entry = kzalloc(sizeof(*tomoyo_query_entry), GFP_NOFS);
2350 if (!tomoyo_query_entry)
2351 goto out;
2352 tomoyo_query_entry->query = kzalloc(len, GFP_NOFS);
2353 if (!tomoyo_query_entry->query)
2354 goto out;
2355 len = ksize(tomoyo_query_entry->query);
2356 INIT_LIST_HEAD(&tomoyo_query_entry->list);
2357 spin_lock(&tomoyo_query_list_lock);
2358 if (tomoyo_quota_for_query && tomoyo_query_memory_size + len +
2359 sizeof(*tomoyo_query_entry) >= tomoyo_quota_for_query) {
2360 quota_exceeded = true;
2361 } else {
2362 tomoyo_query_memory_size += len + sizeof(*tomoyo_query_entry);
2363 tomoyo_query_entry->serial = tomoyo_serial++;
2364 }
2365 spin_unlock(&tomoyo_query_list_lock);
2366 if (quota_exceeded)
2367 goto out;
2368 pos = snprintf(tomoyo_query_entry->query, len - 1, "Q%u-%hu\n%s",
2369 tomoyo_query_entry->serial, r->retry, header);
2370 kfree(header);
2371 header = NULL;
2372 va_start(args, fmt);
2373 vsnprintf(tomoyo_query_entry->query + pos, len - 1 - pos, fmt, args);
2374 tomoyo_query_entry->query_len = strlen(tomoyo_query_entry->query) + 1;
2375 va_end(args);
2376 spin_lock(&tomoyo_query_list_lock);
2377 list_add_tail(&tomoyo_query_entry->list, &tomoyo_query_list);
2378 spin_unlock(&tomoyo_query_list_lock);
2379 /* Give 10 seconds for supervisor's opinion. */
2380 for (tomoyo_query_entry->timer = 0;
2381 atomic_read(&tomoyo_query_observers) && tomoyo_query_entry->timer < 100;
2382 tomoyo_query_entry->timer++) {
2383 wake_up(&tomoyo_query_wait);
2384 set_current_state(TASK_INTERRUPTIBLE);
2385 schedule_timeout(HZ / 10);
2386 if (tomoyo_query_entry->answer)
2387 break;
2388 }
2389 spin_lock(&tomoyo_query_list_lock);
2390 list_del(&tomoyo_query_entry->list);
2391 tomoyo_query_memory_size -= len + sizeof(*tomoyo_query_entry);
2392 spin_unlock(&tomoyo_query_list_lock);
2393 switch (tomoyo_query_entry->answer) {
2394 case 3: /* Asked to retry by administrator. */
2395 error = TOMOYO_RETRY_REQUEST;
2396 r->retry++;
2397 break;
2398 case 1:
2399 /* Granted by administrator. */
2400 error = 0;
2401 break;
2402 case 0:
2403 /* Timed out. */
2404 break;
2405 default:
2406 /* Rejected by administrator. */
2407 break;
2408 }
2409 out:
2410 if (tomoyo_query_entry)
2411 kfree(tomoyo_query_entry->query);
2412 kfree(tomoyo_query_entry);
2413 kfree(header);
2414 return error;
2415}
2416
2417/**
2418 * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query.
2419 *
2420 * @file: Pointer to "struct file".
2421 * @wait: Pointer to "poll_table".
2422 *
2423 * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
2424 *
2425 * Waits for access requests which violated policy in enforcing mode.
2426 */
2427static int tomoyo_poll_query(struct file *file, poll_table *wait)
2428{
2429 struct list_head *tmp;
2430 bool found = false;
2431 u8 i;
2432 for (i = 0; i < 2; i++) {
2433 spin_lock(&tomoyo_query_list_lock);
2434 list_for_each(tmp, &tomoyo_query_list) {
2435 struct tomoyo_query_entry *ptr
2436 = list_entry(tmp, struct tomoyo_query_entry,
2437 list);
2438 if (ptr->answer)
2439 continue;
2440 found = true;
2441 break;
2442 }
2443 spin_unlock(&tomoyo_query_list_lock);
2444 if (found)
2445 return POLLIN | POLLRDNORM;
2446 if (i)
2447 break;
2448 poll_wait(file, &tomoyo_query_wait, wait);
2449 }
2450 return 0;
2451}
2452
2453/**
2454 * tomoyo_read_query - Read access requests which violated policy in enforcing mode.
2455 *
2456 * @head: Pointer to "struct tomoyo_io_buffer".
2457 *
2458 * Returns 0.
2459 */
2460static int tomoyo_read_query(struct tomoyo_io_buffer *head)
2461{
2462 struct list_head *tmp;
2463 int pos = 0;
2464 int len = 0;
2465 char *buf;
2466 if (head->read_avail)
2467 return 0;
2468 if (head->read_buf) {
2469 kfree(head->read_buf);
2470 head->read_buf = NULL;
2471 head->readbuf_size = 0;
2472 }
2473 spin_lock(&tomoyo_query_list_lock);
2474 list_for_each(tmp, &tomoyo_query_list) {
2475 struct tomoyo_query_entry *ptr
2476 = list_entry(tmp, struct tomoyo_query_entry, list);
2477 if (ptr->answer)
2478 continue;
2479 if (pos++ != head->read_step)
2480 continue;
2481 len = ptr->query_len;
2482 break;
2483 }
2484 spin_unlock(&tomoyo_query_list_lock);
2485 if (!len) {
2486 head->read_step = 0;
2487 return 0;
2488 }
2489 buf = kzalloc(len, GFP_NOFS);
2490 if (!buf)
2491 return 0;
2492 pos = 0;
2493 spin_lock(&tomoyo_query_list_lock);
2494 list_for_each(tmp, &tomoyo_query_list) {
2495 struct tomoyo_query_entry *ptr
2496 = list_entry(tmp, struct tomoyo_query_entry, list);
2497 if (ptr->answer)
2498 continue;
2499 if (pos++ != head->read_step)
2500 continue;
2501 /*
2502 * Some query can be skipped because tomoyo_query_list
2503 * can change, but I don't care.
2504 */
2505 if (len == ptr->query_len)
2506 memmove(buf, ptr->query, len);
2507 break;
2508 }
2509 spin_unlock(&tomoyo_query_list_lock);
2510 if (buf[0]) {
2511 head->read_avail = len;
2512 head->readbuf_size = head->read_avail;
2513 head->read_buf = buf;
2514 head->read_step++;
2515 } else {
2516 kfree(buf);
2517 }
2518 return 0;
2519}
2520
2521/**
2522 * tomoyo_write_answer - Write the supervisor's decision.
2523 *
2524 * @head: Pointer to "struct tomoyo_io_buffer".
2525 *
2526 * Returns 0 on success, -EINVAL otherwise.
2527 */
2528static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
2529{
2530 char *data = head->write_buf;
2531 struct list_head *tmp;
2532 unsigned int serial;
2533 unsigned int answer;
2534 spin_lock(&tomoyo_query_list_lock);
2535 list_for_each(tmp, &tomoyo_query_list) {
2536 struct tomoyo_query_entry *ptr
2537 = list_entry(tmp, struct tomoyo_query_entry, list);
2538 ptr->timer = 0;
2539 }
2540 spin_unlock(&tomoyo_query_list_lock);
2541 if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2542 return -EINVAL;
2543 spin_lock(&tomoyo_query_list_lock);
2544 list_for_each(tmp, &tomoyo_query_list) {
2545 struct tomoyo_query_entry *ptr
2546 = list_entry(tmp, struct tomoyo_query_entry, list);
2547 if (ptr->serial != serial)
2548 continue;
2549 if (!ptr->answer)
2550 ptr->answer = answer;
2551 break;
2552 }
2553 spin_unlock(&tomoyo_query_list_lock);
2554 return 0;
2555}
2556
2557/**
2189 * tomoyo_read_version: Get version. 2558 * tomoyo_read_version: Get version.
2190 * 2559 *
2191 * @head: Pointer to "struct tomoyo_io_buffer". 2560 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -2239,6 +2608,7 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2239 if (!head) 2608 if (!head)
2240 return -ENOMEM; 2609 return -ENOMEM;
2241 mutex_init(&head->io_sem); 2610 mutex_init(&head->io_sem);
2611 head->type = type;
2242 switch (type) { 2612 switch (type) {
2243 case TOMOYO_DOMAINPOLICY: 2613 case TOMOYO_DOMAINPOLICY:
2244 /* /sys/kernel/security/tomoyo/domain_policy */ 2614 /* /sys/kernel/security/tomoyo/domain_policy */
@@ -2280,6 +2650,11 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2280 head->write = tomoyo_write_profile; 2650 head->write = tomoyo_write_profile;
2281 head->read = tomoyo_read_profile; 2651 head->read = tomoyo_read_profile;
2282 break; 2652 break;
2653 case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */
2654 head->poll = tomoyo_poll_query;
2655 head->write = tomoyo_write_answer;
2656 head->read = tomoyo_read_query;
2657 break;
2283 case TOMOYO_MANAGER: 2658 case TOMOYO_MANAGER:
2284 /* /sys/kernel/security/tomoyo/manager */ 2659 /* /sys/kernel/security/tomoyo/manager */
2285 head->write = tomoyo_write_manager_policy; 2660 head->write = tomoyo_write_manager_policy;
@@ -2292,7 +2667,9 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2292 * for reading. 2667 * for reading.
2293 */ 2668 */
2294 head->read = NULL; 2669 head->read = NULL;
2295 } else { 2670 head->poll = NULL;
2671 } else if (!head->poll) {
2672 /* Don't allocate read_buf for poll() access. */
2296 if (!head->readbuf_size) 2673 if (!head->readbuf_size)
2297 head->readbuf_size = 4096 * 2; 2674 head->readbuf_size = 4096 * 2;
2298 head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS); 2675 head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS);
@@ -2316,7 +2693,8 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2316 return -ENOMEM; 2693 return -ENOMEM;
2317 } 2694 }
2318 } 2695 }
2319 head->reader_idx = tomoyo_read_lock(); 2696 if (type != TOMOYO_QUERY)
2697 head->reader_idx = tomoyo_read_lock();
2320 file->private_data = head; 2698 file->private_data = head;
2321 /* 2699 /*
2322 * Call the handler now if the file is 2700 * Call the handler now if the file is
@@ -2327,10 +2705,35 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2327 */ 2705 */
2328 if (type == TOMOYO_SELFDOMAIN) 2706 if (type == TOMOYO_SELFDOMAIN)
2329 tomoyo_read_control(file, NULL, 0); 2707 tomoyo_read_control(file, NULL, 0);
2708 /*
2709 * If the file is /sys/kernel/security/tomoyo/query , increment the
2710 * observer counter.
2711 * The obserber counter is used by tomoyo_supervisor() to see if
2712 * there is some process monitoring /sys/kernel/security/tomoyo/query.
2713 */
2714 else if (type == TOMOYO_QUERY)
2715 atomic_inc(&tomoyo_query_observers);
2330 return 0; 2716 return 0;
2331} 2717}
2332 2718
2333/** 2719/**
2720 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
2721 *
2722 * @file: Pointer to "struct file".
2723 * @wait: Pointer to "poll_table".
2724 *
2725 * Waits for read readiness.
2726 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd .
2727 */
2728int tomoyo_poll_control(struct file *file, poll_table *wait)
2729{
2730 struct tomoyo_io_buffer *head = file->private_data;
2731 if (!head->poll)
2732 return -ENOSYS;
2733 return head->poll(file, wait);
2734}
2735
2736/**
2334 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 2737 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
2335 * 2738 *
2336 * @file: Pointer to "struct file". 2739 * @file: Pointer to "struct file".
@@ -2443,7 +2846,14 @@ static int tomoyo_close_control(struct file *file)
2443 struct tomoyo_io_buffer *head = file->private_data; 2846 struct tomoyo_io_buffer *head = file->private_data;
2444 const bool is_write = !!head->write_buf; 2847 const bool is_write = !!head->write_buf;
2445 2848
2446 tomoyo_read_unlock(head->reader_idx); 2849 /*
2850 * If the file is /sys/kernel/security/tomoyo/query , decrement the
2851 * observer counter.
2852 */
2853 if (head->type == TOMOYO_QUERY)
2854 atomic_dec(&tomoyo_query_observers);
2855 else
2856 tomoyo_read_unlock(head->reader_idx);
2447 /* Release memory used for policy I/O. */ 2857 /* Release memory used for policy I/O. */
2448 kfree(head->read_buf); 2858 kfree(head->read_buf);
2449 head->read_buf = NULL; 2859 head->read_buf = NULL;
@@ -2562,6 +2972,8 @@ static int __init tomoyo_initerface_init(void)
2562 return 0; 2972 return 0;
2563 2973
2564 tomoyo_dir = securityfs_create_dir("tomoyo", NULL); 2974 tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
2975 tomoyo_create_entry("query", 0600, tomoyo_dir,
2976 TOMOYO_QUERY);
2565 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir, 2977 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir,
2566 TOMOYO_DOMAINPOLICY); 2978 TOMOYO_DOMAINPOLICY);
2567 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir, 2979 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 3d819b139165..dc5f98f52f61 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -20,6 +20,7 @@
20#include <linux/mount.h> 20#include <linux/mount.h>
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/cred.h> 22#include <linux/cred.h>
23#include <linux/poll.h>
23struct linux_binprm; 24struct linux_binprm;
24 25
25/********** Constants definitions. **********/ 26/********** Constants definitions. **********/
@@ -156,9 +157,12 @@ enum tomoyo_securityfs_interface_index {
156 TOMOYO_SELFDOMAIN, 157 TOMOYO_SELFDOMAIN,
157 TOMOYO_VERSION, 158 TOMOYO_VERSION,
158 TOMOYO_PROFILE, 159 TOMOYO_PROFILE,
160 TOMOYO_QUERY,
159 TOMOYO_MANAGER 161 TOMOYO_MANAGER
160}; 162};
161 163
164#define TOMOYO_RETRY_REQUEST 1 /* Retry this request. */
165
162/********** Structure definitions. **********/ 166/********** Structure definitions. **********/
163 167
164/* 168/*
@@ -176,10 +180,14 @@ struct tomoyo_page_buffer {
176 * tomoyo_request_info is a structure which is used for holding 180 * tomoyo_request_info is a structure which is used for holding
177 * 181 *
178 * (1) Domain information of current process. 182 * (1) Domain information of current process.
179 * (2) Access control mode of the profile. 183 * (2) How many retries are made for this request.
184 * (3) Profile number used for this request.
185 * (4) Access control mode of the profile.
180 */ 186 */
181struct tomoyo_request_info { 187struct tomoyo_request_info {
182 struct tomoyo_domain_info *domain; 188 struct tomoyo_domain_info *domain;
189 u8 retry;
190 u8 profile;
183 u8 mode; /* One of tomoyo_mode_index . */ 191 u8 mode; /* One of tomoyo_mode_index . */
184}; 192};
185 193
@@ -484,6 +492,7 @@ struct tomoyo_mount_acl {
484struct tomoyo_io_buffer { 492struct tomoyo_io_buffer {
485 int (*read) (struct tomoyo_io_buffer *); 493 int (*read) (struct tomoyo_io_buffer *);
486 int (*write) (struct tomoyo_io_buffer *); 494 int (*write) (struct tomoyo_io_buffer *);
495 int (*poll) (struct file *file, poll_table *wait);
487 /* Exclusive lock for this structure. */ 496 /* Exclusive lock for this structure. */
488 struct mutex io_sem; 497 struct mutex io_sem;
489 /* Index returned by tomoyo_read_lock(). */ 498 /* Index returned by tomoyo_read_lock(). */
@@ -514,6 +523,8 @@ struct tomoyo_io_buffer {
514 int write_avail; 523 int write_avail;
515 /* Size of write buffer. */ 524 /* Size of write buffer. */
516 int writebuf_size; 525 int writebuf_size;
526 /* Type of this interface. */
527 u8 type;
517}; 528};
518 529
519/* 530/*
@@ -659,14 +670,15 @@ struct tomoyo_policy_manager_entry {
659 670
660/********** Function prototypes. **********/ 671/********** Function prototypes. **********/
661 672
673extern asmlinkage long sys_getpid(void);
674extern asmlinkage long sys_getppid(void);
675
662/* Check whether the given name matches the given name_union. */ 676/* Check whether the given name matches the given name_union. */
663bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, 677bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
664 const struct tomoyo_name_union *ptr); 678 const struct tomoyo_name_union *ptr);
665/* Check whether the given number matches the given number_union. */ 679/* Check whether the given number matches the given number_union. */
666bool tomoyo_compare_number_union(const unsigned long value, 680bool tomoyo_compare_number_union(const unsigned long value,
667 const struct tomoyo_number_union *ptr); 681 const struct tomoyo_number_union *ptr);
668/* Check whether the domain has too many ACL entries to hold. */
669bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
670/* Transactional sprintf() for policy dump. */ 682/* Transactional sprintf() for policy dump. */
671bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 683bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
672 __attribute__ ((format(printf, 2, 3))); 684 __attribute__ ((format(printf, 2, 3)));
@@ -763,6 +775,8 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete);
763int tomoyo_write_pattern_policy(char *data, const bool is_delete); 775int tomoyo_write_pattern_policy(char *data, const bool is_delete);
764/* Create "path_group" entry in exception policy. */ 776/* Create "path_group" entry in exception policy. */
765int tomoyo_write_path_group_policy(char *data, const bool is_delete); 777int tomoyo_write_path_group_policy(char *data, const bool is_delete);
778int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
779 __attribute__ ((format(printf, 2, 3)));
766/* Create "number_group" entry in exception policy. */ 780/* Create "number_group" entry in exception policy. */
767int tomoyo_write_number_group_policy(char *data, const bool is_delete); 781int tomoyo_write_number_group_policy(char *data, const bool is_delete);
768/* Find a domain by the given name. */ 782/* Find a domain by the given name. */
@@ -771,9 +785,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
771struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * 785struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
772 domainname, 786 domainname,
773 const u8 profile); 787 const u8 profile);
774/* Get patterned pathname. */
775const struct tomoyo_path_info *
776tomoyo_get_file_pattern(const struct tomoyo_path_info *filename);
777/* Allocate memory for "struct tomoyo_path_group". */ 788/* Allocate memory for "struct tomoyo_path_group". */
778struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name); 789struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name);
779struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name); 790struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name);
@@ -807,6 +818,8 @@ char *tomoyo_realpath(const char *pathname);
807char *tomoyo_realpath_nofollow(const char *pathname); 818char *tomoyo_realpath_nofollow(const char *pathname);
808/* Same with tomoyo_realpath() except that the pathname is already solved. */ 819/* Same with tomoyo_realpath() except that the pathname is already solved. */
809char *tomoyo_realpath_from_path(struct path *path); 820char *tomoyo_realpath_from_path(struct path *path);
821/* Get patterned pathname. */
822const char *tomoyo_file_pattern(const struct tomoyo_path_info *filename);
810 823
811/* Check memory quota. */ 824/* Check memory quota. */
812bool tomoyo_memory_ok(void *ptr); 825bool tomoyo_memory_ok(void *ptr);
@@ -878,6 +891,9 @@ extern bool tomoyo_policy_loaded;
878/* The kernel's domain. */ 891/* The kernel's domain. */
879extern struct tomoyo_domain_info tomoyo_kernel_domain; 892extern struct tomoyo_domain_info tomoyo_kernel_domain;
880 893
894extern unsigned int tomoyo_quota_for_query;
895extern unsigned int tomoyo_query_memory_size;
896
881/********** Inlined functions. **********/ 897/********** Inlined functions. **********/
882 898
883static inline int tomoyo_read_lock(void) 899static inline int tomoyo_read_lock(void)
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index afdf26128bfe..7e242d27da5a 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -678,6 +678,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
678 */ 678 */
679int tomoyo_find_next_domain(struct linux_binprm *bprm) 679int tomoyo_find_next_domain(struct linux_binprm *bprm)
680{ 680{
681 struct tomoyo_request_info r;
681 /* 682 /*
682 * This function assumes that the size of buffer returned by 683 * This function assumes that the size of buffer returned by
683 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN. 684 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
@@ -693,11 +694,12 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
693 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE); 694 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE);
694 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); 695 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING);
695 int retval = -ENOMEM; 696 int retval = -ENOMEM;
696 struct tomoyo_path_info r; /* real name */ 697 struct tomoyo_path_info rn; /* real name */
697 struct tomoyo_path_info s; /* symlink name */ 698 struct tomoyo_path_info sn; /* symlink name */
698 struct tomoyo_path_info l; /* last name */ 699 struct tomoyo_path_info ln; /* last name */
699 static bool initialized; 700 static bool initialized;
700 701
702 tomoyo_init_request_info(&r, NULL);
701 if (!tmp) 703 if (!tmp)
702 goto out; 704 goto out;
703 705
@@ -713,6 +715,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
713 initialized = true; 715 initialized = true;
714 } 716 }
715 717
718 retry:
716 /* Get tomoyo_realpath of program. */ 719 /* Get tomoyo_realpath of program. */
717 retval = -ENOENT; 720 retval = -ENOENT;
718 /* I hope tomoyo_realpath() won't fail with -ENOMEM. */ 721 /* I hope tomoyo_realpath() won't fail with -ENOMEM. */
@@ -724,37 +727,39 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
724 if (!symlink_program_name) 727 if (!symlink_program_name)
725 goto out; 728 goto out;
726 729
727 r.name = real_program_name; 730 rn.name = real_program_name;
728 tomoyo_fill_path_info(&r); 731 tomoyo_fill_path_info(&rn);
729 s.name = symlink_program_name; 732 sn.name = symlink_program_name;
730 tomoyo_fill_path_info(&s); 733 tomoyo_fill_path_info(&sn);
731 l.name = tomoyo_get_last_name(old_domain); 734 ln.name = tomoyo_get_last_name(old_domain);
732 tomoyo_fill_path_info(&l); 735 tomoyo_fill_path_info(&ln);
733 736
734 /* Check 'alias' directive. */ 737 /* Check 'alias' directive. */
735 if (tomoyo_pathcmp(&r, &s)) { 738 if (tomoyo_pathcmp(&rn, &sn)) {
736 struct tomoyo_alias_entry *ptr; 739 struct tomoyo_alias_entry *ptr;
737 /* Is this program allowed to be called via symbolic links? */ 740 /* Is this program allowed to be called via symbolic links? */
738 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { 741 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
739 if (ptr->is_deleted || 742 if (ptr->is_deleted ||
740 tomoyo_pathcmp(&r, ptr->original_name) || 743 tomoyo_pathcmp(&rn, ptr->original_name) ||
741 tomoyo_pathcmp(&s, ptr->aliased_name)) 744 tomoyo_pathcmp(&sn, ptr->aliased_name))
742 continue; 745 continue;
743 memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN); 746 memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN);
744 strncpy(real_program_name, ptr->aliased_name->name, 747 strncpy(real_program_name, ptr->aliased_name->name,
745 TOMOYO_MAX_PATHNAME_LEN - 1); 748 TOMOYO_MAX_PATHNAME_LEN - 1);
746 tomoyo_fill_path_info(&r); 749 tomoyo_fill_path_info(&rn);
747 break; 750 break;
748 } 751 }
749 } 752 }
750 753
751 /* Check execute permission. */ 754 /* Check execute permission. */
752 retval = tomoyo_check_exec_perm(old_domain, &r); 755 retval = tomoyo_check_exec_perm(old_domain, &rn);
756 if (retval == TOMOYO_RETRY_REQUEST)
757 goto retry;
753 if (retval < 0) 758 if (retval < 0)
754 goto out; 759 goto out;
755 760
756 new_domain_name = tmp->buffer; 761 new_domain_name = tmp->buffer;
757 if (tomoyo_is_domain_initializer(old_domain->domainname, &r, &l)) { 762 if (tomoyo_is_domain_initializer(old_domain->domainname, &rn, &ln)) {
758 /* Transit to the child of tomoyo_kernel_domain domain. */ 763 /* Transit to the child of tomoyo_kernel_domain domain. */
759 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1, 764 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
760 TOMOYO_ROOT_NAME " " "%s", real_program_name); 765 TOMOYO_ROOT_NAME " " "%s", real_program_name);
@@ -766,7 +771,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
766 * initializers because they might start before /sbin/init. 771 * initializers because they might start before /sbin/init.
767 */ 772 */
768 domain = old_domain; 773 domain = old_domain;
769 } else if (tomoyo_is_domain_keeper(old_domain->domainname, &r, &l)) { 774 } else if (tomoyo_is_domain_keeper(old_domain->domainname, &rn, &ln)) {
770 /* Keep current domain. */ 775 /* Keep current domain. */
771 domain = old_domain; 776 domain = old_domain;
772 } else { 777 } else {
@@ -779,8 +784,14 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
779 domain = tomoyo_find_domain(new_domain_name); 784 domain = tomoyo_find_domain(new_domain_name);
780 if (domain) 785 if (domain)
781 goto done; 786 goto done;
782 if (is_enforce) 787 if (is_enforce) {
783 goto done; 788 int error = tomoyo_supervisor(&r, "# wants to create domain\n"
789 "%s\n", new_domain_name);
790 if (error == TOMOYO_RETRY_REQUEST)
791 goto retry;
792 if (error < 0)
793 goto done;
794 }
784 domain = tomoyo_find_or_assign_new_domain(new_domain_name, 795 domain = tomoyo_find_or_assign_new_domain(new_domain_name,
785 old_domain->profile); 796 old_domain->profile);
786 done: 797 done:
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index ae32cab8ec7e..c629cb4e2c66 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -478,7 +478,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
478} 478}
479 479
480/** 480/**
481 * tomoyo_get_file_pattern - Get patterned pathname. 481 * tomoyo_file_pattern - Get patterned pathname.
482 * 482 *
483 * @filename: The filename to find patterned pathname. 483 * @filename: The filename to find patterned pathname.
484 * 484 *
@@ -486,8 +486,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
486 * 486 *
487 * Caller holds tomoyo_read_lock(). 487 * Caller holds tomoyo_read_lock().
488 */ 488 */
489const struct tomoyo_path_info * 489const char *tomoyo_file_pattern(const struct tomoyo_path_info *filename)
490tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
491{ 490{
492 struct tomoyo_pattern_entry *ptr; 491 struct tomoyo_pattern_entry *ptr;
493 const struct tomoyo_path_info *pattern = NULL; 492 const struct tomoyo_path_info *pattern = NULL;
@@ -507,7 +506,7 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
507 } 506 }
508 if (pattern) 507 if (pattern)
509 filename = pattern; 508 filename = pattern;
510 return filename; 509 return filename->name;
511} 510}
512 511
513/** 512/**
@@ -812,23 +811,25 @@ static int tomoyo_file_perm(struct tomoyo_request_info *r,
812 perm = 1 << TOMOYO_TYPE_EXECUTE; 811 perm = 1 << TOMOYO_TYPE_EXECUTE;
813 } else 812 } else
814 BUG(); 813 BUG();
815 error = tomoyo_path_acl(r, filename, perm, mode != 1); 814 do {
816 if (error && mode == 4 && !r->domain->ignore_global_allow_read 815 error = tomoyo_path_acl(r, filename, perm, mode != 1);
817 && tomoyo_is_globally_readable_file(filename)) 816 if (error && mode == 4 && !r->domain->ignore_global_allow_read
817 && tomoyo_is_globally_readable_file(filename))
818 error = 0;
819 if (!error)
820 break;
821 tomoyo_warn_log(r, "%s %s", msg, filename->name);
822 error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
823 mode == 1 ? filename->name :
824 tomoyo_file_pattern(filename));
825 /*
826 * Do not retry for execute request, for alias may have
827 * changed.
828 */
829 } while (error == TOMOYO_RETRY_REQUEST && mode != 1);
830 if (r->mode != TOMOYO_CONFIG_ENFORCING)
818 error = 0; 831 error = 0;
819 if (!error) 832 return error;
820 return 0;
821 tomoyo_warn_log(r, "%s %s", msg, filename->name);
822 if (r->mode == TOMOYO_CONFIG_ENFORCING)
823 return error;
824 if (tomoyo_domain_quota_is_ok(r)) {
825 /* Don't use patterns for execute permission. */
826 const struct tomoyo_path_info *patterned_file = (mode != 1) ?
827 tomoyo_get_file_pattern(filename) : filename;
828 tomoyo_update_file_acl(mode, patterned_file->name, r->domain,
829 false);
830 }
831 return 0;
832} 833}
833 834
834/** 835/**
@@ -1123,21 +1124,21 @@ static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type,
1123static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 1124static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
1124 const struct tomoyo_path_info *filename) 1125 const struct tomoyo_path_info *filename)
1125{ 1126{
1127 const char *msg;
1126 int error; 1128 int error;
1127 1129
1128 next: 1130 next:
1129 error = tomoyo_path_acl(r, filename, 1 << operation, 1); 1131 do {
1130 if (!error) 1132 error = tomoyo_path_acl(r, filename, 1 << operation, 1);
1131 goto ok; 1133 if (!error)
1132 tomoyo_warn_log(r, "%s %s", tomoyo_path2keyword(operation), 1134 break;
1133 filename->name); 1135 msg = tomoyo_path2keyword(operation);
1134 if (tomoyo_domain_quota_is_ok(r)) { 1136 tomoyo_warn_log(r, "%s %s", msg, filename->name);
1135 const char *name = tomoyo_get_file_pattern(filename)->name; 1137 error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
1136 tomoyo_update_path_acl(operation, name, r->domain, false); 1138 tomoyo_file_pattern(filename));
1137 } 1139 } while (error == TOMOYO_RETRY_REQUEST);
1138 if (r->mode != TOMOYO_CONFIG_ENFORCING) 1140 if (r->mode != TOMOYO_CONFIG_ENFORCING)
1139 error = 0; 1141 error = 0;
1140 ok:
1141 /* 1142 /*
1142 * Since "allow_truncate" doesn't imply "allow_rewrite" permission, 1143 * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
1143 * we need to check "allow_rewrite" permission if the filename is 1144 * we need to check "allow_rewrite" permission if the filename is
@@ -1267,6 +1268,7 @@ static int tomoyo_path_number_perm2(struct tomoyo_request_info *r,
1267 char buffer[64]; 1268 char buffer[64];
1268 int error; 1269 int error;
1269 u8 radix; 1270 u8 radix;
1271 const char *msg;
1270 1272
1271 if (!filename) 1273 if (!filename)
1272 return 0; 1274 return 0;
@@ -1286,15 +1288,16 @@ static int tomoyo_path_number_perm2(struct tomoyo_request_info *r,
1286 break; 1288 break;
1287 } 1289 }
1288 tomoyo_print_ulong(buffer, sizeof(buffer), number, radix); 1290 tomoyo_print_ulong(buffer, sizeof(buffer), number, radix);
1289 error = tomoyo_path_number_acl(r, type, filename, number); 1291 do {
1290 if (!error) 1292 error = tomoyo_path_number_acl(r, type, filename, number);
1291 return 0; 1293 if (!error)
1292 tomoyo_warn_log(r, "%s %s %s", tomoyo_path_number2keyword(type), 1294 break;
1293 filename->name, buffer); 1295 msg = tomoyo_path_number2keyword(type);
1294 if (tomoyo_domain_quota_is_ok(r)) 1296 tomoyo_warn_log(r, "%s %s %s", msg, filename->name, buffer);
1295 tomoyo_update_path_number_acl(type, 1297 error = tomoyo_supervisor(r, "allow_%s %s %s\n", msg,
1296 tomoyo_get_file_pattern(filename) 1298 tomoyo_file_pattern(filename),
1297 ->name, buffer, r->domain, false); 1299 buffer);
1300 } while (error == TOMOYO_RETRY_REQUEST);
1298 if (r->mode != TOMOYO_CONFIG_ENFORCING) 1301 if (r->mode != TOMOYO_CONFIG_ENFORCING)
1299 error = 0; 1302 error = 0;
1300 return error; 1303 return error;
@@ -1484,32 +1487,23 @@ static int tomoyo_path_number3_perm2(struct tomoyo_request_info *r,
1484 const unsigned int dev) 1487 const unsigned int dev)
1485{ 1488{
1486 int error; 1489 int error;
1490 const char *msg;
1487 const unsigned int major = MAJOR(dev); 1491 const unsigned int major = MAJOR(dev);
1488 const unsigned int minor = MINOR(dev); 1492 const unsigned int minor = MINOR(dev);
1489 1493
1490 error = tomoyo_path_number3_acl(r, filename, 1 << operation, mode, 1494 do {
1491 major, minor); 1495 error = tomoyo_path_number3_acl(r, filename, 1 << operation,
1492 if (!error) 1496 mode, major, minor);
1493 return 0; 1497 if (!error)
1494 tomoyo_warn_log(r, "%s %s 0%o %u %u", 1498 break;
1495 tomoyo_path_number32keyword(operation), 1499 msg = tomoyo_path_number32keyword(operation);
1496 filename->name, mode, major, minor); 1500 tomoyo_warn_log(r, "%s %s 0%o %u %u", msg, filename->name,
1497 if (tomoyo_domain_quota_is_ok(r)) { 1501 mode, major, minor);
1498 char mode_buf[64]; 1502 error = tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", msg,
1499 char major_buf[64]; 1503 tomoyo_file_pattern(filename), mode,
1500 char minor_buf[64]; 1504 major, minor);
1501 memset(mode_buf, 0, sizeof(mode_buf)); 1505 } while (error == TOMOYO_RETRY_REQUEST);
1502 memset(major_buf, 0, sizeof(major_buf)); 1506 if (r->mode != TOMOYO_CONFIG_ENFORCING)
1503 memset(minor_buf, 0, sizeof(minor_buf));
1504 snprintf(mode_buf, sizeof(mode_buf) - 1, "0%o", mode);
1505 snprintf(major_buf, sizeof(major_buf) - 1, "%u", major);
1506 snprintf(minor_buf, sizeof(minor_buf) - 1, "%u", minor);
1507 tomoyo_update_path_number3_acl(operation,
1508 tomoyo_get_file_pattern(filename)
1509 ->name, mode_buf, major_buf,
1510 minor_buf, r->domain, false);
1511 }
1512 if (r->mode != TOMOYO_CONFIG_ENFORCING)
1513 error = 0; 1507 error = 0;
1514 return error; 1508 return error;
1515} 1509}
@@ -1562,6 +1556,7 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1562 struct path *path2) 1556 struct path *path2)
1563{ 1557{
1564 int error = -ENOMEM; 1558 int error = -ENOMEM;
1559 const char *msg;
1565 struct tomoyo_path_info *buf1; 1560 struct tomoyo_path_info *buf1;
1566 struct tomoyo_path_info *buf2; 1561 struct tomoyo_path_info *buf2;
1567 struct tomoyo_request_info r; 1562 struct tomoyo_request_info r;
@@ -1591,17 +1586,16 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1591 } 1586 }
1592 } 1587 }
1593 } 1588 }
1594 error = tomoyo_path2_acl(&r, operation, buf1, buf2); 1589 do {
1595 if (!error) 1590 error = tomoyo_path2_acl(&r, operation, buf1, buf2);
1596 goto out; 1591 if (!error)
1597 tomoyo_warn_log(&r, "%s %s %s", tomoyo_path22keyword(operation), 1592 break;
1598 buf1->name, buf2->name); 1593 msg = tomoyo_path22keyword(operation);
1599 if (tomoyo_domain_quota_is_ok(&r)) { 1594 tomoyo_warn_log(&r, "%s %s %s", msg, buf1->name, buf2->name);
1600 const char *name1 = tomoyo_get_file_pattern(buf1)->name; 1595 error = tomoyo_supervisor(&r, "allow_%s %s %s\n", msg,
1601 const char *name2 = tomoyo_get_file_pattern(buf2)->name; 1596 tomoyo_file_pattern(buf1),
1602 tomoyo_update_path2_acl(operation, name1, name2, r.domain, 1597 tomoyo_file_pattern(buf2));
1603 false); 1598 } while (error == TOMOYO_RETRY_REQUEST);
1604 }
1605 out: 1599 out:
1606 kfree(buf1); 1600 kfree(buf1);
1607 kfree(buf2); 1601 kfree(buf2);
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 507be09e93a9..aeac619f787d 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -178,19 +178,12 @@ static int tomoyo_mount_acl2(struct tomoyo_request_info *r, char *dev_name,
178 error = 0; 178 error = 0;
179 break; 179 break;
180 } 180 }
181 if (error) { 181 if (error)
182 const char *dev = tomoyo_get_file_pattern(&rdev)->name; 182 error = tomoyo_supervisor(r, TOMOYO_KEYWORD_ALLOW_MOUNT
183 const char *dir = tomoyo_get_file_pattern(&rdir)->name; 183 "%s %s %s 0x%lX\n",
184 int len = strlen(dev) + strlen(dir) + strlen(requested_type) 184 tomoyo_file_pattern(&rdev),
185 + 64; 185 tomoyo_file_pattern(&rdir),
186 char *buf = kzalloc(len, GFP_NOFS); 186 requested_type, flags);
187 if (buf) {
188 snprintf(buf, len - 1, "%s %s %s 0x%lX",
189 dev, dir, requested_type, flags);
190 tomoyo_write_mount_policy(buf, r->domain, false);
191 kfree(buf);
192 }
193 }
194 out: 187 out:
195 kfree(requested_dev_name); 188 kfree(requested_dev_name);
196 kfree(requested_dir_name); 189 kfree(requested_dir_name);
@@ -279,7 +272,10 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
279 TOMOYO_MOUNT_MAKE_SHARED_KEYWORD, 272 TOMOYO_MOUNT_MAKE_SHARED_KEYWORD,
280 flags & ~MS_SHARED); 273 flags & ~MS_SHARED);
281 else 274 else
282 error = tomoyo_mount_acl2(r, dev_name, dir, type, flags); 275 do {
276 error = tomoyo_mount_acl2(r, dev_name, dir, type,
277 flags);
278 } while (error == TOMOYO_RETRY_REQUEST);
283 if (r->mode != TOMOYO_CONFIG_ENFORCING) 279 if (r->mode != TOMOYO_CONFIG_ENFORCING)
284 error = 0; 280 error = 0;
285 return error; 281 return error;
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index d1b96f019621..3ceb1724c92d 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -333,6 +333,9 @@ void __init tomoyo_realpath_init(void)
333 panic("Can't register tomoyo_kernel_domain"); 333 panic("Can't register tomoyo_kernel_domain");
334} 334}
335 335
336unsigned int tomoyo_quota_for_query;
337unsigned int tomoyo_query_memory_size;
338
336/** 339/**
337 * tomoyo_read_memory_counter - Check for memory usage in bytes. 340 * tomoyo_read_memory_counter - Check for memory usage in bytes.
338 * 341 *
@@ -345,6 +348,7 @@ int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
345 if (!head->read_eof) { 348 if (!head->read_eof) {
346 const unsigned int policy 349 const unsigned int policy
347 = atomic_read(&tomoyo_policy_memory_size); 350 = atomic_read(&tomoyo_policy_memory_size);
351 const unsigned int query = tomoyo_query_memory_size;
348 char buffer[64]; 352 char buffer[64];
349 353
350 memset(buffer, 0, sizeof(buffer)); 354 memset(buffer, 0, sizeof(buffer));
@@ -354,8 +358,17 @@ int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
354 tomoyo_quota_for_policy); 358 tomoyo_quota_for_policy);
355 else 359 else
356 buffer[0] = '\0'; 360 buffer[0] = '\0';
357 tomoyo_io_printf(head, "Policy: %10u%s\n", policy, buffer); 361 tomoyo_io_printf(head, "Policy: %10u%s\n", policy,
358 tomoyo_io_printf(head, "Total: %10u\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);
359 head->read_eof = true; 372 head->read_eof = true;
360 } 373 }
361 return 0; 374 return 0;
@@ -375,5 +388,7 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
375 388
376 if (sscanf(data, "Policy: %u", &size) == 1) 389 if (sscanf(data, "Policy: %u", &size) == 1)
377 tomoyo_quota_for_policy = size; 390 tomoyo_quota_for_policy = size;
391 else if (sscanf(data, "Query lists: %u", &size) == 1)
392 tomoyo_quota_for_query = size;
378 return 0; 393 return 0;
379} 394}