8 #include <linux/slab.h>
164 static const char *
const tomoyo_category_keywords
172 static bool tomoyo_manage_by_non_root;
183 return value ?
"yes" :
"no";
195 static void tomoyo_addprintf(
char *
buffer,
int len,
const char *
fmt, ...)
200 vsnprintf(buffer + pos, len - pos - 1, fmt, args);
213 while (head->
r.w_pos) {
214 const char *
w = head->
r.w[0];
239 for (len = 0; len < head->
r.w_pos; len++)
240 head->
r.w[len] = head->
r.w[len + 1];
256 static void tomoyo_set_string(
struct tomoyo_io_buffer *head,
const char *
string)
259 head->
r.w[head->
r.w_pos++] =
string;
279 size_t pos = head->r.avail;
280 int size = head->readbuf_size -
pos;
284 len =
vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
286 if (pos + len >= head->readbuf_size) {
290 head->r.avail += len;
291 tomoyo_set_string(head, head->read_buf + pos);
303 tomoyo_set_string(head,
" ");
315 tomoyo_set_string(head,
"\n");
316 return !head->
r.w_pos;
328 tomoyo_set_string(head,
"/");
334 static bool tomoyo_namespace_enabled;
366 if (!tomoyo_namespace_enabled)
368 tomoyo_set_string(head,
371 namespace_list)->name);
372 tomoyo_set_space(head);
384 tomoyo_set_space(head);
386 tomoyo_set_string(head,
"@");
387 tomoyo_set_string(head, ptr->
group->group_name->name);
389 tomoyo_set_string(head, ptr->
filename->name);
405 tomoyo_set_string(head,
"@");
406 tomoyo_set_string(head, ptr->
group->group_name->name);
408 tomoyo_set_string(head,
"\"");
409 tomoyo_set_string(head, ptr->
filename->name);
410 tomoyo_set_string(head,
"\"");
422 static void tomoyo_print_number_union_nospace
426 tomoyo_set_string(head,
"@");
427 tomoyo_set_string(head, ptr->
group->group_name->name);
431 const unsigned long max = ptr->
values[1];
436 for (i = 0; i < 2; i++) {
439 tomoyo_addprintf(buffer,
sizeof(buffer),
443 tomoyo_addprintf(buffer,
sizeof(buffer),
447 tomoyo_addprintf(buffer,
sizeof(buffer),
"%lu",
451 if (min == max && min_type == max_type)
453 tomoyo_addprintf(buffer,
sizeof(buffer),
"-");
457 tomoyo_io_printf(head,
"%s", buffer);
472 tomoyo_set_space(head);
473 tomoyo_print_number_union_nospace(head, ptr);
494 entry = kzalloc(
sizeof(*entry),
GFP_NOFS);
506 CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG;
508 CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY;
533 ptr = &tomoyo_null_profile;
545 static s8 tomoyo_find_yesno(
const char *
string,
const char *find)
547 const char *
cp =
strstr(
string, find);
552 else if (!
strncmp(cp,
"=no", 3))
567 static void tomoyo_set_uint(
unsigned int *i,
const char *
string,
570 const char *cp =
strstr(
string, find);
584 static int tomoyo_set_mode(
char *
name,
const char *
value,
589 if (!
strcmp(name,
"CONFIG")) {
600 tomoyo_category_keywords[
c];
602 if (
strncmp(name, category, len) ||
603 name[len++] !=
':' || name[len++] !=
':')
616 if (
strstr(value,
"use_default")) {
620 for (mode = 0; mode < 4; mode++)
626 config = (config & ~7) | mode;
628 switch (tomoyo_find_yesno(value,
"grant_log")) {
636 switch (tomoyo_find_yesno(value,
"reject_log")) {
666 if (
sscanf(data,
"PROFILE_VERSION=%u", &head->
w.ns->profile_version)
673 profile = tomoyo_assign_profile(head->
w.ns, i);
680 if (!
strcmp(data,
"COMMENT")) {
688 old_comment = profile->
comment;
689 profile->
comment = new_comment;
691 tomoyo_put_name(old_comment);
694 if (!
strcmp(data,
"PREFERENCE")) {
696 tomoyo_set_uint(&profile->
pref[i], cp,
697 tomoyo_pref_keywords[i]);
700 return tomoyo_set_mode(data, cp, profile);
715 tomoyo_io_printf(head,
"={ mode=%s grant_log=%s reject_log=%s }\n",
737 index = head->
r.index;
739 switch (head->
r.step) {
741 tomoyo_print_namespace(head);
742 tomoyo_io_printf(head,
"PROFILE_VERSION=%u\n",
762 tomoyo_print_namespace(head);
763 tomoyo_io_printf(head,
"%u-COMMENT=", index);
764 tomoyo_set_string(head, comment ? comment->
name :
"");
766 tomoyo_print_namespace(head);
767 tomoyo_io_printf(head,
"%u-PREFERENCE={ ", index);
769 tomoyo_io_printf(head,
"%s=%u ",
770 tomoyo_pref_keywords[i],
772 tomoyo_set_string(head,
"}\n");
778 tomoyo_print_namespace(head);
779 tomoyo_io_printf(head,
"%u-%s", index,
"CONFIG");
788 const u8 i = head->
r.bit;
792 tomoyo_print_namespace(head);
794 tomoyo_io_printf(head,
"%u-CONFIG::%s::%s",
796 tomoyo_category_keywords
800 tomoyo_io_printf(head,
"%u-CONFIG::%s", index,
802 tomoyo_print_config(head, config);
807 + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
813 if (tomoyo_flush(head))
842 static int tomoyo_update_manager_entry(
const char *
manager,
843 const bool is_delete)
859 tomoyo_same_manager);
878 if (!
strcmp(data,
"manage_by_non_root")) {
879 tomoyo_manage_by_non_root = !head->
w.is_delete;
882 return tomoyo_update_manager_entry(data, head->
w.is_delete);
900 if (ptr->
head.is_deleted)
902 if (!tomoyo_flush(head))
904 tomoyo_set_string(head, ptr->
manager->name);
928 if (!tomoyo_manage_by_non_root &&
936 policy_list[TOMOYO_ID_MANAGER], head.
list) {
937 if (!ptr->
head.is_deleted &&
938 (!tomoyo_pathcmp(domainname, ptr->
manager) ||
945 static pid_t last_pid;
947 if (last_pid != pid) {
949 "update policies.\n", domainname->
name, exe);
975 bool global_pid =
false;
976 if (
strncmp(data,
"select ", 7))
979 if (
sscanf(data,
"pid=%u", &pid) == 1 ||
980 (global_pid =
true,
sscanf(data,
"global-pid=%u", &pid) == 1)) {
988 domain = tomoyo_real_domain(p);
990 }
else if (!
strncmp(data,
"domain=", 7)) {
993 }
else if (
sscanf(data,
"Q=%u", &pid) == 1) {
994 domain = tomoyo_find_domain_by_qid(pid);
997 head->
w.domain = domain;
1001 memset(&head->
r, 0,
sizeof(head->
r));
1002 head->
r.print_this_domain_only =
true;
1004 head->
r.domain = &domain->
list;
1007 tomoyo_io_printf(head,
"# select %s\n", data);
1009 tomoyo_io_printf(head,
"# This is a deleted domain.\n");
1048 tomoyo_same_task_acl,
1064 static int tomoyo_delete_domain(
char *domainname)
1069 name.
name = domainname;
1074 list_for_each_entry_rcu(domain, &tomoyo_domain_list,
list) {
1102 const bool is_delete)
1110 static const struct {
1111 const char *keyword;
1113 } tomoyo_callback[5] = {
1118 {
"task ", tomoyo_write_task },
1122 for (i = 0; i <
ARRAY_SIZE(tomoyo_callback); i++) {
1124 tomoyo_callback[i].keyword))
1126 return tomoyo_callback[
i].write(¶m);
1151 const bool is_delete = head->
w.is_delete;
1158 ret = tomoyo_delete_domain(data);
1163 head->
w.domain = domain;
1169 if (
sscanf(data,
"use_profile %u", &profile) == 1
1175 if (
sscanf(data,
"use_group %u\n", &profile) == 1
1182 const char *cp = tomoyo_dif[
profile];
1188 return tomoyo_write_domain2(ns, &domain->
acl_info_list, data,
1203 switch (head->
r.cond_step) {
1205 head->
r.cond_index = 0;
1206 head->
r.cond_step++;
1208 tomoyo_set_space(head);
1209 tomoyo_set_string(head, cond->
transit->name);
1216 (
typeof(condp)) (cond + 1);
1218 (
typeof(numbers_p)) (condp + condc);
1227 for (skip = 0; skip < head->
r.cond_index; skip++) {
1251 while (head->
r.cond_index < condc) {
1253 const u8 left = condp->
left;
1254 const u8 right = condp->
right;
1255 if (!tomoyo_flush(head))
1258 head->
r.cond_index++;
1259 tomoyo_set_space(head);
1262 tomoyo_io_printf(head,
1263 "exec.argv[%lu]%s=\"",
1266 tomoyo_set_string(head,
1268 tomoyo_set_string(head,
"\"");
1272 tomoyo_set_string(head,
1274 tomoyo_set_string(head,
1276 tomoyo_io_printf(head,
"\"]%s=", envp->
1279 tomoyo_set_string(head,
"\"");
1280 tomoyo_set_string(head, envp->
1282 tomoyo_set_string(head,
"\"");
1284 tomoyo_set_string(head,
1290 tomoyo_print_number_union_nospace
1291 (head, numbers_p++);
1294 tomoyo_set_string(head,
1298 tomoyo_set_string(head, match ?
"=" :
"!=");
1301 tomoyo_print_name_union_quoted
1305 tomoyo_print_number_union_nospace
1306 (head, numbers_p++);
1309 tomoyo_set_string(head,
1315 head->
r.cond_step++;
1318 if (!tomoyo_flush(head))
1320 head->
r.cond_step++;
1324 tomoyo_io_printf(head,
" grant_log=%s",
1327 tomoyo_set_lf(head);
1342 const char *category)
1345 tomoyo_print_namespace(head);
1346 tomoyo_io_printf(head,
"acl_group %u ",
1347 head->
r.acl_group_index);
1349 tomoyo_set_string(head, category);
1363 const u8 acl_type = acl->
type;
1367 if (head->
r.print_cond_part)
1368 goto print_cond_part;
1371 if (!tomoyo_flush(head))
1378 if (!(perm & (1 << bit)))
1380 if (head->
r.print_transition_related_only &&
1384 tomoyo_set_group(head,
"file ");
1387 tomoyo_set_slash(head);
1393 tomoyo_print_name_union(head, &ptr->
name);
1397 tomoyo_set_group(head,
"task ");
1398 tomoyo_set_string(head,
"manual_domain_transition ");
1399 tomoyo_set_string(head, ptr->
domainname->name);
1400 }
else if (head->
r.print_transition_related_only) {
1405 const u8 perm = ptr->
perm;
1407 if (!(perm & (1 << bit)))
1410 tomoyo_set_group(head,
"file ");
1413 tomoyo_set_slash(head);
1420 tomoyo_print_name_union(head, &ptr->
name1);
1421 tomoyo_print_name_union(head, &ptr->
name2);
1425 const u8 perm = ptr->
perm;
1427 if (!(perm & (1 << bit)))
1430 tomoyo_set_group(head,
"file ");
1433 tomoyo_set_slash(head);
1440 tomoyo_print_name_union(head, &ptr->
name);
1441 tomoyo_print_number_union(head, &ptr->
number);
1445 const u8 perm = ptr->
perm;
1447 if (!(perm & (1 << bit)))
1450 tomoyo_set_group(head,
"file ");
1453 tomoyo_set_slash(head);
1460 tomoyo_print_name_union(head, &ptr->
name);
1461 tomoyo_print_number_union(head, &ptr->
mode);
1462 tomoyo_print_number_union(head, &ptr->
major);
1463 tomoyo_print_number_union(head, &ptr->
minor);
1467 const u8 perm = ptr->
perm;
1470 if (!(perm & (1 << bit)))
1473 tomoyo_set_group(head,
"network inet ");
1476 tomoyo_set_space(head);
1479 tomoyo_set_slash(head);
1485 tomoyo_set_space(head);
1487 tomoyo_set_string(head,
"@");
1488 tomoyo_set_string(head, ptr->
address.group->group_name
1493 tomoyo_io_printf(head,
"%s", buf);
1495 tomoyo_print_number_union(head, &ptr->
port);
1499 const u8 perm = ptr->
perm;
1502 if (!(perm & (1 << bit)))
1505 tomoyo_set_group(head,
"network unix ");
1508 tomoyo_set_space(head);
1511 tomoyo_set_slash(head);
1517 tomoyo_print_name_union(head, &ptr->
name);
1521 tomoyo_set_group(head,
"file mount");
1522 tomoyo_print_name_union(head, &ptr->
dev_name);
1523 tomoyo_print_name_union(head, &ptr->
dir_name);
1524 tomoyo_print_name_union(head, &ptr->
fs_type);
1525 tomoyo_print_number_union(head, &ptr->
flags);
1530 tomoyo_set_group(head,
"misc env ");
1531 tomoyo_set_string(head, ptr->
env->name);
1534 head->
r.print_cond_part =
true;
1535 head->
r.cond_step = 0;
1536 if (!tomoyo_flush(head))
1539 if (!tomoyo_print_condition(head, acl->
cond))
1541 head->
r.print_cond_part =
false;
1543 tomoyo_set_lf(head);
1564 if (!tomoyo_print_entry(head, ptr))
1585 switch (head->
r.step) {
1589 !head->
r.print_this_domain_only)
1592 tomoyo_set_string(head, domain->
domainname->name);
1593 tomoyo_set_lf(head);
1594 tomoyo_io_printf(head,
"use_profile %u\n",
1596 tomoyo_io_printf(head,
"use_group %u\n",
1599 if (domain->
flags[i])
1600 tomoyo_set_string(head, tomoyo_dif[i]);
1602 tomoyo_set_lf(head);
1608 if (!tomoyo_set_lf(head))
1613 if (head->
r.print_this_domain_only)
1630 head->
r.eof =
false;
1647 bool global_pid =
false;
1657 if (head->
r.w_pos || head->
r.eof)
1669 domain = tomoyo_real_domain(p);
1673 tomoyo_io_printf(head,
"%u %u ", pid, domain->
profile);
1674 tomoyo_set_string(head, domain->
domainname->name);
1705 const bool is_delete = head->
w.is_delete;
1725 return tomoyo_write_domain2
1726 (head->
w.ns, &head->
w.ns->acl_group[group],
1755 if (!tomoyo_flush(head))
1757 tomoyo_print_namespace(head);
1758 tomoyo_set_string(head, tomoyo_group_name[idx]);
1759 tomoyo_set_string(head, group->
group_name->name);
1761 tomoyo_set_space(head);
1764 head)->member_name->name);
1778 tomoyo_io_printf(head,
" %s", buffer);
1780 tomoyo_set_lf(head);
1784 head->
r.group =
NULL;
1798 static bool tomoyo_read_policy(
struct tomoyo_io_buffer *head,
const int idx)
1808 if (!tomoyo_flush(head))
1815 tomoyo_print_namespace(head);
1816 tomoyo_set_string(head, tomoyo_transition_type
1818 tomoyo_set_string(head, ptr->
program ?
1820 tomoyo_set_string(head,
" from ");
1830 tomoyo_print_namespace(head);
1831 tomoyo_set_string(head,
"aggregator ");
1832 tomoyo_set_string(head,
1834 tomoyo_set_space(head);
1835 tomoyo_set_string(head,
1842 tomoyo_set_lf(head);
1862 tomoyo_read_policy(head, head->
r.step))
1875 if (!tomoyo_read_domain2(head, &ns->
acl_group
1876 [head->
r.acl_group_index]))
1919 static int tomoyo_truncate(
char *
str)
1922 while (*(
unsigned char *) str > (
unsigned char)
' ')
1925 return strlen(start) + 1;
1939 char *realpath =
NULL;
1941 char *symlink =
NULL;
1942 char *cp =
strchr(header,
'\n');
1946 cp =
strchr(cp + 1,
'\n');
1953 argv0 =
strstr(header,
" argv[]={ \"");
1956 len += tomoyo_truncate(argv0) + 14;
1958 realpath =
strstr(header,
" exec={ realpath=\"");
1961 len += tomoyo_truncate(realpath) + 6;
1963 symlink =
strstr(header,
" symlink.target=\"");
1965 len += tomoyo_truncate(symlink + 1) + 1;
1970 snprintf(buffer, len - 1,
"%s", cp);
1972 tomoyo_addprintf(buffer, len,
" exec.%s", realpath);
1974 tomoyo_addprintf(buffer, len,
" exec.argv[0]=%s", argv0);
1976 tomoyo_addprintf(buffer, len,
"%s", symlink);
2000 static unsigned int tomoyo_serial;
2002 bool quota_exceeded =
false;
2004 len =
vsnprintf((
char *) &len, 1, fmt, args) + 1;
2043 spin_lock(&tomoyo_query_list_lock);
2047 quota_exceeded =
true;
2049 entry.
serial = tomoyo_serial++;
2054 spin_unlock(&tomoyo_query_list_lock);
2058 while (entry.
timer < 10) {
2061 (tomoyo_answer_wait, entry.
answer ||
2067 spin_lock(&tomoyo_query_list_lock);
2070 spin_unlock(&tomoyo_query_list_lock);
2101 spin_lock(&tomoyo_query_list_lock);
2103 if (ptr->
serial != serial)
2108 spin_unlock(&tomoyo_query_list_lock);
2124 if (!list_empty(&tomoyo_query_list))
2126 poll_wait(file, &tomoyo_query_wait, wait);
2127 if (!list_empty(&tomoyo_query_list))
2140 unsigned int pos = 0;
2149 spin_lock(&tomoyo_query_list_lock);
2152 if (pos++ != head->
r.query_index)
2157 spin_unlock(&tomoyo_query_list_lock);
2159 head->
r.query_index = 0;
2166 spin_lock(&tomoyo_query_list_lock);
2169 if (pos++ != head->
r.query_index)
2180 spin_unlock(&tomoyo_query_list_lock);
2183 head->
r.w[head->
r.w_pos++] =
buf;
2184 head->
r.query_index++;
2202 unsigned int answer;
2203 spin_lock(&tomoyo_query_list_lock);
2208 spin_unlock(&tomoyo_query_list_lock);
2209 if (
sscanf(data,
"A%u=%u", &serial, &answer) != 2)
2211 spin_lock(&tomoyo_query_list_lock);
2214 if (ptr->
serial != serial)
2219 list_del_init(&ptr->
list);
2222 spin_unlock(&tomoyo_query_list_lock);
2236 tomoyo_io_printf(head,
"2.5.0");
2275 tomoyo_stat_updated[
index]++;
2289 unsigned int total = 0;
2293 tomoyo_io_printf(head,
"Policy %-30s %10u",
2294 tomoyo_policy_headers[i],
2295 tomoyo_stat_updated[i]);
2296 if (tomoyo_stat_modified[i]) {
2299 tomoyo_io_printf(head,
" (Last: %04u/%02u/%02u "
2304 tomoyo_set_lf(head);
2309 tomoyo_io_printf(head,
"Memory used by %-22s %10u",
2310 tomoyo_memory_headers[i], used);
2313 tomoyo_io_printf(head,
" (Quota: %10u)", used);
2314 tomoyo_set_lf(head);
2316 tomoyo_io_printf(head,
"Total memory used: %10u\n",
2358 head->
write = tomoyo_write_domain;
2359 head->
read = tomoyo_read_domain;
2363 head->
write = tomoyo_write_exception;
2364 head->
read = tomoyo_read_exception;
2373 head->
write = tomoyo_write_pid;
2374 head->
read = tomoyo_read_pid;
2378 head->
read = tomoyo_read_version;
2383 head->
write = tomoyo_write_stat;
2384 head->
read = tomoyo_read_stat;
2389 head->
write = tomoyo_write_profile;
2390 head->
read = tomoyo_read_profile;
2393 head->
poll = tomoyo_poll_query;
2394 head->
write = tomoyo_write_answer;
2395 head->
read = tomoyo_read_query;
2399 head->
write = tomoyo_write_manager;
2400 head->
read = tomoyo_read_manager;
2410 }
else if (!head->
poll) {
2426 }
else if (head->
write) {
2472 static inline void tomoyo_set_namespace_cursor(
struct tomoyo_io_buffer *head)
2483 if (!ns || (head->
r.eof && ns->
next != &tomoyo_namespace_list)) {
2485 memset(&head->
r, 0,
sizeof(head->
r));
2497 static inline bool tomoyo_has_more_namespace(
struct tomoyo_io_buffer *head)
2514 const int buffer_len)
2525 idx = tomoyo_read_lock();
2526 if (tomoyo_flush(head))
2529 tomoyo_set_namespace_cursor(head);
2531 }
while (tomoyo_flush(head) &&
2532 tomoyo_has_more_namespace(head));
2533 tomoyo_read_unlock(idx);
2552 head->
w.is_delete = !
strncmp(line,
"delete ", 7);
2553 if (head->
w.is_delete)
2559 char *cp =
strchr(line,
' ');
2573 return head->
write(head);
2586 const char __user *buffer,
const int buffer_len)
2588 int error = buffer_len;
2589 size_t avail_len = buffer_len;
2599 idx = tomoyo_read_lock();
2601 while (avail_len > 0) {
2622 cp0[head->
w.avail++] =
c;
2625 cp0[head->
w.avail - 1] =
'\0';
2628 if (!
strcmp(cp0,
"reset")) {
2630 head->
w.domain =
NULL;
2631 memset(&head->
r, 0,
sizeof(head->
r));
2635 switch (head->
type) {
2640 if (tomoyo_select_domain(head, cp0))
2644 if (!
strcmp(cp0,
"select transition_only")) {
2645 head->
r.print_transition_related_only =
true;
2655 switch (tomoyo_parse_policy(head, cp0)) {
2660 switch (head->
type) {
2675 tomoyo_read_unlock(idx);
2706 const int idx = tomoyo_read_lock();
2714 "Profile version %u is not supported.\n",
2718 "Profile %u (used by '%s') is not defined.\n",
2723 "Userland tools for TOMOYO 2.5 must be installed and "
2724 "policy must be initialized.\n");
2726 "for more information.\n");
2729 tomoyo_read_unlock(idx);
2746 #include "builtin-policy.h"
2748 const int idx = tomoyo_read_lock();
2749 for (i = 0; i < 5; i++) {
2754 start = tomoyo_builtin_profile;
2756 head.
write = tomoyo_write_profile;
2759 start = tomoyo_builtin_exception_policy;
2761 head.
write = tomoyo_write_exception;
2764 start = tomoyo_builtin_domain_policy;
2766 head.
write = tomoyo_write_domain;
2769 start = tomoyo_builtin_manager;
2771 head.
write = tomoyo_write_manager;
2774 start = tomoyo_builtin_stat;
2776 head.
write = tomoyo_write_stat;
2786 tomoyo_parse_policy(&head, start);
2790 tomoyo_read_unlock(idx);
2791 #ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER