3 |
* |
* |
4 |
* Copyright (C) 2005-2010 NTT DATA CORPORATION |
* Copyright (C) 2005-2010 NTT DATA CORPORATION |
5 |
* |
* |
6 |
* Version: 1.7.2+ 2010/06/04 |
* Version: 1.8.0-pre 2010/09/01 |
7 |
* |
* |
8 |
* 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. |
9 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
13 |
#include "internal.h" |
#include "internal.h" |
14 |
|
|
15 |
static struct ccs_profile ccs_default_profile = { |
static struct ccs_profile ccs_default_profile = { |
|
.learning = &ccs_default_profile.preference, |
|
|
.permissive = &ccs_default_profile.preference, |
|
|
.enforcing = &ccs_default_profile.preference, |
|
|
.audit = &ccs_default_profile.preference, |
|
16 |
#ifdef CONFIG_CCSECURITY_AUDIT |
#ifdef CONFIG_CCSECURITY_AUDIT |
17 |
.preference.audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG, |
.preference.audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG, |
18 |
.preference.audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG, |
.preference.audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG, |
20 |
.preference.audit_task_info = true, |
.preference.audit_task_info = true, |
21 |
.preference.audit_path_info = true, |
.preference.audit_path_info = true, |
22 |
.preference.enforcing_penalty = 0, |
.preference.enforcing_penalty = 0, |
|
.preference.enforcing_verbose = true, |
|
23 |
.preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY, |
.preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY, |
|
.preference.learning_verbose = false, |
|
24 |
.preference.learning_exec_realpath = true, |
.preference.learning_exec_realpath = true, |
25 |
.preference.learning_exec_argv0 = true, |
.preference.learning_exec_argv0 = true, |
26 |
.preference.learning_symlink_target = true, |
.preference.learning_symlink_target = true, |
|
.preference.permissive_verbose = true |
|
27 |
}; |
}; |
28 |
|
|
29 |
/* Profile version. Currently only 20090903 is defined. */ |
/* Profile version. Currently only 20100903 is defined. */ |
30 |
static unsigned int ccs_profile_version; |
static unsigned int ccs_profile_version; |
31 |
|
|
32 |
/* Profile table. Memory is allocated as needed. */ |
/* Profile table. Memory is allocated as needed. */ |
88 |
= "file::umount", |
= "file::umount", |
89 |
[CCS_MAC_FILE_PIVOT_ROOT] |
[CCS_MAC_FILE_PIVOT_ROOT] |
90 |
= "file::pivot_root", |
= "file::pivot_root", |
|
[CCS_MAC_FILE_TRANSIT] |
|
|
= "file::transit", |
|
91 |
[CCS_MAC_ENVIRON] |
[CCS_MAC_ENVIRON] |
92 |
= "misc::env", |
= "misc::env", |
93 |
[CCS_MAC_NETWORK_UDP_BIND] |
[CCS_MAC_NETWORK_INET_STREAM_BIND] |
94 |
= "network::inet_udp_bind", |
= "network::inet_stream_bind", |
95 |
[CCS_MAC_NETWORK_UDP_CONNECT] |
[CCS_MAC_NETWORK_INET_STREAM_LISTEN] |
96 |
= "network::inet_udp_connect", |
= "network::inet_stream_listen", |
97 |
[CCS_MAC_NETWORK_TCP_BIND] |
[CCS_MAC_NETWORK_INET_STREAM_CONNECT] |
98 |
= "network::inet_tcp_bind", |
= "network::inet_stream_connect", |
99 |
[CCS_MAC_NETWORK_TCP_LISTEN] |
[CCS_MAC_NETWORK_INET_STREAM_ACCEPT] |
100 |
= "network::inet_tcp_listen", |
= "network::inet_stream_accept", |
101 |
[CCS_MAC_NETWORK_TCP_CONNECT] |
[CCS_MAC_NETWORK_INET_DGRAM_BIND] |
102 |
= "network::inet_tcp_connect", |
= "network::inet_dgram_bind", |
103 |
[CCS_MAC_NETWORK_TCP_ACCEPT] |
[CCS_MAC_NETWORK_INET_DGRAM_SEND] |
104 |
= "network::inet_tcp_accept", |
= "network::inet_dgram_send", |
105 |
[CCS_MAC_NETWORK_RAW_BIND] |
[CCS_MAC_NETWORK_INET_DGRAM_RECV] |
106 |
|
= "network::inet_dgram_recv", |
107 |
|
[CCS_MAC_NETWORK_INET_RAW_BIND] |
108 |
= "network::inet_raw_bind", |
= "network::inet_raw_bind", |
109 |
[CCS_MAC_NETWORK_RAW_CONNECT] |
[CCS_MAC_NETWORK_INET_RAW_SEND] |
110 |
= "network::inet_raw_connect", |
= "network::inet_raw_send", |
111 |
|
[CCS_MAC_NETWORK_INET_RAW_RECV] |
112 |
|
= "network::inet_raw_recv", |
113 |
|
[CCS_MAC_NETWORK_UNIX_STREAM_BIND] |
114 |
|
= "network::unix_stream_bind", |
115 |
|
[CCS_MAC_NETWORK_UNIX_STREAM_LISTEN] |
116 |
|
= "network::unix_stream_listen", |
117 |
|
[CCS_MAC_NETWORK_UNIX_STREAM_CONNECT] |
118 |
|
= "network::unix_stream_connect", |
119 |
|
[CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT] |
120 |
|
= "network::unix_stream_accept", |
121 |
|
[CCS_MAC_NETWORK_UNIX_DGRAM_BIND] |
122 |
|
= "network::unix_dgram_bind", |
123 |
|
[CCS_MAC_NETWORK_UNIX_DGRAM_SEND] |
124 |
|
= "network::unix_dgram_send", |
125 |
|
[CCS_MAC_NETWORK_UNIX_DGRAM_RECV] |
126 |
|
= "network::unix_dgram_recv", |
127 |
|
[CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND] |
128 |
|
= "network::unix_seqpacket_bind", |
129 |
|
[CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] |
130 |
|
= "network::unix_seqpacket_listen", |
131 |
|
[CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] |
132 |
|
= "network::unix_seqpacket_connect", |
133 |
|
[CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT] |
134 |
|
= "network::unix_seqpacket_accept", |
135 |
[CCS_MAC_SIGNAL] |
[CCS_MAC_SIGNAL] |
136 |
= "ipc::signal", |
= "ipc::signal", |
|
[CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CREATE] |
|
|
= "capability::inet_tcp_create", |
|
|
[CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_LISTEN] |
|
|
= "capability::inet_tcp_listen", |
|
|
[CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CONNECT] |
|
|
= "capability::inet_tcp_connect", |
|
|
[CCS_MAX_MAC_INDEX + CCS_USE_INET_DGRAM_SOCKET] |
|
|
= "capability::use_inet_udp", |
|
|
[CCS_MAX_MAC_INDEX + CCS_USE_INET_RAW_SOCKET] |
|
|
= "capability::use_inet_ip", |
|
137 |
[CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET] |
[CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET] |
138 |
= "capability::use_route", |
= "capability::use_route", |
139 |
[CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET] |
[CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET] |
140 |
= "capability::use_packet", |
= "capability::use_packet", |
|
[CCS_MAX_MAC_INDEX + CCS_SYS_MOUNT] |
|
|
= "capability::SYS_MOUNT", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_UMOUNT] |
|
|
= "capability::SYS_UMOUNT", |
|
141 |
[CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT] |
[CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT] |
142 |
= "capability::SYS_REBOOT", |
= "capability::SYS_REBOOT", |
|
[CCS_MAX_MAC_INDEX + CCS_SYS_CHROOT] |
|
|
= "capability::SYS_CHROOT", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_KILL] |
|
|
= "capability::SYS_KILL", |
|
143 |
[CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP] |
[CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP] |
144 |
= "capability::SYS_VHANGUP", |
= "capability::SYS_VHANGUP", |
145 |
[CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME] |
[CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME] |
150 |
= "capability::SYS_SETHOSTNAME", |
= "capability::SYS_SETHOSTNAME", |
151 |
[CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE] |
[CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE] |
152 |
= "capability::use_kernel_module", |
= "capability::use_kernel_module", |
|
[CCS_MAX_MAC_INDEX + CCS_CREATE_FIFO] |
|
|
= "capability::create_fifo", |
|
|
[CCS_MAX_MAC_INDEX + CCS_CREATE_BLOCK_DEV] |
|
|
= "capability::create_block_dev", |
|
|
[CCS_MAX_MAC_INDEX + CCS_CREATE_CHAR_DEV] |
|
|
= "capability::create_char_dev", |
|
|
[CCS_MAX_MAC_INDEX + CCS_CREATE_UNIX_SOCKET] |
|
|
= "capability::create_unix_socket", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_LINK] |
|
|
= "capability::SYS_LINK", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_SYMLINK] |
|
|
= "capability::SYS_SYMLINK", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_RENAME] |
|
|
= "capability::SYS_RENAME", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_UNLINK] |
|
|
= "capability::SYS_UNLINK", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_CHMOD] |
|
|
= "capability::SYS_CHMOD", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_CHOWN] |
|
|
= "capability::SYS_CHOWN", |
|
|
[CCS_MAX_MAC_INDEX + CCS_SYS_IOCTL] |
|
|
= "capability::SYS_IOCTL", |
|
153 |
[CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD] |
[CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD] |
154 |
= "capability::SYS_KEXEC_LOAD", |
= "capability::SYS_KEXEC_LOAD", |
|
[CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT] |
|
|
= "capability::SYS_PIVOT_ROOT", |
|
155 |
[CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE] |
[CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE] |
156 |
= "capability::SYS_PTRACE", |
= "capability::SYS_PTRACE", |
|
[CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT] |
|
|
= "capability::conceal_mount", |
|
157 |
[CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX |
[CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX |
158 |
+ CCS_MAC_CATEGORY_FILE] = "file", |
+ CCS_MAC_CATEGORY_FILE] = "file", |
159 |
[CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX |
[CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX |
260 |
head->r.w[head->r.w_pos++] = string; |
head->r.w[head->r.w_pos++] = string; |
261 |
ccs_flush(head); |
ccs_flush(head); |
262 |
} else |
} else |
263 |
WARN_ON(1); |
printk(KERN_WARNING "Too many words in a line.\n"); |
264 |
} |
} |
265 |
|
|
266 |
/** |
/** |
281 |
len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1; |
len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1; |
282 |
va_end(args); |
va_end(args); |
283 |
if (pos + len >= head->readbuf_size) { |
if (pos + len >= head->readbuf_size) { |
284 |
WARN_ON(1); |
printk(KERN_WARNING "Too many words in a line.\n"); |
285 |
return; |
return; |
286 |
} |
} |
287 |
head->r.avail += len; |
head->r.avail += len; |
321 |
ptr = ccs_profile_ptr[profile]; |
ptr = ccs_profile_ptr[profile]; |
322 |
if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) { |
if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) { |
323 |
ptr = entry; |
ptr = entry; |
|
ptr->audit = &ccs_default_profile.preference; |
|
|
ptr->learning = &ccs_default_profile.preference; |
|
|
ptr->permissive = &ccs_default_profile.preference; |
|
|
ptr->enforcing = &ccs_default_profile.preference; |
|
324 |
ptr->default_config = CCS_CONFIG_DISABLED | |
ptr->default_config = CCS_CONFIG_DISABLED | |
325 |
|
CCS_CONFIG_VERBOSE | |
326 |
CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG; |
CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG; |
327 |
memset(ptr->config, CCS_CONFIG_USE_DEFAULT, |
memset(ptr->config, CCS_CONFIG_USE_DEFAULT, |
328 |
sizeof(ptr->config)); |
sizeof(ptr->config)); |
352 |
profile, domain->domainname->name); |
profile, domain->domainname->name); |
353 |
} |
} |
354 |
ccs_read_unlock(idx); |
ccs_read_unlock(idx); |
355 |
if (ccs_profile_version != 20090903) |
if (ccs_profile_version != 20100903) |
356 |
panic("Profile version %u is not supported.\n", |
panic("Profile version %u is not supported.\n", |
357 |
ccs_profile_version); |
ccs_profile_version); |
358 |
printk(KERN_INFO "CCSecurity: 1.7.2+ 2010/06/04\n"); |
printk(KERN_INFO "CCSecurity: 1.8.0-pre 2010/09/01\n"); |
359 |
printk(KERN_INFO "Mandatory Access Control activated.\n"); |
printk(KERN_INFO "Mandatory Access Control activated.\n"); |
360 |
} |
} |
361 |
|
|
408 |
} |
} |
409 |
|
|
410 |
static void ccs_set_pref(const char *name, const char *value, |
static void ccs_set_pref(const char *name, const char *value, |
411 |
const bool use_default, struct ccs_profile *profile) |
struct ccs_profile *profile) |
412 |
{ |
{ |
|
struct ccs_preference **pref; |
|
|
bool *verbose; |
|
413 |
if (!strcmp(name, "audit")) { |
if (!strcmp(name, "audit")) { |
|
if (use_default) { |
|
|
pref = &profile->audit; |
|
|
goto set_default; |
|
|
} |
|
|
profile->audit = &profile->preference; |
|
414 |
#ifdef CONFIG_CCSECURITY_AUDIT |
#ifdef CONFIG_CCSECURITY_AUDIT |
415 |
ccs_set_uint(&profile->preference.audit_max_grant_log, value, |
ccs_set_uint(&profile->preference.audit_max_grant_log, value, |
416 |
"max_grant_log"); |
"max_grant_log"); |
424 |
return; |
return; |
425 |
} |
} |
426 |
if (!strcmp(name, "enforcing")) { |
if (!strcmp(name, "enforcing")) { |
|
if (use_default) { |
|
|
pref = &profile->enforcing; |
|
|
goto set_default; |
|
|
} |
|
|
profile->enforcing = &profile->preference; |
|
427 |
ccs_set_uint(&profile->preference.enforcing_penalty, value, |
ccs_set_uint(&profile->preference.enforcing_penalty, value, |
428 |
"penalty"); |
"penalty"); |
429 |
verbose = &profile->preference.enforcing_verbose; |
return; |
|
goto set_verbose; |
|
|
} |
|
|
if (!strcmp(name, "permissive")) { |
|
|
if (use_default) { |
|
|
pref = &profile->permissive; |
|
|
goto set_default; |
|
|
} |
|
|
profile->permissive = &profile->preference; |
|
|
verbose = &profile->preference.permissive_verbose; |
|
|
goto set_verbose; |
|
430 |
} |
} |
431 |
if (!strcmp(name, "learning")) { |
if (!strcmp(name, "learning")) { |
|
if (use_default) { |
|
|
pref = &profile->learning; |
|
|
goto set_default; |
|
|
} |
|
|
profile->learning = &profile->preference; |
|
432 |
ccs_set_uint(&profile->preference.learning_max_entry, value, |
ccs_set_uint(&profile->preference.learning_max_entry, value, |
433 |
"max_entry"); |
"max_entry"); |
434 |
ccs_set_bool(&profile->preference.learning_exec_realpath, |
ccs_set_bool(&profile->preference.learning_exec_realpath, |
437 |
"exec.argv0"); |
"exec.argv0"); |
438 |
ccs_set_bool(&profile->preference.learning_symlink_target, |
ccs_set_bool(&profile->preference.learning_symlink_target, |
439 |
value, "symlink.target"); |
value, "symlink.target"); |
440 |
verbose = &profile->preference.learning_verbose; |
return; |
|
goto set_verbose; |
|
441 |
} |
} |
|
return; |
|
|
set_default: |
|
|
*pref = &ccs_default_profile.preference; |
|
|
return; |
|
|
set_verbose: |
|
|
ccs_set_bool(verbose, value, "verbose"); |
|
442 |
} |
} |
443 |
|
|
444 |
static int ccs_set_mode(char *name, const char *value, const bool use_default, |
static int ccs_set_mode(char *name, const char *value, |
445 |
struct ccs_profile *profile) |
struct ccs_profile *profile) |
446 |
{ |
{ |
447 |
u8 i; |
u8 i; |
465 |
} else { |
} else { |
466 |
return -EINVAL; |
return -EINVAL; |
467 |
} |
} |
468 |
if (use_default) { |
if (strstr(value, "use_default")) { |
469 |
config = CCS_CONFIG_USE_DEFAULT; |
config = CCS_CONFIG_USE_DEFAULT; |
470 |
} else { |
} else { |
471 |
u8 mode; |
u8 mode; |
476 |
* 'config' from 'CCS_CONFIG_USE_DEAFULT'. |
* 'config' from 'CCS_CONFIG_USE_DEAFULT'. |
477 |
*/ |
*/ |
478 |
config = (config & ~7) | mode; |
config = (config & ~7) | mode; |
|
#ifdef CONFIG_CCSECURITY_AUDIT |
|
479 |
if (config != CCS_CONFIG_USE_DEFAULT) { |
if (config != CCS_CONFIG_USE_DEFAULT) { |
480 |
|
switch (ccs_find_yesno(value, "verbose")) { |
481 |
|
case 1: |
482 |
|
config |= CCS_CONFIG_VERBOSE; |
483 |
|
break; |
484 |
|
case 0: |
485 |
|
config &= ~CCS_CONFIG_VERBOSE; |
486 |
|
break; |
487 |
|
} |
488 |
|
#ifdef CONFIG_CCSECURITY_AUDIT |
489 |
switch (ccs_find_yesno(value, "grant_log")) { |
switch (ccs_find_yesno(value, "grant_log")) { |
490 |
case 1: |
case 1: |
491 |
config |= CCS_CONFIG_WANT_GRANT_LOG; |
config |= CCS_CONFIG_WANT_GRANT_LOG; |
502 |
config &= ~CCS_CONFIG_WANT_REJECT_LOG; |
config &= ~CCS_CONFIG_WANT_REJECT_LOG; |
503 |
break; |
break; |
504 |
} |
} |
|
} |
|
505 |
#endif |
#endif |
506 |
|
} |
507 |
} |
} |
508 |
if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX |
if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX |
509 |
+ CCS_MAX_MAC_CATEGORY_INDEX) |
+ CCS_MAX_MAC_CATEGORY_INDEX) |
524 |
{ |
{ |
525 |
char *data = head->write_buf; |
char *data = head->write_buf; |
526 |
unsigned int i; |
unsigned int i; |
|
bool use_default = false; |
|
527 |
char *cp; |
char *cp; |
528 |
struct ccs_profile *profile; |
struct ccs_profile *profile; |
529 |
if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1) |
if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1) |
530 |
return 0; |
return 0; |
531 |
i = simple_strtoul(data, &cp, 10); |
i = simple_strtoul(data, &cp, 10); |
532 |
if (data == cp) { |
if (*cp != '-') |
533 |
profile = &ccs_default_profile; |
return -EINVAL; |
534 |
} else { |
data = cp + 1; |
535 |
if (*cp != '-') |
profile = ccs_assign_profile(i); |
536 |
return -EINVAL; |
if (!profile) |
537 |
data = cp + 1; |
return -EINVAL; |
|
profile = ccs_assign_profile(i); |
|
|
if (!profile) |
|
|
return -EINVAL; |
|
|
} |
|
538 |
cp = strchr(data, '='); |
cp = strchr(data, '='); |
539 |
if (!cp) |
if (!cp) |
540 |
return -EINVAL; |
return -EINVAL; |
541 |
*cp++ = '\0'; |
*cp++ = '\0'; |
|
if (profile != &ccs_default_profile) |
|
|
use_default = strstr(cp, "use_default") != NULL; |
|
542 |
if (ccs_str_starts(&data, "PREFERENCE::")) { |
if (ccs_str_starts(&data, "PREFERENCE::")) { |
543 |
ccs_set_pref(data, cp, use_default, profile); |
ccs_set_pref(data, cp, profile); |
544 |
return 0; |
return 0; |
545 |
} |
} |
|
if (profile == &ccs_default_profile) |
|
|
return -EINVAL; |
|
546 |
if (!strcmp(data, "COMMENT")) { |
if (!strcmp(data, "COMMENT")) { |
547 |
const struct ccs_path_info *old_comment = profile->comment; |
const struct ccs_path_info *old_comment = profile->comment; |
548 |
profile->comment = ccs_get_name(cp); |
profile->comment = ccs_get_name(cp); |
549 |
ccs_put_name(old_comment); |
ccs_put_name(old_comment); |
550 |
return 0; |
return 0; |
551 |
} |
} |
552 |
return ccs_set_mode(data, cp, use_default, profile); |
return ccs_set_mode(data, cp, profile); |
553 |
} |
} |
554 |
|
|
555 |
static void ccs_print_preference(struct ccs_io_buffer *head, const int idx) |
static void ccs_print_preference(struct ccs_io_buffer *head, const int index) |
556 |
{ |
{ |
557 |
struct ccs_preference *pref = &ccs_default_profile.preference; |
struct ccs_profile *profile = ccs_profile_ptr[index]; |
558 |
const struct ccs_profile *profile = idx >= 0 ? |
struct ccs_preference *pref = &profile->preference; |
559 |
ccs_profile_ptr[idx] : NULL; |
ccs_io_printf(head, "%u-PREFERENCE::%s={ " |
|
char buffer[16] = ""; |
|
|
if (profile) { |
|
|
buffer[sizeof(buffer) - 1] = '\0'; |
|
|
snprintf(buffer, sizeof(buffer) - 1, "%u-", idx); |
|
|
} |
|
|
if (profile) { |
|
|
pref = profile->audit; |
|
|
if (pref == &ccs_default_profile.preference) |
|
|
goto skip0; |
|
|
} |
|
|
ccs_io_printf(head, "%sPREFERENCE::%s={ " |
|
560 |
#ifdef CONFIG_CCSECURITY_AUDIT |
#ifdef CONFIG_CCSECURITY_AUDIT |
561 |
"max_grant_log=%u max_reject_log=%u " |
"max_grant_log=%u max_reject_log=%u " |
562 |
#endif |
#endif |
563 |
"task_info=%s path_info=%s }\n", buffer, |
"task_info=%s path_info=%s }\n", index, |
564 |
"audit", |
"audit", |
565 |
#ifdef CONFIG_CCSECURITY_AUDIT |
#ifdef CONFIG_CCSECURITY_AUDIT |
566 |
pref->audit_max_grant_log, |
pref->audit_max_grant_log, |
568 |
#endif |
#endif |
569 |
ccs_yesno(pref->audit_task_info), |
ccs_yesno(pref->audit_task_info), |
570 |
ccs_yesno(pref->audit_path_info)); |
ccs_yesno(pref->audit_path_info)); |
571 |
skip0: |
ccs_io_printf(head, "%u-PREFERENCE::%s={ " |
572 |
if (profile) { |
"max_entry=%u exec.realpath=%s " |
|
pref = profile->learning; |
|
|
if (pref == &ccs_default_profile.preference) |
|
|
goto skip1; |
|
|
} |
|
|
ccs_io_printf(head, "%sPREFERENCE::%s={ " |
|
|
"verbose=%s max_entry=%u exec.realpath=%s " |
|
573 |
"exec.argv0=%s symlink.target=%s }\n", |
"exec.argv0=%s symlink.target=%s }\n", |
574 |
buffer, "learning", |
index, "learning", |
|
ccs_yesno(pref->learning_verbose), |
|
575 |
pref->learning_max_entry, |
pref->learning_max_entry, |
576 |
ccs_yesno(pref->learning_exec_realpath), |
ccs_yesno(pref->learning_exec_realpath), |
577 |
ccs_yesno(pref->learning_exec_argv0), |
ccs_yesno(pref->learning_exec_argv0), |
578 |
ccs_yesno(pref->learning_symlink_target)); |
ccs_yesno(pref->learning_symlink_target)); |
579 |
skip1: |
ccs_io_printf(head, "%u-PREFERENCE::%s={ penalty=%u }\n", index, |
580 |
if (profile) { |
"enforcing", pref->enforcing_penalty); |
|
pref = profile->permissive; |
|
|
if (pref == &ccs_default_profile.preference) |
|
|
goto skip2; |
|
|
} |
|
|
ccs_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n", |
|
|
buffer, "permissive", |
|
|
ccs_yesno(pref->permissive_verbose)); |
|
|
skip2: |
|
|
if (profile) { |
|
|
pref = profile->enforcing; |
|
|
if (pref == &ccs_default_profile.preference) |
|
|
return; |
|
|
} |
|
|
ccs_io_printf(head, "%sPREFERENCE::%s={ verbose=%s " |
|
|
"penalty=%u }\n", buffer, "enforcing", |
|
|
ccs_yesno(pref->enforcing_verbose), |
|
|
pref->enforcing_penalty); |
|
581 |
} |
} |
582 |
|
|
583 |
static void ccs_print_config(struct ccs_io_buffer *head, const u8 config) |
static void ccs_print_config(struct ccs_io_buffer *head, const u8 config) |
584 |
{ |
{ |
585 |
ccs_io_printf(head, "={ mode=%s", ccs_mode[config & 3]); |
ccs_io_printf(head, "={ mode=%s verbose=%s", ccs_mode[config & 3], |
586 |
|
ccs_yesno(config & CCS_CONFIG_VERBOSE)); |
587 |
#ifdef CONFIG_CCSECURITY_AUDIT |
#ifdef CONFIG_CCSECURITY_AUDIT |
588 |
ccs_io_printf(head, " grant_log=%s reject_log=%s", |
ccs_io_printf(head, " grant_log=%s reject_log=%s", |
589 |
ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG), |
ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG), |
606 |
profile = ccs_profile_ptr[index]; |
profile = ccs_profile_ptr[index]; |
607 |
switch (head->r.step) { |
switch (head->r.step) { |
608 |
case 0: |
case 0: |
609 |
ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903"); |
ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20100903"); |
|
ccs_print_preference(head, -1); |
|
610 |
head->r.step++; |
head->r.step++; |
611 |
break; |
break; |
612 |
case 1: |
case 1: |
804 |
static char *ccs_find_condition_part(char *data) |
static char *ccs_find_condition_part(char *data) |
805 |
{ |
{ |
806 |
char *cp = strstr(data, " if "); |
char *cp = strstr(data, " if "); |
807 |
if (!cp) |
if (cp) { |
808 |
cp = strstr(data, " ; set "); |
while (1) { |
809 |
if (cp) |
char *cp2 = strstr(cp + 3, " if "); |
810 |
*cp++ = '\0'; |
if (!cp2) |
811 |
|
break; |
812 |
|
cp = cp2; |
813 |
|
} |
814 |
|
*cp = '\0'; |
815 |
|
cp += 4; |
816 |
|
} |
817 |
return cp; |
return cp; |
818 |
} |
} |
819 |
|
|
863 |
return true; /* Do nothing if open(O_WRONLY). */ |
return true; /* Do nothing if open(O_WRONLY). */ |
864 |
memset(&head->r, 0, sizeof(head->r)); |
memset(&head->r, 0, sizeof(head->r)); |
865 |
head->r.print_this_domain_only = true; |
head->r.print_this_domain_only = true; |
866 |
head->r.eof = !domain; |
if (domain) |
867 |
head->r.domain = &domain->list; |
head->r.domain = &domain->list; |
868 |
|
else |
869 |
|
head->r.eof = true; |
870 |
ccs_io_printf(head, "# select %s\n", data); |
ccs_io_printf(head, "# select %s\n", data); |
871 |
if (domain && domain->is_deleted) |
if (domain && domain->is_deleted) |
872 |
ccs_set_string(head, "# This is a deleted domain.\n"); |
ccs_set_string(head, "# This is a deleted domain.\n"); |
873 |
return true; |
return true; |
874 |
} |
} |
875 |
|
|
876 |
|
static bool ccs_same_handler_acl(const struct ccs_acl_info *a, |
877 |
|
const struct ccs_acl_info *b) |
878 |
|
{ |
879 |
|
const struct ccs_handler_acl *p1 = container_of(a, typeof(*p1), head); |
880 |
|
const struct ccs_handler_acl *p2 = container_of(b, typeof(*p2), head); |
881 |
|
return ccs_same_acl_head(&p1->head, &p2->head) && |
882 |
|
p1->handler == p2->handler; |
883 |
|
} |
884 |
|
|
885 |
|
static bool ccs_same_task_acl(const struct ccs_acl_info *a, |
886 |
|
const struct ccs_acl_info *b) |
887 |
|
{ |
888 |
|
const struct ccs_task_acl *p1 = container_of(a, typeof(*p1), head); |
889 |
|
const struct ccs_task_acl *p2 = container_of(b, typeof(*p2), head); |
890 |
|
return ccs_same_acl_head(&p1->head, &p2->head) && |
891 |
|
p1->domainname == p2->domainname; |
892 |
|
} |
893 |
|
|
894 |
|
/** |
895 |
|
* ccs_write_task - Update task related list. |
896 |
|
* |
897 |
|
* @data: String to parse. |
898 |
|
* @domain: Pointer to "struct ccs_domain_info". |
899 |
|
* @condition: Pointer to "struct ccs_condition". Maybe NULL. |
900 |
|
* @is_delete: True if it is a delete request. |
901 |
|
* |
902 |
|
* Returns 0 on success, negative value otherwise. |
903 |
|
*/ |
904 |
|
static int ccs_write_task(char *data, struct ccs_domain_info *domain, |
905 |
|
struct ccs_condition *condition, |
906 |
|
const bool is_delete) |
907 |
|
{ |
908 |
|
int error; |
909 |
|
const bool is_auto = ccs_str_starts(&data, "auto_domain_transition "); |
910 |
|
if (!is_auto && !ccs_str_starts(&data, "manual_domain_transition ")) { |
911 |
|
struct ccs_handler_acl e = { |
912 |
|
.head.cond = condition, |
913 |
|
}; |
914 |
|
if (ccs_str_starts(&data, "auto_execute_handler ")) |
915 |
|
e.head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER; |
916 |
|
else if (ccs_str_starts(&data, "denied_execute_handler ")) |
917 |
|
e.head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER; |
918 |
|
else |
919 |
|
return -EINVAL; |
920 |
|
if (!ccs_correct_path(data)) |
921 |
|
return -EINVAL; |
922 |
|
e.handler = ccs_get_name(data); |
923 |
|
if (!e.handler) |
924 |
|
return -ENOMEM; |
925 |
|
if (e.handler->is_patterned) |
926 |
|
error = -EINVAL; /* No patterns allowed. */ |
927 |
|
else |
928 |
|
error = ccs_update_domain(&e.head, sizeof(e), |
929 |
|
is_delete, domain, |
930 |
|
ccs_same_handler_acl, NULL); |
931 |
|
ccs_put_name(e.handler); |
932 |
|
} else { |
933 |
|
struct ccs_task_acl e = { |
934 |
|
.head.type = is_auto ? |
935 |
|
CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL, |
936 |
|
.head.cond = condition, |
937 |
|
}; |
938 |
|
if (!ccs_correct_domain(data)) |
939 |
|
return -EINVAL; |
940 |
|
e.domainname = ccs_get_name(data); |
941 |
|
if (!e.domainname) |
942 |
|
return -ENOMEM; |
943 |
|
error = ccs_update_domain(&e.head, sizeof(e), is_delete, |
944 |
|
domain, ccs_same_task_acl, NULL); |
945 |
|
ccs_put_name(e.domainname); |
946 |
|
} |
947 |
|
return error; |
948 |
|
} |
949 |
|
|
950 |
static int ccs_write_domain2(char *data, struct ccs_domain_info *domain, |
static int ccs_write_domain2(char *data, struct ccs_domain_info *domain, |
951 |
const bool is_delete) |
const bool is_delete) |
952 |
{ |
{ |
954 |
const char *keyword; |
const char *keyword; |
955 |
int (*write) (char *, struct ccs_domain_info *, |
int (*write) (char *, struct ccs_domain_info *, |
956 |
struct ccs_condition *, const bool); |
struct ccs_condition *, const bool); |
957 |
} ccs_callback[4] = { |
} ccs_callback[7] = { |
958 |
{ "network ", ccs_write_network }, |
{ "file ", ccs_write_file }, |
959 |
|
{ "network inet ", ccs_write_inet_network }, |
960 |
|
{ "network unix ", ccs_write_unix_network }, |
961 |
{ "misc ", ccs_write_misc }, |
{ "misc ", ccs_write_misc }, |
962 |
{ "capability ", ccs_write_capability }, |
{ "capability ", ccs_write_capability }, |
963 |
{ "ipc ", ccs_write_ipc }, |
{ "ipc ", ccs_write_ipc }, |
964 |
|
{ "task ", ccs_write_task }, |
965 |
}; |
}; |
966 |
int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *, |
int error = -EINVAL; |
|
const bool) = ccs_write_file; |
|
|
int error; |
|
967 |
u8 i; |
u8 i; |
968 |
struct ccs_condition *cond = NULL; |
struct ccs_condition *cond = NULL; |
969 |
char *cp = ccs_find_condition_part(data); |
char *cp = ccs_find_condition_part(data); |
972 |
if (!cond) |
if (!cond) |
973 |
return -EINVAL; |
return -EINVAL; |
974 |
} |
} |
975 |
for (i = 0; i < 4; i++) { |
for (i = 0; i < 7; i++) { |
976 |
if (!ccs_str_starts(&data, ccs_callback[i].keyword)) |
if (!ccs_str_starts(&data, ccs_callback[i].keyword)) |
977 |
continue; |
continue; |
978 |
write = ccs_callback[i].write; |
error = ccs_callback[i].write(data, domain, cond, is_delete); |
979 |
break; |
break; |
980 |
} |
} |
|
error = write(data, domain, cond, is_delete); |
|
981 |
if (cond) |
if (cond) |
982 |
ccs_put_condition(cond); |
ccs_put_condition(cond); |
983 |
return error; |
return error; |
985 |
|
|
986 |
static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = { |
static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = { |
987 |
[CCS_DIF_QUOTA_WARNED] = CCS_KEYWORD_QUOTA_EXCEEDED "\n", |
[CCS_DIF_QUOTA_WARNED] = CCS_KEYWORD_QUOTA_EXCEEDED "\n", |
|
[CCS_DIF_IGNORE_GLOBAL] = CCS_KEYWORD_IGNORE_GLOBAL "\n", |
|
988 |
[CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n" |
[CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n" |
989 |
}; |
}; |
990 |
|
|
1018 |
else if (is_select) |
else if (is_select) |
1019 |
domain = ccs_find_domain(data); |
domain = ccs_find_domain(data); |
1020 |
else |
else |
1021 |
domain = ccs_assign_domain(data, 0); |
domain = ccs_assign_domain(data, 0, 0, false); |
1022 |
head->w.domain = domain; |
head->w.domain = domain; |
1023 |
return 0; |
return 0; |
1024 |
} |
} |
1031 |
domain->profile = (u8) profile; |
domain->profile = (u8) profile; |
1032 |
return 0; |
return 0; |
1033 |
} |
} |
1034 |
|
if (sscanf(data, CCS_KEYWORD_USE_GROUP "%u", &profile) == 1 |
1035 |
|
&& profile < CCS_MAX_ACL_GROUPS) { |
1036 |
|
domain->group = (u8) profile; |
1037 |
|
return 0; |
1038 |
|
} |
1039 |
for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) { |
for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) { |
1040 |
const char *cp = ccs_dif[profile]; |
const char *cp = ccs_dif[profile]; |
1041 |
if (strncmp(data, cp, strlen(cp) - 1)) |
if (strncmp(data, cp, strlen(cp) - 1)) |
1131 |
switch (head->r.cond_step) { |
switch (head->r.cond_step) { |
1132 |
case 0: |
case 0: |
1133 |
{ |
{ |
1134 |
if (cond->condc) |
ccs_set_string(head, " if"); |
|
ccs_set_string(head, " if"); |
|
1135 |
head->r.cond_index = 0; |
head->r.cond_index = 0; |
1136 |
head->r.cond_step++; |
head->r.cond_step++; |
1137 |
} |
} |
1243 |
head->r.cond_step++; |
head->r.cond_step++; |
1244 |
/* fall through */ |
/* fall through */ |
1245 |
case 3: |
case 3: |
1246 |
{ |
if (cond->audit) |
1247 |
u8 j; |
ccs_io_printf(head, " audit=%s", |
1248 |
const u8 i = cond->post_state[3]; |
ccs_yesno(cond->audit == 2)); |
1249 |
if (i) |
if (cond->transit) { |
1250 |
ccs_set_string(head, " ; set"); |
ccs_set_string(head, " auto_domain_transitition=\""); |
1251 |
for (j = 0; j < 3; j++) |
ccs_set_string(head, cond->transit->name); |
1252 |
if ((i & (1 << j))) |
ccs_set_string(head, "\""); |
|
ccs_io_printf(head, |
|
|
" task.state[%u]=%u", j, |
|
|
cond->post_state[j]); |
|
|
if (i & (1 << 4)) |
|
|
ccs_io_printf(head, " audit=%s", |
|
|
ccs_yesno(cond->post_state[4])); |
|
1253 |
} |
} |
1254 |
ccs_set_lf(head); |
ccs_set_lf(head); |
1255 |
return true; |
return true; |
1273 |
return bit; |
return bit; |
1274 |
} |
} |
1275 |
|
|
1276 |
|
static void ccs_set_group(struct ccs_io_buffer *head) |
1277 |
|
{ |
1278 |
|
if (head->type == CCS_EXCEPTIONPOLICY) |
1279 |
|
ccs_io_printf(head, "acl_group %u ", head->r.group_index); |
1280 |
|
} |
1281 |
|
|
1282 |
/** |
/** |
1283 |
* ccs_print_entry - Print an ACL entry. |
* ccs_print_entry - Print an ACL entry. |
1284 |
* |
* |
1308 |
if (!(perm & (1 << bit))) |
if (!(perm & (1 << bit))) |
1309 |
continue; |
continue; |
1310 |
if (head->r.print_execute_only && |
if (head->r.print_execute_only && |
1311 |
bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT) |
bit != CCS_TYPE_EXECUTE |
1312 |
|
/* && bit != CCS_TYPE_TRANSIT */) |
1313 |
continue; |
continue; |
1314 |
break; |
break; |
1315 |
} |
} |
1316 |
if (bit >= CCS_MAX_PATH_OPERATION) |
if (bit >= CCS_MAX_PATH_OPERATION) |
1317 |
goto done; |
goto done; |
1318 |
|
ccs_set_group(head); |
1319 |
ccs_set_string(head, "file "); |
ccs_set_string(head, "file "); |
1320 |
ccs_set_string(head, ccs_path_keyword[bit]); |
ccs_set_string(head, ccs_path_keyword[bit]); |
1321 |
ccs_print_name_union(head, &ptr->name); |
ccs_print_name_union(head, &ptr->name); |
1322 |
} else if (acl_type == CCS_TYPE_EXECUTE_HANDLER || |
} else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER || |
1323 |
acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) { |
acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) { |
1324 |
struct ccs_execute_handler *ptr |
struct ccs_handler_acl *ptr |
1325 |
= container_of(acl, typeof(*ptr), head); |
= container_of(acl, typeof(*ptr), head); |
1326 |
ccs_io_printf(head, "%s ", |
ccs_set_group(head); |
1327 |
acl_type == CCS_TYPE_EXECUTE_HANDLER ? |
ccs_set_string(head, "task "); |
1328 |
CCS_KEYWORD_EXECUTE_HANDLER : |
ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER |
1329 |
CCS_KEYWORD_DENIED_EXECUTE_HANDLER); |
? "auto_execute_handler " : |
1330 |
|
"denied_execute_handler "); |
1331 |
ccs_set_string(head, ptr->handler->name); |
ccs_set_string(head, ptr->handler->name); |
1332 |
|
} else if (acl_type == CCS_TYPE_AUTO_TASK_ACL || |
1333 |
|
acl_type == CCS_TYPE_MANUAL_TASK_ACL) { |
1334 |
|
struct ccs_task_acl *ptr = |
1335 |
|
container_of(acl, typeof(*ptr), head); |
1336 |
|
ccs_set_group(head); |
1337 |
|
ccs_set_string(head, "task "); |
1338 |
|
ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ? |
1339 |
|
"auto_domain_transition " : |
1340 |
|
"manual_domain_transition "); |
1341 |
|
ccs_set_string(head, ptr->domainname->name); |
1342 |
} else if (head->r.print_execute_only) { |
} else if (head->r.print_execute_only) { |
1343 |
return true; |
return true; |
1344 |
} else if (acl_type == CCS_TYPE_MKDEV_ACL) { |
} else if (acl_type == CCS_TYPE_MKDEV_ACL) { |
1347 |
bit = ccs_fns(ptr->perm, bit); |
bit = ccs_fns(ptr->perm, bit); |
1348 |
if (bit >= CCS_MAX_MKDEV_OPERATION) |
if (bit >= CCS_MAX_MKDEV_OPERATION) |
1349 |
goto done; |
goto done; |
1350 |
|
ccs_set_group(head); |
1351 |
ccs_set_string(head, "file "); |
ccs_set_string(head, "file "); |
1352 |
ccs_set_string(head, ccs_mkdev_keyword[bit]); |
ccs_set_string(head, ccs_mkdev_keyword[bit]); |
1353 |
ccs_print_name_union(head, &ptr->name); |
ccs_print_name_union(head, &ptr->name); |
1360 |
bit = ccs_fns(ptr->perm, bit); |
bit = ccs_fns(ptr->perm, bit); |
1361 |
if (bit >= CCS_MAX_PATH2_OPERATION) |
if (bit >= CCS_MAX_PATH2_OPERATION) |
1362 |
goto done; |
goto done; |
1363 |
|
ccs_set_group(head); |
1364 |
ccs_set_string(head, "file "); |
ccs_set_string(head, "file "); |
1365 |
ccs_set_string(head, ccs_path2_keyword[bit]); |
ccs_set_string(head, ccs_path2_keyword[bit]); |
1366 |
ccs_print_name_union(head, &ptr->name1); |
ccs_print_name_union(head, &ptr->name1); |
1371 |
bit = ccs_fns(ptr->perm, bit); |
bit = ccs_fns(ptr->perm, bit); |
1372 |
if (bit >= CCS_MAX_PATH_NUMBER_OPERATION) |
if (bit >= CCS_MAX_PATH_NUMBER_OPERATION) |
1373 |
goto done; |
goto done; |
1374 |
|
ccs_set_group(head); |
1375 |
ccs_set_string(head, "file "); |
ccs_set_string(head, "file "); |
1376 |
ccs_set_string(head, ccs_path_number_keyword[bit]); |
ccs_set_string(head, ccs_path_number_keyword[bit]); |
1377 |
ccs_print_name_union(head, &ptr->name); |
ccs_print_name_union(head, &ptr->name); |
1379 |
} else if (acl_type == CCS_TYPE_ENV_ACL) { |
} else if (acl_type == CCS_TYPE_ENV_ACL) { |
1380 |
struct ccs_env_acl *ptr = |
struct ccs_env_acl *ptr = |
1381 |
container_of(acl, typeof(*ptr), head); |
container_of(acl, typeof(*ptr), head); |
1382 |
|
ccs_set_group(head); |
1383 |
ccs_set_string(head, "misc env "); |
ccs_set_string(head, "misc env "); |
1384 |
ccs_set_string(head, ptr->env->name); |
ccs_set_string(head, ptr->env->name); |
1385 |
} else if (acl_type == CCS_TYPE_CAPABILITY_ACL) { |
} else if (acl_type == CCS_TYPE_CAPABILITY_ACL) { |
1386 |
struct ccs_capability_acl *ptr = |
struct ccs_capability_acl *ptr = |
1387 |
container_of(acl, typeof(*ptr), head); |
container_of(acl, typeof(*ptr), head); |
1388 |
|
ccs_set_group(head); |
1389 |
ccs_set_string(head, "capability "); |
ccs_set_string(head, "capability "); |
1390 |
ccs_set_string(head, ccs_cap2keyword(ptr->operation)); |
ccs_set_string(head, ccs_cap2keyword(ptr->operation)); |
1391 |
} else if (acl_type == CCS_TYPE_IP_NETWORK_ACL) { |
} else if (acl_type == CCS_TYPE_INET_ACL) { |
1392 |
struct ccs_ip_network_acl *ptr = |
struct ccs_inet_acl *ptr = |
1393 |
container_of(acl, typeof(*ptr), head); |
container_of(acl, typeof(*ptr), head); |
1394 |
bit = ccs_fns(ptr->perm, bit); |
bit = ccs_fns(ptr->perm, bit); |
1395 |
if (bit >= CCS_MAX_NETWORK_OPERATION) |
if (bit >= CCS_MAX_NETWORK_OPERATION) |
1396 |
goto done; |
goto done; |
1397 |
ccs_set_string(head, "network "); |
ccs_set_group(head); |
1398 |
ccs_set_string(head, ccs_net_keyword[bit]); |
ccs_set_string(head, "network inet "); |
1399 |
|
ccs_set_string(head, ccs_proto_keyword[ptr->protocol]); |
1400 |
|
ccs_set_space(head); |
1401 |
|
ccs_set_string(head, ccs_socket_keyword[bit]); |
1402 |
ccs_set_space(head); |
ccs_set_space(head); |
1403 |
switch (ptr->address_type) { |
switch (ptr->address_type) { |
1404 |
char buf[128]; |
char buf[128]; |
1419 |
break; |
break; |
1420 |
} |
} |
1421 |
ccs_print_number_union(head, &ptr->port); |
ccs_print_number_union(head, &ptr->port); |
1422 |
|
} else if (acl_type == CCS_TYPE_UNIX_ACL) { |
1423 |
|
struct ccs_unix_acl *ptr = |
1424 |
|
container_of(acl, typeof(*ptr), head); |
1425 |
|
bit = ccs_fns(ptr->perm, bit); |
1426 |
|
if (bit >= CCS_MAX_NETWORK_OPERATION) |
1427 |
|
goto done; |
1428 |
|
ccs_set_group(head); |
1429 |
|
ccs_set_string(head, "network unix "); |
1430 |
|
ccs_set_string(head, ccs_proto_keyword[ptr->protocol]); |
1431 |
|
ccs_set_space(head); |
1432 |
|
ccs_set_string(head, ccs_socket_keyword[bit]); |
1433 |
|
ccs_print_name_union(head, &ptr->name); |
1434 |
} else if (acl_type == CCS_TYPE_SIGNAL_ACL) { |
} else if (acl_type == CCS_TYPE_SIGNAL_ACL) { |
1435 |
struct ccs_signal_acl *ptr = |
struct ccs_signal_acl *ptr = |
1436 |
container_of(acl, typeof(*ptr), head); |
container_of(acl, typeof(*ptr), head); |
1437 |
|
ccs_set_group(head); |
1438 |
ccs_set_string(head, "ipc signal "); |
ccs_set_string(head, "ipc signal "); |
1439 |
ccs_io_printf(head, "%u ", ptr->sig); |
ccs_io_printf(head, "%u ", ptr->sig); |
1440 |
ccs_set_string(head, ptr->domainname->name); |
ccs_set_string(head, ptr->domainname->name); |
1441 |
} else if (acl_type == CCS_TYPE_MOUNT_ACL) { |
} else if (acl_type == CCS_TYPE_MOUNT_ACL) { |
1442 |
struct ccs_mount_acl *ptr = |
struct ccs_mount_acl *ptr = |
1443 |
container_of(acl, typeof(*ptr), head); |
container_of(acl, typeof(*ptr), head); |
1444 |
|
ccs_set_group(head); |
1445 |
ccs_io_printf(head, "file mount"); |
ccs_io_printf(head, "file mount"); |
1446 |
ccs_print_name_union(head, &ptr->dev_name); |
ccs_print_name_union(head, &ptr->dev_name); |
1447 |
ccs_print_name_union(head, &ptr->dir_name); |
ccs_print_name_union(head, &ptr->dir_name); |
1466 |
case CCS_TYPE_MKDEV_ACL: |
case CCS_TYPE_MKDEV_ACL: |
1467 |
case CCS_TYPE_PATH2_ACL: |
case CCS_TYPE_PATH2_ACL: |
1468 |
case CCS_TYPE_PATH_NUMBER_ACL: |
case CCS_TYPE_PATH_NUMBER_ACL: |
1469 |
case CCS_TYPE_IP_NETWORK_ACL: |
case CCS_TYPE_INET_ACL: |
1470 |
|
case CCS_TYPE_UNIX_ACL: |
1471 |
goto next; |
goto next; |
1472 |
} |
} |
1473 |
done: |
done: |
1480 |
* |
* |
1481 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
1482 |
* @domain: Pointer to "struct ccs_domain_info". |
* @domain: Pointer to "struct ccs_domain_info". |
1483 |
|
* @index: Index number. |
1484 |
* |
* |
1485 |
* Caller holds ccs_read_lock(). |
* Caller holds ccs_read_lock(). |
1486 |
* |
* |
1487 |
* Returns true on success, false otherwise. |
* Returns true on success, false otherwise. |
1488 |
*/ |
*/ |
1489 |
static bool ccs_read_domain2(struct ccs_io_buffer *head, |
static bool ccs_read_domain2(struct ccs_io_buffer *head, |
1490 |
struct ccs_domain_info *domain) |
struct ccs_domain_info *domain, |
1491 |
|
const u8 index) |
1492 |
{ |
{ |
1493 |
list_for_each_cookie(head->r.acl, &domain->acl_info_list) { |
list_for_each_cookie(head->r.acl, &domain->acl_info_list[index]) { |
1494 |
struct ccs_acl_info *ptr = |
struct ccs_acl_info *ptr = |
1495 |
list_entry(head->r.acl, typeof(*ptr), list); |
list_entry(head->r.acl, typeof(*ptr), list); |
1496 |
if (!ccs_print_entry(head, ptr)) |
if (!ccs_print_entry(head, ptr)) |
1525 |
ccs_set_lf(head); |
ccs_set_lf(head); |
1526 |
ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n", |
ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n", |
1527 |
domain->profile); |
domain->profile); |
1528 |
|
ccs_io_printf(head, CCS_KEYWORD_USE_GROUP "%u\n", |
1529 |
|
domain->group); |
1530 |
for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++) |
for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++) |
1531 |
if (domain->flags[i]) |
if (domain->flags[i]) |
1532 |
ccs_set_string(head, ccs_dif[i]); |
ccs_set_string(head, ccs_dif[i]); |
1534 |
ccs_set_lf(head); |
ccs_set_lf(head); |
1535 |
/* fall through */ |
/* fall through */ |
1536 |
case 1: |
case 1: |
1537 |
if (!ccs_read_domain2(head, domain)) |
if (!ccs_read_domain2(head, domain, 0)) |
1538 |
|
return; |
1539 |
|
head->r.step++; |
1540 |
|
/* fall through */ |
1541 |
|
case 2: |
1542 |
|
if (!ccs_read_domain2(head, domain, 1)) |
1543 |
return; |
return; |
1544 |
head->r.step++; |
head->r.step++; |
1545 |
if (!ccs_set_lf(head)) |
if (!ccs_set_lf(head)) |
1546 |
return; |
return; |
1547 |
/* fall through */ |
/* fall through */ |
1548 |
case 2: |
case 3: |
1549 |
head->r.step = 0; |
head->r.step = 0; |
1550 |
if (head->r.print_this_domain_only) |
if (head->r.print_this_domain_only) |
1551 |
goto done; |
goto done; |
1685 |
ccs_io_printf(head, "%u %u ", pid, domain->profile); |
ccs_io_printf(head, "%u %u ", pid, domain->profile); |
1686 |
ccs_set_string(head, domain->domainname->name); |
ccs_set_string(head, domain->domainname->name); |
1687 |
} else { |
} else { |
1688 |
ccs_io_printf(head, "%u manager=%s execute_handler=%s " |
ccs_io_printf(head, "%u manager=%s execute_handler=%s ", pid, |
|
"state[0]=%u state[1]=%u state[2]=%u", pid, |
|
1689 |
ccs_yesno(ccs_flags & |
ccs_yesno(ccs_flags & |
1690 |
CCS_TASK_IS_MANAGER), |
CCS_TASK_IS_MANAGER), |
1691 |
ccs_yesno(ccs_flags & |
ccs_yesno(ccs_flags & |
1692 |
CCS_TASK_IS_EXECUTE_HANDLER), |
CCS_TASK_IS_EXECUTE_HANDLER)); |
|
(u8) (ccs_flags >> 24), |
|
|
(u8) (ccs_flags >> 16), |
|
|
(u8) (ccs_flags >> 8)); |
|
1693 |
} |
} |
1694 |
} |
} |
1695 |
|
|
1737 |
for (i = 0; i < CCS_MAX_GROUP; i++) |
for (i = 0; i < CCS_MAX_GROUP; i++) |
1738 |
if (ccs_str_starts(&data, ccs_group_name[i])) |
if (ccs_str_starts(&data, ccs_group_name[i])) |
1739 |
return ccs_write_group(data, is_delete, i); |
return ccs_write_group(data, is_delete, i); |
1740 |
return ccs_write_domain2(data, &ccs_global_domain, is_delete); |
if (ccs_str_starts(&data, "acl_group ")) { |
1741 |
|
unsigned int group; |
1742 |
|
if (sscanf(data, "%u", &group) == 1 && |
1743 |
|
group < CCS_MAX_ACL_GROUPS) { |
1744 |
|
data = strchr(data, ' '); |
1745 |
|
if (data) |
1746 |
|
return ccs_write_domain2(data + 1, |
1747 |
|
&ccs_acl_group[group], |
1748 |
|
is_delete); |
1749 |
|
} |
1750 |
|
} |
1751 |
|
return -EINVAL; |
1752 |
} |
} |
1753 |
|
|
1754 |
/** |
/** |
1902 |
head->r.step++; |
head->r.step++; |
1903 |
if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP) |
if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP) |
1904 |
return; |
return; |
1905 |
head->r.eof = ccs_read_domain2(head, &ccs_global_domain); |
while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP |
1906 |
|
+ CCS_MAX_ACL_GROUPS * 2) { |
1907 |
|
head->r.group_index = (head->r.step - CCS_MAX_POLICY |
1908 |
|
- CCS_MAX_GROUP) / 2; |
1909 |
|
if (!ccs_read_domain2(head, |
1910 |
|
&ccs_acl_group[head->r.group_index], |
1911 |
|
head->r.step & 1)) |
1912 |
|
return; |
1913 |
|
head->r.step++; |
1914 |
|
} |
1915 |
|
head->r.eof = true; |
1916 |
} |
} |
1917 |
|
|
1918 |
/* Wait queue for ccs_query_list. */ |
/* Wait queue for ccs_query_list. */ |
1981 |
header = ccs_init_log(&len, r); |
header = ccs_init_log(&len, r); |
1982 |
if (!header) |
if (!header) |
1983 |
return 0; |
return 0; |
1984 |
pref = ccs_profile(r->profile)->learning; |
pref = &ccs_profile(r->profile)->preference; |
1985 |
/* strstr() will return NULL if ordering is wrong. */ |
/* strstr() will return NULL if ordering is wrong. */ |
1986 |
if (r->param_type == CCS_TYPE_PATH_ACL && |
if (r->param_type == CCS_TYPE_PATH_ACL && |
1987 |
r->param.path.operation == CCS_TYPE_EXECUTE) { |
r->param.path.operation == CCS_TYPE_EXECUTE) { |
2044 |
int i; |
int i; |
2045 |
if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) |
if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) |
2046 |
return -EPERM; |
return -EPERM; |
2047 |
for (i = 0; i < ccs_profile(domain->profile)->enforcing-> |
for (i = 0; i < ccs_profile(domain->profile)->preference. |
2048 |
enforcing_penalty; i++) { |
enforcing_penalty; i++) { |
2049 |
set_current_state(TASK_INTERRUPTIBLE); |
set_current_state(TASK_INTERRUPTIBLE); |
2050 |
schedule_timeout(HZ / 10); |
schedule_timeout(HZ / 10); |
2260 |
{ |
{ |
2261 |
if (head->r.eof) |
if (head->r.eof) |
2262 |
return; |
return; |
2263 |
ccs_set_string(head, "1.7.2"); |
ccs_set_string(head, "1.8.0-pre"); |
2264 |
head->r.eof = true; |
head->r.eof = true; |
2265 |
} |
} |
2266 |
|
|