5 |
* |
* |
6 |
* Copyright (C) 2005-2008 NTT DATA CORPORATION |
* Copyright (C) 2005-2008 NTT DATA CORPORATION |
7 |
* |
* |
8 |
* Version: 1.6.1 2008/06/05 |
* Version: 1.6.4 2008/09/03 |
9 |
* |
* |
10 |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
11 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
45 |
#endif |
#endif |
46 |
|
|
47 |
/* Set default specified by the kernel config. */ |
/* Set default specified by the kernel config. */ |
48 |
|
#ifdef CONFIG_TOMOYO |
49 |
#define MAX_ACCEPT_ENTRY (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY) |
#define MAX_ACCEPT_ENTRY (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY) |
50 |
#define MAX_GRANT_LOG (CONFIG_TOMOYO_MAX_GRANT_LOG) |
#define MAX_GRANT_LOG (CONFIG_TOMOYO_MAX_GRANT_LOG) |
51 |
#define MAX_REJECT_LOG (CONFIG_TOMOYO_MAX_REJECT_LOG) |
#define MAX_REJECT_LOG (CONFIG_TOMOYO_MAX_REJECT_LOG) |
52 |
|
#else |
53 |
|
#define MAX_ACCEPT_ENTRY 0 |
54 |
|
#define MAX_GRANT_LOG 0 |
55 |
|
#define MAX_REJECT_LOG 0 |
56 |
|
#endif |
57 |
|
|
58 |
/* Has /sbin/init started? */ |
/* Has /sbin/init started? */ |
59 |
bool sbin_init_started = false; |
bool sbin_init_started = false; |
94 |
[CCS_TOMOYO_MAX_REJECT_LOG] |
[CCS_TOMOYO_MAX_REJECT_LOG] |
95 |
= { "MAX_REJECT_LOG", MAX_REJECT_LOG, INT_MAX }, |
= { "MAX_REJECT_LOG", MAX_REJECT_LOG, INT_MAX }, |
96 |
[CCS_TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, |
[CCS_TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, |
|
[CCS_ALLOW_ENFORCE_GRACE] = { "ALLOW_ENFORCE_GRACE", 0, 1 }, |
|
97 |
[CCS_SLEEP_PERIOD] |
[CCS_SLEEP_PERIOD] |
98 |
= { "SLEEP_PERIOD", 0, 3000 }, /* in 0.1 second */ |
= { "SLEEP_PERIOD", 0, 3000 }, /* in 0.1 second */ |
99 |
}; |
}; |
189 |
*/ |
*/ |
190 |
static bool is_decimal(const char c) |
static bool is_decimal(const char c) |
191 |
{ |
{ |
192 |
return (c >= '0' && c <= '9'); |
return c >= '0' && c <= '9'; |
193 |
} |
} |
194 |
|
|
195 |
/** |
/** |
201 |
*/ |
*/ |
202 |
static bool is_hexadecimal(const char c) |
static bool is_hexadecimal(const char c) |
203 |
{ |
{ |
204 |
return ((c >= '0' && c <= '9') || |
return (c >= '0' && c <= '9') || |
205 |
(c >= 'A' && c <= 'F') || |
(c >= 'A' && c <= 'F') || |
206 |
(c >= 'a' && c <= 'f')); |
(c >= 'a' && c <= 'f'); |
207 |
} |
} |
208 |
|
|
209 |
/** |
/** |
215 |
*/ |
*/ |
216 |
static bool is_alphabet_char(const char c) |
static bool is_alphabet_char(const char c) |
217 |
{ |
{ |
218 |
return ((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')); |
return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); |
219 |
} |
} |
220 |
|
|
221 |
/** |
/** |
670 |
while (*pattern == '\\' && |
while (*pattern == '\\' && |
671 |
(*(pattern + 1) == '*' || *(pattern + 1) == '@')) |
(*(pattern + 1) == '*' || *(pattern + 1) == '@')) |
672 |
pattern += 2; |
pattern += 2; |
673 |
return (filename == filename_end && pattern == pattern_end); |
return filename == filename_end && pattern == pattern_end; |
674 |
} |
} |
675 |
|
|
676 |
/** |
/** |
772 |
while (*p == '\\' && |
while (*p == '\\' && |
773 |
(*(p + 1) == '*' || *(p + 1) == '@')) |
(*(p + 1) == '*' || *(p + 1) == '@')) |
774 |
p += 2; |
p += 2; |
775 |
return (!*f && !*p); |
return !*f && !*p; |
776 |
} |
} |
777 |
|
|
778 |
/** |
/** |
1125 |
switch (i) { |
switch (i) { |
1126 |
case CCS_SAKURA_RESTRICT_AUTOBIND: |
case CCS_SAKURA_RESTRICT_AUTOBIND: |
1127 |
case CCS_TOMOYO_VERBOSE: |
case CCS_TOMOYO_VERBOSE: |
|
case CCS_ALLOW_ENFORCE_GRACE: |
|
1128 |
modes = mode_2; |
modes = mode_2; |
1129 |
break; |
break; |
1130 |
default: |
default: |
2371 |
envp[2] = NULL; |
envp[2] = NULL; |
2372 |
call_usermodehelper(argv[0], argv, envp, 1); |
call_usermodehelper(argv[0], argv, envp, 1); |
2373 |
} |
} |
2374 |
|
#elif defined(TASK_DEAD) |
2375 |
|
{ |
2376 |
|
/* Copied from kernel/kmod.c */ |
2377 |
|
struct task_struct *task = current; |
2378 |
|
pid_t pid = kernel_thread(run_ccs_loader, NULL, 0); |
2379 |
|
sigset_t tmpsig; |
2380 |
|
spin_lock_irq(&task->sighand->siglock); |
2381 |
|
tmpsig = task->blocked; |
2382 |
|
siginitsetinv(&task->blocked, |
2383 |
|
sigmask(SIGKILL) | sigmask(SIGSTOP)); |
2384 |
|
recalc_sigpending(); |
2385 |
|
spin_unlock_irq(¤t->sighand->siglock); |
2386 |
|
if (pid >= 0) |
2387 |
|
waitpid(pid, NULL, __WCLONE); |
2388 |
|
spin_lock_irq(&task->sighand->siglock); |
2389 |
|
task->blocked = tmpsig; |
2390 |
|
recalc_sigpending(); |
2391 |
|
spin_unlock_irq(&task->sighand->siglock); |
2392 |
|
} |
2393 |
#else |
#else |
2394 |
{ |
{ |
2395 |
/* Copied from kernel/kmod.c */ |
/* Copied from kernel/kmod.c */ |
2411 |
} |
} |
2412 |
#endif |
#endif |
2413 |
#ifdef CONFIG_SAKURA |
#ifdef CONFIG_SAKURA |
2414 |
printk(KERN_INFO "SAKURA: 1.6.1 2008/06/05\n"); |
printk(KERN_INFO "SAKURA: 1.6.4 2008/09/03\n"); |
2415 |
#endif |
#endif |
2416 |
#ifdef CONFIG_TOMOYO |
#ifdef CONFIG_TOMOYO |
2417 |
printk(KERN_INFO "TOMOYO: 1.6.1 2008/06/05\n"); |
printk(KERN_INFO "TOMOYO: 1.6.4 2008/09/03\n"); |
2418 |
#endif |
#endif |
2419 |
printk(KERN_INFO "Mandatory Access Control activated.\n"); |
printk(KERN_INFO "Mandatory Access Control activated.\n"); |
2420 |
sbin_init_started = true; |
sbin_init_started = true; |
2456 |
/** |
/** |
2457 |
* ccs_check_supervisor - Ask for the supervisor's decision. |
* ccs_check_supervisor - Ask for the supervisor's decision. |
2458 |
* |
* |
2459 |
* @fmt: The printf()'s format string, followed by parameters. |
* @bprm: Pointer to "struct linux_binprm". May be NULL. |
2460 |
|
* @fmt: The printf()'s format string, followed by parameters. |
2461 |
* |
* |
2462 |
* Returns 0 if the supervisor decided to permit the access request which |
* Returns 0 if the supervisor decided to permit the access request which |
2463 |
* violated the policy in enforcing mode, -EPERM otherwise. |
* violated the policy in enforcing mode, -EPERM otherwise. |
2464 |
*/ |
*/ |
2465 |
int ccs_check_supervisor(const char *fmt, ...) |
int ccs_check_supervisor(struct linux_binprm *bprm, const char *fmt, ...) |
2466 |
{ |
{ |
2467 |
va_list args; |
va_list args; |
2468 |
int error = -EPERM; |
int error = -EPERM; |
2469 |
int pos; |
int pos; |
2470 |
int len; |
int len; |
2471 |
static unsigned int serial; |
static unsigned int serial; |
2472 |
struct query_entry *query_entry; |
struct query_entry *query_entry = NULL; |
2473 |
if (!ccs_check_flags(CCS_ALLOW_ENFORCE_GRACE) |
char *header; |
2474 |
|| !atomic_read(&queryd_watcher)) { |
if (!atomic_read(&queryd_watcher)) { |
2475 |
int i; |
int i; |
2476 |
if (current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) |
if (current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) |
2477 |
return -EPERM; |
return -EPERM; |
2484 |
va_start(args, fmt); |
va_start(args, fmt); |
2485 |
len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32; |
len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32; |
2486 |
va_end(args); |
va_end(args); |
2487 |
|
#ifdef CONFIG_TOMOYO |
2488 |
|
header = ccs_init_audit_log(&len, current->domain_info->profile, |
2489 |
|
3, bprm); |
2490 |
|
#else |
2491 |
|
header = ccs_alloc(1); |
2492 |
|
#endif |
2493 |
|
if (!header) |
2494 |
|
goto out; |
2495 |
query_entry = ccs_alloc(sizeof(*query_entry)); |
query_entry = ccs_alloc(sizeof(*query_entry)); |
2496 |
if (!query_entry) |
if (!query_entry) |
2497 |
goto out; |
goto out; |
2504 |
query_entry->serial = serial++; |
query_entry->serial = serial++; |
2505 |
spin_unlock(&query_lock); |
spin_unlock(&query_lock); |
2506 |
/***** CRITICAL SECTION END *****/ |
/***** CRITICAL SECTION END *****/ |
2507 |
pos = snprintf(query_entry->query, len - 1, "Q%u\n", |
pos = snprintf(query_entry->query, len - 1, "Q%u\n%s", |
2508 |
query_entry->serial); |
query_entry->serial, header); |
2509 |
|
ccs_free(header); |
2510 |
|
header = NULL; |
2511 |
va_start(args, fmt); |
va_start(args, fmt); |
2512 |
vsnprintf(query_entry->query + pos, len - 1 - pos, fmt, args); |
vsnprintf(query_entry->query + pos, len - 1 - pos, fmt, args); |
2513 |
query_entry->query_len = strlen(query_entry->query) + 1; |
query_entry->query_len = strlen(query_entry->query) + 1; |
2520 |
ccs_update_counter(CCS_UPDATES_COUNTER_QUERY); |
ccs_update_counter(CCS_UPDATES_COUNTER_QUERY); |
2521 |
/* Give 10 seconds for supervisor's opinion. */ |
/* Give 10 seconds for supervisor's opinion. */ |
2522 |
for (query_entry->timer = 0; atomic_read(&queryd_watcher) |
for (query_entry->timer = 0; atomic_read(&queryd_watcher) |
|
&& ccs_check_flags(CCS_ALLOW_ENFORCE_GRACE) |
|
2523 |
&& query_entry->timer < 100; query_entry->timer++) { |
&& query_entry->timer < 100; query_entry->timer++) { |
2524 |
wake_up(&query_wait); |
wake_up(&query_wait); |
2525 |
set_current_state(TASK_INTERRUPTIBLE); |
set_current_state(TASK_INTERRUPTIBLE); |
2549 |
if (query_entry) |
if (query_entry) |
2550 |
ccs_free(query_entry->query); |
ccs_free(query_entry->query); |
2551 |
ccs_free(query_entry); |
ccs_free(query_entry); |
2552 |
|
ccs_free(header); |
2553 |
return error; |
return error; |
2554 |
} |
} |
2555 |
|
|
2764 |
static int read_version(struct ccs_io_buffer *head) |
static int read_version(struct ccs_io_buffer *head) |
2765 |
{ |
{ |
2766 |
if (!head->read_eof) { |
if (!head->read_eof) { |
2767 |
ccs_io_printf(head, "1.6.1"); |
ccs_io_printf(head, "1.6.4"); |
2768 |
head->read_eof = true; |
head->read_eof = true; |
2769 |
} |
} |
2770 |
return 0; |
return 0; |