Tetsuo Handa
from-****@I-lov*****
Fri Nov 26 21:24:04 JST 2010
Jamie Nguyen wrote: > > I prefer unifying interface for audit logs rather than adding new interfaces. > > Yes, I totally agree. > > > What about renaming /proc/ccs/grant_log and /proc/ccs/reject_log to > > /proc/ccs/audit (and add a field for telling this log is generated by "found" > > or by "not found")? > > > > The ccs-auditd reads all logs from /proc/ccs/audit and sorts by > > "directive name" (e.g. use_profile/use_group) and/or "access control mode" > > (e.g. "mode=disabled") and/or "profile number" (e.g. "profile=0") and writes to > > specified files. We will want a configuration file like syslog.conf . > > I think this could be nice. > OK. Here is the patch for merging /proc/ccs/grant_log and /proc/ccs/reject_log into /proc/ccs/audit . A new field "granted=yes" or "granted=no" is added in the first line of audit logs. Index: trunk/1.8.x/ccs-patch/security/ccsecurity/Kconfig =================================================================== --- trunk/1.8.x/ccs-patch/security/ccsecurity/Kconfig (revision 4165) +++ trunk/1.8.x/ccs-patch/security/ccsecurity/Kconfig (working copy) @@ -87,26 +87,13 @@ domain so that you won't give the <kernel> domain permission to execute /bin/sh . -config CCSECURITY_MAX_GRANT_LOG - int "Default maximal count for grant log" +config CCSECURITY_MAX_AUDIT_LOG + int "Default maximal count for audit log" default 1024 range 0 2147483647 depends on CCSECURITY help This is the default value for maximal entries for - access grant logs that the kernel can hold on memory. - You can read the log via /proc/ccs/grant_log. - If you don't need access grant logs, - you may set this value to 0. - -config CCSECURITY_MAX_REJECT_LOG - int "Default maximal count for reject log" - default 1024 - range 0 2147483647 - depends on CCSECURITY - help - This is the default value for maximal entries for - access reject logs that the kernel can hold on memory. - You can read the log via /proc/ccs/reject_log. - If you don't need access reject logs, - you may set this value to 0. + audit logs that the kernel can hold on memory. + You can read the log via /proc/ccs/audit. + If you don't need audit logs, you may set this value to 0. Index: trunk/1.8.x/ccs-patch/security/ccsecurity/audit.c =================================================================== --- trunk/1.8.x/ccs-patch/security/ccsecurity/audit.c (revision 4165) +++ trunk/1.8.x/ccs-patch/security/ccsecurity/audit.c (working copy) @@ -183,11 +183,12 @@ } pos = snprintf(buffer, ccs_buffer_len - 1, "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s " - "(global-pid=%u) task={ pid=%u ppid=%u uid=%u gid=%u " - "euid=%u egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u " - "type%s=execute_handler }", stamp.year, stamp.month, - stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile, - ccs_mode[r->mode], gpid, ccs_sys_getpid(), + "granted=%s (global-pid=%u) task={ pid=%u ppid=%u " + "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u " + "fsuid=%u fsgid=%u type%s=execute_handler }", + stamp.year, stamp.month, stamp.day, stamp.hour, + stamp.min, stamp.sec, r->profile, ccs_mode[r->mode], + ccs_yesno(r->granted), gpid, ccs_sys_getpid(), ccs_sys_getppid(), current_uid(), current_gid(), current_euid(), current_egid(), current_suid(), current_sgid(), current_fsuid(), current_fsgid(), @@ -355,11 +356,8 @@ kfree(buf); } -/* Wait queue for /proc/ccs/grant_log and /proc/ccs/reject_log. */ -static wait_queue_head_t ccs_log_wait[2] = { - __WAIT_QUEUE_HEAD_INITIALIZER(ccs_log_wait[0]), - __WAIT_QUEUE_HEAD_INITIALIZER(ccs_log_wait[1]), -}; +/* Wait queue for /proc/ccs/audit. */ +static DECLARE_WAIT_QUEUE_HEAD(ccs_log_wait); /* Structure for audit log. */ struct ccs_log { @@ -369,14 +367,13 @@ }; /* The list for "struct ccs_log". */ -static struct list_head ccs_log[2] = { - LIST_HEAD_INIT(ccs_log[0]), LIST_HEAD_INIT(ccs_log[1]), -}; -/* Lock for "struct list_head ccs_log[2]". */ +static LIST_HEAD(ccs_log); + +/* Lock for "struct list_head ccs_log". */ static DEFINE_SPINLOCK(ccs_log_lock); -/* Length of "stuct list_head ccs_log[2]". */ -static unsigned int ccs_log_count[2]; +/* Length of "stuct list_head ccs_log". */ +static unsigned int ccs_log_count; /** * ccs_get_audit - Get audit mode. @@ -392,18 +389,13 @@ const struct ccs_acl_info *matched_acl, const bool is_granted) { - unsigned int len; u8 mode; const u8 category = ccs_index2category[index] + CCS_MAX_MAC_INDEX; struct ccs_profile *p; if (!ccs_policy_loaded) return false; p = ccs_profile(profile); - if (is_granted) - len = p->pref[CCS_PREF_MAX_GRANT_LOG]; - else - len = p->pref[CCS_PREF_MAX_REJECT_LOG]; - if (ccs_log_count[is_granted] >= len) + if (ccs_log_count >= p->pref[CCS_PREF_MAX_AUDIT_LOG]) return false; if (is_granted && matched_acl && matched_acl->cond && matched_acl->cond->grant_log != CCS_GRANTLOG_AUTO) @@ -434,8 +426,7 @@ char *buf; struct ccs_log *entry; bool quota_exceeded = false; - const bool is_granted = r->granted; - if (!ccs_get_audit(r->profile, r->type, r->matched_acl, is_granted)) + if (!ccs_get_audit(r->profile, r->type, r->matched_acl, r->granted)) goto out; buf = ccs_init_log(r, len, fmt, args); if (!buf) @@ -459,8 +450,8 @@ quota_exceeded = true; } else { ccs_memory_used[CCS_MEMORY_AUDIT] += entry->size; - list_add_tail(&entry->list, &ccs_log[is_granted]); - ccs_log_count[is_granted]++; + list_add_tail(&entry->list, &ccs_log); + ccs_log_count++; } spin_unlock(&ccs_log_lock); if (quota_exceeded) { @@ -468,7 +459,7 @@ kfree(entry); goto out; } - wake_up(&ccs_log_wait[is_granted]); + wake_up(&ccs_log_wait); out: ccs_update_task_domain(r); } @@ -503,7 +494,6 @@ void ccs_read_log(struct ccs_io_buffer *head) { struct ccs_log *ptr = NULL; - const bool is_granted = head->type == CCS_GRANTLOG; if (head->r.w_pos) return; if (head->read_buf) { @@ -511,10 +501,10 @@ head->read_buf = NULL; } spin_lock(&ccs_log_lock); - if (!list_empty(&ccs_log[is_granted])) { - ptr = list_entry(ccs_log[is_granted].next, typeof(*ptr), list); + if (!list_empty(&ccs_log)) { + ptr = list_entry(ccs_log.next, typeof(*ptr), list); list_del(&ptr->list); - ccs_log_count[is_granted]--; + ccs_log_count--; ccs_memory_used[CCS_MEMORY_AUDIT] -= ptr->size; } spin_unlock(&ccs_log_lock); @@ -535,12 +525,10 @@ */ int ccs_poll_log(struct file *file, poll_table *wait) { - struct ccs_io_buffer *head = file->private_data; - const bool is_granted = head->type == CCS_GRANTLOG; - if (ccs_log_count[is_granted]) + if (ccs_log_count) return POLLIN | POLLRDNORM; - poll_wait(file, &ccs_log_wait[is_granted], wait); - if (ccs_log_count[is_granted]) + poll_wait(file, &ccs_log_wait, wait); + if (ccs_log_count) return POLLIN | POLLRDNORM; return 0; } Index: trunk/1.8.x/ccs-patch/security/ccsecurity/internal.h =================================================================== --- trunk/1.8.x/ccs-patch/security/ccsecurity/internal.h (revision 4165) +++ trunk/1.8.x/ccs-patch/security/ccsecurity/internal.h (working copy) @@ -652,8 +652,7 @@ /* Index numbers for profile's PREFERENCE values. */ enum ccs_pref_index { - CCS_PREF_MAX_GRANT_LOG, - CCS_PREF_MAX_REJECT_LOG, + CCS_PREF_MAX_AUDIT_LOG, CCS_PREF_MAX_LEARNING_ENTRY, CCS_PREF_ENFORCING_PENALTY, CCS_MAX_PREF @@ -667,8 +666,7 @@ CCS_PROCESS_STATUS, CCS_MEMINFO, CCS_STAT, - CCS_GRANTLOG, - CCS_REJECTLOG, + CCS_AUDIT, CCS_VERSION, CCS_PROFILE, CCS_QUERY, @@ -1422,6 +1420,7 @@ va_list args); char *ccs_read_token(struct ccs_acl_param *param); char *ccs_realpath_from_path(struct path *path); +const char *ccs_yesno(const unsigned int value); const char *ccs_get_exe(void); const struct ccs_path_info *ccs_compare_name_union (const struct ccs_path_info *name, const struct ccs_name_union *ptr); Index: trunk/1.8.x/ccs-patch/security/ccsecurity/proc_if.c =================================================================== --- trunk/1.8.x/ccs-patch/security/ccsecurity/proc_if.c (revision 4165) +++ trunk/1.8.x/ccs-patch/security/ccsecurity/proc_if.c (working copy) @@ -312,8 +312,7 @@ ccs_create_entry("domain_policy", 0600, ccs_dir, CCS_DOMAINPOLICY); ccs_create_entry("exception_policy", 0600, ccs_dir, CCS_EXCEPTIONPOLICY); - ccs_create_entry("grant_log", 0400, ccs_dir, CCS_GRANTLOG); - ccs_create_entry("reject_log", 0400, ccs_dir, CCS_REJECTLOG); + ccs_create_entry("audit", 0400, ccs_dir, CCS_AUDIT); ccs_create_entry(".domain_status", 0600, ccs_dir, CCS_DOMAIN_STATUS); ccs_create_entry(".process_status", 0600, ccs_dir, CCS_PROCESS_STATUS); Index: trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c =================================================================== --- trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c (revision 4165) +++ trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c (working copy) @@ -257,8 +257,7 @@ /* String table for PREFERENCE keyword. */ static const char * const ccs_pref_keywords[CCS_MAX_PREF] = { - [CCS_PREF_MAX_GRANT_LOG] = "max_grant_log", - [CCS_PREF_MAX_REJECT_LOG] = "max_reject_log", + [CCS_PREF_MAX_AUDIT_LOG] = "max_audit_log", [CCS_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry", [CCS_PREF_ENFORCING_PENALTY] = "enforcing_penalty", }; @@ -273,7 +272,7 @@ * * Returns "yes" if @value is not 0, "no" otherwise. */ -static const char *ccs_yesno(const unsigned int value) +const char *ccs_yesno(const unsigned int value) { return value ? "yes" : "no"; } @@ -442,10 +441,8 @@ CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG; memset(ptr->config, CCS_CONFIG_USE_DEFAULT, sizeof(ptr->config)); - ptr->pref[CCS_PREF_MAX_GRANT_LOG] = - CONFIG_CCSECURITY_MAX_GRANT_LOG; - ptr->pref[CCS_PREF_MAX_REJECT_LOG] = - CONFIG_CCSECURITY_MAX_REJECT_LOG; + ptr->pref[CCS_PREF_MAX_AUDIT_LOG] = + CONFIG_CCSECURITY_MAX_AUDIT_LOG; ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY; mb(); /* Avoid out-of-order execution. */ @@ -2144,7 +2141,7 @@ va_start(args, fmt); len = vsnprintf((char *) &len, 1, fmt, args) + 1; va_end(args); - /* Write /proc/ccs/grant_log or /proc/ccs/reject_log. */ + /* Write /proc/ccs/audit. */ va_start(args, fmt); ccs_write_log2(r, len, fmt, args); va_end(args); @@ -2557,8 +2554,7 @@ head->write = ccs_write_exception; head->read = ccs_read_exception; break; - case CCS_GRANTLOG: /* /proc/ccs/grant_log */ - case CCS_REJECTLOG: /* /proc/ccs/reject_log */ + case CCS_AUDIT: /* /proc/ccs/audit */ head->poll = ccs_poll_log; head->read = ccs_read_log; break; @@ -2644,9 +2640,8 @@ */ if (type == CCS_QUERY) atomic_inc(&ccs_query_observers); - else if (type != CCS_GRANTLOG && type != CCS_REJECTLOG && - type != CCS_VERSION && type != CCS_MEMINFO && - type != CCS_STAT) + else if (type != CCS_AUDIT && type != CCS_VERSION && + type != CCS_MEMINFO && type != CCS_STAT) head->reader_idx = ccs_lock(); file->private_data = head; return 0; @@ -2662,8 +2657,7 @@ * * Waits for read readiness. * /proc/ccs/query is handled by /usr/sbin/ccs-queryd and - * /proc/ccs/grant_log and /proc/ccs/reject_log are handled by - * /usr/sbin/ccs-auditd. + * /proc/ccs/audit is handled by /usr/sbin/ccs-auditd. */ int ccs_poll_control(struct file *file, poll_table *wait) { @@ -2801,9 +2795,8 @@ if (type == CCS_QUERY) { if (atomic_dec_and_test(&ccs_query_observers)) wake_up_all(&ccs_answer_wait); - } else if (type != CCS_GRANTLOG && type != CCS_REJECTLOG && - type != CCS_VERSION && type != CCS_MEMINFO && - type != CCS_STAT) + } else if (type != CCS_AUDIT && type != CCS_VERSION && + type != CCS_MEMINFO && type != CCS_STAT) ccs_unlock(head->reader_idx); /* Release memory used for policy I/O. */ kfree(head->read_buf); Index: trunk/1.8.x/ccs-patch/security/ccsecurity/Config.in =================================================================== --- trunk/1.8.x/ccs-patch/security/ccsecurity/Config.in (revision 4165) +++ trunk/1.8.x/ccs-patch/security/ccsecurity/Config.in (working copy) @@ -25,14 +25,10 @@ string ' Built-in domain initializer programs' CONFIG_CCSECURITY_BUILTIN_INITIALIZERS "/sbin/modprobe /sbin/hotplug" - [ -z "$CONFIG_CCSECURITY_MAX_GRANT_LOG" ] && define_int CONFIG_CCSECURITY_MAX_GRANT_LOG 1024 - [ $CONFIG_CCSECURITY_MAX_GRANT_LOG -lt 0 ] && define_int CONFIG_CCSECURITY_MAX_GRANT_LOG 0 - int ' Default maximal count for grant log' CONFIG_CCSECURITY_MAX_GRANT_LOG + [ -z "$CONFIG_CCSECURITY_MAX_AUDIT_LOG" ] && define_int CONFIG_CCSECURITY_MAX_AUDIT_LOG 1024 + [ $CONFIG_CCSECURITY_MAX_AUDIT_LOG -lt 0 ] && define_int CONFIG_CCSECURITY_MAX_AUDIT_LOG 0 + int ' Default maximal count for audit log' CONFIG_CCSECURITY_MAX_AUDIT_LOG - [ -z "$CONFIG_CCSECURITY_MAX_REJECT_LOG" ] && define_int CONFIG_CCSECURITY_MAX_REJECT_LOG 1024 - [ $CONFIG_CCSECURITY_MAX_REJECT_LOG -lt 0 ] && define_int CONFIG_CCSECURITY_MAX_REJECT_LOG 0 - int ' Default maximal count for reject log' CONFIG_CCSECURITY_MAX_REJECT_LOG - fi endmenu Index: trunk/1.8.x/ccs-patch/config.ccs =================================================================== --- trunk/1.8.x/ccs-patch/config.ccs (revision 4165) +++ trunk/1.8.x/ccs-patch/config.ccs (working copy) @@ -6,5 +6,4 @@ CONFIG_CCSECURITY_DEFAULT_LOADER="/sbin/ccs-init" CONFIG_CCSECURITY_ALTERNATIVE_TRIGGER="/sbin/ccs-start" CONFIG_CCSECURITY_BUILTIN_INITIALIZERS="/sbin/modprobe /sbin/hotplug" -CONFIG_CCSECURITY_MAX_GRANT_LOG=1024 -CONFIG_CCSECURITY_MAX_REJECT_LOG=1024 +CONFIG_CCSECURITY_MAX_AUDIT_LOG=1024 After applying above patch, /proc/ccs/audit will include (1) Logs of access requests which were found in the domain policy. (Currently sent to /proc/ccs/grant_log .) (2) Logs of access requests which were not found in the domain policy. (Currently sent to /proc/ccs/reject_log .) (3) Logs of domain creation requests which were not found in the domain policy. (Currently sent to /proc/ccs/reject_log .) (1) and (2) are generated by learning/permissive/enforcing modes because disabled mode does not check permissions. (3) is genareted by disabled/learning/permissive/enforcing modes because domain transition has to be performed regardless of modes and a new domain has to be added to domain policy if domain to transit to was not found in the domain policy. > I still believe that the default profiles should be changed. If I run > ccs-auditd and set all domains to Disabled Mode, then I don't expect > anything at all to be written to files in /var/log, regardless of what > name or role the log files are, and regardless of what /proc interface > the log files are drawn from. If the mode is named "Disabled Mode" > then my expectation is that the logging of any domain with this mode > should be completely disabled. I speak purely about logging to > /var/log. What goes on in /proc is a different matter, which I shall > discuss separately at the end of this email. > > In my mind, here is how a user would make use of logs in /var/log/tomoyo: > 1) See access requests that violate domain policy (reject.log) > 2) Take appropriate action (e.g. allow in domain policy, or manage in > realtime with ccs-queryd) > > This is essentially the primary use case of logs in /var/log/tomoyo. > Thus, the logfile containing access requests that violate domain > policy should contain only this information and nothing else, and only > for domains that matter. The domains set to Disabled Mode or Learning > Mode do not matter in this use case. There is also no reason for > domain creation information to reside in the same log file. > > I still think the simplest solution would be to change the default > profiles to something like this: > > 0-COMMENT=-----Disabled Mode----- > 0-PREFERENCE={ max_grant_log=0 max_reject_log=0 max_learning_entry=0 > enforcing_penalty=0 } > 0-CONFIG={ mode=disabled grant_log=no reject_log=no } > 1-COMMENT=-----Learning Mode----- > 1-PREFERENCE={ max_grant_log=0 max_reject_log=0 > max_learning_entry=2048 enforcing_penalty=0 } > 1-CONFIG={ mode=learning grant_log=no reject_log=no } > 2-COMMENT=-----Permissive Mode----- > 2-PREFERENCE={ max_grant_log=0 max_reject_log=1024 > max_learning_entry=2048 enforcing_penalty=0 } > 2-CONFIG={ mode=permissive grant_log=no reject_log=yes } > 3-COMMENT=-----Enforcing Mode----- > 3-PREFERENCE={ max_grant_log=0 max_reject_log=1024 > max_learning_entry=2048 enforcing_penalty=0 } > 3-CONFIG={ mode=enforcing grant_log=no reject_log=yes } > > This would ensure that if a user runs init_policy and starts the > ccs-auditd daemon, then the logs in /var/log/tomoyo won't get filled > with information even though all domains are set to Disabled Mode. > This patch will change userland part, with changes in default profiles. Index: trunk/1.8.x/ccs-tools/ccstools/kernel_test/arglog.c =================================================================== --- trunk/1.8.x/ccs-tools/ccstools/kernel_test/arglog.c (revision 4165) +++ trunk/1.8.x/ccs-tools/ccstools/kernel_test/arglog.c (working copy) @@ -27,8 +27,7 @@ int main(int argc0, char *argv0[]) { - int fd1 = open("/proc/ccs/grant_log", O_RDONLY); - int fd2 = open("/proc/ccs/reject_log", O_RDONLY); + int fd = open("/proc/ccs/audit", O_RDONLY); char *argv[12]; char *envp[12]; int j; @@ -56,14 +55,11 @@ execve("/bin/true", argv, envp); _exit(0); } - while ((len = read(fd1, buffer, sizeof(buffer))) > 0) + while ((len = read(fd, buffer, sizeof(buffer))) > 0) write(1, buffer, len); - while ((len = read(fd2, buffer, sizeof(buffer))) > 0) - write(1, buffer, len); wait(NULL); } } - close(fd1); - close(fd2); + close(fd); return 0; } Index: trunk/1.8.x/ccs-tools/ccstools/kernel_test/include.h =================================================================== --- trunk/1.8.x/ccs-tools/ccstools/kernel_test/include.h (revision 4165) +++ trunk/1.8.x/ccs-tools/ccstools/kernel_test/include.h (working copy) @@ -109,8 +109,7 @@ #define proc_policy_profile "/proc/ccs/profile" #define proc_policy_manager "/proc/ccs/manager" #define proc_policy_query "/proc/ccs/query" -#define proc_policy_grant_log "/proc/ccs/grant_log" -#define proc_policy_reject_log "/proc/ccs/reject_log" +#define proc_policy_audit "/proc/ccs/audit" #define proc_policy_domain_status "/proc/ccs/.domain_status" #define proc_policy_process_status "/proc/ccs/.process_status" #define proc_policy_self_domain "/proc/ccs/self_domain" Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccstools.h =================================================================== --- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccstools.h (revision 4165) +++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccstools.h (working copy) @@ -58,13 +58,12 @@ #define CCS_PROC_POLICY_DOMAIN_POLICY "/proc/ccs/domain_policy" #define CCS_PROC_POLICY_DOMAIN_STATUS "/proc/ccs/.domain_status" #define CCS_PROC_POLICY_EXCEPTION_POLICY "/proc/ccs/exception_policy" -#define CCS_PROC_POLICY_GRANT_LOG "/proc/ccs/grant_log" +#define CCS_PROC_POLICY_AUDIT "/proc/ccs/audit" #define CCS_PROC_POLICY_MANAGER "/proc/ccs/manager" #define CCS_PROC_POLICY_MEMINFO "/proc/ccs/meminfo" #define CCS_PROC_POLICY_PROCESS_STATUS "/proc/ccs/.process_status" #define CCS_PROC_POLICY_PROFILE "/proc/ccs/profile" #define CCS_PROC_POLICY_QUERY "/proc/ccs/query" -#define CCS_PROC_POLICY_REJECT_LOG "/proc/ccs/reject_log" #define CCS_DISK_POLICY_DIR "/etc/ccs/" #define CCS_DISK_POLICY_DOMAIN_POLICY "domain_policy.conf" Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-auditd.c =================================================================== --- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-auditd.c (revision 4165) +++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-auditd.c (working copy) @@ -22,17 +22,14 @@ */ #include "ccstools.h" #include <syslog.h> +#include <poll.h> #define CCS_AUDITD_MAX_FILES 2 int main(int argc, char *argv[]) { - const char *procfile_path[CCS_AUDITD_MAX_FILES] = { - CCS_PROC_POLICY_GRANT_LOG, - CCS_PROC_POLICY_REJECT_LOG - }; int i; - int fd_in[CCS_AUDITD_MAX_FILES]; + int fd_in; FILE *fp_out[CCS_AUDITD_MAX_FILES]; const char *logfile_path[2] = { NULL, NULL }; @@ -55,8 +52,6 @@ ccs_network_mode = true; if (!ccs_check_remote_host()) return 1; - procfile_path[0] = "proc:grant_log"; - procfile_path[1] = "proc:reject_log"; } else goto usage; } @@ -64,7 +59,7 @@ goto usage; if (ccs_network_mode) goto start; - if (access(procfile_path[0], R_OK) || access(procfile_path[1], R_OK)) { + if (access(CCS_PROC_POLICY_AUDIT, R_OK)) { fprintf(stderr, "You can't run this daemon for this kernel.\n"); return 0; } @@ -113,59 +108,60 @@ close(1); close(2); openlog("ccs-auditd", 0, LOG_USER); - for (i = 0; i < CCS_AUDITD_MAX_FILES; i++) { - if (ccs_network_mode) - fd_in[i] = ccs_open_stream(procfile_path[i]); - else - fd_in[i] = open(procfile_path[i], O_RDONLY); - if (fd_in[i] == EOF) { - syslog(LOG_WARNING, "Can't open %s for reading.\n", - procfile_path[i]); - return 1; - } + if (ccs_network_mode) + fd_in = ccs_open_stream("proc:audit"); + else + fd_in = open(CCS_PROC_POLICY_AUDIT, O_RDONLY); + if (fd_in == EOF) { + syslog(LOG_WARNING, "Can't open %s for reading.\n", + CCS_PROC_POLICY_AUDIT); + return 1; } syslog(LOG_WARNING, "Started.\n"); while (true) { char buffer[32768]; - fd_set rfds; - FD_ZERO(&rfds); - for (i = 0; i < CCS_AUDITD_MAX_FILES; i++) - FD_SET(fd_in[i], &rfds); - /* Wait for data. */ - if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) == EOF) - break; - for (i = 0; i < CCS_AUDITD_MAX_FILES; i++) { - if (!FD_ISSET(fd_in[i], &rfds)) - continue; - memset(buffer, 0, sizeof(buffer)); - if (ccs_network_mode) { - int j; - for (j = 0; j < sizeof(buffer) - 1; j++) { - if (read(fd_in[i], buffer + j, 1) != 1) - goto out; - if (!buffer[j]) - break; - } - if (j == sizeof(buffer) - 1) + memset(buffer, 0, sizeof(buffer)); + if (ccs_network_mode) { + int j; + for (j = 0; j < sizeof(buffer) - 1; j++) { + if (read(fd_in, buffer + j, 1) != 1) goto out; - } else - if (read(fd_in[i], buffer, sizeof(buffer) - 1) - < 0) - continue; - /* Open destination file. */ - if (access(logfile_path[i], F_OK)) { - fclose(fp_out[i]); - fp_out[i] = fopen(logfile_path[i], "a"); - if (!fp_out[i]) { - syslog(LOG_WARNING, - "Can't open %s for writing.\n", - logfile_path[i]); + if (!buffer[j]) + break; + } + if (j == sizeof(buffer) - 1) + goto out; + } else { + while (read(fd_in, buffer, sizeof(buffer) - 1) <= 0) { + /* Wait for data. */ + struct pollfd pfd = { + .fd = fd_in, .events = POLLIN + }; + if (poll(&pfd, 1, -1) == EOF) goto out; - } } - fprintf(fp_out[i], "%s\n", buffer); - fflush(fp_out[i]); } + { + char *cp = strchr(buffer, '\n'); + if (cp) + *cp = '\0'; + i = strstr(buffer, "granted=yes") == NULL; + if (cp) + *cp = '\n'; + } + /* Open destination file. */ + if (access(logfile_path[i], F_OK)) { + fclose(fp_out[i]); + fp_out[i] = fopen(logfile_path[i], "a"); + if (!fp_out[i]) { + syslog(LOG_WARNING, + "Can't open %s for writing.\n", + logfile_path[i]); + goto out; + } + } + fprintf(fp_out[i], "%s\n", buffer); + fflush(fp_out[i]); } out: syslog(LOG_WARNING, "Terminated.\n"); Index: trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/convert-exec-param.c =================================================================== --- trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/convert-exec-param.c (revision 4165) +++ trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/convert-exec-param.c (working copy) @@ -29,8 +29,7 @@ int line = 0; memset(buffer, 0, sizeof(buffer)); if (argc > 1) { - fprintf(stderr, "Usage: %s < /proc/ccs/grant_log or " - "/proc/ccs/reject_log\n", argv[0]); + fprintf(stderr, "Usage: %s < /proc/ccs/audit\n", argv[0]); return 0; } while (1) { Index: trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/ccs-editpolicy-agent.c =================================================================== --- trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/ccs-editpolicy-agent.c (revision 4165) +++ trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/ccs-editpolicy-agent.c (working copy) @@ -142,10 +142,10 @@ fflush(fp); } -static void handle_stream(const int client, const char *filename) +static void handle_audit(const int client) { int ret_ignored; - const int fd = open(filename, O_RDONLY); + const int fd = open("audit", O_RDONLY); if (fd == EOF) return; /* Return \0 to indicate success. */ @@ -281,9 +281,8 @@ goto out; if (!strcmp(buffer, "proc:query")) handle_query(client); - else if (!strcmp(buffer, "proc:grant_log") || - !strcmp(buffer, "proc:reject_log")) - handle_stream(client, buffer + 5); + else if (!strcmp(buffer, "proc:audit")) + handle_audit(client); else if (!strncmp(buffer, "proc:", 5)) { /* Open /proc/\$/ for reading. */ FILE *fp = fdopen(client, "w"); Index: trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/init_policy.c =================================================================== --- trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/init_policy.c (revision 4165) +++ trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/init_policy.c (working copy) @@ -610,10 +610,7 @@ fprintf(stderr, "failed.\n"); } -static const char *grant_log = "no"; -static const char *reject_log = "yes"; -static unsigned int max_grant_log = 1024; -static unsigned int max_reject_log = 1024; +static unsigned int max_audit_log = 1024; static unsigned int max_learning_entry = 2048; static unsigned int enforcing_penalty = 0; @@ -633,29 +630,24 @@ file_only = "::file"; fprintf(fp, "PROFILE_VERSION=20100903\n"); fprintf(fp, "0-COMMENT=-----Disabled Mode-----\n" - "0-PREFERENCE={ max_grant_log=%u max_reject_log=%u " - "max_learning_entry=%u enforcing_penalty=%u }\n" - "0-CONFIG%s={ mode=disabled grant_log=%s reject_log=%s }\n", - max_grant_log, max_reject_log, max_learning_entry, - enforcing_penalty, file_only, grant_log, reject_log); + "0-PREFERENCE={ max_audit_log=0 max_learning_entry=0 " + "enforcing_penalty=0 }\n" + "0-CONFIG={ mode=disabled grant_log=no reject_log=no }\n"); fprintf(fp, "1-COMMENT=-----Learning Mode-----\n" - "1-PREFERENCE={ max_grant_log=%u max_reject_log=%u " - "max_learning_entry=%u enforcing_penalty=%u }\n" - "1-CONFIG%s={ mode=learning grant_log=%s reject_log=%s }\n", - max_grant_log, max_reject_log, max_learning_entry, - enforcing_penalty, file_only, grant_log, reject_log); + "1-PREFERENCE={ max_audit_log=0 max_learning_entry=%u " + "enforcing_penalty=0 }\n" + "1-CONFIG%s={ mode=learning grant_log=no reject_log=no }\n", + max_learning_entry, file_only); fprintf(fp, "2-COMMENT=-----Permissive Mode-----\n" - "2-PREFERENCE={ max_grant_log=%u max_reject_log=%u " - "max_learning_entry=%u enforcing_penalty=%u }\n" - "2-CONFIG%s={ mode=permissive grant_log=%s reject_log=%s }\n", - max_grant_log, max_reject_log, max_learning_entry, - enforcing_penalty, file_only, grant_log, reject_log); + "2-PREFERENCE={ max_audit_log=%u max_learning_entry=0 " + "enforcing_penalty=0 }\n" + "2-CONFIG%s={ mode=permissive grant_log=no reject_log=yes }\n", + max_audit_log, file_only); fprintf(fp, "3-COMMENT=-----Enforcing Mode-----\n" - "3-PREFERENCE={ max_grant_log=%u max_reject_log=%u " - "max_learning_entry=%u enforcing_penalty=%u }\n" - "3-CONFIG%s={ mode=enforcing grant_log=%s reject_log=%s }\n", - max_grant_log, max_reject_log, max_learning_entry, - enforcing_penalty, file_only, grant_log, reject_log); + "3-PREFERENCE={ max_audit_log=%u max_learning_entry=0 " + "enforcing_penalty=%u }\n" + "3-CONFIG%s={ mode=enforcing grant_log=no reject_log=yes }\n", + max_audit_log, enforcing_penalty, file_only); fclose(fp); if (!chdir(policy_dir) && !rename("profile.tmp", "profile.conf")) fprintf(stderr, "OK\n"); @@ -762,14 +754,7 @@ default_profile = atoi(arg + 12); } else if (!strncmp(arg, "use_group=", 10)) { default_group = atoi(arg + 10); - } else if (!strncmp(arg, "grant_log=", 10)) { - grant_log = arg + 10; - } else if (!strncmp(arg, "reject_log=", 11)) { - reject_log = arg + 11; - } else if (!sscanf(arg, "max_grant_log=%u", - &max_grant_log) && - !sscanf(arg, "max_reject_log=%u", - &max_reject_log) && + } else if (!sscanf(arg, "max_audit_log=%u", &max_audit_log) && !sscanf(arg, "max_learning_entry=%u", &max_learning_entry) && !sscanf(arg, "enforcing_penalty=%u", > I think Learning Mode should receive the same treatment. This is the > workflow that makes sense to me: > > 1) Identify a domain > 2) Switch domain to Learning Mode to identify access requirements > 3) Adjust policy > 4) Switch domain to Permissive Mode to identify access rejections that > you want to allow > 5) Adjust policy > 6) Switch domain to Enforcing Mode > 7) Watch for further policy violations > 8) Repeat 1) to 7) for another domain > > Using such a workflow, Disabled Mode and Learning Mode both do not > have a requirement for logs in /var/log/tomoyo. Only at step 4 when > switching to Permissive Mode should log files in /var/log/tomoyo be > written to. This information can then be used to refine policy > further. As demonstrated at "Step 3: Reviewing gathered permissions" in http://tomoyo.sourceforge.jp/1.8/learning.html.en , /var/log/tomoyo/reject_log.conf is designed to serve as data source when generating /proc/ccs/domain_policy . If we drop domain creation information from /var/log/tomoyo/reject_log.conf , we cannot construct <kernel> /usr/sbin/httpd /bin/sh /usr/bin/id use_profile 1 use_group 0 part from /var/log/tomoyo/reject_log.conf . When users want to add to domain policy at step 2, these lines are no longer retrievable. Your workflow assumes that all domains are defined before reaching step 1. But actually, we have to create domains as needed. If domain creation logs are not preserved for disabled/learning modes, we cannot create domains from audit logs. > The above workflow represents both what a new user will do > after init_policy, as well as a user refining their system with some > domains already set to Enforcing Mode and others still in Disabled > Mode. In the latter case, the existing information in > /var/log/tomoyo/reject.log would be obfuscated by the irrelevant > information from domains in Disabled/Learning Mode. My preference is to keep these lines in order to keep ability to create domain policy from /var/log/tomoyo/reject_log.conf . Your preference is to drop these lines in order to save disk storage and to avoid obfuscation by the irrelevant information. > I don't think I really mind what you do with the > interfaces in /proc/ccs, as long as the log files in /var/log/tomoyo > are not being written to by domains in Disabled/Learning Mode. I can > change this easily myself of course by editing the profiles, but I > think the default behaviour should be changed. If we give up ability to create domain policy from /var/log/tomoyo/reject_log.conf , it would be OK to change default behaviour. Now, this discussion is public. So, let's hear from subscriber's preferences. Feel free to join this discussion. Regards.