aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c426
1 files changed, 419 insertions, 7 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,