12 |
|
|
13 |
#include "internal.h" |
#include "internal.h" |
14 |
|
|
15 |
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) |
16 |
|
|
17 |
|
/** |
18 |
|
* __wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses. |
19 |
|
* |
20 |
|
* @wq: The waitqueue to wait on. |
21 |
|
* @condition: A C expression for the event to wait for. |
22 |
|
* @ret: Timeout, in jiffies. |
23 |
|
* |
24 |
|
* Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a |
25 |
|
* signal, and the remaining jiffies otherwise if the condition evaluated to |
26 |
|
* true before the timeout elapsed. |
27 |
|
* |
28 |
|
* This is for compatibility with older kernels. |
29 |
|
*/ |
30 |
|
#define __wait_event_interruptible_timeout(wq, condition, ret) \ |
31 |
|
do { \ |
32 |
|
wait_queue_t __wait; \ |
33 |
|
init_waitqueue_entry(&__wait, current); \ |
34 |
|
\ |
35 |
|
add_wait_queue(&wq, &__wait); \ |
36 |
|
for (;;) { \ |
37 |
|
set_current_state(TASK_INTERRUPTIBLE); \ |
38 |
|
if (condition) \ |
39 |
|
break; \ |
40 |
|
if (!signal_pending(current)) { \ |
41 |
|
ret = schedule_timeout(ret); \ |
42 |
|
if (!ret) \ |
43 |
|
break; \ |
44 |
|
continue; \ |
45 |
|
} \ |
46 |
|
ret = -ERESTARTSYS; \ |
47 |
|
break; \ |
48 |
|
} \ |
49 |
|
current->state = TASK_RUNNING; \ |
50 |
|
remove_wait_queue(&wq, &__wait); \ |
51 |
|
} while (0) |
52 |
|
|
53 |
|
/** |
54 |
|
* wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses. |
55 |
|
* |
56 |
|
* @wq: The waitqueue to wait on. |
57 |
|
* @condition: A C expression for the event to wait for. |
58 |
|
* @timeout: Timeout, in jiffies. |
59 |
|
* |
60 |
|
* Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a |
61 |
|
* signal, and the remaining jiffies otherwise if the condition evaluated to |
62 |
|
* true before the timeout elapsed. |
63 |
|
* |
64 |
|
* This is for compatibility with older kernels. |
65 |
|
*/ |
66 |
|
#define wait_event_interruptible_timeout(wq, condition, timeout) \ |
67 |
|
({ \ |
68 |
|
long __ret = timeout; \ |
69 |
|
if (!(condition)) \ |
70 |
|
__wait_event_interruptible_timeout(wq, condition, __ret); \ |
71 |
|
__ret; \ |
72 |
|
}) |
73 |
|
|
74 |
|
#endif |
75 |
|
|
76 |
|
/** |
77 |
|
* list_for_each_cookie - iterate over a list with cookie. |
78 |
|
* |
79 |
|
* @pos: Pointer to "struct list_head". |
80 |
|
* @head: Pointer to "struct list_head". |
81 |
|
*/ |
82 |
|
#define list_for_each_cookie(pos, head) \ |
83 |
|
for (pos = pos ? pos : srcu_dereference((head)->next, &ccs_ss); \ |
84 |
|
pos != (head); pos = srcu_dereference(pos->next, &ccs_ss)) |
85 |
|
|
86 |
|
|
87 |
/* Profile version. Currently only 20100903 is defined. */ |
/* Profile version. Currently only 20100903 is defined. */ |
88 |
static unsigned int ccs_profile_version; |
static unsigned int ccs_profile_version; |
89 |
|
|
287 |
__attribute__ ((format(printf, 3, 4))); |
__attribute__ ((format(printf, 3, 4))); |
288 |
|
|
289 |
/** |
/** |
290 |
* ccs_addprintf - snprint()-like-strncat(). |
* ccs_addprintf - strncat()-like-snprintf(). |
291 |
* |
* |
292 |
* @buffer: Buffer to write to. Must be '\0'-terminated. |
* @buffer: Buffer to write to. Must be '\0'-terminated. |
293 |
* @len: Size of @buffer. |
* @len: Size of @buffer. |
353 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
354 |
* @string: String to print. |
* @string: String to print. |
355 |
* |
* |
356 |
|
* Returns nothing. |
357 |
|
* |
358 |
* Note that @string has to be kept valid until @head is kfree()d. |
* Note that @string has to be kept valid until @head is kfree()d. |
359 |
* This means that char[] allocated on stack memory cannot be passed to |
* This means that char[] allocated on stack memory cannot be passed to |
360 |
* this function. Use ccs_io_printf() for char[] allocated on stack memory. |
* this function. Use ccs_io_printf() for char[] allocated on stack memory. |
|
* |
|
|
* Returns nothing. |
|
361 |
*/ |
*/ |
362 |
static void ccs_set_string(struct ccs_io_buffer *head, const char *string) |
static void ccs_set_string(struct ccs_io_buffer *head, const char *string) |
363 |
{ |
{ |
690 |
* ccs_read_profile - Read profile table. |
* ccs_read_profile - Read profile table. |
691 |
* |
* |
692 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
693 |
|
* |
694 |
|
* Returns nothing. |
695 |
*/ |
*/ |
696 |
static void ccs_read_profile(struct ccs_io_buffer *head) |
static void ccs_read_profile(struct ccs_io_buffer *head) |
697 |
{ |
{ |
836 |
* |
* |
837 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
838 |
* |
* |
839 |
|
* Returns nothing. |
840 |
|
* |
841 |
* Caller holds ccs_read_lock(). |
* Caller holds ccs_read_lock(). |
842 |
*/ |
*/ |
843 |
static void ccs_read_manager(struct ccs_io_buffer *head) |
static void ccs_read_manager(struct ccs_io_buffer *head) |
1596 |
* @domain: Pointer to "struct ccs_domain_info". |
* @domain: Pointer to "struct ccs_domain_info". |
1597 |
* @index: Index number. |
* @index: Index number. |
1598 |
* |
* |
|
* Caller holds ccs_read_lock(). |
|
|
* |
|
1599 |
* Returns true on success, false otherwise. |
* Returns true on success, false otherwise. |
1600 |
|
* |
1601 |
|
* Caller holds ccs_read_lock(). |
1602 |
*/ |
*/ |
1603 |
static bool ccs_read_domain2(struct ccs_io_buffer *head, |
static bool ccs_read_domain2(struct ccs_io_buffer *head, |
1604 |
struct ccs_domain_info *domain, |
struct ccs_domain_info *domain, |
1619 |
* |
* |
1620 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
1621 |
* |
* |
1622 |
|
* Returns nothing. |
1623 |
|
* |
1624 |
* Caller holds ccs_read_lock(). |
* Caller holds ccs_read_lock(). |
1625 |
*/ |
*/ |
1626 |
static void ccs_read_domain(struct ccs_io_buffer *head) |
static void ccs_read_domain(struct ccs_io_buffer *head) |
1707 |
* |
* |
1708 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
1709 |
* |
* |
1710 |
|
* Returns nothing. |
1711 |
|
* |
1712 |
* This is equivalent to doing |
* This is equivalent to doing |
1713 |
* |
* |
1714 |
* grep -A 1 '^<kernel>' /proc/ccs/domain_policy | |
* grep -A 1 '^<kernel>' /proc/ccs/domain_policy | |
1994 |
* |
* |
1995 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
1996 |
* |
* |
1997 |
|
* Returns nothing. |
1998 |
|
* |
1999 |
* Caller holds ccs_read_lock(). |
* Caller holds ccs_read_lock(). |
2000 |
*/ |
*/ |
2001 |
static void ccs_read_exception(struct ccs_io_buffer *head) |
static void ccs_read_exception(struct ccs_io_buffer *head) |
2030 |
/* Wait queue for userspace -> kernel notification. */ |
/* Wait queue for userspace -> kernel notification. */ |
2031 |
static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait); |
static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait); |
2032 |
|
|
|
/* Lock for manipulating ccs_query_list. */ |
|
|
static DEFINE_SPINLOCK(ccs_query_list_lock); |
|
|
|
|
2033 |
/* Structure for query. */ |
/* Structure for query. */ |
2034 |
struct ccs_query { |
struct ccs_query { |
2035 |
struct list_head list; |
struct list_head list; |
2044 |
/* The list for "struct ccs_query". */ |
/* The list for "struct ccs_query". */ |
2045 |
static LIST_HEAD(ccs_query_list); |
static LIST_HEAD(ccs_query_list); |
2046 |
|
|
2047 |
|
/* Lock for manipulating ccs_query_list. */ |
2048 |
|
static DEFINE_SPINLOCK(ccs_query_list_lock); |
2049 |
|
|
2050 |
/* Number of "struct file" referring /proc/ccs/query interface. */ |
/* Number of "struct file" referring /proc/ccs/query interface. */ |
2051 |
static atomic_t ccs_query_observers = ATOMIC_INIT(0); |
static atomic_t ccs_query_observers = ATOMIC_INIT(0); |
2052 |
|
|
2148 |
va_start(args, fmt); |
va_start(args, fmt); |
2149 |
len = vsnprintf((char *) &len, 1, fmt, args) + 1; |
len = vsnprintf((char *) &len, 1, fmt, args) + 1; |
2150 |
va_end(args); |
va_end(args); |
2151 |
/* Write /proc/ccs/grant_log or /proc/ccs/reject_log . */ |
/* Write /proc/ccs/grant_log or /proc/ccs/reject_log. */ |
2152 |
va_start(args, fmt); |
va_start(args, fmt); |
2153 |
ccs_write_log2(r, len, fmt, args); |
ccs_write_log2(r, len, fmt, args); |
2154 |
va_end(args); |
va_end(args); |
2543 |
* @type: Type of interface. |
* @type: Type of interface. |
2544 |
* @file: Pointer to "struct file". |
* @file: Pointer to "struct file". |
2545 |
* |
* |
2546 |
* Associates policy handler and returns 0 on success, -ENOMEM otherwise. |
* Returns 0 on success, negative value otherwise. |
2547 |
*/ |
*/ |
2548 |
int ccs_open_control(const u8 type, struct file *file) |
int ccs_open_control(const u8 type, struct file *file) |
2549 |
{ |
{ |
2642 |
} |
} |
2643 |
} |
} |
2644 |
/* |
/* |
2645 |
* If the file is /proc/ccs/query , increment the observer counter. |
* If the file is /proc/ccs/query, increment the observer counter. |
2646 |
* The obserber counter is used by ccs_supervisor() to see if |
* The obserber counter is used by ccs_supervisor() to see if |
2647 |
* there is some process monitoring /proc/ccs/query. |
* there is some process monitoring /proc/ccs/query. |
2648 |
*/ |
*/ |
2667 |
* Waits for read readiness. |
* Waits for read readiness. |
2668 |
* /proc/ccs/query is handled by /usr/sbin/ccs-queryd and |
* /proc/ccs/query is handled by /usr/sbin/ccs-queryd and |
2669 |
* /proc/ccs/grant_log and /proc/ccs/reject_log are handled by |
* /proc/ccs/grant_log and /proc/ccs/reject_log are handled by |
2670 |
* /usr/sbin/ccs-auditd . |
* /usr/sbin/ccs-auditd. |
2671 |
*/ |
*/ |
2672 |
int ccs_poll_control(struct file *file, poll_table *wait) |
int ccs_poll_control(struct file *file, poll_table *wait) |
2673 |
{ |
{ |
2792 |
* |
* |
2793 |
* @file: Pointer to "struct file". |
* @file: Pointer to "struct file". |
2794 |
* |
* |
2795 |
* Releases memory and returns 0. |
* Returns 0. |
2796 |
*/ |
*/ |
2797 |
int ccs_close_control(struct file *file) |
int ccs_close_control(struct file *file) |
2798 |
{ |
{ |
2800 |
const bool is_write = head->write_buf != NULL; |
const bool is_write = head->write_buf != NULL; |
2801 |
const u8 type = head->type; |
const u8 type = head->type; |
2802 |
/* |
/* |
2803 |
* If the file is /proc/ccs/query , decrement the observer counter. |
* If the file is /proc/ccs/query, decrement the observer counter. |
2804 |
*/ |
*/ |
2805 |
if (type == CCS_QUERY) { |
if (type == CCS_QUERY) { |
2806 |
if (atomic_dec_and_test(&ccs_query_observers)) |
if (atomic_dec_and_test(&ccs_query_observers)) |