summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/security/tomoyo
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/security/tomoyo')
-rw-r--r--ANDROID_3.4.5/security/tomoyo/Kconfig74
-rw-r--r--ANDROID_3.4.5/security/tomoyo/Makefile48
-rw-r--r--ANDROID_3.4.5/security/tomoyo/audit.c461
-rw-r--r--ANDROID_3.4.5/security/tomoyo/common.c2806
-rw-r--r--ANDROID_3.4.5/security/tomoyo/common.h1331
-rw-r--r--ANDROID_3.4.5/security/tomoyo/condition.c1094
-rw-r--r--ANDROID_3.4.5/security/tomoyo/domain.c901
-rw-r--r--ANDROID_3.4.5/security/tomoyo/environ.c122
-rw-r--r--ANDROID_3.4.5/security/tomoyo/file.c1026
-rw-r--r--ANDROID_3.4.5/security/tomoyo/gc.c655
-rw-r--r--ANDROID_3.4.5/security/tomoyo/group.c198
-rw-r--r--ANDROID_3.4.5/security/tomoyo/load_policy.c109
-rw-r--r--ANDROID_3.4.5/security/tomoyo/memory.c201
-rw-r--r--ANDROID_3.4.5/security/tomoyo/mount.c235
-rw-r--r--ANDROID_3.4.5/security/tomoyo/network.c771
-rw-r--r--ANDROID_3.4.5/security/tomoyo/realpath.c328
-rw-r--r--ANDROID_3.4.5/security/tomoyo/securityfs_if.c273
-rw-r--r--ANDROID_3.4.5/security/tomoyo/tomoyo.c560
-rw-r--r--ANDROID_3.4.5/security/tomoyo/util.c1090
19 files changed, 0 insertions, 12283 deletions
diff --git a/ANDROID_3.4.5/security/tomoyo/Kconfig b/ANDROID_3.4.5/security/tomoyo/Kconfig
deleted file mode 100644
index 8eb779b9..00000000
--- a/ANDROID_3.4.5/security/tomoyo/Kconfig
+++ /dev/null
@@ -1,74 +0,0 @@
-config SECURITY_TOMOYO
- bool "TOMOYO Linux Support"
- depends on SECURITY
- depends on NET
- select SECURITYFS
- select SECURITY_PATH
- select SECURITY_NETWORK
- default n
- help
- This selects TOMOYO Linux, pathname-based access control.
- Required userspace tools and further information may be
- found at <http://tomoyo.sourceforge.jp/>.
- If you are unsure how to answer this question, answer N.
-
-config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY
- int "Default maximal count for learning mode"
- default 2048
- range 0 2147483647
- depends on SECURITY_TOMOYO
- help
- This is the default value for maximal ACL entries
- that are automatically appended into policy at "learning mode".
- Some programs access thousands of objects, so running
- such programs in "learning mode" dulls the system response
- and consumes much memory.
- This is the safeguard for such programs.
-
-config SECURITY_TOMOYO_MAX_AUDIT_LOG
- int "Default maximal count for audit log"
- default 1024
- range 0 2147483647
- depends on SECURITY_TOMOYO
- help
- This is the default value for maximal entries for
- audit logs that the kernel can hold on memory.
- You can read the log via /sys/kernel/security/tomoyo/audit.
- If you don't need audit logs, you may set this value to 0.
-
-config SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
- bool "Activate without calling userspace policy loader."
- default n
- depends on SECURITY_TOMOYO
- ---help---
- Say Y here if you want to activate access control as soon as built-in
- policy was loaded. This option will be useful for systems where
- operations which can lead to the hijacking of the boot sequence are
- needed before loading the policy. For example, you can activate
- immediately after loading the fixed part of policy which will allow
- only operations needed for mounting a partition which contains the
- variant part of policy and verifying (e.g. running GPG check) and
- loading the variant part of policy. Since you can start using
- enforcing mode from the beginning, you can reduce the possibility of
- hijacking the boot sequence.
-
-config SECURITY_TOMOYO_POLICY_LOADER
- string "Location of userspace policy loader"
- default "/sbin/tomoyo-init"
- depends on SECURITY_TOMOYO
- depends on !SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
- ---help---
- This is the default pathname of policy loader which is called before
- activation. You can override this setting via TOMOYO_loader= kernel
- command line option.
-
-config SECURITY_TOMOYO_ACTIVATION_TRIGGER
- string "Trigger for calling userspace policy loader"
- default "/sbin/init"
- depends on SECURITY_TOMOYO
- depends on !SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
- ---help---
- This is the default pathname of activation trigger.
- You can override this setting via TOMOYO_trigger= kernel command line
- option. For example, if you pass init=/bin/systemd option, you may
- want to also pass TOMOYO_trigger=/bin/systemd option.
diff --git a/ANDROID_3.4.5/security/tomoyo/Makefile b/ANDROID_3.4.5/security/tomoyo/Makefile
deleted file mode 100644
index 56a0c7be..00000000
--- a/ANDROID_3.4.5/security/tomoyo/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o
-
-$(obj)/policy/profile.conf:
- @mkdir -p $(obj)/policy/
- @echo Creating an empty policy/profile.conf
- @touch $@
-
-$(obj)/policy/exception_policy.conf:
- @mkdir -p $(obj)/policy/
- @echo Creating a default policy/exception_policy.conf
- @echo initialize_domain /sbin/modprobe from any >> $@
- @echo initialize_domain /sbin/hotplug from any >> $@
-
-$(obj)/policy/domain_policy.conf:
- @mkdir -p $(obj)/policy/
- @echo Creating an empty policy/domain_policy.conf
- @touch $@
-
-$(obj)/policy/manager.conf:
- @mkdir -p $(obj)/policy/
- @echo Creating an empty policy/manager.conf
- @touch $@
-
-$(obj)/policy/stat.conf:
- @mkdir -p $(obj)/policy/
- @echo Creating an empty policy/stat.conf
- @touch $@
-
-$(obj)/builtin-policy.h: $(obj)/policy/profile.conf $(obj)/policy/exception_policy.conf $(obj)/policy/domain_policy.conf $(obj)/policy/manager.conf $(obj)/policy/stat.conf
- @echo Generating built-in policy for TOMOYO 2.5.x.
- @echo "static char tomoyo_builtin_profile[] __initdata =" > $@.tmp
- @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/profile.conf >> $@.tmp
- @echo "\"\";" >> $@.tmp
- @echo "static char tomoyo_builtin_exception_policy[] __initdata =" >> $@.tmp
- @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/exception_policy.conf >> $@.tmp
- @echo "\"\";" >> $@.tmp
- @echo "static char tomoyo_builtin_domain_policy[] __initdata =" >> $@.tmp
- @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/domain_policy.conf >> $@.tmp
- @echo "\"\";" >> $@.tmp
- @echo "static char tomoyo_builtin_manager[] __initdata =" >> $@.tmp
- @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/manager.conf >> $@.tmp
- @echo "\"\";" >> $@.tmp
- @echo "static char tomoyo_builtin_stat[] __initdata =" >> $@.tmp
- @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/stat.conf >> $@.tmp
- @echo "\"\";" >> $@.tmp
- @mv $@.tmp $@
-
-$(obj)/common.o: $(obj)/builtin-policy.h
diff --git a/ANDROID_3.4.5/security/tomoyo/audit.c b/ANDROID_3.4.5/security/tomoyo/audit.c
deleted file mode 100644
index 7ef9fa3e..00000000
--- a/ANDROID_3.4.5/security/tomoyo/audit.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * security/tomoyo/audit.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-#include <linux/slab.h>
-
-/**
- * tomoyo_print_bprm - Print "struct linux_binprm" for auditing.
- *
- * @bprm: Pointer to "struct linux_binprm".
- * @dump: Pointer to "struct tomoyo_page_dump".
- *
- * Returns the contents of @bprm on success, NULL otherwise.
- *
- * This function uses kzalloc(), so caller must kfree() if this function
- * didn't return NULL.
- */
-static char *tomoyo_print_bprm(struct linux_binprm *bprm,
- struct tomoyo_page_dump *dump)
-{
- static const int tomoyo_buffer_len = 4096 * 2;
- char *buffer = kzalloc(tomoyo_buffer_len, GFP_NOFS);
- char *cp;
- char *last_start;
- int len;
- unsigned long pos = bprm->p;
- int offset = pos % PAGE_SIZE;
- int argv_count = bprm->argc;
- int envp_count = bprm->envc;
- bool truncated = false;
- if (!buffer)
- return NULL;
- len = snprintf(buffer, tomoyo_buffer_len - 1, "argv[]={ ");
- cp = buffer + len;
- if (!argv_count) {
- memmove(cp, "} envp[]={ ", 11);
- cp += 11;
- }
- last_start = cp;
- while (argv_count || envp_count) {
- if (!tomoyo_dump_page(bprm, pos, dump))
- goto out;
- pos += PAGE_SIZE - offset;
- /* Read. */
- while (offset < PAGE_SIZE) {
- const char *kaddr = dump->data;
- const unsigned char c = kaddr[offset++];
- if (cp == last_start)
- *cp++ = '"';
- if (cp >= buffer + tomoyo_buffer_len - 32) {
- /* Reserve some room for "..." string. */
- truncated = true;
- } else if (c == '\\') {
- *cp++ = '\\';
- *cp++ = '\\';
- } else if (c > ' ' && c < 127) {
- *cp++ = c;
- } else if (!c) {
- *cp++ = '"';
- *cp++ = ' ';
- last_start = cp;
- } else {
- *cp++ = '\\';
- *cp++ = (c >> 6) + '0';
- *cp++ = ((c >> 3) & 7) + '0';
- *cp++ = (c & 7) + '0';
- }
- if (c)
- continue;
- if (argv_count) {
- if (--argv_count == 0) {
- if (truncated) {
- cp = last_start;
- memmove(cp, "... ", 4);
- cp += 4;
- }
- memmove(cp, "} envp[]={ ", 11);
- cp += 11;
- last_start = cp;
- truncated = false;
- }
- } else if (envp_count) {
- if (--envp_count == 0) {
- if (truncated) {
- cp = last_start;
- memmove(cp, "... ", 4);
- cp += 4;
- }
- }
- }
- if (!argv_count && !envp_count)
- break;
- }
- offset = 0;
- }
- *cp++ = '}';
- *cp = '\0';
- return buffer;
-out:
- snprintf(buffer, tomoyo_buffer_len - 1,
- "argv[]={ ... } envp[]= { ... }");
- return buffer;
-}
-
-/**
- * tomoyo_filetype - Get string representation of file type.
- *
- * @mode: Mode value for stat().
- *
- * Returns file type string.
- */
-static inline const char *tomoyo_filetype(const umode_t mode)
-{
- switch (mode & S_IFMT) {
- case S_IFREG:
- case 0:
- return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE];
- case S_IFDIR:
- return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY];
- case S_IFLNK:
- return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK];
- case S_IFIFO:
- return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO];
- case S_IFSOCK:
- return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET];
- case S_IFBLK:
- return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV];
- case S_IFCHR:
- return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV];
- }
- return "unknown"; /* This should not happen. */
-}
-
-/**
- * tomoyo_print_header - Get header line of audit log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns string representation.
- *
- * This function uses kmalloc(), so caller must kfree() if this function
- * didn't return NULL.
- */
-static char *tomoyo_print_header(struct tomoyo_request_info *r)
-{
- struct tomoyo_time stamp;
- const pid_t gpid = task_pid_nr(current);
- struct tomoyo_obj_info *obj = r->obj;
- static const int tomoyo_buffer_len = 4096;
- char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
- int pos;
- u8 i;
- if (!buffer)
- return NULL;
- {
- struct timeval tv;
- do_gettimeofday(&tv);
- tomoyo_convert_time(tv.tv_sec, &stamp);
- }
- pos = snprintf(buffer, tomoyo_buffer_len - 1,
- "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
- "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 }", stamp.year, stamp.month,
- stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile,
- tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid,
- tomoyo_sys_getpid(), tomoyo_sys_getppid(),
- current_uid(), current_gid(), current_euid(),
- current_egid(), current_suid(), current_sgid(),
- current_fsuid(), current_fsgid());
- if (!obj)
- goto no_obj_info;
- if (!obj->validate_done) {
- tomoyo_get_attributes(obj);
- obj->validate_done = true;
- }
- for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
- struct tomoyo_mini_stat *stat;
- unsigned int dev;
- umode_t mode;
- if (!obj->stat_valid[i])
- continue;
- stat = &obj->stat[i];
- dev = stat->dev;
- mode = stat->mode;
- if (i & 1) {
- pos += snprintf(buffer + pos,
- tomoyo_buffer_len - 1 - pos,
- " path%u.parent={ uid=%u gid=%u "
- "ino=%lu perm=0%o }", (i >> 1) + 1,
- stat->uid, stat->gid, (unsigned long)
- stat->ino, stat->mode & S_IALLUGO);
- continue;
- }
- pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
- " path%u={ uid=%u gid=%u ino=%lu major=%u"
- " minor=%u perm=0%o type=%s", (i >> 1) + 1,
- stat->uid, stat->gid, (unsigned long)
- stat->ino, MAJOR(dev), MINOR(dev),
- mode & S_IALLUGO, tomoyo_filetype(mode));
- if (S_ISCHR(mode) || S_ISBLK(mode)) {
- dev = stat->rdev;
- pos += snprintf(buffer + pos,
- tomoyo_buffer_len - 1 - pos,
- " dev_major=%u dev_minor=%u",
- MAJOR(dev), MINOR(dev));
- }
- pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
- " }");
- }
-no_obj_info:
- if (pos < tomoyo_buffer_len - 1)
- return buffer;
- kfree(buffer);
- return NULL;
-}
-
-/**
- * tomoyo_init_log - Allocate buffer for audit logs.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @len: Buffer size needed for @fmt and @args.
- * @fmt: The printf()'s format string.
- * @args: va_list structure for @fmt.
- *
- * Returns pointer to allocated memory.
- *
- * This function uses kzalloc(), so caller must kfree() if this function
- * didn't return NULL.
- */
-char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
- va_list args)
-{
- char *buf = NULL;
- char *bprm_info = NULL;
- const char *header = NULL;
- char *realpath = NULL;
- const char *symlink = NULL;
- int pos;
- const char *domainname = r->domain->domainname->name;
- header = tomoyo_print_header(r);
- if (!header)
- return NULL;
- /* +10 is for '\n' etc. and '\0'. */
- len += strlen(domainname) + strlen(header) + 10;
- if (r->ee) {
- struct file *file = r->ee->bprm->file;
- realpath = tomoyo_realpath_from_path(&file->f_path);
- bprm_info = tomoyo_print_bprm(r->ee->bprm, &r->ee->dump);
- if (!realpath || !bprm_info)
- goto out;
- /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
- len += strlen(realpath) + 80 + strlen(bprm_info);
- } else if (r->obj && r->obj->symlink_target) {
- symlink = r->obj->symlink_target->name;
- /* +18 is for " symlink.target=\"%s\"" */
- len += 18 + strlen(symlink);
- }
- len = tomoyo_round2(len);
- buf = kzalloc(len, GFP_NOFS);
- if (!buf)
- goto out;
- len--;
- pos = snprintf(buf, len, "%s", header);
- if (realpath) {
- struct linux_binprm *bprm = r->ee->bprm;
- pos += snprintf(buf + pos, len - pos,
- " exec={ realpath=\"%s\" argc=%d envc=%d %s }",
- realpath, bprm->argc, bprm->envc, bprm_info);
- } else if (symlink)
- pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
- symlink);
- pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
- vsnprintf(buf + pos, len - pos, fmt, args);
-out:
- kfree(realpath);
- kfree(bprm_info);
- kfree(header);
- return buf;
-}
-
-/* Wait queue for /sys/kernel/security/tomoyo/audit. */
-static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait);
-
-/* Structure for audit log. */
-struct tomoyo_log {
- struct list_head list;
- char *log;
- int size;
-};
-
-/* The list for "struct tomoyo_log". */
-static LIST_HEAD(tomoyo_log);
-
-/* Lock for "struct list_head tomoyo_log". */
-static DEFINE_SPINLOCK(tomoyo_log_lock);
-
-/* Length of "stuct list_head tomoyo_log". */
-static unsigned int tomoyo_log_count;
-
-/**
- * tomoyo_get_audit - Get audit mode.
- *
- * @ns: Pointer to "struct tomoyo_policy_namespace".
- * @profile: Profile number.
- * @index: Index number of functionality.
- * @is_granted: True if granted log, false otherwise.
- *
- * Returns true if this request should be audited, false otherwise.
- */
-static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
- const u8 profile, const u8 index,
- const struct tomoyo_acl_info *matched_acl,
- const bool is_granted)
-{
- u8 mode;
- const u8 category = tomoyo_index2category[index] +
- TOMOYO_MAX_MAC_INDEX;
- struct tomoyo_profile *p;
- if (!tomoyo_policy_loaded)
- return false;
- p = tomoyo_profile(ns, profile);
- if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
- return false;
- if (is_granted && matched_acl && matched_acl->cond &&
- matched_acl->cond->grant_log != TOMOYO_GRANTLOG_AUTO)
- return matched_acl->cond->grant_log == TOMOYO_GRANTLOG_YES;
- mode = p->config[index];
- if (mode == TOMOYO_CONFIG_USE_DEFAULT)
- mode = p->config[category];
- if (mode == TOMOYO_CONFIG_USE_DEFAULT)
- mode = p->default_config;
- if (is_granted)
- return mode & TOMOYO_CONFIG_WANT_GRANT_LOG;
- return mode & TOMOYO_CONFIG_WANT_REJECT_LOG;
-}
-
-/**
- * tomoyo_write_log2 - Write an audit log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @len: Buffer size needed for @fmt and @args.
- * @fmt: The printf()'s format string.
- * @args: va_list structure for @fmt.
- *
- * Returns nothing.
- */
-void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
- va_list args)
-{
- char *buf;
- struct tomoyo_log *entry;
- bool quota_exceeded = false;
- if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type,
- r->matched_acl, r->granted))
- goto out;
- buf = tomoyo_init_log(r, len, fmt, args);
- if (!buf)
- goto out;
- entry = kzalloc(sizeof(*entry), GFP_NOFS);
- if (!entry) {
- kfree(buf);
- goto out;
- }
- entry->log = buf;
- len = tomoyo_round2(strlen(buf) + 1);
- /*
- * The entry->size is used for memory quota checks.
- * Don't go beyond strlen(entry->log).
- */
- entry->size = len + tomoyo_round2(sizeof(*entry));
- spin_lock(&tomoyo_log_lock);
- if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] &&
- tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >=
- tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) {
- quota_exceeded = true;
- } else {
- tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size;
- list_add_tail(&entry->list, &tomoyo_log);
- tomoyo_log_count++;
- }
- spin_unlock(&tomoyo_log_lock);
- if (quota_exceeded) {
- kfree(buf);
- kfree(entry);
- goto out;
- }
- wake_up(&tomoyo_log_wait);
-out:
- return;
-}
-
-/**
- * tomoyo_write_log - Write an audit log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @fmt: The printf()'s format string, followed by parameters.
- *
- * Returns nothing.
- */
-void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
-{
- va_list args;
- int len;
- va_start(args, fmt);
- len = vsnprintf((char *) &len, 1, fmt, args) + 1;
- va_end(args);
- va_start(args, fmt);
- tomoyo_write_log2(r, len, fmt, args);
- va_end(args);
-}
-
-/**
- * tomoyo_read_log - Read an audit log.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-void tomoyo_read_log(struct tomoyo_io_buffer *head)
-{
- struct tomoyo_log *ptr = NULL;
- if (head->r.w_pos)
- return;
- kfree(head->read_buf);
- head->read_buf = NULL;
- spin_lock(&tomoyo_log_lock);
- if (!list_empty(&tomoyo_log)) {
- ptr = list_entry(tomoyo_log.next, typeof(*ptr), list);
- list_del(&ptr->list);
- tomoyo_log_count--;
- tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size;
- }
- spin_unlock(&tomoyo_log_lock);
- if (ptr) {
- head->read_buf = ptr->log;
- head->r.w[head->r.w_pos++] = head->read_buf;
- kfree(ptr);
- }
-}
-
-/**
- * tomoyo_poll_log - Wait for an audit log.
- *
- * @file: Pointer to "struct file".
- * @wait: Pointer to "poll_table". Maybe NULL.
- *
- * Returns POLLIN | POLLRDNORM when ready to read an audit log.
- */
-unsigned int tomoyo_poll_log(struct file *file, poll_table *wait)
-{
- if (tomoyo_log_count)
- return POLLIN | POLLRDNORM;
- poll_wait(file, &tomoyo_log_wait, wait);
- if (tomoyo_log_count)
- return POLLIN | POLLRDNORM;
- return 0;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/common.c b/ANDROID_3.4.5/security/tomoyo/common.c
deleted file mode 100644
index 8656b16e..00000000
--- a/ANDROID_3.4.5/security/tomoyo/common.c
+++ /dev/null
@@ -1,2806 +0,0 @@
-/*
- * security/tomoyo/common.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/security.h>
-#include "common.h"
-
-/* String table for operation mode. */
-const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
- [TOMOYO_CONFIG_DISABLED] = "disabled",
- [TOMOYO_CONFIG_LEARNING] = "learning",
- [TOMOYO_CONFIG_PERMISSIVE] = "permissive",
- [TOMOYO_CONFIG_ENFORCING] = "enforcing"
-};
-
-/* String table for /sys/kernel/security/tomoyo/profile */
-const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
- + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
- /* CONFIG::file group */
- [TOMOYO_MAC_FILE_EXECUTE] = "execute",
- [TOMOYO_MAC_FILE_OPEN] = "open",
- [TOMOYO_MAC_FILE_CREATE] = "create",
- [TOMOYO_MAC_FILE_UNLINK] = "unlink",
- [TOMOYO_MAC_FILE_GETATTR] = "getattr",
- [TOMOYO_MAC_FILE_MKDIR] = "mkdir",
- [TOMOYO_MAC_FILE_RMDIR] = "rmdir",
- [TOMOYO_MAC_FILE_MKFIFO] = "mkfifo",
- [TOMOYO_MAC_FILE_MKSOCK] = "mksock",
- [TOMOYO_MAC_FILE_TRUNCATE] = "truncate",
- [TOMOYO_MAC_FILE_SYMLINK] = "symlink",
- [TOMOYO_MAC_FILE_MKBLOCK] = "mkblock",
- [TOMOYO_MAC_FILE_MKCHAR] = "mkchar",
- [TOMOYO_MAC_FILE_LINK] = "link",
- [TOMOYO_MAC_FILE_RENAME] = "rename",
- [TOMOYO_MAC_FILE_CHMOD] = "chmod",
- [TOMOYO_MAC_FILE_CHOWN] = "chown",
- [TOMOYO_MAC_FILE_CHGRP] = "chgrp",
- [TOMOYO_MAC_FILE_IOCTL] = "ioctl",
- [TOMOYO_MAC_FILE_CHROOT] = "chroot",
- [TOMOYO_MAC_FILE_MOUNT] = "mount",
- [TOMOYO_MAC_FILE_UMOUNT] = "unmount",
- [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root",
- /* CONFIG::network group */
- [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] = "inet_stream_bind",
- [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] = "inet_stream_listen",
- [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] = "inet_stream_connect",
- [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] = "inet_dgram_bind",
- [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] = "inet_dgram_send",
- [TOMOYO_MAC_NETWORK_INET_RAW_BIND] = "inet_raw_bind",
- [TOMOYO_MAC_NETWORK_INET_RAW_SEND] = "inet_raw_send",
- [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] = "unix_stream_bind",
- [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] = "unix_stream_listen",
- [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] = "unix_stream_connect",
- [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] = "unix_dgram_bind",
- [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] = "unix_dgram_send",
- [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind",
- [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen",
- [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
- /* CONFIG::misc group */
- [TOMOYO_MAC_ENVIRON] = "env",
- /* CONFIG group */
- [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
- [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_NETWORK] = "network",
- [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc",
-};
-
-/* String table for conditions. */
-const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
- [TOMOYO_TASK_UID] = "task.uid",
- [TOMOYO_TASK_EUID] = "task.euid",
- [TOMOYO_TASK_SUID] = "task.suid",
- [TOMOYO_TASK_FSUID] = "task.fsuid",
- [TOMOYO_TASK_GID] = "task.gid",
- [TOMOYO_TASK_EGID] = "task.egid",
- [TOMOYO_TASK_SGID] = "task.sgid",
- [TOMOYO_TASK_FSGID] = "task.fsgid",
- [TOMOYO_TASK_PID] = "task.pid",
- [TOMOYO_TASK_PPID] = "task.ppid",
- [TOMOYO_EXEC_ARGC] = "exec.argc",
- [TOMOYO_EXEC_ENVC] = "exec.envc",
- [TOMOYO_TYPE_IS_SOCKET] = "socket",
- [TOMOYO_TYPE_IS_SYMLINK] = "symlink",
- [TOMOYO_TYPE_IS_FILE] = "file",
- [TOMOYO_TYPE_IS_BLOCK_DEV] = "block",
- [TOMOYO_TYPE_IS_DIRECTORY] = "directory",
- [TOMOYO_TYPE_IS_CHAR_DEV] = "char",
- [TOMOYO_TYPE_IS_FIFO] = "fifo",
- [TOMOYO_MODE_SETUID] = "setuid",
- [TOMOYO_MODE_SETGID] = "setgid",
- [TOMOYO_MODE_STICKY] = "sticky",
- [TOMOYO_MODE_OWNER_READ] = "owner_read",
- [TOMOYO_MODE_OWNER_WRITE] = "owner_write",
- [TOMOYO_MODE_OWNER_EXECUTE] = "owner_execute",
- [TOMOYO_MODE_GROUP_READ] = "group_read",
- [TOMOYO_MODE_GROUP_WRITE] = "group_write",
- [TOMOYO_MODE_GROUP_EXECUTE] = "group_execute",
- [TOMOYO_MODE_OTHERS_READ] = "others_read",
- [TOMOYO_MODE_OTHERS_WRITE] = "others_write",
- [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute",
- [TOMOYO_EXEC_REALPATH] = "exec.realpath",
- [TOMOYO_SYMLINK_TARGET] = "symlink.target",
- [TOMOYO_PATH1_UID] = "path1.uid",
- [TOMOYO_PATH1_GID] = "path1.gid",
- [TOMOYO_PATH1_INO] = "path1.ino",
- [TOMOYO_PATH1_MAJOR] = "path1.major",
- [TOMOYO_PATH1_MINOR] = "path1.minor",
- [TOMOYO_PATH1_PERM] = "path1.perm",
- [TOMOYO_PATH1_TYPE] = "path1.type",
- [TOMOYO_PATH1_DEV_MAJOR] = "path1.dev_major",
- [TOMOYO_PATH1_DEV_MINOR] = "path1.dev_minor",
- [TOMOYO_PATH2_UID] = "path2.uid",
- [TOMOYO_PATH2_GID] = "path2.gid",
- [TOMOYO_PATH2_INO] = "path2.ino",
- [TOMOYO_PATH2_MAJOR] = "path2.major",
- [TOMOYO_PATH2_MINOR] = "path2.minor",
- [TOMOYO_PATH2_PERM] = "path2.perm",
- [TOMOYO_PATH2_TYPE] = "path2.type",
- [TOMOYO_PATH2_DEV_MAJOR] = "path2.dev_major",
- [TOMOYO_PATH2_DEV_MINOR] = "path2.dev_minor",
- [TOMOYO_PATH1_PARENT_UID] = "path1.parent.uid",
- [TOMOYO_PATH1_PARENT_GID] = "path1.parent.gid",
- [TOMOYO_PATH1_PARENT_INO] = "path1.parent.ino",
- [TOMOYO_PATH1_PARENT_PERM] = "path1.parent.perm",
- [TOMOYO_PATH2_PARENT_UID] = "path2.parent.uid",
- [TOMOYO_PATH2_PARENT_GID] = "path2.parent.gid",
- [TOMOYO_PATH2_PARENT_INO] = "path2.parent.ino",
- [TOMOYO_PATH2_PARENT_PERM] = "path2.parent.perm",
-};
-
-/* String table for PREFERENCE keyword. */
-static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = {
- [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log",
- [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
-};
-
-/* String table for path operation. */
-const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
- [TOMOYO_TYPE_EXECUTE] = "execute",
- [TOMOYO_TYPE_READ] = "read",
- [TOMOYO_TYPE_WRITE] = "write",
- [TOMOYO_TYPE_APPEND] = "append",
- [TOMOYO_TYPE_UNLINK] = "unlink",
- [TOMOYO_TYPE_GETATTR] = "getattr",
- [TOMOYO_TYPE_RMDIR] = "rmdir",
- [TOMOYO_TYPE_TRUNCATE] = "truncate",
- [TOMOYO_TYPE_SYMLINK] = "symlink",
- [TOMOYO_TYPE_CHROOT] = "chroot",
- [TOMOYO_TYPE_UMOUNT] = "unmount",
-};
-
-/* String table for socket's operation. */
-const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION] = {
- [TOMOYO_NETWORK_BIND] = "bind",
- [TOMOYO_NETWORK_LISTEN] = "listen",
- [TOMOYO_NETWORK_CONNECT] = "connect",
- [TOMOYO_NETWORK_SEND] = "send",
-};
-
-/* String table for categories. */
-static const char * const tomoyo_category_keywords
-[TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
- [TOMOYO_MAC_CATEGORY_FILE] = "file",
- [TOMOYO_MAC_CATEGORY_NETWORK] = "network",
- [TOMOYO_MAC_CATEGORY_MISC] = "misc",
-};
-
-/* Permit policy management by non-root user? */
-static bool tomoyo_manage_by_non_root;
-
-/* Utility functions. */
-
-/**
- * tomoyo_yesno - Return "yes" or "no".
- *
- * @value: Bool value.
- */
-const char *tomoyo_yesno(const unsigned int value)
-{
- return value ? "yes" : "no";
-}
-
-/**
- * tomoyo_addprintf - strncat()-like-snprintf().
- *
- * @buffer: Buffer to write to. Must be '\0'-terminated.
- * @len: Size of @buffer.
- * @fmt: The printf()'s format string, followed by parameters.
- *
- * Returns nothing.
- */
-static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
-{
- va_list args;
- const int pos = strlen(buffer);
- va_start(args, fmt);
- vsnprintf(buffer + pos, len - pos - 1, fmt, args);
- va_end(args);
-}
-
-/**
- * tomoyo_flush - Flush queued string to userspace's buffer.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns true if all data was flushed, false otherwise.
- */
-static bool tomoyo_flush(struct tomoyo_io_buffer *head)
-{
- while (head->r.w_pos) {
- const char *w = head->r.w[0];
- size_t len = strlen(w);
- if (len) {
- if (len > head->read_user_buf_avail)
- len = head->read_user_buf_avail;
- if (!len)
- return false;
- if (copy_to_user(head->read_user_buf, w, len))
- return false;
- head->read_user_buf_avail -= len;
- head->read_user_buf += len;
- w += len;
- }
- head->r.w[0] = w;
- if (*w)
- return false;
- /* Add '\0' for audit logs and query. */
- if (head->poll) {
- if (!head->read_user_buf_avail ||
- copy_to_user(head->read_user_buf, "", 1))
- return false;
- head->read_user_buf_avail--;
- head->read_user_buf++;
- }
- head->r.w_pos--;
- for (len = 0; len < head->r.w_pos; len++)
- head->r.w[len] = head->r.w[len + 1];
- }
- head->r.avail = 0;
- return true;
-}
-
-/**
- * tomoyo_set_string - Queue string to "struct tomoyo_io_buffer" structure.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @string: String to print.
- *
- * Note that @string has to be kept valid until @head is kfree()d.
- * This means that char[] allocated on stack memory cannot be passed to
- * this function. Use tomoyo_io_printf() for char[] allocated on stack memory.
- */
-static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
-{
- if (head->r.w_pos < TOMOYO_MAX_IO_READ_QUEUE) {
- head->r.w[head->r.w_pos++] = string;
- tomoyo_flush(head);
- } else
- WARN_ON(1);
-}
-
-static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
- ...) __printf(2, 3);
-
-/**
- * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @fmt: The printf()'s format string, followed by parameters.
- */
-static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
- ...)
-{
- va_list args;
- size_t len;
- size_t pos = head->r.avail;
- int size = head->readbuf_size - pos;
- if (size <= 0)
- return;
- va_start(args, fmt);
- len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
- va_end(args);
- if (pos + len >= head->readbuf_size) {
- WARN_ON(1);
- return;
- }
- head->r.avail += len;
- tomoyo_set_string(head, head->read_buf + pos);
-}
-
-/**
- * tomoyo_set_space - Put a space to "struct tomoyo_io_buffer" structure.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-static void tomoyo_set_space(struct tomoyo_io_buffer *head)
-{
- tomoyo_set_string(head, " ");
-}
-
-/**
- * tomoyo_set_lf - Put a line feed to "struct tomoyo_io_buffer" structure.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
-{
- tomoyo_set_string(head, "\n");
- return !head->r.w_pos;
-}
-
-/**
- * tomoyo_set_slash - Put a shash to "struct tomoyo_io_buffer" structure.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-static void tomoyo_set_slash(struct tomoyo_io_buffer *head)
-{
- tomoyo_set_string(head, "/");
-}
-
-/* List of namespaces. */
-LIST_HEAD(tomoyo_namespace_list);
-/* True if namespace other than tomoyo_kernel_namespace is defined. */
-static bool tomoyo_namespace_enabled;
-
-/**
- * tomoyo_init_policy_namespace - Initialize namespace.
- *
- * @ns: Pointer to "struct tomoyo_policy_namespace".
- *
- * Returns nothing.
- */
-void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns)
-{
- unsigned int idx;
- for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++)
- INIT_LIST_HEAD(&ns->acl_group[idx]);
- for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
- INIT_LIST_HEAD(&ns->group_list[idx]);
- for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
- INIT_LIST_HEAD(&ns->policy_list[idx]);
- ns->profile_version = 20110903;
- tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list);
- list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list);
-}
-
-/**
- * tomoyo_print_namespace - Print namespace header.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-static void tomoyo_print_namespace(struct tomoyo_io_buffer *head)
-{
- if (!tomoyo_namespace_enabled)
- return;
- tomoyo_set_string(head,
- container_of(head->r.ns,
- struct tomoyo_policy_namespace,
- namespace_list)->name);
- tomoyo_set_space(head);
-}
-
-/**
- * tomoyo_print_name_union - Print a tomoyo_name_union.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @ptr: Pointer to "struct tomoyo_name_union".
- */
-static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
- const struct tomoyo_name_union *ptr)
-{
- tomoyo_set_space(head);
- if (ptr->group) {
- tomoyo_set_string(head, "@");
- tomoyo_set_string(head, ptr->group->group_name->name);
- } else {
- tomoyo_set_string(head, ptr->filename->name);
- }
-}
-
-/**
- * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @ptr: Pointer to "struct tomoyo_name_union".
- *
- * Returns nothing.
- */
-static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
- const struct tomoyo_name_union *ptr)
-{
- if (ptr->group) {
- tomoyo_set_string(head, "@");
- tomoyo_set_string(head, ptr->group->group_name->name);
- } else {
- tomoyo_set_string(head, "\"");
- tomoyo_set_string(head, ptr->filename->name);
- tomoyo_set_string(head, "\"");
- }
-}
-
-/**
- * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @ptr: Pointer to "struct tomoyo_number_union".
- *
- * Returns nothing.
- */
-static void tomoyo_print_number_union_nospace
-(struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr)
-{
- if (ptr->group) {
- tomoyo_set_string(head, "@");
- tomoyo_set_string(head, ptr->group->group_name->name);
- } else {
- int i;
- unsigned long min = ptr->values[0];
- const unsigned long max = ptr->values[1];
- u8 min_type = ptr->value_type[0];
- const u8 max_type = ptr->value_type[1];
- char buffer[128];
- buffer[0] = '\0';
- for (i = 0; i < 2; i++) {
- switch (min_type) {
- case TOMOYO_VALUE_TYPE_HEXADECIMAL:
- tomoyo_addprintf(buffer, sizeof(buffer),
- "0x%lX", min);
- break;
- case TOMOYO_VALUE_TYPE_OCTAL:
- tomoyo_addprintf(buffer, sizeof(buffer),
- "0%lo", min);
- break;
- default:
- tomoyo_addprintf(buffer, sizeof(buffer), "%lu",
- min);
- break;
- }
- if (min == max && min_type == max_type)
- break;
- tomoyo_addprintf(buffer, sizeof(buffer), "-");
- min_type = max_type;
- min = max;
- }
- tomoyo_io_printf(head, "%s", buffer);
- }
-}
-
-/**
- * tomoyo_print_number_union - Print a tomoyo_number_union.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @ptr: Pointer to "struct tomoyo_number_union".
- *
- * Returns nothing.
- */
-static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
- const struct tomoyo_number_union *ptr)
-{
- tomoyo_set_space(head);
- tomoyo_print_number_union_nospace(head, ptr);
-}
-
-/**
- * tomoyo_assign_profile - Create a new profile.
- *
- * @ns: Pointer to "struct tomoyo_policy_namespace".
- * @profile: Profile number to create.
- *
- * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
- */
-static struct tomoyo_profile *tomoyo_assign_profile
-(struct tomoyo_policy_namespace *ns, const unsigned int profile)
-{
- struct tomoyo_profile *ptr;
- struct tomoyo_profile *entry;
- if (profile >= TOMOYO_MAX_PROFILES)
- return NULL;
- ptr = ns->profile_ptr[profile];
- if (ptr)
- return ptr;
- entry = kzalloc(sizeof(*entry), GFP_NOFS);
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- goto out;
- ptr = ns->profile_ptr[profile];
- if (!ptr && tomoyo_memory_ok(entry)) {
- ptr = entry;
- ptr->default_config = TOMOYO_CONFIG_DISABLED |
- TOMOYO_CONFIG_WANT_GRANT_LOG |
- TOMOYO_CONFIG_WANT_REJECT_LOG;
- memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
- sizeof(ptr->config));
- ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] =
- CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG;
- ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] =
- CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY;
- mb(); /* Avoid out-of-order execution. */
- ns->profile_ptr[profile] = ptr;
- entry = NULL;
- }
- mutex_unlock(&tomoyo_policy_lock);
- out:
- kfree(entry);
- return ptr;
-}
-
-/**
- * tomoyo_profile - Find a profile.
- *
- * @ns: Pointer to "struct tomoyo_policy_namespace".
- * @profile: Profile number to find.
- *
- * Returns pointer to "struct tomoyo_profile".
- */
-struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
- const u8 profile)
-{
- static struct tomoyo_profile tomoyo_null_profile;
- struct tomoyo_profile *ptr = ns->profile_ptr[profile];
- if (!ptr)
- ptr = &tomoyo_null_profile;
- return ptr;
-}
-
-/**
- * tomoyo_find_yesno - Find values for specified keyword.
- *
- * @string: String to check.
- * @find: Name of keyword.
- *
- * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
- */
-static s8 tomoyo_find_yesno(const char *string, const char *find)
-{
- const char *cp = strstr(string, find);
- if (cp) {
- cp += strlen(find);
- if (!strncmp(cp, "=yes", 4))
- return 1;
- else if (!strncmp(cp, "=no", 3))
- return 0;
- }
- return -1;
-}
-
-/**
- * tomoyo_set_uint - Set value for specified preference.
- *
- * @i: Pointer to "unsigned int".
- * @string: String to check.
- * @find: Name of keyword.
- *
- * Returns nothing.
- */
-static void tomoyo_set_uint(unsigned int *i, const char *string,
- const char *find)
-{
- const char *cp = strstr(string, find);
- if (cp)
- sscanf(cp + strlen(find), "=%u", i);
-}
-
-/**
- * tomoyo_set_mode - Set mode for specified profile.
- *
- * @name: Name of functionality.
- * @value: Mode for @name.
- * @profile: Pointer to "struct tomoyo_profile".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_set_mode(char *name, const char *value,
- struct tomoyo_profile *profile)
-{
- u8 i;
- u8 config;
- if (!strcmp(name, "CONFIG")) {
- i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX;
- config = profile->default_config;
- } else if (tomoyo_str_starts(&name, "CONFIG::")) {
- config = 0;
- for (i = 0; i < TOMOYO_MAX_MAC_INDEX
- + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
- int len = 0;
- if (i < TOMOYO_MAX_MAC_INDEX) {
- const u8 c = tomoyo_index2category[i];
- const char *category =
- tomoyo_category_keywords[c];
- len = strlen(category);
- if (strncmp(name, category, len) ||
- name[len++] != ':' || name[len++] != ':')
- continue;
- }
- if (strcmp(name + len, tomoyo_mac_keywords[i]))
- continue;
- config = profile->config[i];
- break;
- }
- if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
- return -EINVAL;
- } else {
- return -EINVAL;
- }
- if (strstr(value, "use_default")) {
- config = TOMOYO_CONFIG_USE_DEFAULT;
- } else {
- u8 mode;
- for (mode = 0; mode < 4; mode++)
- if (strstr(value, tomoyo_mode[mode]))
- /*
- * Update lower 3 bits in order to distinguish
- * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
- */
- config = (config & ~7) | mode;
- if (config != TOMOYO_CONFIG_USE_DEFAULT) {
- switch (tomoyo_find_yesno(value, "grant_log")) {
- case 1:
- config |= TOMOYO_CONFIG_WANT_GRANT_LOG;
- break;
- case 0:
- config &= ~TOMOYO_CONFIG_WANT_GRANT_LOG;
- break;
- }
- switch (tomoyo_find_yesno(value, "reject_log")) {
- case 1:
- config |= TOMOYO_CONFIG_WANT_REJECT_LOG;
- break;
- case 0:
- config &= ~TOMOYO_CONFIG_WANT_REJECT_LOG;
- break;
- }
- }
- }
- if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
- profile->config[i] = config;
- else if (config != TOMOYO_CONFIG_USE_DEFAULT)
- profile->default_config = config;
- return 0;
-}
-
-/**
- * tomoyo_write_profile - Write profile table.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
-{
- char *data = head->write_buf;
- unsigned int i;
- char *cp;
- struct tomoyo_profile *profile;
- if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
- == 1)
- return 0;
- i = simple_strtoul(data, &cp, 10);
- if (*cp != '-')
- return -EINVAL;
- data = cp + 1;
- profile = tomoyo_assign_profile(head->w.ns, i);
- if (!profile)
- return -EINVAL;
- cp = strchr(data, '=');
- if (!cp)
- return -EINVAL;
- *cp++ = '\0';
- if (!strcmp(data, "COMMENT")) {
- static DEFINE_SPINLOCK(lock);
- const struct tomoyo_path_info *new_comment
- = tomoyo_get_name(cp);
- const struct tomoyo_path_info *old_comment;
- if (!new_comment)
- return -ENOMEM;
- spin_lock(&lock);
- old_comment = profile->comment;
- profile->comment = new_comment;
- spin_unlock(&lock);
- tomoyo_put_name(old_comment);
- return 0;
- }
- if (!strcmp(data, "PREFERENCE")) {
- for (i = 0; i < TOMOYO_MAX_PREF; i++)
- tomoyo_set_uint(&profile->pref[i], cp,
- tomoyo_pref_keywords[i]);
- return 0;
- }
- return tomoyo_set_mode(data, cp, profile);
-}
-
-/**
- * tomoyo_print_config - Print mode for specified functionality.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @config: Mode for that functionality.
- *
- * Returns nothing.
- *
- * Caller prints functionality's name.
- */
-static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
-{
- tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
- tomoyo_mode[config & 3],
- tomoyo_yesno(config & TOMOYO_CONFIG_WANT_GRANT_LOG),
- tomoyo_yesno(config & TOMOYO_CONFIG_WANT_REJECT_LOG));
-}
-
-/**
- * tomoyo_read_profile - Read profile table.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
-{
- u8 index;
- struct tomoyo_policy_namespace *ns =
- container_of(head->r.ns, typeof(*ns), namespace_list);
- const struct tomoyo_profile *profile;
- if (head->r.eof)
- return;
- next:
- index = head->r.index;
- profile = ns->profile_ptr[index];
- switch (head->r.step) {
- case 0:
- tomoyo_print_namespace(head);
- tomoyo_io_printf(head, "PROFILE_VERSION=%u\n",
- ns->profile_version);
- head->r.step++;
- break;
- case 1:
- for ( ; head->r.index < TOMOYO_MAX_PROFILES;
- head->r.index++)
- if (ns->profile_ptr[head->r.index])
- break;
- if (head->r.index == TOMOYO_MAX_PROFILES) {
- head->r.eof = true;
- return;
- }
- head->r.step++;
- break;
- case 2:
- {
- u8 i;
- const struct tomoyo_path_info *comment =
- profile->comment;
- tomoyo_print_namespace(head);
- tomoyo_io_printf(head, "%u-COMMENT=", index);
- tomoyo_set_string(head, comment ? comment->name : "");
- tomoyo_set_lf(head);
- tomoyo_print_namespace(head);
- tomoyo_io_printf(head, "%u-PREFERENCE={ ", index);
- for (i = 0; i < TOMOYO_MAX_PREF; i++)
- tomoyo_io_printf(head, "%s=%u ",
- tomoyo_pref_keywords[i],
- profile->pref[i]);
- tomoyo_set_string(head, "}\n");
- head->r.step++;
- }
- break;
- case 3:
- {
- tomoyo_print_namespace(head);
- tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
- tomoyo_print_config(head, profile->default_config);
- head->r.bit = 0;
- head->r.step++;
- }
- break;
- case 4:
- for ( ; head->r.bit < TOMOYO_MAX_MAC_INDEX
- + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
- const u8 i = head->r.bit;
- const u8 config = profile->config[i];
- if (config == TOMOYO_CONFIG_USE_DEFAULT)
- continue;
- tomoyo_print_namespace(head);
- if (i < TOMOYO_MAX_MAC_INDEX)
- tomoyo_io_printf(head, "%u-CONFIG::%s::%s",
- index,
- tomoyo_category_keywords
- [tomoyo_index2category[i]],
- tomoyo_mac_keywords[i]);
- else
- tomoyo_io_printf(head, "%u-CONFIG::%s", index,
- tomoyo_mac_keywords[i]);
- tomoyo_print_config(head, config);
- head->r.bit++;
- break;
- }
- if (head->r.bit == TOMOYO_MAX_MAC_INDEX
- + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
- head->r.index++;
- head->r.step = 1;
- }
- break;
- }
- if (tomoyo_flush(head))
- goto next;
-}
-
-/**
- * tomoyo_same_manager - Check for duplicated "struct tomoyo_manager" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_head".
- * @b: Pointer to "struct tomoyo_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_manager(const struct tomoyo_acl_head *a,
- const struct tomoyo_acl_head *b)
-{
- return container_of(a, struct tomoyo_manager, head)->manager ==
- container_of(b, struct tomoyo_manager, head)->manager;
-}
-
-/**
- * tomoyo_update_manager_entry - Add a manager entry.
- *
- * @manager: The path to manager or the domainnamme.
- * @is_delete: True if it is a delete request.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_update_manager_entry(const char *manager,
- const bool is_delete)
-{
- struct tomoyo_manager e = { };
- struct tomoyo_acl_param param = {
- /* .ns = &tomoyo_kernel_namespace, */
- .is_delete = is_delete,
- .list = &tomoyo_kernel_namespace.
- policy_list[TOMOYO_ID_MANAGER],
- };
- int error = is_delete ? -ENOENT : -ENOMEM;
- if (tomoyo_domain_def(manager)) {
- if (!tomoyo_correct_domain(manager))
- return -EINVAL;
- e.is_domain = true;
- } else {
- if (!tomoyo_correct_path(manager))
- return -EINVAL;
- }
- e.manager = tomoyo_get_name(manager);
- if (e.manager) {
- error = tomoyo_update_policy(&e.head, sizeof(e), &param,
- tomoyo_same_manager);
- tomoyo_put_name(e.manager);
- }
- return error;
-}
-
-/**
- * tomoyo_write_manager - Write manager policy.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_write_manager(struct tomoyo_io_buffer *head)
-{
- char *data = head->write_buf;
-
- if (!strcmp(data, "manage_by_non_root")) {
- tomoyo_manage_by_non_root = !head->w.is_delete;
- return 0;
- }
- return tomoyo_update_manager_entry(data, head->w.is_delete);
-}
-
-/**
- * tomoyo_read_manager - Read manager policy.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Caller holds tomoyo_read_lock().
- */
-static void tomoyo_read_manager(struct tomoyo_io_buffer *head)
-{
- if (head->r.eof)
- return;
- list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.
- policy_list[TOMOYO_ID_MANAGER]) {
- struct tomoyo_manager *ptr =
- list_entry(head->r.acl, typeof(*ptr), head.list);
- if (ptr->head.is_deleted)
- continue;
- if (!tomoyo_flush(head))
- return;
- tomoyo_set_string(head, ptr->manager->name);
- tomoyo_set_lf(head);
- }
- head->r.eof = true;
-}
-
-/**
- * tomoyo_manager - Check whether the current process is a policy manager.
- *
- * Returns true if the current process is permitted to modify policy
- * via /sys/kernel/security/tomoyo/ interface.
- *
- * Caller holds tomoyo_read_lock().
- */
-static bool tomoyo_manager(void)
-{
- struct tomoyo_manager *ptr;
- const char *exe;
- const struct task_struct *task = current;
- const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname;
- bool found = false;
-
- if (!tomoyo_policy_loaded)
- return true;
- if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
- return false;
- list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
- policy_list[TOMOYO_ID_MANAGER], head.list) {
- if (!ptr->head.is_deleted && ptr->is_domain
- && !tomoyo_pathcmp(domainname, ptr->manager)) {
- found = true;
- break;
- }
- }
- if (found)
- return true;
- exe = tomoyo_get_exe();
- if (!exe)
- return false;
- list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
- policy_list[TOMOYO_ID_MANAGER], head.list) {
- if (!ptr->head.is_deleted && !ptr->is_domain
- && !strcmp(exe, ptr->manager->name)) {
- found = true;
- break;
- }
- }
- if (!found) { /* Reduce error messages. */
- static pid_t last_pid;
- const pid_t pid = current->pid;
- if (last_pid != pid) {
- printk(KERN_WARNING "%s ( %s ) is not permitted to "
- "update policies.\n", domainname->name, exe);
- last_pid = pid;
- }
- }
- kfree(exe);
- return found;
-}
-
-static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
-(unsigned int serial);
-
-/**
- * tomoyo_select_domain - Parse select command.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @data: String to parse.
- *
- * Returns true on success, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
- const char *data)
-{
- unsigned int pid;
- struct tomoyo_domain_info *domain = NULL;
- bool global_pid = false;
- if (strncmp(data, "select ", 7))
- return false;
- data += 7;
- if (sscanf(data, "pid=%u", &pid) == 1 ||
- (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
- struct task_struct *p;
- rcu_read_lock();
- if (global_pid)
- p = find_task_by_pid_ns(pid, &init_pid_ns);
- else
- p = find_task_by_vpid(pid);
- if (p)
- domain = tomoyo_real_domain(p);
- rcu_read_unlock();
- } else if (!strncmp(data, "domain=", 7)) {
- if (tomoyo_domain_def(data + 7))
- domain = tomoyo_find_domain(data + 7);
- } else if (sscanf(data, "Q=%u", &pid) == 1) {
- domain = tomoyo_find_domain_by_qid(pid);
- } else
- return false;
- head->w.domain = domain;
- /* Accessing read_buf is safe because head->io_sem is held. */
- if (!head->read_buf)
- return true; /* Do nothing if open(O_WRONLY). */
- memset(&head->r, 0, sizeof(head->r));
- head->r.print_this_domain_only = true;
- if (domain)
- head->r.domain = &domain->list;
- else
- head->r.eof = 1;
- tomoyo_io_printf(head, "# select %s\n", data);
- if (domain && domain->is_deleted)
- tomoyo_io_printf(head, "# This is a deleted domain.\n");
- return true;
-}
-
-/**
- * tomoyo_same_task_acl - Check for duplicated "struct tomoyo_task_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head);
- return p1->domainname == p2->domainname;
-}
-
-/**
- * tomoyo_write_task - Update task related list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_write_task(struct tomoyo_acl_param *param)
-{
- int error = -EINVAL;
- if (tomoyo_str_starts(&param->data, "manual_domain_transition ")) {
- struct tomoyo_task_acl e = {
- .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL,
- .domainname = tomoyo_get_domainname(param),
- };
- if (e.domainname)
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_task_acl,
- NULL);
- tomoyo_put_name(e.domainname);
- }
- return error;
-}
-
-/**
- * tomoyo_delete_domain - Delete a domain.
- *
- * @domainname: The name of domain.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_delete_domain(char *domainname)
-{
- struct tomoyo_domain_info *domain;
- struct tomoyo_path_info name;
-
- name.name = domainname;
- tomoyo_fill_path_info(&name);
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- return -EINTR;
- /* Is there an active domain? */
- list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
- /* Never delete tomoyo_kernel_domain */
- if (domain == &tomoyo_kernel_domain)
- continue;
- if (domain->is_deleted ||
- tomoyo_pathcmp(domain->domainname, &name))
- continue;
- domain->is_deleted = true;
- break;
- }
- mutex_unlock(&tomoyo_policy_lock);
- return 0;
-}
-
-/**
- * tomoyo_write_domain2 - Write domain policy.
- *
- * @ns: Pointer to "struct tomoyo_policy_namespace".
- * @list: Pointer to "struct list_head".
- * @data: Policy to be interpreted.
- * @is_delete: True if it is a delete request.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
- struct list_head *list, char *data,
- const bool is_delete)
-{
- struct tomoyo_acl_param param = {
- .ns = ns,
- .list = list,
- .data = data,
- .is_delete = is_delete,
- };
- static const struct {
- const char *keyword;
- int (*write) (struct tomoyo_acl_param *);
- } tomoyo_callback[5] = {
- { "file ", tomoyo_write_file },
- { "network inet ", tomoyo_write_inet_network },
- { "network unix ", tomoyo_write_unix_network },
- { "misc ", tomoyo_write_misc },
- { "task ", tomoyo_write_task },
- };
- u8 i;
-
- for (i = 0; i < ARRAY_SIZE(tomoyo_callback); i++) {
- if (!tomoyo_str_starts(&param.data,
- tomoyo_callback[i].keyword))
- continue;
- return tomoyo_callback[i].write(&param);
- }
- return -EINVAL;
-}
-
-/* String table for domain flags. */
-const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS] = {
- [TOMOYO_DIF_QUOTA_WARNED] = "quota_exceeded\n",
- [TOMOYO_DIF_TRANSITION_FAILED] = "transition_failed\n",
-};
-
-/**
- * tomoyo_write_domain - Write domain policy.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
-{
- char *data = head->write_buf;
- struct tomoyo_policy_namespace *ns;
- struct tomoyo_domain_info *domain = head->w.domain;
- const bool is_delete = head->w.is_delete;
- bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
- unsigned int profile;
- if (*data == '<') {
- int ret = 0;
- domain = NULL;
- if (is_delete)
- ret = tomoyo_delete_domain(data);
- else if (is_select)
- domain = tomoyo_find_domain(data);
- else
- domain = tomoyo_assign_domain(data, false);
- head->w.domain = domain;
- return ret;
- }
- if (!domain)
- return -EINVAL;
- ns = domain->ns;
- if (sscanf(data, "use_profile %u", &profile) == 1
- && profile < TOMOYO_MAX_PROFILES) {
- if (!tomoyo_policy_loaded || ns->profile_ptr[profile])
- domain->profile = (u8) profile;
- return 0;
- }
- if (sscanf(data, "use_group %u\n", &profile) == 1
- && profile < TOMOYO_MAX_ACL_GROUPS) {
- if (!is_delete)
- domain->group = (u8) profile;
- return 0;
- }
- for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) {
- const char *cp = tomoyo_dif[profile];
- if (strncmp(data, cp, strlen(cp) - 1))
- continue;
- domain->flags[profile] = !is_delete;
- return 0;
- }
- return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
- is_delete);
-}
-
-/**
- * tomoyo_print_condition - Print condition part.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @cond: Pointer to "struct tomoyo_condition".
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
- const struct tomoyo_condition *cond)
-{
- switch (head->r.cond_step) {
- case 0:
- head->r.cond_index = 0;
- head->r.cond_step++;
- if (cond->transit) {
- tomoyo_set_space(head);
- tomoyo_set_string(head, cond->transit->name);
- }
- /* fall through */
- case 1:
- {
- const u16 condc = cond->condc;
- const struct tomoyo_condition_element *condp =
- (typeof(condp)) (cond + 1);
- const struct tomoyo_number_union *numbers_p =
- (typeof(numbers_p)) (condp + condc);
- const struct tomoyo_name_union *names_p =
- (typeof(names_p))
- (numbers_p + cond->numbers_count);
- const struct tomoyo_argv *argv =
- (typeof(argv)) (names_p + cond->names_count);
- const struct tomoyo_envp *envp =
- (typeof(envp)) (argv + cond->argc);
- u16 skip;
- for (skip = 0; skip < head->r.cond_index; skip++) {
- const u8 left = condp->left;
- const u8 right = condp->right;
- condp++;
- switch (left) {
- case TOMOYO_ARGV_ENTRY:
- argv++;
- continue;
- case TOMOYO_ENVP_ENTRY:
- envp++;
- continue;
- case TOMOYO_NUMBER_UNION:
- numbers_p++;
- break;
- }
- switch (right) {
- case TOMOYO_NAME_UNION:
- names_p++;
- break;
- case TOMOYO_NUMBER_UNION:
- numbers_p++;
- break;
- }
- }
- while (head->r.cond_index < condc) {
- const u8 match = condp->equals;
- const u8 left = condp->left;
- const u8 right = condp->right;
- if (!tomoyo_flush(head))
- return false;
- condp++;
- head->r.cond_index++;
- tomoyo_set_space(head);
- switch (left) {
- case TOMOYO_ARGV_ENTRY:
- tomoyo_io_printf(head,
- "exec.argv[%lu]%s=\"",
- argv->index, argv->
- is_not ? "!" : "");
- tomoyo_set_string(head,
- argv->value->name);
- tomoyo_set_string(head, "\"");
- argv++;
- continue;
- case TOMOYO_ENVP_ENTRY:
- tomoyo_set_string(head,
- "exec.envp[\"");
- tomoyo_set_string(head,
- envp->name->name);
- tomoyo_io_printf(head, "\"]%s=", envp->
- is_not ? "!" : "");
- if (envp->value) {
- tomoyo_set_string(head, "\"");
- tomoyo_set_string(head, envp->
- value->name);
- tomoyo_set_string(head, "\"");
- } else {
- tomoyo_set_string(head,
- "NULL");
- }
- envp++;
- continue;
- case TOMOYO_NUMBER_UNION:
- tomoyo_print_number_union_nospace
- (head, numbers_p++);
- break;
- default:
- tomoyo_set_string(head,
- tomoyo_condition_keyword[left]);
- break;
- }
- tomoyo_set_string(head, match ? "=" : "!=");
- switch (right) {
- case TOMOYO_NAME_UNION:
- tomoyo_print_name_union_quoted
- (head, names_p++);
- break;
- case TOMOYO_NUMBER_UNION:
- tomoyo_print_number_union_nospace
- (head, numbers_p++);
- break;
- default:
- tomoyo_set_string(head,
- tomoyo_condition_keyword[right]);
- break;
- }
- }
- }
- head->r.cond_step++;
- /* fall through */
- case 2:
- if (!tomoyo_flush(head))
- break;
- head->r.cond_step++;
- /* fall through */
- case 3:
- if (cond->grant_log != TOMOYO_GRANTLOG_AUTO)
- tomoyo_io_printf(head, " grant_log=%s",
- tomoyo_yesno(cond->grant_log ==
- TOMOYO_GRANTLOG_YES));
- tomoyo_set_lf(head);
- return true;
- }
- return false;
-}
-
-/**
- * tomoyo_set_group - Print "acl_group " header keyword and category name.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @category: Category name.
- *
- * Returns nothing.
- */
-static void tomoyo_set_group(struct tomoyo_io_buffer *head,
- const char *category)
-{
- if (head->type == TOMOYO_EXCEPTIONPOLICY) {
- tomoyo_print_namespace(head);
- tomoyo_io_printf(head, "acl_group %u ",
- head->r.acl_group_index);
- }
- tomoyo_set_string(head, category);
-}
-
-/**
- * tomoyo_print_entry - Print an ACL entry.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @acl: Pointer to an ACL entry.
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
- struct tomoyo_acl_info *acl)
-{
- const u8 acl_type = acl->type;
- bool first = true;
- u8 bit;
-
- if (head->r.print_cond_part)
- goto print_cond_part;
- if (acl->is_deleted)
- return true;
- if (!tomoyo_flush(head))
- return false;
- else if (acl_type == TOMOYO_TYPE_PATH_ACL) {
- struct tomoyo_path_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- const u16 perm = ptr->perm;
- for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
- if (!(perm & (1 << bit)))
- continue;
- if (head->r.print_transition_related_only &&
- bit != TOMOYO_TYPE_EXECUTE)
- continue;
- if (first) {
- tomoyo_set_group(head, "file ");
- first = false;
- } else {
- tomoyo_set_slash(head);
- }
- tomoyo_set_string(head, tomoyo_path_keyword[bit]);
- }
- if (first)
- return true;
- tomoyo_print_name_union(head, &ptr->name);
- } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) {
- struct tomoyo_task_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- tomoyo_set_group(head, "task ");
- tomoyo_set_string(head, "manual_domain_transition ");
- tomoyo_set_string(head, ptr->domainname->name);
- } else if (head->r.print_transition_related_only) {
- return true;
- } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
- struct tomoyo_path2_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- const u8 perm = ptr->perm;
- for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
- if (!(perm & (1 << bit)))
- continue;
- if (first) {
- tomoyo_set_group(head, "file ");
- first = false;
- } else {
- tomoyo_set_slash(head);
- }
- tomoyo_set_string(head, tomoyo_mac_keywords
- [tomoyo_pp2mac[bit]]);
- }
- if (first)
- return true;
- tomoyo_print_name_union(head, &ptr->name1);
- tomoyo_print_name_union(head, &ptr->name2);
- } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) {
- struct tomoyo_path_number_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- const u8 perm = ptr->perm;
- for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) {
- if (!(perm & (1 << bit)))
- continue;
- if (first) {
- tomoyo_set_group(head, "file ");
- first = false;
- } else {
- tomoyo_set_slash(head);
- }
- tomoyo_set_string(head, tomoyo_mac_keywords
- [tomoyo_pn2mac[bit]]);
- }
- if (first)
- return true;
- tomoyo_print_name_union(head, &ptr->name);
- tomoyo_print_number_union(head, &ptr->number);
- } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) {
- struct tomoyo_mkdev_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- const u8 perm = ptr->perm;
- for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) {
- if (!(perm & (1 << bit)))
- continue;
- if (first) {
- tomoyo_set_group(head, "file ");
- first = false;
- } else {
- tomoyo_set_slash(head);
- }
- tomoyo_set_string(head, tomoyo_mac_keywords
- [tomoyo_pnnn2mac[bit]]);
- }
- if (first)
- return true;
- tomoyo_print_name_union(head, &ptr->name);
- tomoyo_print_number_union(head, &ptr->mode);
- tomoyo_print_number_union(head, &ptr->major);
- tomoyo_print_number_union(head, &ptr->minor);
- } else if (acl_type == TOMOYO_TYPE_INET_ACL) {
- struct tomoyo_inet_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- const u8 perm = ptr->perm;
-
- for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) {
- if (!(perm & (1 << bit)))
- continue;
- if (first) {
- tomoyo_set_group(head, "network inet ");
- tomoyo_set_string(head, tomoyo_proto_keyword
- [ptr->protocol]);
- tomoyo_set_space(head);
- first = false;
- } else {
- tomoyo_set_slash(head);
- }
- tomoyo_set_string(head, tomoyo_socket_keyword[bit]);
- }
- if (first)
- return true;
- tomoyo_set_space(head);
- if (ptr->address.group) {
- tomoyo_set_string(head, "@");
- tomoyo_set_string(head, ptr->address.group->group_name
- ->name);
- } else {
- char buf[128];
- tomoyo_print_ip(buf, sizeof(buf), &ptr->address);
- tomoyo_io_printf(head, "%s", buf);
- }
- tomoyo_print_number_union(head, &ptr->port);
- } else if (acl_type == TOMOYO_TYPE_UNIX_ACL) {
- struct tomoyo_unix_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- const u8 perm = ptr->perm;
-
- for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) {
- if (!(perm & (1 << bit)))
- continue;
- if (first) {
- tomoyo_set_group(head, "network unix ");
- tomoyo_set_string(head, tomoyo_proto_keyword
- [ptr->protocol]);
- tomoyo_set_space(head);
- first = false;
- } else {
- tomoyo_set_slash(head);
- }
- tomoyo_set_string(head, tomoyo_socket_keyword[bit]);
- }
- if (first)
- return true;
- tomoyo_print_name_union(head, &ptr->name);
- } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
- struct tomoyo_mount_acl *ptr =
- container_of(acl, typeof(*ptr), head);
- tomoyo_set_group(head, "file mount");
- tomoyo_print_name_union(head, &ptr->dev_name);
- tomoyo_print_name_union(head, &ptr->dir_name);
- tomoyo_print_name_union(head, &ptr->fs_type);
- tomoyo_print_number_union(head, &ptr->flags);
- } else if (acl_type == TOMOYO_TYPE_ENV_ACL) {
- struct tomoyo_env_acl *ptr =
- container_of(acl, typeof(*ptr), head);
-
- tomoyo_set_group(head, "misc env ");
- tomoyo_set_string(head, ptr->env->name);
- }
- if (acl->cond) {
- head->r.print_cond_part = true;
- head->r.cond_step = 0;
- if (!tomoyo_flush(head))
- return false;
-print_cond_part:
- if (!tomoyo_print_condition(head, acl->cond))
- return false;
- head->r.print_cond_part = false;
- } else {
- tomoyo_set_lf(head);
- }
- return true;
-}
-
-/**
- * tomoyo_read_domain2 - Read domain policy.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @list: Pointer to "struct list_head".
- *
- * Caller holds tomoyo_read_lock().
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head,
- struct list_head *list)
-{
- list_for_each_cookie(head->r.acl, list) {
- struct tomoyo_acl_info *ptr =
- list_entry(head->r.acl, typeof(*ptr), list);
- if (!tomoyo_print_entry(head, ptr))
- return false;
- }
- head->r.acl = NULL;
- return true;
-}
-
-/**
- * tomoyo_read_domain - Read domain policy.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Caller holds tomoyo_read_lock().
- */
-static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
-{
- if (head->r.eof)
- return;
- list_for_each_cookie(head->r.domain, &tomoyo_domain_list) {
- struct tomoyo_domain_info *domain =
- list_entry(head->r.domain, typeof(*domain), list);
- switch (head->r.step) {
- u8 i;
- case 0:
- if (domain->is_deleted &&
- !head->r.print_this_domain_only)
- continue;
- /* Print domainname and flags. */
- tomoyo_set_string(head, domain->domainname->name);
- tomoyo_set_lf(head);
- tomoyo_io_printf(head, "use_profile %u\n",
- domain->profile);
- tomoyo_io_printf(head, "use_group %u\n",
- domain->group);
- for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
- if (domain->flags[i])
- tomoyo_set_string(head, tomoyo_dif[i]);
- head->r.step++;
- tomoyo_set_lf(head);
- /* fall through */
- case 1:
- if (!tomoyo_read_domain2(head, &domain->acl_info_list))
- return;
- head->r.step++;
- if (!tomoyo_set_lf(head))
- return;
- /* fall through */
- case 2:
- head->r.step = 0;
- if (head->r.print_this_domain_only)
- goto done;
- }
- }
- done:
- head->r.eof = true;
-}
-
-/**
- * tomoyo_write_pid: Specify PID to obtain domainname.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0.
- */
-static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
-{
- head->r.eof = false;
- return 0;
-}
-
-/**
- * tomoyo_read_pid - Get domainname of the specified PID.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns the domainname which the specified PID is in on success,
- * empty string otherwise.
- * The PID is specified by tomoyo_write_pid() so that the user can obtain
- * using read()/write() interface rather than sysctl() interface.
- */
-static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
-{
- char *buf = head->write_buf;
- bool global_pid = false;
- unsigned int pid;
- struct task_struct *p;
- struct tomoyo_domain_info *domain = NULL;
-
- /* Accessing write_buf is safe because head->io_sem is held. */
- if (!buf) {
- head->r.eof = true;
- return; /* Do nothing if open(O_RDONLY). */
- }
- if (head->r.w_pos || head->r.eof)
- return;
- head->r.eof = true;
- if (tomoyo_str_starts(&buf, "global-pid "))
- global_pid = true;
- pid = (unsigned int) simple_strtoul(buf, NULL, 10);
- rcu_read_lock();
- if (global_pid)
- p = find_task_by_pid_ns(pid, &init_pid_ns);
- else
- p = find_task_by_vpid(pid);
- if (p)
- domain = tomoyo_real_domain(p);
- rcu_read_unlock();
- if (!domain)
- return;
- tomoyo_io_printf(head, "%u %u ", pid, domain->profile);
- tomoyo_set_string(head, domain->domainname->name);
-}
-
-/* String table for domain transition control keywords. */
-static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
- [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ",
- [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ",
- [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
- [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ",
- [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ",
- [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain ",
-};
-
-/* String table for grouping keywords. */
-static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
- [TOMOYO_PATH_GROUP] = "path_group ",
- [TOMOYO_NUMBER_GROUP] = "number_group ",
- [TOMOYO_ADDRESS_GROUP] = "address_group ",
-};
-
-/**
- * tomoyo_write_exception - Write exception policy.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
-{
- const bool is_delete = head->w.is_delete;
- struct tomoyo_acl_param param = {
- .ns = head->w.ns,
- .is_delete = is_delete,
- .data = head->write_buf,
- };
- u8 i;
- if (tomoyo_str_starts(&param.data, "aggregator "))
- return tomoyo_write_aggregator(&param);
- for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
- if (tomoyo_str_starts(&param.data, tomoyo_transition_type[i]))
- return tomoyo_write_transition_control(&param, i);
- for (i = 0; i < TOMOYO_MAX_GROUP; i++)
- if (tomoyo_str_starts(&param.data, tomoyo_group_name[i]))
- return tomoyo_write_group(&param, i);
- if (tomoyo_str_starts(&param.data, "acl_group ")) {
- unsigned int group;
- char *data;
- group = simple_strtoul(param.data, &data, 10);
- if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ')
- return tomoyo_write_domain2
- (head->w.ns, &head->w.ns->acl_group[group],
- data, is_delete);
- }
- return -EINVAL;
-}
-
-/**
- * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @idx: Index number.
- *
- * Returns true on success, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
-{
- struct tomoyo_policy_namespace *ns =
- container_of(head->r.ns, typeof(*ns), namespace_list);
- struct list_head *list = &ns->group_list[idx];
- list_for_each_cookie(head->r.group, list) {
- struct tomoyo_group *group =
- list_entry(head->r.group, typeof(*group), head.list);
- list_for_each_cookie(head->r.acl, &group->member_list) {
- struct tomoyo_acl_head *ptr =
- list_entry(head->r.acl, typeof(*ptr), list);
- if (ptr->is_deleted)
- continue;
- if (!tomoyo_flush(head))
- return false;
- tomoyo_print_namespace(head);
- tomoyo_set_string(head, tomoyo_group_name[idx]);
- tomoyo_set_string(head, group->group_name->name);
- if (idx == TOMOYO_PATH_GROUP) {
- tomoyo_set_space(head);
- tomoyo_set_string(head, container_of
- (ptr, struct tomoyo_path_group,
- head)->member_name->name);
- } else if (idx == TOMOYO_NUMBER_GROUP) {
- tomoyo_print_number_union(head, &container_of
- (ptr,
- struct tomoyo_number_group,
- head)->number);
- } else if (idx == TOMOYO_ADDRESS_GROUP) {
- char buffer[128];
-
- struct tomoyo_address_group *member =
- container_of(ptr, typeof(*member),
- head);
- tomoyo_print_ip(buffer, sizeof(buffer),
- &member->address);
- tomoyo_io_printf(head, " %s", buffer);
- }
- tomoyo_set_lf(head);
- }
- head->r.acl = NULL;
- }
- head->r.group = NULL;
- return true;
-}
-
-/**
- * tomoyo_read_policy - Read "struct tomoyo_..._entry" list.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @idx: Index number.
- *
- * Returns true on success, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
-{
- struct tomoyo_policy_namespace *ns =
- container_of(head->r.ns, typeof(*ns), namespace_list);
- struct list_head *list = &ns->policy_list[idx];
- list_for_each_cookie(head->r.acl, list) {
- struct tomoyo_acl_head *acl =
- container_of(head->r.acl, typeof(*acl), list);
- if (acl->is_deleted)
- continue;
- if (!tomoyo_flush(head))
- return false;
- switch (idx) {
- case TOMOYO_ID_TRANSITION_CONTROL:
- {
- struct tomoyo_transition_control *ptr =
- container_of(acl, typeof(*ptr), head);
- tomoyo_print_namespace(head);
- tomoyo_set_string(head, tomoyo_transition_type
- [ptr->type]);
- tomoyo_set_string(head, ptr->program ?
- ptr->program->name : "any");
- tomoyo_set_string(head, " from ");
- tomoyo_set_string(head, ptr->domainname ?
- ptr->domainname->name :
- "any");
- }
- break;
- case TOMOYO_ID_AGGREGATOR:
- {
- struct tomoyo_aggregator *ptr =
- container_of(acl, typeof(*ptr), head);
- tomoyo_print_namespace(head);
- tomoyo_set_string(head, "aggregator ");
- tomoyo_set_string(head,
- ptr->original_name->name);
- tomoyo_set_space(head);
- tomoyo_set_string(head,
- ptr->aggregated_name->name);
- }
- break;
- default:
- continue;
- }
- tomoyo_set_lf(head);
- }
- head->r.acl = NULL;
- return true;
-}
-
-/**
- * tomoyo_read_exception - Read exception policy.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Caller holds tomoyo_read_lock().
- */
-static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
-{
- struct tomoyo_policy_namespace *ns =
- container_of(head->r.ns, typeof(*ns), namespace_list);
- if (head->r.eof)
- return;
- while (head->r.step < TOMOYO_MAX_POLICY &&
- tomoyo_read_policy(head, head->r.step))
- head->r.step++;
- if (head->r.step < TOMOYO_MAX_POLICY)
- return;
- while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP &&
- tomoyo_read_group(head, head->r.step - TOMOYO_MAX_POLICY))
- head->r.step++;
- if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
- return;
- while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP
- + TOMOYO_MAX_ACL_GROUPS) {
- head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY
- - TOMOYO_MAX_GROUP;
- if (!tomoyo_read_domain2(head, &ns->acl_group
- [head->r.acl_group_index]))
- return;
- head->r.step++;
- }
- head->r.eof = true;
-}
-
-/* Wait queue for kernel -> userspace notification. */
-static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait);
-/* Wait queue for userspace -> kernel notification. */
-static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait);
-
-/* Structure for query. */
-struct tomoyo_query {
- struct list_head list;
- struct tomoyo_domain_info *domain;
- char *query;
- size_t query_len;
- unsigned int serial;
- u8 timer;
- u8 answer;
- u8 retry;
-};
-
-/* The list for "struct tomoyo_query". */
-static LIST_HEAD(tomoyo_query_list);
-
-/* Lock for manipulating tomoyo_query_list. */
-static DEFINE_SPINLOCK(tomoyo_query_list_lock);
-
-/*
- * Number of "struct file" referring /sys/kernel/security/tomoyo/query
- * interface.
- */
-static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
-
-/**
- * tomoyo_truncate - Truncate a line.
- *
- * @str: String to truncate.
- *
- * Returns length of truncated @str.
- */
-static int tomoyo_truncate(char *str)
-{
- char *start = str;
- while (*(unsigned char *) str > (unsigned char) ' ')
- str++;
- *str = '\0';
- return strlen(start) + 1;
-}
-
-/**
- * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
- *
- * @domain: Pointer to "struct tomoyo_domain_info".
- * @header: Lines containing ACL.
- *
- * Returns nothing.
- */
-static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
-{
- char *buffer;
- char *realpath = NULL;
- char *argv0 = NULL;
- char *symlink = NULL;
- char *cp = strchr(header, '\n');
- int len;
- if (!cp)
- return;
- cp = strchr(cp + 1, '\n');
- if (!cp)
- return;
- *cp++ = '\0';
- len = strlen(cp) + 1;
- /* strstr() will return NULL if ordering is wrong. */
- if (*cp == 'f') {
- argv0 = strstr(header, " argv[]={ \"");
- if (argv0) {
- argv0 += 10;
- len += tomoyo_truncate(argv0) + 14;
- }
- realpath = strstr(header, " exec={ realpath=\"");
- if (realpath) {
- realpath += 8;
- len += tomoyo_truncate(realpath) + 6;
- }
- symlink = strstr(header, " symlink.target=\"");
- if (symlink)
- len += tomoyo_truncate(symlink + 1) + 1;
- }
- buffer = kmalloc(len, GFP_NOFS);
- if (!buffer)
- return;
- snprintf(buffer, len - 1, "%s", cp);
- if (realpath)
- tomoyo_addprintf(buffer, len, " exec.%s", realpath);
- if (argv0)
- tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
- if (symlink)
- tomoyo_addprintf(buffer, len, "%s", symlink);
- tomoyo_normalize_line(buffer);
- if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
- false))
- tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
- kfree(buffer);
-}
-
-/**
- * tomoyo_supervisor - Ask for the supervisor's decision.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @fmt: The printf()'s format string, followed by parameters.
- *
- * Returns 0 if the supervisor decided to permit the access request which
- * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
- * supervisor decided to retry the access request which violated the policy in
- * enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise.
- */
-int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
-{
- va_list args;
- int error;
- int len;
- static unsigned int tomoyo_serial;
- struct tomoyo_query entry = { };
- bool quota_exceeded = false;
- va_start(args, fmt);
- len = vsnprintf((char *) &len, 1, fmt, args) + 1;
- va_end(args);
- /* Write /sys/kernel/security/tomoyo/audit. */
- va_start(args, fmt);
- tomoyo_write_log2(r, len, fmt, args);
- va_end(args);
- /* Nothing more to do if granted. */
- if (r->granted)
- return 0;
- if (r->mode)
- tomoyo_update_stat(r->mode);
- switch (r->mode) {
- case TOMOYO_CONFIG_ENFORCING:
- error = -EPERM;
- if (atomic_read(&tomoyo_query_observers))
- break;
- goto out;
- case TOMOYO_CONFIG_LEARNING:
- error = 0;
- /* Check max_learning_entry parameter. */
- if (tomoyo_domain_quota_is_ok(r))
- break;
- /* fall through */
- default:
- return 0;
- }
- /* Get message. */
- va_start(args, fmt);
- entry.query = tomoyo_init_log(r, len, fmt, args);
- va_end(args);
- if (!entry.query)
- goto out;
- entry.query_len = strlen(entry.query) + 1;
- if (!error) {
- tomoyo_add_entry(r->domain, entry.query);
- goto out;
- }
- len = tomoyo_round2(entry.query_len);
- entry.domain = r->domain;
- spin_lock(&tomoyo_query_list_lock);
- if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] &&
- tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len
- >= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) {
- quota_exceeded = true;
- } else {
- entry.serial = tomoyo_serial++;
- entry.retry = r->retry;
- tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len;
- list_add_tail(&entry.list, &tomoyo_query_list);
- }
- spin_unlock(&tomoyo_query_list_lock);
- if (quota_exceeded)
- goto out;
- /* Give 10 seconds for supervisor's opinion. */
- while (entry.timer < 10) {
- wake_up_all(&tomoyo_query_wait);
- if (wait_event_interruptible_timeout
- (tomoyo_answer_wait, entry.answer ||
- !atomic_read(&tomoyo_query_observers), HZ))
- break;
- else
- entry.timer++;
- }
- spin_lock(&tomoyo_query_list_lock);
- list_del(&entry.list);
- tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len;
- spin_unlock(&tomoyo_query_list_lock);
- switch (entry.answer) {
- case 3: /* Asked to retry by administrator. */
- error = TOMOYO_RETRY_REQUEST;
- r->retry++;
- break;
- case 1:
- /* Granted by administrator. */
- error = 0;
- break;
- default:
- /* Timed out or rejected by administrator. */
- break;
- }
-out:
- kfree(entry.query);
- return error;
-}
-
-/**
- * tomoyo_find_domain_by_qid - Get domain by query id.
- *
- * @serial: Query ID assigned by tomoyo_supervisor().
- *
- * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
- */
-static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
-(unsigned int serial)
-{
- struct tomoyo_query *ptr;
- struct tomoyo_domain_info *domain = NULL;
- spin_lock(&tomoyo_query_list_lock);
- list_for_each_entry(ptr, &tomoyo_query_list, list) {
- if (ptr->serial != serial)
- continue;
- domain = ptr->domain;
- break;
- }
- spin_unlock(&tomoyo_query_list_lock);
- return domain;
-}
-
-/**
- * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query.
- *
- * @file: Pointer to "struct file".
- * @wait: Pointer to "poll_table".
- *
- * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
- *
- * Waits for access requests which violated policy in enforcing mode.
- */
-static unsigned int tomoyo_poll_query(struct file *file, poll_table *wait)
-{
- if (!list_empty(&tomoyo_query_list))
- return POLLIN | POLLRDNORM;
- poll_wait(file, &tomoyo_query_wait, wait);
- if (!list_empty(&tomoyo_query_list))
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-/**
- * tomoyo_read_query - Read access requests which violated policy in enforcing mode.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- */
-static void tomoyo_read_query(struct tomoyo_io_buffer *head)
-{
- struct list_head *tmp;
- unsigned int pos = 0;
- size_t len = 0;
- char *buf;
- if (head->r.w_pos)
- return;
- if (head->read_buf) {
- kfree(head->read_buf);
- head->read_buf = NULL;
- }
- spin_lock(&tomoyo_query_list_lock);
- list_for_each(tmp, &tomoyo_query_list) {
- struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
- if (pos++ != head->r.query_index)
- continue;
- len = ptr->query_len;
- break;
- }
- spin_unlock(&tomoyo_query_list_lock);
- if (!len) {
- head->r.query_index = 0;
- return;
- }
- buf = kzalloc(len + 32, GFP_NOFS);
- if (!buf)
- return;
- pos = 0;
- spin_lock(&tomoyo_query_list_lock);
- list_for_each(tmp, &tomoyo_query_list) {
- struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
- if (pos++ != head->r.query_index)
- continue;
- /*
- * Some query can be skipped because tomoyo_query_list
- * can change, but I don't care.
- */
- if (len == ptr->query_len)
- snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
- ptr->retry, ptr->query);
- break;
- }
- spin_unlock(&tomoyo_query_list_lock);
- if (buf[0]) {
- head->read_buf = buf;
- head->r.w[head->r.w_pos++] = buf;
- head->r.query_index++;
- } else {
- kfree(buf);
- }
-}
-
-/**
- * tomoyo_write_answer - Write the supervisor's decision.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0 on success, -EINVAL otherwise.
- */
-static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
-{
- char *data = head->write_buf;
- struct list_head *tmp;
- unsigned int serial;
- unsigned int answer;
- spin_lock(&tomoyo_query_list_lock);
- list_for_each(tmp, &tomoyo_query_list) {
- struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
- ptr->timer = 0;
- }
- spin_unlock(&tomoyo_query_list_lock);
- if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
- return -EINVAL;
- spin_lock(&tomoyo_query_list_lock);
- list_for_each(tmp, &tomoyo_query_list) {
- struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
- if (ptr->serial != serial)
- continue;
- ptr->answer = answer;
- /* Remove from tomoyo_query_list. */
- if (ptr->answer)
- list_del_init(&ptr->list);
- break;
- }
- spin_unlock(&tomoyo_query_list_lock);
- return 0;
-}
-
-/**
- * tomoyo_read_version: Get version.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns version information.
- */
-static void tomoyo_read_version(struct tomoyo_io_buffer *head)
-{
- if (!head->r.eof) {
- tomoyo_io_printf(head, "2.5.0");
- head->r.eof = true;
- }
-}
-
-/* String table for /sys/kernel/security/tomoyo/stat interface. */
-static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = {
- [TOMOYO_STAT_POLICY_UPDATES] = "update:",
- [TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:",
- [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
- [TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:",
-};
-
-/* String table for /sys/kernel/security/tomoyo/stat interface. */
-static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = {
- [TOMOYO_MEMORY_POLICY] = "policy:",
- [TOMOYO_MEMORY_AUDIT] = "audit log:",
- [TOMOYO_MEMORY_QUERY] = "query message:",
-};
-
-/* Timestamp counter for last updated. */
-static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
-/* Counter for number of updates. */
-static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
-
-/**
- * tomoyo_update_stat - Update statistic counters.
- *
- * @index: Index for policy type.
- *
- * Returns nothing.
- */
-void tomoyo_update_stat(const u8 index)
-{
- struct timeval tv;
- do_gettimeofday(&tv);
- /*
- * I don't use atomic operations because race condition is not fatal.
- */
- tomoyo_stat_updated[index]++;
- tomoyo_stat_modified[index] = tv.tv_sec;
-}
-
-/**
- * tomoyo_read_stat - Read statistic data.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-static void tomoyo_read_stat(struct tomoyo_io_buffer *head)
-{
- u8 i;
- unsigned int total = 0;
- if (head->r.eof)
- return;
- for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) {
- tomoyo_io_printf(head, "Policy %-30s %10u",
- tomoyo_policy_headers[i],
- tomoyo_stat_updated[i]);
- if (tomoyo_stat_modified[i]) {
- struct tomoyo_time stamp;
- tomoyo_convert_time(tomoyo_stat_modified[i], &stamp);
- tomoyo_io_printf(head, " (Last: %04u/%02u/%02u "
- "%02u:%02u:%02u)",
- stamp.year, stamp.month, stamp.day,
- stamp.hour, stamp.min, stamp.sec);
- }
- tomoyo_set_lf(head);
- }
- for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) {
- unsigned int used = tomoyo_memory_used[i];
- total += used;
- tomoyo_io_printf(head, "Memory used by %-22s %10u",
- tomoyo_memory_headers[i], used);
- used = tomoyo_memory_quota[i];
- if (used)
- tomoyo_io_printf(head, " (Quota: %10u)", used);
- tomoyo_set_lf(head);
- }
- tomoyo_io_printf(head, "Total memory used: %10u\n",
- total);
- head->r.eof = true;
-}
-
-/**
- * tomoyo_write_stat - Set memory quota.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0.
- */
-static int tomoyo_write_stat(struct tomoyo_io_buffer *head)
-{
- char *data = head->write_buf;
- u8 i;
- if (tomoyo_str_starts(&data, "Memory used by "))
- for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++)
- if (tomoyo_str_starts(&data, tomoyo_memory_headers[i]))
- sscanf(data, "%u", &tomoyo_memory_quota[i]);
- return 0;
-}
-
-/**
- * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
- *
- * @type: Type of interface.
- * @file: Pointer to "struct file".
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_open_control(const u8 type, struct file *file)
-{
- struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS);
-
- if (!head)
- return -ENOMEM;
- mutex_init(&head->io_sem);
- head->type = type;
- switch (type) {
- case TOMOYO_DOMAINPOLICY:
- /* /sys/kernel/security/tomoyo/domain_policy */
- head->write = tomoyo_write_domain;
- head->read = tomoyo_read_domain;
- break;
- case TOMOYO_EXCEPTIONPOLICY:
- /* /sys/kernel/security/tomoyo/exception_policy */
- head->write = tomoyo_write_exception;
- head->read = tomoyo_read_exception;
- break;
- case TOMOYO_AUDIT:
- /* /sys/kernel/security/tomoyo/audit */
- head->poll = tomoyo_poll_log;
- head->read = tomoyo_read_log;
- break;
- case TOMOYO_PROCESS_STATUS:
- /* /sys/kernel/security/tomoyo/.process_status */
- head->write = tomoyo_write_pid;
- head->read = tomoyo_read_pid;
- break;
- case TOMOYO_VERSION:
- /* /sys/kernel/security/tomoyo/version */
- head->read = tomoyo_read_version;
- head->readbuf_size = 128;
- break;
- case TOMOYO_STAT:
- /* /sys/kernel/security/tomoyo/stat */
- head->write = tomoyo_write_stat;
- head->read = tomoyo_read_stat;
- head->readbuf_size = 1024;
- break;
- case TOMOYO_PROFILE:
- /* /sys/kernel/security/tomoyo/profile */
- head->write = tomoyo_write_profile;
- head->read = tomoyo_read_profile;
- break;
- case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */
- head->poll = tomoyo_poll_query;
- head->write = tomoyo_write_answer;
- head->read = tomoyo_read_query;
- break;
- case TOMOYO_MANAGER:
- /* /sys/kernel/security/tomoyo/manager */
- head->write = tomoyo_write_manager;
- head->read = tomoyo_read_manager;
- break;
- }
- if (!(file->f_mode & FMODE_READ)) {
- /*
- * No need to allocate read_buf since it is not opened
- * for reading.
- */
- head->read = NULL;
- head->poll = NULL;
- } else if (!head->poll) {
- /* Don't allocate read_buf for poll() access. */
- if (!head->readbuf_size)
- head->readbuf_size = 4096 * 2;
- head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS);
- if (!head->read_buf) {
- kfree(head);
- return -ENOMEM;
- }
- }
- if (!(file->f_mode & FMODE_WRITE)) {
- /*
- * No need to allocate write_buf since it is not opened
- * for writing.
- */
- head->write = NULL;
- } else if (head->write) {
- head->writebuf_size = 4096 * 2;
- head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS);
- if (!head->write_buf) {
- kfree(head->read_buf);
- kfree(head);
- return -ENOMEM;
- }
- }
- /*
- * If the file is /sys/kernel/security/tomoyo/query , increment the
- * observer counter.
- * The obserber counter is used by tomoyo_supervisor() to see if
- * there is some process monitoring /sys/kernel/security/tomoyo/query.
- */
- if (type == TOMOYO_QUERY)
- atomic_inc(&tomoyo_query_observers);
- file->private_data = head;
- tomoyo_notify_gc(head, true);
- return 0;
-}
-
-/**
- * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
- *
- * @file: Pointer to "struct file".
- * @wait: Pointer to "poll_table". Maybe NULL.
- *
- * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write,
- * POLLOUT | POLLWRNORM otherwise.
- */
-unsigned int tomoyo_poll_control(struct file *file, poll_table *wait)
-{
- struct tomoyo_io_buffer *head = file->private_data;
- if (head->poll)
- return head->poll(file, wait) | POLLOUT | POLLWRNORM;
- return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
-}
-
-/**
- * tomoyo_set_namespace_cursor - Set namespace to read.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns nothing.
- */
-static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head)
-{
- struct list_head *ns;
- if (head->type != TOMOYO_EXCEPTIONPOLICY &&
- head->type != TOMOYO_PROFILE)
- return;
- /*
- * If this is the first read, or reading previous namespace finished
- * and has more namespaces to read, update the namespace cursor.
- */
- ns = head->r.ns;
- if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) {
- /* Clearing is OK because tomoyo_flush() returned true. */
- memset(&head->r, 0, sizeof(head->r));
- head->r.ns = ns ? ns->next : tomoyo_namespace_list.next;
- }
-}
-
-/**
- * tomoyo_has_more_namespace - Check for unread namespaces.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns true if we have more entries to print, false otherwise.
- */
-static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
-{
- return (head->type == TOMOYO_EXCEPTIONPOLICY ||
- head->type == TOMOYO_PROFILE) && head->r.eof &&
- head->r.ns->next != &tomoyo_namespace_list;
-}
-
-/**
- * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @buffer: Poiner to buffer to write to.
- * @buffer_len: Size of @buffer.
- *
- * Returns bytes read on success, negative value otherwise.
- */
-ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
- const int buffer_len)
-{
- int len;
- int idx;
-
- if (!head->read)
- return -ENOSYS;
- if (mutex_lock_interruptible(&head->io_sem))
- return -EINTR;
- head->read_user_buf = buffer;
- head->read_user_buf_avail = buffer_len;
- idx = tomoyo_read_lock();
- if (tomoyo_flush(head))
- /* Call the policy handler. */
- do {
- tomoyo_set_namespace_cursor(head);
- head->read(head);
- } while (tomoyo_flush(head) &&
- tomoyo_has_more_namespace(head));
- tomoyo_read_unlock(idx);
- len = head->read_user_buf - buffer;
- mutex_unlock(&head->io_sem);
- return len;
-}
-
-/**
- * tomoyo_parse_policy - Parse a policy line.
- *
- * @head: Poiter to "struct tomoyo_io_buffer".
- * @line: Line to parse.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
-{
- /* Delete request? */
- head->w.is_delete = !strncmp(line, "delete ", 7);
- if (head->w.is_delete)
- memmove(line, line + 7, strlen(line + 7) + 1);
- /* Selecting namespace to update. */
- if (head->type == TOMOYO_EXCEPTIONPOLICY ||
- head->type == TOMOYO_PROFILE) {
- if (*line == '<') {
- char *cp = strchr(line, ' ');
- if (cp) {
- *cp++ = '\0';
- head->w.ns = tomoyo_assign_namespace(line);
- memmove(line, cp, strlen(cp) + 1);
- } else
- head->w.ns = NULL;
- } else
- head->w.ns = &tomoyo_kernel_namespace;
- /* Don't allow updating if namespace is invalid. */
- if (!head->w.ns)
- return -ENOENT;
- }
- /* Do the update. */
- return head->write(head);
-}
-
-/**
- * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @buffer: Pointer to buffer to read from.
- * @buffer_len: Size of @buffer.
- *
- * Returns @buffer_len on success, negative value otherwise.
- */
-ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
- const char __user *buffer, const int buffer_len)
-{
- int error = buffer_len;
- size_t avail_len = buffer_len;
- char *cp0 = head->write_buf;
- int idx;
- if (!head->write)
- return -ENOSYS;
- if (!access_ok(VERIFY_READ, buffer, buffer_len))
- return -EFAULT;
- if (mutex_lock_interruptible(&head->io_sem))
- return -EINTR;
- head->read_user_buf_avail = 0;
- idx = tomoyo_read_lock();
- /* Read a line and dispatch it to the policy handler. */
- while (avail_len > 0) {
- char c;
- if (head->w.avail >= head->writebuf_size - 1) {
- const int len = head->writebuf_size * 2;
- char *cp = kzalloc(len, GFP_NOFS);
- if (!cp) {
- error = -ENOMEM;
- break;
- }
- memmove(cp, cp0, head->w.avail);
- kfree(cp0);
- head->write_buf = cp;
- cp0 = cp;
- head->writebuf_size = len;
- }
- if (get_user(c, buffer)) {
- error = -EFAULT;
- break;
- }
- buffer++;
- avail_len--;
- cp0[head->w.avail++] = c;
- if (c != '\n')
- continue;
- cp0[head->w.avail - 1] = '\0';
- head->w.avail = 0;
- tomoyo_normalize_line(cp0);
- if (!strcmp(cp0, "reset")) {
- head->w.ns = &tomoyo_kernel_namespace;
- head->w.domain = NULL;
- memset(&head->r, 0, sizeof(head->r));
- continue;
- }
- /* Don't allow updating policies by non manager programs. */
- switch (head->type) {
- case TOMOYO_PROCESS_STATUS:
- /* This does not write anything. */
- break;
- case TOMOYO_DOMAINPOLICY:
- if (tomoyo_select_domain(head, cp0))
- continue;
- /* fall through */
- case TOMOYO_EXCEPTIONPOLICY:
- if (!strcmp(cp0, "select transition_only")) {
- head->r.print_transition_related_only = true;
- continue;
- }
- /* fall through */
- default:
- if (!tomoyo_manager()) {
- error = -EPERM;
- goto out;
- }
- }
- switch (tomoyo_parse_policy(head, cp0)) {
- case -EPERM:
- error = -EPERM;
- goto out;
- case 0:
- switch (head->type) {
- case TOMOYO_DOMAINPOLICY:
- case TOMOYO_EXCEPTIONPOLICY:
- case TOMOYO_STAT:
- case TOMOYO_PROFILE:
- case TOMOYO_MANAGER:
- tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
- break;
- default:
- break;
- }
- break;
- }
- }
-out:
- tomoyo_read_unlock(idx);
- mutex_unlock(&head->io_sem);
- return error;
-}
-
-/**
- * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0.
- */
-int tomoyo_close_control(struct tomoyo_io_buffer *head)
-{
- /*
- * If the file is /sys/kernel/security/tomoyo/query , decrement the
- * observer counter.
- */
- if (head->type == TOMOYO_QUERY &&
- atomic_dec_and_test(&tomoyo_query_observers))
- wake_up_all(&tomoyo_answer_wait);
- tomoyo_notify_gc(head, false);
- return 0;
-}
-
-/**
- * tomoyo_check_profile - Check all profiles currently assigned to domains are defined.
- */
-void tomoyo_check_profile(void)
-{
- struct tomoyo_domain_info *domain;
- const int idx = tomoyo_read_lock();
- tomoyo_policy_loaded = true;
- printk(KERN_INFO "TOMOYO: 2.5.0\n");
- list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
- const u8 profile = domain->profile;
- const struct tomoyo_policy_namespace *ns = domain->ns;
- if (ns->profile_version != 20110903)
- printk(KERN_ERR
- "Profile version %u is not supported.\n",
- ns->profile_version);
- else if (!ns->profile_ptr[profile])
- printk(KERN_ERR
- "Profile %u (used by '%s') is not defined.\n",
- profile, domain->domainname->name);
- else
- continue;
- printk(KERN_ERR
- "Userland tools for TOMOYO 2.5 must be installed and "
- "policy must be initialized.\n");
- printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.5/ "
- "for more information.\n");
- panic("STOP!");
- }
- tomoyo_read_unlock(idx);
- printk(KERN_INFO "Mandatory Access Control activated.\n");
-}
-
-/**
- * tomoyo_load_builtin_policy - Load built-in policy.
- *
- * Returns nothing.
- */
-void __init tomoyo_load_builtin_policy(void)
-{
- /*
- * This include file is manually created and contains built-in policy
- * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy",
- * "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager",
- * "tomoyo_builtin_stat" in the form of "static char [] __initdata".
- */
-#include "builtin-policy.h"
- u8 i;
- const int idx = tomoyo_read_lock();
- for (i = 0; i < 5; i++) {
- struct tomoyo_io_buffer head = { };
- char *start = "";
- switch (i) {
- case 0:
- start = tomoyo_builtin_profile;
- head.type = TOMOYO_PROFILE;
- head.write = tomoyo_write_profile;
- break;
- case 1:
- start = tomoyo_builtin_exception_policy;
- head.type = TOMOYO_EXCEPTIONPOLICY;
- head.write = tomoyo_write_exception;
- break;
- case 2:
- start = tomoyo_builtin_domain_policy;
- head.type = TOMOYO_DOMAINPOLICY;
- head.write = tomoyo_write_domain;
- break;
- case 3:
- start = tomoyo_builtin_manager;
- head.type = TOMOYO_MANAGER;
- head.write = tomoyo_write_manager;
- break;
- case 4:
- start = tomoyo_builtin_stat;
- head.type = TOMOYO_STAT;
- head.write = tomoyo_write_stat;
- break;
- }
- while (1) {
- char *end = strchr(start, '\n');
- if (!end)
- break;
- *end = '\0';
- tomoyo_normalize_line(start);
- head.write_buf = start;
- tomoyo_parse_policy(&head, start);
- start = end + 1;
- }
- }
- tomoyo_read_unlock(idx);
-#ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
- tomoyo_check_profile();
-#endif
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/common.h b/ANDROID_3.4.5/security/tomoyo/common.h
deleted file mode 100644
index 30fd9836..00000000
--- a/ANDROID_3.4.5/security/tomoyo/common.h
+++ /dev/null
@@ -1,1331 +0,0 @@
-/*
- * security/tomoyo/common.h
- *
- * Header file for TOMOYO.
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#ifndef _SECURITY_TOMOYO_COMMON_H
-#define _SECURITY_TOMOYO_COMMON_H
-
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/file.h>
-#include <linux/kmod.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/namei.h>
-#include <linux/mount.h>
-#include <linux/list.h>
-#include <linux/cred.h>
-#include <linux/poll.h>
-#include <linux/binfmts.h>
-#include <linux/highmem.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/un.h>
-#include <net/sock.h>
-#include <net/af_unix.h>
-#include <net/ip.h>
-#include <net/ipv6.h>
-#include <net/udp.h>
-
-/********** Constants definitions. **********/
-
-/*
- * TOMOYO uses this hash only when appending a string into the string
- * table. Frequency of appending strings is very low. So we don't need
- * large (e.g. 64k) hash size. 256 will be sufficient.
- */
-#define TOMOYO_HASH_BITS 8
-#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
-
-/*
- * TOMOYO checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET.
- * Therefore, we don't need SOCK_MAX.
- */
-#define TOMOYO_SOCK_MAX 6
-
-#define TOMOYO_EXEC_TMPSIZE 4096
-
-/* Garbage collector is trying to kfree() this element. */
-#define TOMOYO_GC_IN_PROGRESS -1
-
-/* Profile number is an integer between 0 and 255. */
-#define TOMOYO_MAX_PROFILES 256
-
-/* Group number is an integer between 0 and 255. */
-#define TOMOYO_MAX_ACL_GROUPS 256
-
-/* Index numbers for "struct tomoyo_condition". */
-enum tomoyo_conditions_index {
- TOMOYO_TASK_UID, /* current_uid() */
- TOMOYO_TASK_EUID, /* current_euid() */
- TOMOYO_TASK_SUID, /* current_suid() */
- TOMOYO_TASK_FSUID, /* current_fsuid() */
- TOMOYO_TASK_GID, /* current_gid() */
- TOMOYO_TASK_EGID, /* current_egid() */
- TOMOYO_TASK_SGID, /* current_sgid() */
- TOMOYO_TASK_FSGID, /* current_fsgid() */
- TOMOYO_TASK_PID, /* sys_getpid() */
- TOMOYO_TASK_PPID, /* sys_getppid() */
- TOMOYO_EXEC_ARGC, /* "struct linux_binprm *"->argc */
- TOMOYO_EXEC_ENVC, /* "struct linux_binprm *"->envc */
- TOMOYO_TYPE_IS_SOCKET, /* S_IFSOCK */
- TOMOYO_TYPE_IS_SYMLINK, /* S_IFLNK */
- TOMOYO_TYPE_IS_FILE, /* S_IFREG */
- TOMOYO_TYPE_IS_BLOCK_DEV, /* S_IFBLK */
- TOMOYO_TYPE_IS_DIRECTORY, /* S_IFDIR */
- TOMOYO_TYPE_IS_CHAR_DEV, /* S_IFCHR */
- TOMOYO_TYPE_IS_FIFO, /* S_IFIFO */
- TOMOYO_MODE_SETUID, /* S_ISUID */
- TOMOYO_MODE_SETGID, /* S_ISGID */
- TOMOYO_MODE_STICKY, /* S_ISVTX */
- TOMOYO_MODE_OWNER_READ, /* S_IRUSR */
- TOMOYO_MODE_OWNER_WRITE, /* S_IWUSR */
- TOMOYO_MODE_OWNER_EXECUTE, /* S_IXUSR */
- TOMOYO_MODE_GROUP_READ, /* S_IRGRP */
- TOMOYO_MODE_GROUP_WRITE, /* S_IWGRP */
- TOMOYO_MODE_GROUP_EXECUTE, /* S_IXGRP */
- TOMOYO_MODE_OTHERS_READ, /* S_IROTH */
- TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */
- TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */
- TOMOYO_EXEC_REALPATH,
- TOMOYO_SYMLINK_TARGET,
- TOMOYO_PATH1_UID,
- TOMOYO_PATH1_GID,
- TOMOYO_PATH1_INO,
- TOMOYO_PATH1_MAJOR,
- TOMOYO_PATH1_MINOR,
- TOMOYO_PATH1_PERM,
- TOMOYO_PATH1_TYPE,
- TOMOYO_PATH1_DEV_MAJOR,
- TOMOYO_PATH1_DEV_MINOR,
- TOMOYO_PATH2_UID,
- TOMOYO_PATH2_GID,
- TOMOYO_PATH2_INO,
- TOMOYO_PATH2_MAJOR,
- TOMOYO_PATH2_MINOR,
- TOMOYO_PATH2_PERM,
- TOMOYO_PATH2_TYPE,
- TOMOYO_PATH2_DEV_MAJOR,
- TOMOYO_PATH2_DEV_MINOR,
- TOMOYO_PATH1_PARENT_UID,
- TOMOYO_PATH1_PARENT_GID,
- TOMOYO_PATH1_PARENT_INO,
- TOMOYO_PATH1_PARENT_PERM,
- TOMOYO_PATH2_PARENT_UID,
- TOMOYO_PATH2_PARENT_GID,
- TOMOYO_PATH2_PARENT_INO,
- TOMOYO_PATH2_PARENT_PERM,
- TOMOYO_MAX_CONDITION_KEYWORD,
- TOMOYO_NUMBER_UNION,
- TOMOYO_NAME_UNION,
- TOMOYO_ARGV_ENTRY,
- TOMOYO_ENVP_ENTRY,
-};
-
-
-/* Index numbers for stat(). */
-enum tomoyo_path_stat_index {
- /* Do not change this order. */
- TOMOYO_PATH1,
- TOMOYO_PATH1_PARENT,
- TOMOYO_PATH2,
- TOMOYO_PATH2_PARENT,
- TOMOYO_MAX_PATH_STAT
-};
-
-/* Index numbers for operation mode. */
-enum tomoyo_mode_index {
- TOMOYO_CONFIG_DISABLED,
- TOMOYO_CONFIG_LEARNING,
- TOMOYO_CONFIG_PERMISSIVE,
- TOMOYO_CONFIG_ENFORCING,
- TOMOYO_CONFIG_MAX_MODE,
- TOMOYO_CONFIG_WANT_REJECT_LOG = 64,
- TOMOYO_CONFIG_WANT_GRANT_LOG = 128,
- TOMOYO_CONFIG_USE_DEFAULT = 255,
-};
-
-/* Index numbers for entry type. */
-enum tomoyo_policy_id {
- TOMOYO_ID_GROUP,
- TOMOYO_ID_ADDRESS_GROUP,
- TOMOYO_ID_PATH_GROUP,
- TOMOYO_ID_NUMBER_GROUP,
- TOMOYO_ID_TRANSITION_CONTROL,
- TOMOYO_ID_AGGREGATOR,
- TOMOYO_ID_MANAGER,
- TOMOYO_ID_CONDITION,
- TOMOYO_ID_NAME,
- TOMOYO_ID_ACL,
- TOMOYO_ID_DOMAIN,
- TOMOYO_MAX_POLICY
-};
-
-/* Index numbers for domain's attributes. */
-enum tomoyo_domain_info_flags_index {
- /* Quota warnning flag. */
- TOMOYO_DIF_QUOTA_WARNED,
- /*
- * This domain was unable to create a new domain at
- * tomoyo_find_next_domain() because the name of the domain to be
- * created was too long or it could not allocate memory.
- * More than one process continued execve() without domain transition.
- */
- TOMOYO_DIF_TRANSITION_FAILED,
- TOMOYO_MAX_DOMAIN_INFO_FLAGS
-};
-
-/* Index numbers for audit type. */
-enum tomoyo_grant_log {
- /* Follow profile's configuration. */
- TOMOYO_GRANTLOG_AUTO,
- /* Do not generate grant log. */
- TOMOYO_GRANTLOG_NO,
- /* Generate grant_log. */
- TOMOYO_GRANTLOG_YES,
-};
-
-/* Index numbers for group entries. */
-enum tomoyo_group_id {
- TOMOYO_PATH_GROUP,
- TOMOYO_NUMBER_GROUP,
- TOMOYO_ADDRESS_GROUP,
- TOMOYO_MAX_GROUP
-};
-
-/* Index numbers for type of numeric values. */
-enum tomoyo_value_type {
- TOMOYO_VALUE_TYPE_INVALID,
- TOMOYO_VALUE_TYPE_DECIMAL,
- TOMOYO_VALUE_TYPE_OCTAL,
- TOMOYO_VALUE_TYPE_HEXADECIMAL,
-};
-
-/* Index numbers for domain transition control keywords. */
-enum tomoyo_transition_type {
- /* Do not change this order, */
- TOMOYO_TRANSITION_CONTROL_NO_RESET,
- TOMOYO_TRANSITION_CONTROL_RESET,
- TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE,
- TOMOYO_TRANSITION_CONTROL_INITIALIZE,
- TOMOYO_TRANSITION_CONTROL_NO_KEEP,
- TOMOYO_TRANSITION_CONTROL_KEEP,
- TOMOYO_MAX_TRANSITION_TYPE
-};
-
-/* Index numbers for Access Controls. */
-enum tomoyo_acl_entry_type_index {
- TOMOYO_TYPE_PATH_ACL,
- TOMOYO_TYPE_PATH2_ACL,
- TOMOYO_TYPE_PATH_NUMBER_ACL,
- TOMOYO_TYPE_MKDEV_ACL,
- TOMOYO_TYPE_MOUNT_ACL,
- TOMOYO_TYPE_INET_ACL,
- TOMOYO_TYPE_UNIX_ACL,
- TOMOYO_TYPE_ENV_ACL,
- TOMOYO_TYPE_MANUAL_TASK_ACL,
-};
-
-/* Index numbers for access controls with one pathname. */
-enum tomoyo_path_acl_index {
- TOMOYO_TYPE_EXECUTE,
- TOMOYO_TYPE_READ,
- TOMOYO_TYPE_WRITE,
- TOMOYO_TYPE_APPEND,
- TOMOYO_TYPE_UNLINK,
- TOMOYO_TYPE_GETATTR,
- TOMOYO_TYPE_RMDIR,
- TOMOYO_TYPE_TRUNCATE,
- TOMOYO_TYPE_SYMLINK,
- TOMOYO_TYPE_CHROOT,
- TOMOYO_TYPE_UMOUNT,
- TOMOYO_MAX_PATH_OPERATION
-};
-
-/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
-enum tomoyo_memory_stat_type {
- TOMOYO_MEMORY_POLICY,
- TOMOYO_MEMORY_AUDIT,
- TOMOYO_MEMORY_QUERY,
- TOMOYO_MAX_MEMORY_STAT
-};
-
-enum tomoyo_mkdev_acl_index {
- TOMOYO_TYPE_MKBLOCK,
- TOMOYO_TYPE_MKCHAR,
- TOMOYO_MAX_MKDEV_OPERATION
-};
-
-/* Index numbers for socket operations. */
-enum tomoyo_network_acl_index {
- TOMOYO_NETWORK_BIND, /* bind() operation. */
- TOMOYO_NETWORK_LISTEN, /* listen() operation. */
- TOMOYO_NETWORK_CONNECT, /* connect() operation. */
- TOMOYO_NETWORK_SEND, /* send() operation. */
- TOMOYO_MAX_NETWORK_OPERATION
-};
-
-/* Index numbers for access controls with two pathnames. */
-enum tomoyo_path2_acl_index {
- TOMOYO_TYPE_LINK,
- TOMOYO_TYPE_RENAME,
- TOMOYO_TYPE_PIVOT_ROOT,
- TOMOYO_MAX_PATH2_OPERATION
-};
-
-/* Index numbers for access controls with one pathname and one number. */
-enum tomoyo_path_number_acl_index {
- TOMOYO_TYPE_CREATE,
- TOMOYO_TYPE_MKDIR,
- TOMOYO_TYPE_MKFIFO,
- TOMOYO_TYPE_MKSOCK,
- TOMOYO_TYPE_IOCTL,
- TOMOYO_TYPE_CHMOD,
- TOMOYO_TYPE_CHOWN,
- TOMOYO_TYPE_CHGRP,
- TOMOYO_MAX_PATH_NUMBER_OPERATION
-};
-
-/* Index numbers for /sys/kernel/security/tomoyo/ interfaces. */
-enum tomoyo_securityfs_interface_index {
- TOMOYO_DOMAINPOLICY,
- TOMOYO_EXCEPTIONPOLICY,
- TOMOYO_PROCESS_STATUS,
- TOMOYO_STAT,
- TOMOYO_AUDIT,
- TOMOYO_VERSION,
- TOMOYO_PROFILE,
- TOMOYO_QUERY,
- TOMOYO_MANAGER
-};
-
-/* Index numbers for special mount operations. */
-enum tomoyo_special_mount {
- TOMOYO_MOUNT_BIND, /* mount --bind /source /dest */
- TOMOYO_MOUNT_MOVE, /* mount --move /old /new */
- TOMOYO_MOUNT_REMOUNT, /* mount -o remount /dir */
- TOMOYO_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */
- TOMOYO_MOUNT_MAKE_PRIVATE, /* mount --make-private /dir */
- TOMOYO_MOUNT_MAKE_SLAVE, /* mount --make-slave /dir */
- TOMOYO_MOUNT_MAKE_SHARED, /* mount --make-shared /dir */
- TOMOYO_MAX_SPECIAL_MOUNT
-};
-
-/* Index numbers for functionality. */
-enum tomoyo_mac_index {
- TOMOYO_MAC_FILE_EXECUTE,
- TOMOYO_MAC_FILE_OPEN,
- TOMOYO_MAC_FILE_CREATE,
- TOMOYO_MAC_FILE_UNLINK,
- TOMOYO_MAC_FILE_GETATTR,
- TOMOYO_MAC_FILE_MKDIR,
- TOMOYO_MAC_FILE_RMDIR,
- TOMOYO_MAC_FILE_MKFIFO,
- TOMOYO_MAC_FILE_MKSOCK,
- TOMOYO_MAC_FILE_TRUNCATE,
- TOMOYO_MAC_FILE_SYMLINK,
- TOMOYO_MAC_FILE_MKBLOCK,
- TOMOYO_MAC_FILE_MKCHAR,
- TOMOYO_MAC_FILE_LINK,
- TOMOYO_MAC_FILE_RENAME,
- TOMOYO_MAC_FILE_CHMOD,
- TOMOYO_MAC_FILE_CHOWN,
- TOMOYO_MAC_FILE_CHGRP,
- TOMOYO_MAC_FILE_IOCTL,
- TOMOYO_MAC_FILE_CHROOT,
- TOMOYO_MAC_FILE_MOUNT,
- TOMOYO_MAC_FILE_UMOUNT,
- TOMOYO_MAC_FILE_PIVOT_ROOT,
- TOMOYO_MAC_NETWORK_INET_STREAM_BIND,
- TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN,
- TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT,
- TOMOYO_MAC_NETWORK_INET_DGRAM_BIND,
- TOMOYO_MAC_NETWORK_INET_DGRAM_SEND,
- TOMOYO_MAC_NETWORK_INET_RAW_BIND,
- TOMOYO_MAC_NETWORK_INET_RAW_SEND,
- TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND,
- TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN,
- TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT,
- TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND,
- TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND,
- TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND,
- TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
- TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
- TOMOYO_MAC_ENVIRON,
- TOMOYO_MAX_MAC_INDEX
-};
-
-/* Index numbers for category of functionality. */
-enum tomoyo_mac_category_index {
- TOMOYO_MAC_CATEGORY_FILE,
- TOMOYO_MAC_CATEGORY_NETWORK,
- TOMOYO_MAC_CATEGORY_MISC,
- TOMOYO_MAX_MAC_CATEGORY_INDEX
-};
-
-/*
- * Retry this request. Returned by tomoyo_supervisor() if policy violation has
- * occurred in enforcing mode and the userspace daemon decided to retry.
- *
- * We must choose a positive value in order to distinguish "granted" (which is
- * 0) and "rejected" (which is a negative value) and "retry".
- */
-#define TOMOYO_RETRY_REQUEST 1
-
-/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
-enum tomoyo_policy_stat_type {
- /* Do not change this order. */
- TOMOYO_STAT_POLICY_UPDATES,
- TOMOYO_STAT_POLICY_LEARNING, /* == TOMOYO_CONFIG_LEARNING */
- TOMOYO_STAT_POLICY_PERMISSIVE, /* == TOMOYO_CONFIG_PERMISSIVE */
- TOMOYO_STAT_POLICY_ENFORCING, /* == TOMOYO_CONFIG_ENFORCING */
- TOMOYO_MAX_POLICY_STAT
-};
-
-/* Index numbers for profile's PREFERENCE values. */
-enum tomoyo_pref_index {
- TOMOYO_PREF_MAX_AUDIT_LOG,
- TOMOYO_PREF_MAX_LEARNING_ENTRY,
- TOMOYO_MAX_PREF
-};
-
-/********** Structure definitions. **********/
-
-/* Common header for holding ACL entries. */
-struct tomoyo_acl_head {
- struct list_head list;
- s8 is_deleted; /* true or false or TOMOYO_GC_IN_PROGRESS */
-} __packed;
-
-/* Common header for shared entries. */
-struct tomoyo_shared_acl_head {
- struct list_head list;
- atomic_t users;
-} __packed;
-
-struct tomoyo_policy_namespace;
-
-/* Structure for request info. */
-struct tomoyo_request_info {
- /*
- * For holding parameters specific to operations which deal files.
- * NULL if not dealing files.
- */
- struct tomoyo_obj_info *obj;
- /*
- * For holding parameters specific to execve() request.
- * NULL if not dealing do_execve().
- */
- struct tomoyo_execve *ee;
- struct tomoyo_domain_info *domain;
- /* For holding parameters. */
- union {
- struct {
- const struct tomoyo_path_info *filename;
- /* For using wildcards at tomoyo_find_next_domain(). */
- const struct tomoyo_path_info *matched_path;
- /* One of values in "enum tomoyo_path_acl_index". */
- u8 operation;
- } path;
- struct {
- const struct tomoyo_path_info *filename1;
- const struct tomoyo_path_info *filename2;
- /* One of values in "enum tomoyo_path2_acl_index". */
- u8 operation;
- } path2;
- struct {
- const struct tomoyo_path_info *filename;
- unsigned int mode;
- unsigned int major;
- unsigned int minor;
- /* One of values in "enum tomoyo_mkdev_acl_index". */
- u8 operation;
- } mkdev;
- struct {
- const struct tomoyo_path_info *filename;
- unsigned long number;
- /*
- * One of values in
- * "enum tomoyo_path_number_acl_index".
- */
- u8 operation;
- } path_number;
- struct {
- const struct tomoyo_path_info *name;
- } environ;
- struct {
- const __be32 *address;
- u16 port;
- /* One of values smaller than TOMOYO_SOCK_MAX. */
- u8 protocol;
- /* One of values in "enum tomoyo_network_acl_index". */
- u8 operation;
- bool is_ipv6;
- } inet_network;
- struct {
- const struct tomoyo_path_info *address;
- /* One of values smaller than TOMOYO_SOCK_MAX. */
- u8 protocol;
- /* One of values in "enum tomoyo_network_acl_index". */
- u8 operation;
- } unix_network;
- struct {
- const struct tomoyo_path_info *type;
- const struct tomoyo_path_info *dir;
- const struct tomoyo_path_info *dev;
- unsigned long flags;
- int need_dev;
- } mount;
- struct {
- const struct tomoyo_path_info *domainname;
- } task;
- } param;
- struct tomoyo_acl_info *matched_acl;
- u8 param_type;
- bool granted;
- u8 retry;
- u8 profile;
- u8 mode; /* One of tomoyo_mode_index . */
- u8 type;
-};
-
-/* Structure for holding a token. */
-struct tomoyo_path_info {
- const char *name;
- u32 hash; /* = full_name_hash(name, strlen(name)) */
- u16 const_len; /* = tomoyo_const_part_length(name) */
- bool is_dir; /* = tomoyo_strendswith(name, "/") */
- bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
-};
-
-/* Structure for holding string data. */
-struct tomoyo_name {
- struct tomoyo_shared_acl_head head;
- struct tomoyo_path_info entry;
-};
-
-/* Structure for holding a word. */
-struct tomoyo_name_union {
- /* Either @filename or @group is NULL. */
- const struct tomoyo_path_info *filename;
- struct tomoyo_group *group;
-};
-
-/* Structure for holding a number. */
-struct tomoyo_number_union {
- unsigned long values[2];
- struct tomoyo_group *group; /* Maybe NULL. */
- /* One of values in "enum tomoyo_value_type". */
- u8 value_type[2];
-};
-
-/* Structure for holding an IP address. */
-struct tomoyo_ipaddr_union {
- struct in6_addr ip[2]; /* Big endian. */
- struct tomoyo_group *group; /* Pointer to address group. */
- bool is_ipv6; /* Valid only if @group == NULL. */
-};
-
-/* Structure for "path_group"/"number_group"/"address_group" directive. */
-struct tomoyo_group {
- struct tomoyo_shared_acl_head head;
- const struct tomoyo_path_info *group_name;
- struct list_head member_list;
-};
-
-/* Structure for "path_group" directive. */
-struct tomoyo_path_group {
- struct tomoyo_acl_head head;
- const struct tomoyo_path_info *member_name;
-};
-
-/* Structure for "number_group" directive. */
-struct tomoyo_number_group {
- struct tomoyo_acl_head head;
- struct tomoyo_number_union number;
-};
-
-/* Structure for "address_group" directive. */
-struct tomoyo_address_group {
- struct tomoyo_acl_head head;
- /* Structure for holding an IP address. */
- struct tomoyo_ipaddr_union address;
-};
-
-/* Subset of "struct stat". Used by conditional ACL and audit logs. */
-struct tomoyo_mini_stat {
- uid_t uid;
- gid_t gid;
- ino_t ino;
- umode_t mode;
- dev_t dev;
- dev_t rdev;
-};
-
-/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
-struct tomoyo_page_dump {
- struct page *page; /* Previously dumped page. */
- char *data; /* Contents of "page". Size is PAGE_SIZE. */
-};
-
-/* Structure for attribute checks in addition to pathname checks. */
-struct tomoyo_obj_info {
- /*
- * True if tomoyo_get_attributes() was already called, false otherwise.
- */
- bool validate_done;
- /* True if @stat[] is valid. */
- bool stat_valid[TOMOYO_MAX_PATH_STAT];
- /* First pathname. Initialized with { NULL, NULL } if no path. */
- struct path path1;
- /* Second pathname. Initialized with { NULL, NULL } if no path. */
- struct path path2;
- /*
- * Information on @path1, @path1's parent directory, @path2, @path2's
- * parent directory.
- */
- struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT];
- /*
- * Content of symbolic link to be created. NULL for operations other
- * than symlink().
- */
- struct tomoyo_path_info *symlink_target;
-};
-
-/* Structure for argv[]. */
-struct tomoyo_argv {
- unsigned long index;
- const struct tomoyo_path_info *value;
- bool is_not;
-};
-
-/* Structure for envp[]. */
-struct tomoyo_envp {
- const struct tomoyo_path_info *name;
- const struct tomoyo_path_info *value;
- bool is_not;
-};
-
-/* Structure for execve() operation. */
-struct tomoyo_execve {
- struct tomoyo_request_info r;
- struct tomoyo_obj_info obj;
- struct linux_binprm *bprm;
- const struct tomoyo_path_info *transition;
- /* For dumping argv[] and envp[]. */
- struct tomoyo_page_dump dump;
- /* For temporary use. */
- char *tmp; /* Size is TOMOYO_EXEC_TMPSIZE bytes */
-};
-
-/* Structure for entries which follows "struct tomoyo_condition". */
-struct tomoyo_condition_element {
- /*
- * Left hand operand. A "struct tomoyo_argv" for TOMOYO_ARGV_ENTRY, a
- * "struct tomoyo_envp" for TOMOYO_ENVP_ENTRY is attached to the tail
- * of the array of this struct.
- */
- u8 left;
- /*
- * Right hand operand. A "struct tomoyo_number_union" for
- * TOMOYO_NUMBER_UNION, a "struct tomoyo_name_union" for
- * TOMOYO_NAME_UNION is attached to the tail of the array of this
- * struct.
- */
- u8 right;
- /* Equation operator. True if equals or overlaps, false otherwise. */
- bool equals;
-};
-
-/* Structure for optional arguments. */
-struct tomoyo_condition {
- struct tomoyo_shared_acl_head head;
- u32 size; /* Memory size allocated for this entry. */
- u16 condc; /* Number of conditions in this struct. */
- u16 numbers_count; /* Number of "struct tomoyo_number_union values". */
- u16 names_count; /* Number of "struct tomoyo_name_union names". */
- u16 argc; /* Number of "struct tomoyo_argv". */
- u16 envc; /* Number of "struct tomoyo_envp". */
- u8 grant_log; /* One of values in "enum tomoyo_grant_log". */
- const struct tomoyo_path_info *transit; /* Maybe NULL. */
- /*
- * struct tomoyo_condition_element condition[condc];
- * struct tomoyo_number_union values[numbers_count];
- * struct tomoyo_name_union names[names_count];
- * struct tomoyo_argv argv[argc];
- * struct tomoyo_envp envp[envc];
- */
-};
-
-/* Common header for individual entries. */
-struct tomoyo_acl_info {
- struct list_head list;
- struct tomoyo_condition *cond; /* Maybe NULL. */
- s8 is_deleted; /* true or false or TOMOYO_GC_IN_PROGRESS */
- u8 type; /* One of values in "enum tomoyo_acl_entry_type_index". */
-} __packed;
-
-/* Structure for domain information. */
-struct tomoyo_domain_info {
- struct list_head list;
- struct list_head acl_info_list;
- /* Name of this domain. Never NULL. */
- const struct tomoyo_path_info *domainname;
- /* Namespace for this domain. Never NULL. */
- struct tomoyo_policy_namespace *ns;
- u8 profile; /* Profile number to use. */
- u8 group; /* Group number to use. */
- bool is_deleted; /* Delete flag. */
- bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
- atomic_t users; /* Number of referring credentials. */
-};
-
-/*
- * Structure for "task manual_domain_transition" directive.
- */
-struct tomoyo_task_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MANUAL_TASK_ACL */
- /* Pointer to domainname. */
- const struct tomoyo_path_info *domainname;
-};
-
-/*
- * Structure for "file execute", "file read", "file write", "file append",
- * "file unlink", "file getattr", "file rmdir", "file truncate",
- * "file symlink", "file chroot" and "file unmount" directive.
- */
-struct tomoyo_path_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
- u16 perm; /* Bitmask of values in "enum tomoyo_path_acl_index". */
- struct tomoyo_name_union name;
-};
-
-/*
- * Structure for "file create", "file mkdir", "file mkfifo", "file mksock",
- * "file ioctl", "file chmod", "file chown" and "file chgrp" directive.
- */
-struct tomoyo_path_number_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_NUMBER_ACL */
- /* Bitmask of values in "enum tomoyo_path_number_acl_index". */
- u8 perm;
- struct tomoyo_name_union name;
- struct tomoyo_number_union number;
-};
-
-/* Structure for "file mkblock" and "file mkchar" directive. */
-struct tomoyo_mkdev_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MKDEV_ACL */
- u8 perm; /* Bitmask of values in "enum tomoyo_mkdev_acl_index". */
- struct tomoyo_name_union name;
- struct tomoyo_number_union mode;
- struct tomoyo_number_union major;
- struct tomoyo_number_union minor;
-};
-
-/*
- * Structure for "file rename", "file link" and "file pivot_root" directive.
- */
-struct tomoyo_path2_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */
- u8 perm; /* Bitmask of values in "enum tomoyo_path2_acl_index". */
- struct tomoyo_name_union name1;
- struct tomoyo_name_union name2;
-};
-
-/* Structure for "file mount" directive. */
-struct tomoyo_mount_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MOUNT_ACL */
- struct tomoyo_name_union dev_name;
- struct tomoyo_name_union dir_name;
- struct tomoyo_name_union fs_type;
- struct tomoyo_number_union flags;
-};
-
-/* Structure for "misc env" directive in domain policy. */
-struct tomoyo_env_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_ENV_ACL */
- const struct tomoyo_path_info *env; /* environment variable */
-};
-
-/* Structure for "network inet" directive. */
-struct tomoyo_inet_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_INET_ACL */
- u8 protocol;
- u8 perm; /* Bitmask of values in "enum tomoyo_network_acl_index" */
- struct tomoyo_ipaddr_union address;
- struct tomoyo_number_union port;
-};
-
-/* Structure for "network unix" directive. */
-struct tomoyo_unix_acl {
- struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_UNIX_ACL */
- u8 protocol;
- u8 perm; /* Bitmask of values in "enum tomoyo_network_acl_index" */
- struct tomoyo_name_union name;
-};
-
-/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */
-struct tomoyo_acl_param {
- char *data;
- struct list_head *list;
- struct tomoyo_policy_namespace *ns;
- bool is_delete;
-};
-
-#define TOMOYO_MAX_IO_READ_QUEUE 64
-
-/*
- * Structure for reading/writing policy via /sys/kernel/security/tomoyo
- * interfaces.
- */
-struct tomoyo_io_buffer {
- void (*read) (struct tomoyo_io_buffer *);
- int (*write) (struct tomoyo_io_buffer *);
- unsigned int (*poll) (struct file *file, poll_table *wait);
- /* Exclusive lock for this structure. */
- struct mutex io_sem;
- char __user *read_user_buf;
- size_t read_user_buf_avail;
- struct {
- struct list_head *ns;
- struct list_head *domain;
- struct list_head *group;
- struct list_head *acl;
- size_t avail;
- unsigned int step;
- unsigned int query_index;
- u16 index;
- u16 cond_index;
- u8 acl_group_index;
- u8 cond_step;
- u8 bit;
- u8 w_pos;
- bool eof;
- bool print_this_domain_only;
- bool print_transition_related_only;
- bool print_cond_part;
- const char *w[TOMOYO_MAX_IO_READ_QUEUE];
- } r;
- struct {
- struct tomoyo_policy_namespace *ns;
- /* The position currently writing to. */
- struct tomoyo_domain_info *domain;
- /* Bytes available for writing. */
- size_t avail;
- bool is_delete;
- } w;
- /* Buffer for reading. */
- char *read_buf;
- /* Size of read buffer. */
- size_t readbuf_size;
- /* Buffer for writing. */
- char *write_buf;
- /* Size of write buffer. */
- size_t writebuf_size;
- /* Type of this interface. */
- enum tomoyo_securityfs_interface_index type;
- /* Users counter protected by tomoyo_io_buffer_list_lock. */
- u8 users;
- /* List for telling GC not to kfree() elements. */
- struct list_head list;
-};
-
-/*
- * Structure for "initialize_domain"/"no_initialize_domain"/"keep_domain"/
- * "no_keep_domain" keyword.
- */
-struct tomoyo_transition_control {
- struct tomoyo_acl_head head;
- u8 type; /* One of values in "enum tomoyo_transition_type". */
- /* True if the domainname is tomoyo_get_last_name(). */
- bool is_last_name;
- const struct tomoyo_path_info *domainname; /* Maybe NULL */
- const struct tomoyo_path_info *program; /* Maybe NULL */
-};
-
-/* Structure for "aggregator" keyword. */
-struct tomoyo_aggregator {
- struct tomoyo_acl_head head;
- const struct tomoyo_path_info *original_name;
- const struct tomoyo_path_info *aggregated_name;
-};
-
-/* Structure for policy manager. */
-struct tomoyo_manager {
- struct tomoyo_acl_head head;
- bool is_domain; /* True if manager is a domainname. */
- /* A path to program or a domainname. */
- const struct tomoyo_path_info *manager;
-};
-
-struct tomoyo_preference {
- unsigned int learning_max_entry;
- bool enforcing_verbose;
- bool learning_verbose;
- bool permissive_verbose;
-};
-
-/* Structure for /sys/kernel/security/tomnoyo/profile interface. */
-struct tomoyo_profile {
- const struct tomoyo_path_info *comment;
- struct tomoyo_preference *learning;
- struct tomoyo_preference *permissive;
- struct tomoyo_preference *enforcing;
- struct tomoyo_preference preference;
- u8 default_config;
- u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX];
- unsigned int pref[TOMOYO_MAX_PREF];
-};
-
-/* Structure for representing YYYY/MM/DD hh/mm/ss. */
-struct tomoyo_time {
- u16 year;
- u8 month;
- u8 day;
- u8 hour;
- u8 min;
- u8 sec;
-};
-
-/* Structure for policy namespace. */
-struct tomoyo_policy_namespace {
- /* Profile table. Memory is allocated as needed. */
- struct tomoyo_profile *profile_ptr[TOMOYO_MAX_PROFILES];
- /* List of "struct tomoyo_group". */
- struct list_head group_list[TOMOYO_MAX_GROUP];
- /* List of policy. */
- struct list_head policy_list[TOMOYO_MAX_POLICY];
- /* The global ACL referred by "use_group" keyword. */
- struct list_head acl_group[TOMOYO_MAX_ACL_GROUPS];
- /* List for connecting to tomoyo_namespace_list list. */
- struct list_head namespace_list;
- /* Profile version. Currently only 20110903 is defined. */
- unsigned int profile_version;
- /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
- const char *name;
-};
-
-/********** Function prototypes. **********/
-
-bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
- const struct tomoyo_group *group);
-bool tomoyo_compare_number_union(const unsigned long value,
- const struct tomoyo_number_union *ptr);
-bool tomoyo_condition(struct tomoyo_request_info *r,
- const struct tomoyo_condition *cond);
-bool tomoyo_correct_domain(const unsigned char *domainname);
-bool tomoyo_correct_path(const char *filename);
-bool tomoyo_correct_word(const char *string);
-bool tomoyo_domain_def(const unsigned char *buffer);
-bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
-bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
- struct tomoyo_page_dump *dump);
-bool tomoyo_memory_ok(void *ptr);
-bool tomoyo_number_matches_group(const unsigned long min,
- const unsigned long max,
- const struct tomoyo_group *group);
-bool tomoyo_parse_ipaddr_union(struct tomoyo_acl_param *param,
- struct tomoyo_ipaddr_union *ptr);
-bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
- struct tomoyo_name_union *ptr);
-bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
- struct tomoyo_number_union *ptr);
-bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
- const struct tomoyo_path_info *pattern);
-bool tomoyo_permstr(const char *string, const char *keyword);
-bool tomoyo_str_starts(char **src, const char *find);
-char *tomoyo_encode(const char *str);
-char *tomoyo_encode2(const char *str, int str_len);
-char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
- va_list args);
-char *tomoyo_read_token(struct tomoyo_acl_param *param);
-char *tomoyo_realpath_from_path(struct path *path);
-char *tomoyo_realpath_nofollow(const char *pathname);
-const char *tomoyo_get_exe(void);
-const char *tomoyo_yesno(const unsigned int value);
-const struct tomoyo_path_info *tomoyo_compare_name_union
-(const struct tomoyo_path_info *name, const struct tomoyo_name_union *ptr);
-const struct tomoyo_path_info *tomoyo_get_domainname
-(struct tomoyo_acl_param *param);
-const struct tomoyo_path_info *tomoyo_get_name(const char *name);
-const struct tomoyo_path_info *tomoyo_path_matches_group
-(const struct tomoyo_path_info *pathname, const struct tomoyo_group *group);
-int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
- struct path *path, const int flag);
-int tomoyo_close_control(struct tomoyo_io_buffer *head);
-int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env);
-int tomoyo_execute_permission(struct tomoyo_request_info *r,
- const struct tomoyo_path_info *filename);
-int tomoyo_find_next_domain(struct linux_binprm *bprm);
-int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
- const u8 index);
-int tomoyo_init_request_info(struct tomoyo_request_info *r,
- struct tomoyo_domain_info *domain,
- const u8 index);
-int tomoyo_mkdev_perm(const u8 operation, struct path *path,
- const unsigned int mode, unsigned int dev);
-int tomoyo_mount_permission(char *dev_name, struct path *path,
- const char *type, unsigned long flags,
- void *data_page);
-int tomoyo_open_control(const u8 type, struct file *file);
-int tomoyo_path2_perm(const u8 operation, struct path *path1,
- struct path *path2);
-int tomoyo_path_number_perm(const u8 operation, struct path *path,
- unsigned long number);
-int tomoyo_path_perm(const u8 operation, struct path *path,
- const char *target);
-unsigned int tomoyo_poll_control(struct file *file, poll_table *wait);
-unsigned int tomoyo_poll_log(struct file *file, poll_table *wait);
-int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
- int addr_len);
-int tomoyo_socket_connect_permission(struct socket *sock,
- struct sockaddr *addr, int addr_len);
-int tomoyo_socket_listen_permission(struct socket *sock);
-int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg,
- int size);
-int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
- __printf(2, 3);
-int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
- struct tomoyo_acl_param *param,
- bool (*check_duplicate)
- (const struct tomoyo_acl_info *,
- const struct tomoyo_acl_info *),
- bool (*merge_duplicate)
- (struct tomoyo_acl_info *, struct tomoyo_acl_info *,
- const bool));
-int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
- struct tomoyo_acl_param *param,
- bool (*check_duplicate)
- (const struct tomoyo_acl_head *,
- const struct tomoyo_acl_head *));
-int tomoyo_write_aggregator(struct tomoyo_acl_param *param);
-int tomoyo_write_file(struct tomoyo_acl_param *param);
-int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type);
-int tomoyo_write_misc(struct tomoyo_acl_param *param);
-int tomoyo_write_inet_network(struct tomoyo_acl_param *param);
-int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
- const u8 type);
-int tomoyo_write_unix_network(struct tomoyo_acl_param *param);
-ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
- const int buffer_len);
-ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
- const char __user *buffer, const int buffer_len);
-struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param);
-struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
- const bool transit);
-struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
-struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
- const u8 idx);
-struct tomoyo_policy_namespace *tomoyo_assign_namespace
-(const char *domainname);
-struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
- const u8 profile);
-unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
- const u8 index);
-u8 tomoyo_parse_ulong(unsigned long *result, char **str);
-void *tomoyo_commit_ok(void *data, const unsigned int size);
-void __init tomoyo_load_builtin_policy(void);
-void __init tomoyo_mm_init(void);
-void tomoyo_check_acl(struct tomoyo_request_info *r,
- bool (*check_entry) (struct tomoyo_request_info *,
- const struct tomoyo_acl_info *));
-void tomoyo_check_profile(void);
-void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp);
-void tomoyo_del_condition(struct list_head *element);
-void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
-void tomoyo_get_attributes(struct tomoyo_obj_info *obj);
-void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns);
-void tomoyo_load_policy(const char *filename);
-void tomoyo_normalize_line(unsigned char *buffer);
-void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register);
-void tomoyo_print_ip(char *buf, const unsigned int size,
- const struct tomoyo_ipaddr_union *ptr);
-void tomoyo_print_ulong(char *buffer, const int buffer_len,
- const unsigned long value, const u8 type);
-void tomoyo_put_name_union(struct tomoyo_name_union *ptr);
-void tomoyo_put_number_union(struct tomoyo_number_union *ptr);
-void tomoyo_read_log(struct tomoyo_io_buffer *head);
-void tomoyo_update_stat(const u8 index);
-void tomoyo_warn_oom(const char *function);
-void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
- __printf(2, 3);
-void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
- va_list args);
-
-/********** External variable definitions. **********/
-
-extern bool tomoyo_policy_loaded;
-extern const char * const tomoyo_condition_keyword
-[TOMOYO_MAX_CONDITION_KEYWORD];
-extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
-extern const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
- + TOMOYO_MAX_MAC_CATEGORY_INDEX];
-extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE];
-extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION];
-extern const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX];
-extern const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION];
-extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX];
-extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION];
-extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION];
-extern const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION];
-extern struct list_head tomoyo_condition_list;
-extern struct list_head tomoyo_domain_list;
-extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
-extern struct list_head tomoyo_namespace_list;
-extern struct mutex tomoyo_policy_lock;
-extern struct srcu_struct tomoyo_ss;
-extern struct tomoyo_domain_info tomoyo_kernel_domain;
-extern struct tomoyo_policy_namespace tomoyo_kernel_namespace;
-extern unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
-extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
-
-/********** Inlined functions. **********/
-
-/**
- * tomoyo_read_lock - Take lock for protecting policy.
- *
- * Returns index number for tomoyo_read_unlock().
- */
-static inline int tomoyo_read_lock(void)
-{
- return srcu_read_lock(&tomoyo_ss);
-}
-
-/**
- * tomoyo_read_unlock - Release lock for protecting policy.
- *
- * @idx: Index number returned by tomoyo_read_lock().
- *
- * Returns nothing.
- */
-static inline void tomoyo_read_unlock(int idx)
-{
- srcu_read_unlock(&tomoyo_ss, idx);
-}
-
-/**
- * tomoyo_sys_getppid - Copy of getppid().
- *
- * Returns parent process's PID.
- *
- * Alpha does not have getppid() defined. To be able to build this module on
- * Alpha, I have to copy getppid() from kernel/timer.c.
- */
-static inline pid_t tomoyo_sys_getppid(void)
-{
- pid_t pid;
- rcu_read_lock();
- pid = task_tgid_vnr(rcu_dereference(current->real_parent));
- rcu_read_unlock();
- return pid;
-}
-
-/**
- * tomoyo_sys_getpid - Copy of getpid().
- *
- * Returns current thread's PID.
- *
- * Alpha does not have getpid() defined. To be able to build this module on
- * Alpha, I have to copy getpid() from kernel/timer.c.
- */
-static inline pid_t tomoyo_sys_getpid(void)
-{
- return task_tgid_vnr(current);
-}
-
-/**
- * tomoyo_pathcmp - strcmp() for "struct tomoyo_path_info" structure.
- *
- * @a: Pointer to "struct tomoyo_path_info".
- * @b: Pointer to "struct tomoyo_path_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
- const struct tomoyo_path_info *b)
-{
- return a->hash != b->hash || strcmp(a->name, b->name);
-}
-
-/**
- * tomoyo_put_name - Drop reference on "struct tomoyo_name".
- *
- * @name: Pointer to "struct tomoyo_path_info". Maybe NULL.
- *
- * Returns nothing.
- */
-static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
-{
- if (name) {
- struct tomoyo_name *ptr =
- container_of(name, typeof(*ptr), entry);
- atomic_dec(&ptr->head.users);
- }
-}
-
-/**
- * tomoyo_put_condition - Drop reference on "struct tomoyo_condition".
- *
- * @cond: Pointer to "struct tomoyo_condition". Maybe NULL.
- *
- * Returns nothing.
- */
-static inline void tomoyo_put_condition(struct tomoyo_condition *cond)
-{
- if (cond)
- atomic_dec(&cond->head.users);
-}
-
-/**
- * tomoyo_put_group - Drop reference on "struct tomoyo_group".
- *
- * @group: Pointer to "struct tomoyo_group". Maybe NULL.
- *
- * Returns nothing.
- */
-static inline void tomoyo_put_group(struct tomoyo_group *group)
-{
- if (group)
- atomic_dec(&group->head.users);
-}
-
-/**
- * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
- *
- * Returns pointer to "struct tomoyo_domain_info" for current thread.
- */
-static inline struct tomoyo_domain_info *tomoyo_domain(void)
-{
- return current_cred()->security;
-}
-
-/**
- * tomoyo_real_domain - Get "struct tomoyo_domain_info" for specified thread.
- *
- * @task: Pointer to "struct task_struct".
- *
- * Returns pointer to "struct tomoyo_security" for specified thread.
- */
-static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
- *task)
-{
- return task_cred_xxx(task, security);
-}
-
-/**
- * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
- *
- * @a: Pointer to "struct tomoyo_name_union".
- * @b: Pointer to "struct tomoyo_name_union".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool tomoyo_same_name_union
-(const struct tomoyo_name_union *a, const struct tomoyo_name_union *b)
-{
- return a->filename == b->filename && a->group == b->group;
-}
-
-/**
- * tomoyo_same_number_union - Check for duplicated "struct tomoyo_number_union" entry.
- *
- * @a: Pointer to "struct tomoyo_number_union".
- * @b: Pointer to "struct tomoyo_number_union".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool tomoyo_same_number_union
-(const struct tomoyo_number_union *a, const struct tomoyo_number_union *b)
-{
- return a->values[0] == b->values[0] && a->values[1] == b->values[1] &&
- a->group == b->group && a->value_type[0] == b->value_type[0] &&
- a->value_type[1] == b->value_type[1];
-}
-
-/**
- * tomoyo_same_ipaddr_union - Check for duplicated "struct tomoyo_ipaddr_union" entry.
- *
- * @a: Pointer to "struct tomoyo_ipaddr_union".
- * @b: Pointer to "struct tomoyo_ipaddr_union".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool tomoyo_same_ipaddr_union
-(const struct tomoyo_ipaddr_union *a, const struct tomoyo_ipaddr_union *b)
-{
- return !memcmp(a->ip, b->ip, sizeof(a->ip)) && a->group == b->group &&
- a->is_ipv6 == b->is_ipv6;
-}
-
-/**
- * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread.
- *
- * Returns pointer to "struct tomoyo_policy_namespace" for current thread.
- */
-static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
-{
- return tomoyo_domain()->ns;
-}
-
-#if defined(CONFIG_SLOB)
-
-/**
- * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
- *
- * @size: Size to be rounded up.
- *
- * Returns @size.
- *
- * Since SLOB does not round up, this function simply returns @size.
- */
-static inline int tomoyo_round2(size_t size)
-{
- return size;
-}
-
-#else
-
-/**
- * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
- *
- * @size: Size to be rounded up.
- *
- * Returns rounded size.
- *
- * Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of
- * (e.g.) 128 bytes.
- */
-static inline int tomoyo_round2(size_t size)
-{
-#if PAGE_SIZE == 4096
- size_t bsize = 32;
-#else
- size_t bsize = 64;
-#endif
- if (!size)
- return 0;
- while (size > bsize)
- bsize <<= 1;
- return bsize;
-}
-
-#endif
-
-/**
- * list_for_each_cookie - iterate over a list with cookie.
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- */
-#define list_for_each_cookie(pos, head) \
- if (!pos) \
- pos = srcu_dereference((head)->next, &tomoyo_ss); \
- for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss))
-
-#endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
diff --git a/ANDROID_3.4.5/security/tomoyo/condition.c b/ANDROID_3.4.5/security/tomoyo/condition.c
deleted file mode 100644
index 986330b8..00000000
--- a/ANDROID_3.4.5/security/tomoyo/condition.c
+++ /dev/null
@@ -1,1094 +0,0 @@
-/*
- * security/tomoyo/condition.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-#include <linux/slab.h>
-
-/* List of "struct tomoyo_condition". */
-LIST_HEAD(tomoyo_condition_list);
-
-/**
- * tomoyo_argv - Check argv[] in "struct linux_binbrm".
- *
- * @index: Index number of @arg_ptr.
- * @arg_ptr: Contents of argv[@index].
- * @argc: Length of @argv.
- * @argv: Pointer to "struct tomoyo_argv".
- * @checked: Set to true if @argv[@index] was found.
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_argv(const unsigned int index, const char *arg_ptr,
- const int argc, const struct tomoyo_argv *argv,
- u8 *checked)
-{
- int i;
- struct tomoyo_path_info arg;
- arg.name = arg_ptr;
- for (i = 0; i < argc; argv++, checked++, i++) {
- bool result;
- if (index != argv->index)
- continue;
- *checked = 1;
- tomoyo_fill_path_info(&arg);
- result = tomoyo_path_matches_pattern(&arg, argv->value);
- if (argv->is_not)
- result = !result;
- if (!result)
- return false;
- }
- return true;
-}
-
-/**
- * tomoyo_envp - Check envp[] in "struct linux_binbrm".
- *
- * @env_name: The name of environment variable.
- * @env_value: The value of environment variable.
- * @envc: Length of @envp.
- * @envp: Pointer to "struct tomoyo_envp".
- * @checked: Set to true if @envp[@env_name] was found.
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_envp(const char *env_name, const char *env_value,
- const int envc, const struct tomoyo_envp *envp,
- u8 *checked)
-{
- int i;
- struct tomoyo_path_info name;
- struct tomoyo_path_info value;
- name.name = env_name;
- tomoyo_fill_path_info(&name);
- value.name = env_value;
- tomoyo_fill_path_info(&value);
- for (i = 0; i < envc; envp++, checked++, i++) {
- bool result;
- if (!tomoyo_path_matches_pattern(&name, envp->name))
- continue;
- *checked = 1;
- if (envp->value) {
- result = tomoyo_path_matches_pattern(&value,
- envp->value);
- if (envp->is_not)
- result = !result;
- } else {
- result = true;
- if (!envp->is_not)
- result = !result;
- }
- if (!result)
- return false;
- }
- return true;
-}
-
-/**
- * tomoyo_scan_bprm - Scan "struct linux_binprm".
- *
- * @ee: Pointer to "struct tomoyo_execve".
- * @argc: Length of @argc.
- * @argv: Pointer to "struct tomoyo_argv".
- * @envc: Length of @envp.
- * @envp: Poiner to "struct tomoyo_envp".
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_scan_bprm(struct tomoyo_execve *ee,
- const u16 argc, const struct tomoyo_argv *argv,
- const u16 envc, const struct tomoyo_envp *envp)
-{
- struct linux_binprm *bprm = ee->bprm;
- struct tomoyo_page_dump *dump = &ee->dump;
- char *arg_ptr = ee->tmp;
- int arg_len = 0;
- unsigned long pos = bprm->p;
- int offset = pos % PAGE_SIZE;
- int argv_count = bprm->argc;
- int envp_count = bprm->envc;
- bool result = true;
- u8 local_checked[32];
- u8 *checked;
- if (argc + envc <= sizeof(local_checked)) {
- checked = local_checked;
- memset(local_checked, 0, sizeof(local_checked));
- } else {
- checked = kzalloc(argc + envc, GFP_NOFS);
- if (!checked)
- return false;
- }
- while (argv_count || envp_count) {
- if (!tomoyo_dump_page(bprm, pos, dump)) {
- result = false;
- goto out;
- }
- pos += PAGE_SIZE - offset;
- while (offset < PAGE_SIZE) {
- /* Read. */
- const char *kaddr = dump->data;
- const unsigned char c = kaddr[offset++];
- if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) {
- if (c == '\\') {
- arg_ptr[arg_len++] = '\\';
- arg_ptr[arg_len++] = '\\';
- } else if (c > ' ' && c < 127) {
- arg_ptr[arg_len++] = c;
- } else {
- arg_ptr[arg_len++] = '\\';
- arg_ptr[arg_len++] = (c >> 6) + '0';
- arg_ptr[arg_len++] =
- ((c >> 3) & 7) + '0';
- arg_ptr[arg_len++] = (c & 7) + '0';
- }
- } else {
- arg_ptr[arg_len] = '\0';
- }
- if (c)
- continue;
- /* Check. */
- if (argv_count) {
- if (!tomoyo_argv(bprm->argc - argv_count,
- arg_ptr, argc, argv,
- checked)) {
- result = false;
- break;
- }
- argv_count--;
- } else if (envp_count) {
- char *cp = strchr(arg_ptr, '=');
- if (cp) {
- *cp = '\0';
- if (!tomoyo_envp(arg_ptr, cp + 1,
- envc, envp,
- checked + argc)) {
- result = false;
- break;
- }
- }
- envp_count--;
- } else {
- break;
- }
- arg_len = 0;
- }
- offset = 0;
- if (!result)
- break;
- }
-out:
- if (result) {
- int i;
- /* Check not-yet-checked entries. */
- for (i = 0; i < argc; i++) {
- if (checked[i])
- continue;
- /*
- * Return true only if all unchecked indexes in
- * bprm->argv[] are not matched.
- */
- if (argv[i].is_not)
- continue;
- result = false;
- break;
- }
- for (i = 0; i < envc; envp++, i++) {
- if (checked[argc + i])
- continue;
- /*
- * Return true only if all unchecked environ variables
- * in bprm->envp[] are either undefined or not matched.
- */
- if ((!envp->value && !envp->is_not) ||
- (envp->value && envp->is_not))
- continue;
- result = false;
- break;
- }
- }
- if (checked != local_checked)
- kfree(checked);
- return result;
-}
-
-/**
- * tomoyo_scan_exec_realpath - Check "exec.realpath" parameter of "struct tomoyo_condition".
- *
- * @file: Pointer to "struct file".
- * @ptr: Pointer to "struct tomoyo_name_union".
- * @match: True if "exec.realpath=", false if "exec.realpath!=".
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_scan_exec_realpath(struct file *file,
- const struct tomoyo_name_union *ptr,
- const bool match)
-{
- bool result;
- struct tomoyo_path_info exe;
- if (!file)
- return false;
- exe.name = tomoyo_realpath_from_path(&file->f_path);
- if (!exe.name)
- return false;
- tomoyo_fill_path_info(&exe);
- result = tomoyo_compare_name_union(&exe, ptr);
- kfree(exe.name);
- return result == match;
-}
-
-/**
- * tomoyo_get_dqword - tomoyo_get_name() for a quoted string.
- *
- * @start: String to save.
- *
- * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
- */
-static const struct tomoyo_path_info *tomoyo_get_dqword(char *start)
-{
- char *cp = start + strlen(start) - 1;
- if (cp == start || *start++ != '"' || *cp != '"')
- return NULL;
- *cp = '\0';
- if (*start && !tomoyo_correct_word(start))
- return NULL;
- return tomoyo_get_name(start);
-}
-
-/**
- * tomoyo_parse_name_union_quoted - Parse a quoted word.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @ptr: Pointer to "struct tomoyo_name_union".
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_parse_name_union_quoted(struct tomoyo_acl_param *param,
- struct tomoyo_name_union *ptr)
-{
- char *filename = param->data;
- if (*filename == '@')
- return tomoyo_parse_name_union(param, ptr);
- ptr->filename = tomoyo_get_dqword(filename);
- return ptr->filename != NULL;
-}
-
-/**
- * tomoyo_parse_argv - Parse an argv[] condition part.
- *
- * @left: Lefthand value.
- * @right: Righthand value.
- * @argv: Pointer to "struct tomoyo_argv".
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_parse_argv(char *left, char *right,
- struct tomoyo_argv *argv)
-{
- if (tomoyo_parse_ulong(&argv->index, &left) !=
- TOMOYO_VALUE_TYPE_DECIMAL || *left++ != ']' || *left)
- return false;
- argv->value = tomoyo_get_dqword(right);
- return argv->value != NULL;
-}
-
-/**
- * tomoyo_parse_envp - Parse an envp[] condition part.
- *
- * @left: Lefthand value.
- * @right: Righthand value.
- * @envp: Pointer to "struct tomoyo_envp".
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_parse_envp(char *left, char *right,
- struct tomoyo_envp *envp)
-{
- const struct tomoyo_path_info *name;
- const struct tomoyo_path_info *value;
- char *cp = left + strlen(left) - 1;
- if (*cp-- != ']' || *cp != '"')
- goto out;
- *cp = '\0';
- if (!tomoyo_correct_word(left))
- goto out;
- name = tomoyo_get_name(left);
- if (!name)
- goto out;
- if (!strcmp(right, "NULL")) {
- value = NULL;
- } else {
- value = tomoyo_get_dqword(right);
- if (!value) {
- tomoyo_put_name(name);
- goto out;
- }
- }
- envp->name = name;
- envp->value = value;
- return true;
-out:
- return false;
-}
-
-/**
- * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry.
- *
- * @a: Pointer to "struct tomoyo_condition".
- * @b: Pointer to "struct tomoyo_condition".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
- const struct tomoyo_condition *b)
-{
- return a->size == b->size && a->condc == b->condc &&
- a->numbers_count == b->numbers_count &&
- a->names_count == b->names_count &&
- a->argc == b->argc && a->envc == b->envc &&
- a->grant_log == b->grant_log && a->transit == b->transit &&
- !memcmp(a + 1, b + 1, a->size - sizeof(*a));
-}
-
-/**
- * tomoyo_condition_type - Get condition type.
- *
- * @word: Keyword string.
- *
- * Returns one of values in "enum tomoyo_conditions_index" on success,
- * TOMOYO_MAX_CONDITION_KEYWORD otherwise.
- */
-static u8 tomoyo_condition_type(const char *word)
-{
- u8 i;
- for (i = 0; i < TOMOYO_MAX_CONDITION_KEYWORD; i++) {
- if (!strcmp(word, tomoyo_condition_keyword[i]))
- break;
- }
- return i;
-}
-
-/* Define this to enable debug mode. */
-/* #define DEBUG_CONDITION */
-
-#ifdef DEBUG_CONDITION
-#define dprintk printk
-#else
-#define dprintk(...) do { } while (0)
-#endif
-
-/**
- * tomoyo_commit_condition - Commit "struct tomoyo_condition".
- *
- * @entry: Pointer to "struct tomoyo_condition".
- *
- * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
- *
- * This function merges duplicated entries. This function returns NULL if
- * @entry is not duplicated but memory quota for policy has exceeded.
- */
-static struct tomoyo_condition *tomoyo_commit_condition
-(struct tomoyo_condition *entry)
-{
- struct tomoyo_condition *ptr;
- bool found = false;
- if (mutex_lock_interruptible(&tomoyo_policy_lock)) {
- dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
- ptr = NULL;
- found = true;
- goto out;
- }
- list_for_each_entry(ptr, &tomoyo_condition_list, head.list) {
- if (!tomoyo_same_condition(ptr, entry) ||
- atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
- continue;
- /* Same entry found. Share this entry. */
- atomic_inc(&ptr->head.users);
- found = true;
- break;
- }
- if (!found) {
- if (tomoyo_memory_ok(entry)) {
- atomic_set(&entry->head.users, 1);
- list_add(&entry->head.list, &tomoyo_condition_list);
- } else {
- found = true;
- ptr = NULL;
- }
- }
- mutex_unlock(&tomoyo_policy_lock);
-out:
- if (found) {
- tomoyo_del_condition(&entry->head.list);
- kfree(entry);
- entry = ptr;
- }
- return entry;
-}
-
-/**
- * tomoyo_get_transit_preference - Parse domain transition preference for execve().
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @e: Pointer to "struct tomoyo_condition".
- *
- * Returns the condition string part.
- */
-static char *tomoyo_get_transit_preference(struct tomoyo_acl_param *param,
- struct tomoyo_condition *e)
-{
- char * const pos = param->data;
- bool flag;
- if (*pos == '<') {
- e->transit = tomoyo_get_domainname(param);
- goto done;
- }
- {
- char *cp = strchr(pos, ' ');
- if (cp)
- *cp = '\0';
- flag = tomoyo_correct_path(pos) || !strcmp(pos, "keep") ||
- !strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
- !strcmp(pos, "child") || !strcmp(pos, "parent");
- if (cp)
- *cp = ' ';
- }
- if (!flag)
- return pos;
- e->transit = tomoyo_get_name(tomoyo_read_token(param));
-done:
- if (e->transit)
- return param->data;
- /*
- * Return a bad read-only condition string that will let
- * tomoyo_get_condition() return NULL.
- */
- return "/";
-}
-
-/**
- * tomoyo_get_condition - Parse condition part.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
- */
-struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
-{
- struct tomoyo_condition *entry = NULL;
- struct tomoyo_condition_element *condp = NULL;
- struct tomoyo_number_union *numbers_p = NULL;
- struct tomoyo_name_union *names_p = NULL;
- struct tomoyo_argv *argv = NULL;
- struct tomoyo_envp *envp = NULL;
- struct tomoyo_condition e = { };
- char * const start_of_string =
- tomoyo_get_transit_preference(param, &e);
- char * const end_of_string = start_of_string + strlen(start_of_string);
- char *pos;
-rerun:
- pos = start_of_string;
- while (1) {
- u8 left = -1;
- u8 right = -1;
- char *left_word = pos;
- char *cp;
- char *right_word;
- bool is_not;
- if (!*left_word)
- break;
- /*
- * Since left-hand condition does not allow use of "path_group"
- * or "number_group" and environment variable's names do not
- * accept '=', it is guaranteed that the original line consists
- * of one or more repetition of $left$operator$right blocks
- * where "$left is free from '=' and ' '" and "$operator is
- * either '=' or '!='" and "$right is free from ' '".
- * Therefore, we can reconstruct the original line at the end
- * of dry run even if we overwrite $operator with '\0'.
- */
- cp = strchr(pos, ' ');
- if (cp) {
- *cp = '\0'; /* Will restore later. */
- pos = cp + 1;
- } else {
- pos = "";
- }
- right_word = strchr(left_word, '=');
- if (!right_word || right_word == left_word)
- goto out;
- is_not = *(right_word - 1) == '!';
- if (is_not)
- *(right_word++ - 1) = '\0'; /* Will restore later. */
- else if (*(right_word + 1) != '=')
- *right_word++ = '\0'; /* Will restore later. */
- else
- goto out;
- dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
- is_not ? "!" : "", right_word);
- if (!strcmp(left_word, "grant_log")) {
- if (entry) {
- if (is_not ||
- entry->grant_log != TOMOYO_GRANTLOG_AUTO)
- goto out;
- else if (!strcmp(right_word, "yes"))
- entry->grant_log = TOMOYO_GRANTLOG_YES;
- else if (!strcmp(right_word, "no"))
- entry->grant_log = TOMOYO_GRANTLOG_NO;
- else
- goto out;
- }
- continue;
- }
- if (!strncmp(left_word, "exec.argv[", 10)) {
- if (!argv) {
- e.argc++;
- e.condc++;
- } else {
- e.argc--;
- e.condc--;
- left = TOMOYO_ARGV_ENTRY;
- argv->is_not = is_not;
- if (!tomoyo_parse_argv(left_word + 10,
- right_word, argv++))
- goto out;
- }
- goto store_value;
- }
- if (!strncmp(left_word, "exec.envp[\"", 11)) {
- if (!envp) {
- e.envc++;
- e.condc++;
- } else {
- e.envc--;
- e.condc--;
- left = TOMOYO_ENVP_ENTRY;
- envp->is_not = is_not;
- if (!tomoyo_parse_envp(left_word + 11,
- right_word, envp++))
- goto out;
- }
- goto store_value;
- }
- left = tomoyo_condition_type(left_word);
- dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
- left);
- if (left == TOMOYO_MAX_CONDITION_KEYWORD) {
- if (!numbers_p) {
- e.numbers_count++;
- } else {
- e.numbers_count--;
- left = TOMOYO_NUMBER_UNION;
- param->data = left_word;
- if (*left_word == '@' ||
- !tomoyo_parse_number_union(param,
- numbers_p++))
- goto out;
- }
- }
- if (!condp)
- e.condc++;
- else
- e.condc--;
- if (left == TOMOYO_EXEC_REALPATH ||
- left == TOMOYO_SYMLINK_TARGET) {
- if (!names_p) {
- e.names_count++;
- } else {
- e.names_count--;
- right = TOMOYO_NAME_UNION;
- param->data = right_word;
- if (!tomoyo_parse_name_union_quoted(param,
- names_p++))
- goto out;
- }
- goto store_value;
- }
- right = tomoyo_condition_type(right_word);
- if (right == TOMOYO_MAX_CONDITION_KEYWORD) {
- if (!numbers_p) {
- e.numbers_count++;
- } else {
- e.numbers_count--;
- right = TOMOYO_NUMBER_UNION;
- param->data = right_word;
- if (!tomoyo_parse_number_union(param,
- numbers_p++))
- goto out;
- }
- }
-store_value:
- if (!condp) {
- dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
- "match=%u\n", __LINE__, left, right, !is_not);
- continue;
- }
- condp->left = left;
- condp->right = right;
- condp->equals = !is_not;
- dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
- __LINE__, condp->left, condp->right,
- condp->equals);
- condp++;
- }
- dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
- __LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
- e.envc);
- if (entry) {
- BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc |
- e.condc);
- return tomoyo_commit_condition(entry);
- }
- e.size = sizeof(*entry)
- + e.condc * sizeof(struct tomoyo_condition_element)
- + e.numbers_count * sizeof(struct tomoyo_number_union)
- + e.names_count * sizeof(struct tomoyo_name_union)
- + e.argc * sizeof(struct tomoyo_argv)
- + e.envc * sizeof(struct tomoyo_envp);
- entry = kzalloc(e.size, GFP_NOFS);
- if (!entry)
- goto out2;
- *entry = e;
- e.transit = NULL;
- condp = (struct tomoyo_condition_element *) (entry + 1);
- numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
- names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
- argv = (struct tomoyo_argv *) (names_p + e.names_count);
- envp = (struct tomoyo_envp *) (argv + e.argc);
- {
- bool flag = false;
- for (pos = start_of_string; pos < end_of_string; pos++) {
- if (*pos)
- continue;
- if (flag) /* Restore " ". */
- *pos = ' ';
- else if (*(pos + 1) == '=') /* Restore "!=". */
- *pos = '!';
- else /* Restore "=". */
- *pos = '=';
- flag = !flag;
- }
- }
- goto rerun;
-out:
- dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
- if (entry) {
- tomoyo_del_condition(&entry->head.list);
- kfree(entry);
- }
-out2:
- tomoyo_put_name(e.transit);
- return NULL;
-}
-
-/**
- * tomoyo_get_attributes - Revalidate "struct inode".
- *
- * @obj: Pointer to "struct tomoyo_obj_info".
- *
- * Returns nothing.
- */
-void tomoyo_get_attributes(struct tomoyo_obj_info *obj)
-{
- u8 i;
- struct dentry *dentry = NULL;
-
- for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
- struct inode *inode;
- switch (i) {
- case TOMOYO_PATH1:
- dentry = obj->path1.dentry;
- if (!dentry)
- continue;
- break;
- case TOMOYO_PATH2:
- dentry = obj->path2.dentry;
- if (!dentry)
- continue;
- break;
- default:
- if (!dentry)
- continue;
- dentry = dget_parent(dentry);
- break;
- }
- inode = dentry->d_inode;
- if (inode) {
- struct tomoyo_mini_stat *stat = &obj->stat[i];
- stat->uid = inode->i_uid;
- stat->gid = inode->i_gid;
- stat->ino = inode->i_ino;
- stat->mode = inode->i_mode;
- stat->dev = inode->i_sb->s_dev;
- stat->rdev = inode->i_rdev;
- obj->stat_valid[i] = true;
- }
- if (i & 1) /* i == TOMOYO_PATH1_PARENT ||
- i == TOMOYO_PATH2_PARENT */
- dput(dentry);
- }
-}
-
-/**
- * tomoyo_condition - Check condition part.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @cond: Pointer to "struct tomoyo_condition". Maybe NULL.
- *
- * Returns true on success, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-bool tomoyo_condition(struct tomoyo_request_info *r,
- const struct tomoyo_condition *cond)
-{
- u32 i;
- unsigned long min_v[2] = { 0, 0 };
- unsigned long max_v[2] = { 0, 0 };
- const struct tomoyo_condition_element *condp;
- const struct tomoyo_number_union *numbers_p;
- const struct tomoyo_name_union *names_p;
- const struct tomoyo_argv *argv;
- const struct tomoyo_envp *envp;
- struct tomoyo_obj_info *obj;
- u16 condc;
- u16 argc;
- u16 envc;
- struct linux_binprm *bprm = NULL;
- if (!cond)
- return true;
- condc = cond->condc;
- argc = cond->argc;
- envc = cond->envc;
- obj = r->obj;
- if (r->ee)
- bprm = r->ee->bprm;
- if (!bprm && (argc || envc))
- return false;
- condp = (struct tomoyo_condition_element *) (cond + 1);
- numbers_p = (const struct tomoyo_number_union *) (condp + condc);
- names_p = (const struct tomoyo_name_union *)
- (numbers_p + cond->numbers_count);
- argv = (const struct tomoyo_argv *) (names_p + cond->names_count);
- envp = (const struct tomoyo_envp *) (argv + argc);
- for (i = 0; i < condc; i++) {
- const bool match = condp->equals;
- const u8 left = condp->left;
- const u8 right = condp->right;
- bool is_bitop[2] = { false, false };
- u8 j;
- condp++;
- /* Check argv[] and envp[] later. */
- if (left == TOMOYO_ARGV_ENTRY || left == TOMOYO_ENVP_ENTRY)
- continue;
- /* Check string expressions. */
- if (right == TOMOYO_NAME_UNION) {
- const struct tomoyo_name_union *ptr = names_p++;
- switch (left) {
- struct tomoyo_path_info *symlink;
- struct tomoyo_execve *ee;
- struct file *file;
- case TOMOYO_SYMLINK_TARGET:
- symlink = obj ? obj->symlink_target : NULL;
- if (!symlink ||
- !tomoyo_compare_name_union(symlink, ptr)
- == match)
- goto out;
- break;
- case TOMOYO_EXEC_REALPATH:
- ee = r->ee;
- file = ee ? ee->bprm->file : NULL;
- if (!tomoyo_scan_exec_realpath(file, ptr,
- match))
- goto out;
- break;
- }
- continue;
- }
- /* Check numeric or bit-op expressions. */
- for (j = 0; j < 2; j++) {
- const u8 index = j ? right : left;
- unsigned long value = 0;
- switch (index) {
- case TOMOYO_TASK_UID:
- value = current_uid();
- break;
- case TOMOYO_TASK_EUID:
- value = current_euid();
- break;
- case TOMOYO_TASK_SUID:
- value = current_suid();
- break;
- case TOMOYO_TASK_FSUID:
- value = current_fsuid();
- break;
- case TOMOYO_TASK_GID:
- value = current_gid();
- break;
- case TOMOYO_TASK_EGID:
- value = current_egid();
- break;
- case TOMOYO_TASK_SGID:
- value = current_sgid();
- break;
- case TOMOYO_TASK_FSGID:
- value = current_fsgid();
- break;
- case TOMOYO_TASK_PID:
- value = tomoyo_sys_getpid();
- break;
- case TOMOYO_TASK_PPID:
- value = tomoyo_sys_getppid();
- break;
- case TOMOYO_TYPE_IS_SOCKET:
- value = S_IFSOCK;
- break;
- case TOMOYO_TYPE_IS_SYMLINK:
- value = S_IFLNK;
- break;
- case TOMOYO_TYPE_IS_FILE:
- value = S_IFREG;
- break;
- case TOMOYO_TYPE_IS_BLOCK_DEV:
- value = S_IFBLK;
- break;
- case TOMOYO_TYPE_IS_DIRECTORY:
- value = S_IFDIR;
- break;
- case TOMOYO_TYPE_IS_CHAR_DEV:
- value = S_IFCHR;
- break;
- case TOMOYO_TYPE_IS_FIFO:
- value = S_IFIFO;
- break;
- case TOMOYO_MODE_SETUID:
- value = S_ISUID;
- break;
- case TOMOYO_MODE_SETGID:
- value = S_ISGID;
- break;
- case TOMOYO_MODE_STICKY:
- value = S_ISVTX;
- break;
- case TOMOYO_MODE_OWNER_READ:
- value = S_IRUSR;
- break;
- case TOMOYO_MODE_OWNER_WRITE:
- value = S_IWUSR;
- break;
- case TOMOYO_MODE_OWNER_EXECUTE:
- value = S_IXUSR;
- break;
- case TOMOYO_MODE_GROUP_READ:
- value = S_IRGRP;
- break;
- case TOMOYO_MODE_GROUP_WRITE:
- value = S_IWGRP;
- break;
- case TOMOYO_MODE_GROUP_EXECUTE:
- value = S_IXGRP;
- break;
- case TOMOYO_MODE_OTHERS_READ:
- value = S_IROTH;
- break;
- case TOMOYO_MODE_OTHERS_WRITE:
- value = S_IWOTH;
- break;
- case TOMOYO_MODE_OTHERS_EXECUTE:
- value = S_IXOTH;
- break;
- case TOMOYO_EXEC_ARGC:
- if (!bprm)
- goto out;
- value = bprm->argc;
- break;
- case TOMOYO_EXEC_ENVC:
- if (!bprm)
- goto out;
- value = bprm->envc;
- break;
- case TOMOYO_NUMBER_UNION:
- /* Fetch values later. */
- break;
- default:
- if (!obj)
- goto out;
- if (!obj->validate_done) {
- tomoyo_get_attributes(obj);
- obj->validate_done = true;
- }
- {
- u8 stat_index;
- struct tomoyo_mini_stat *stat;
- switch (index) {
- case TOMOYO_PATH1_UID:
- case TOMOYO_PATH1_GID:
- case TOMOYO_PATH1_INO:
- case TOMOYO_PATH1_MAJOR:
- case TOMOYO_PATH1_MINOR:
- case TOMOYO_PATH1_TYPE:
- case TOMOYO_PATH1_DEV_MAJOR:
- case TOMOYO_PATH1_DEV_MINOR:
- case TOMOYO_PATH1_PERM:
- stat_index = TOMOYO_PATH1;
- break;
- case TOMOYO_PATH2_UID:
- case TOMOYO_PATH2_GID:
- case TOMOYO_PATH2_INO:
- case TOMOYO_PATH2_MAJOR:
- case TOMOYO_PATH2_MINOR:
- case TOMOYO_PATH2_TYPE:
- case TOMOYO_PATH2_DEV_MAJOR:
- case TOMOYO_PATH2_DEV_MINOR:
- case TOMOYO_PATH2_PERM:
- stat_index = TOMOYO_PATH2;
- break;
- case TOMOYO_PATH1_PARENT_UID:
- case TOMOYO_PATH1_PARENT_GID:
- case TOMOYO_PATH1_PARENT_INO:
- case TOMOYO_PATH1_PARENT_PERM:
- stat_index =
- TOMOYO_PATH1_PARENT;
- break;
- case TOMOYO_PATH2_PARENT_UID:
- case TOMOYO_PATH2_PARENT_GID:
- case TOMOYO_PATH2_PARENT_INO:
- case TOMOYO_PATH2_PARENT_PERM:
- stat_index =
- TOMOYO_PATH2_PARENT;
- break;
- default:
- goto out;
- }
- if (!obj->stat_valid[stat_index])
- goto out;
- stat = &obj->stat[stat_index];
- switch (index) {
- case TOMOYO_PATH1_UID:
- case TOMOYO_PATH2_UID:
- case TOMOYO_PATH1_PARENT_UID:
- case TOMOYO_PATH2_PARENT_UID:
- value = stat->uid;
- break;
- case TOMOYO_PATH1_GID:
- case TOMOYO_PATH2_GID:
- case TOMOYO_PATH1_PARENT_GID:
- case TOMOYO_PATH2_PARENT_GID:
- value = stat->gid;
- break;
- case TOMOYO_PATH1_INO:
- case TOMOYO_PATH2_INO:
- case TOMOYO_PATH1_PARENT_INO:
- case TOMOYO_PATH2_PARENT_INO:
- value = stat->ino;
- break;
- case TOMOYO_PATH1_MAJOR:
- case TOMOYO_PATH2_MAJOR:
- value = MAJOR(stat->dev);
- break;
- case TOMOYO_PATH1_MINOR:
- case TOMOYO_PATH2_MINOR:
- value = MINOR(stat->dev);
- break;
- case TOMOYO_PATH1_TYPE:
- case TOMOYO_PATH2_TYPE:
- value = stat->mode & S_IFMT;
- break;
- case TOMOYO_PATH1_DEV_MAJOR:
- case TOMOYO_PATH2_DEV_MAJOR:
- value = MAJOR(stat->rdev);
- break;
- case TOMOYO_PATH1_DEV_MINOR:
- case TOMOYO_PATH2_DEV_MINOR:
- value = MINOR(stat->rdev);
- break;
- case TOMOYO_PATH1_PERM:
- case TOMOYO_PATH2_PERM:
- case TOMOYO_PATH1_PARENT_PERM:
- case TOMOYO_PATH2_PARENT_PERM:
- value = stat->mode & S_IALLUGO;
- break;
- }
- }
- break;
- }
- max_v[j] = value;
- min_v[j] = value;
- switch (index) {
- case TOMOYO_MODE_SETUID:
- case TOMOYO_MODE_SETGID:
- case TOMOYO_MODE_STICKY:
- case TOMOYO_MODE_OWNER_READ:
- case TOMOYO_MODE_OWNER_WRITE:
- case TOMOYO_MODE_OWNER_EXECUTE:
- case TOMOYO_MODE_GROUP_READ:
- case TOMOYO_MODE_GROUP_WRITE:
- case TOMOYO_MODE_GROUP_EXECUTE:
- case TOMOYO_MODE_OTHERS_READ:
- case TOMOYO_MODE_OTHERS_WRITE:
- case TOMOYO_MODE_OTHERS_EXECUTE:
- is_bitop[j] = true;
- }
- }
- if (left == TOMOYO_NUMBER_UNION) {
- /* Fetch values now. */
- const struct tomoyo_number_union *ptr = numbers_p++;
- min_v[0] = ptr->values[0];
- max_v[0] = ptr->values[1];
- }
- if (right == TOMOYO_NUMBER_UNION) {
- /* Fetch values now. */
- const struct tomoyo_number_union *ptr = numbers_p++;
- if (ptr->group) {
- if (tomoyo_number_matches_group(min_v[0],
- max_v[0],
- ptr->group)
- == match)
- continue;
- } else {
- if ((min_v[0] <= ptr->values[1] &&
- max_v[0] >= ptr->values[0]) == match)
- continue;
- }
- goto out;
- }
- /*
- * Bit operation is valid only when counterpart value
- * represents permission.
- */
- if (is_bitop[0] && is_bitop[1]) {
- goto out;
- } else if (is_bitop[0]) {
- switch (right) {
- case TOMOYO_PATH1_PERM:
- case TOMOYO_PATH1_PARENT_PERM:
- case TOMOYO_PATH2_PERM:
- case TOMOYO_PATH2_PARENT_PERM:
- if (!(max_v[0] & max_v[1]) == !match)
- continue;
- }
- goto out;
- } else if (is_bitop[1]) {
- switch (left) {
- case TOMOYO_PATH1_PERM:
- case TOMOYO_PATH1_PARENT_PERM:
- case TOMOYO_PATH2_PERM:
- case TOMOYO_PATH2_PARENT_PERM:
- if (!(max_v[0] & max_v[1]) == !match)
- continue;
- }
- goto out;
- }
- /* Normal value range comparison. */
- if ((min_v[0] <= max_v[1] && max_v[0] >= min_v[1]) == match)
- continue;
-out:
- return false;
- }
- /* Check argv[] and envp[] now. */
- if (r->ee && (argc || envc))
- return tomoyo_scan_bprm(r->ee, argc, argv, envc, envp);
- return true;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/domain.c b/ANDROID_3.4.5/security/tomoyo/domain.c
deleted file mode 100644
index 38651454..00000000
--- a/ANDROID_3.4.5/security/tomoyo/domain.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * security/tomoyo/domain.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-#include <linux/binfmts.h>
-#include <linux/slab.h>
-
-/* Variables definitions.*/
-
-/* The initial domain. */
-struct tomoyo_domain_info tomoyo_kernel_domain;
-
-/**
- * tomoyo_update_policy - Update an entry for exception policy.
- *
- * @new_entry: Pointer to "struct tomoyo_acl_info".
- * @size: Size of @new_entry in bytes.
- * @param: Pointer to "struct tomoyo_acl_param".
- * @check_duplicate: Callback function to find duplicated entry.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
- struct tomoyo_acl_param *param,
- bool (*check_duplicate) (const struct tomoyo_acl_head
- *,
- const struct tomoyo_acl_head
- *))
-{
- int error = param->is_delete ? -ENOENT : -ENOMEM;
- struct tomoyo_acl_head *entry;
- struct list_head *list = param->list;
-
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- return -ENOMEM;
- list_for_each_entry_rcu(entry, list, list) {
- if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
- continue;
- if (!check_duplicate(entry, new_entry))
- continue;
- entry->is_deleted = param->is_delete;
- error = 0;
- break;
- }
- if (error && !param->is_delete) {
- entry = tomoyo_commit_ok(new_entry, size);
- if (entry) {
- list_add_tail_rcu(&entry->list, list);
- error = 0;
- }
- }
- mutex_unlock(&tomoyo_policy_lock);
- return error;
-}
-
-/**
- * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- return a->type == b->type && a->cond == b->cond;
-}
-
-/**
- * tomoyo_update_domain - Update an entry for domain policy.
- *
- * @new_entry: Pointer to "struct tomoyo_acl_info".
- * @size: Size of @new_entry in bytes.
- * @param: Pointer to "struct tomoyo_acl_param".
- * @check_duplicate: Callback function to find duplicated entry.
- * @merge_duplicate: Callback function to merge duplicated entry.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
- struct tomoyo_acl_param *param,
- bool (*check_duplicate) (const struct tomoyo_acl_info
- *,
- const struct tomoyo_acl_info
- *),
- bool (*merge_duplicate) (struct tomoyo_acl_info *,
- struct tomoyo_acl_info *,
- const bool))
-{
- const bool is_delete = param->is_delete;
- int error = is_delete ? -ENOENT : -ENOMEM;
- struct tomoyo_acl_info *entry;
- struct list_head * const list = param->list;
-
- if (param->data[0]) {
- new_entry->cond = tomoyo_get_condition(param);
- if (!new_entry->cond)
- return -EINVAL;
- /*
- * Domain transition preference is allowed for only
- * "file execute" entries.
- */
- if (new_entry->cond->transit &&
- !(new_entry->type == TOMOYO_TYPE_PATH_ACL &&
- container_of(new_entry, struct tomoyo_path_acl, head)
- ->perm == 1 << TOMOYO_TYPE_EXECUTE))
- goto out;
- }
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- goto out;
- list_for_each_entry_rcu(entry, list, list) {
- if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
- continue;
- if (!tomoyo_same_acl_head(entry, new_entry) ||
- !check_duplicate(entry, new_entry))
- continue;
- if (merge_duplicate)
- entry->is_deleted = merge_duplicate(entry, new_entry,
- is_delete);
- else
- entry->is_deleted = is_delete;
- error = 0;
- break;
- }
- if (error && !is_delete) {
- entry = tomoyo_commit_ok(new_entry, size);
- if (entry) {
- list_add_tail_rcu(&entry->list, list);
- error = 0;
- }
- }
- mutex_unlock(&tomoyo_policy_lock);
-out:
- tomoyo_put_condition(new_entry->cond);
- return error;
-}
-
-/**
- * tomoyo_check_acl - Do permission check.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @check_entry: Callback function to check type specific parameters.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-void tomoyo_check_acl(struct tomoyo_request_info *r,
- bool (*check_entry) (struct tomoyo_request_info *,
- const struct tomoyo_acl_info *))
-{
- const struct tomoyo_domain_info *domain = r->domain;
- struct tomoyo_acl_info *ptr;
- bool retried = false;
- const struct list_head *list = &domain->acl_info_list;
-
-retry:
- list_for_each_entry_rcu(ptr, list, list) {
- if (ptr->is_deleted || ptr->type != r->param_type)
- continue;
- if (!check_entry(r, ptr))
- continue;
- if (!tomoyo_condition(r, ptr->cond))
- continue;
- r->matched_acl = ptr;
- r->granted = true;
- return;
- }
- if (!retried) {
- retried = true;
- list = &domain->ns->acl_group[domain->group];
- goto retry;
- }
- r->granted = false;
-}
-
-/* The list for "struct tomoyo_domain_info". */
-LIST_HEAD(tomoyo_domain_list);
-
-/**
- * tomoyo_last_word - Get last component of a domainname.
- *
- * @name: Domainname to check.
- *
- * Returns the last word of @domainname.
- */
-static const char *tomoyo_last_word(const char *name)
-{
- const char *cp = strrchr(name, ' ');
- if (cp)
- return cp + 1;
- return name;
-}
-
-/**
- * tomoyo_same_transition_control - Check for duplicated "struct tomoyo_transition_control" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_head".
- * @b: Pointer to "struct tomoyo_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
- const struct tomoyo_acl_head *b)
-{
- const struct tomoyo_transition_control *p1 = container_of(a,
- typeof(*p1),
- head);
- const struct tomoyo_transition_control *p2 = container_of(b,
- typeof(*p2),
- head);
- return p1->type == p2->type && p1->is_last_name == p2->is_last_name
- && p1->domainname == p2->domainname
- && p1->program == p2->program;
-}
-
-/**
- * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @type: Type of this entry.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
- const u8 type)
-{
- struct tomoyo_transition_control e = { .type = type };
- int error = param->is_delete ? -ENOENT : -ENOMEM;
- char *program = param->data;
- char *domainname = strstr(program, " from ");
- if (domainname) {
- *domainname = '\0';
- domainname += 6;
- } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
- type == TOMOYO_TRANSITION_CONTROL_KEEP) {
- domainname = program;
- program = NULL;
- }
- if (program && strcmp(program, "any")) {
- if (!tomoyo_correct_path(program))
- return -EINVAL;
- e.program = tomoyo_get_name(program);
- if (!e.program)
- goto out;
- }
- if (domainname && strcmp(domainname, "any")) {
- if (!tomoyo_correct_domain(domainname)) {
- if (!tomoyo_correct_path(domainname))
- goto out;
- e.is_last_name = true;
- }
- e.domainname = tomoyo_get_name(domainname);
- if (!e.domainname)
- goto out;
- }
- param->list = &param->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
- error = tomoyo_update_policy(&e.head, sizeof(e), param,
- tomoyo_same_transition_control);
-out:
- tomoyo_put_name(e.domainname);
- tomoyo_put_name(e.program);
- return error;
-}
-
-/**
- * tomoyo_scan_transition - Try to find specific domain transition type.
- *
- * @list: Pointer to "struct list_head".
- * @domainname: The name of current domain.
- * @program: The name of requested program.
- * @last_name: The last component of @domainname.
- * @type: One of values in "enum tomoyo_transition_type".
- *
- * Returns true if found one, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static inline bool tomoyo_scan_transition
-(const struct list_head *list, const struct tomoyo_path_info *domainname,
- const struct tomoyo_path_info *program, const char *last_name,
- const enum tomoyo_transition_type type)
-{
- const struct tomoyo_transition_control *ptr;
- list_for_each_entry_rcu(ptr, list, head.list) {
- if (ptr->head.is_deleted || ptr->type != type)
- continue;
- if (ptr->domainname) {
- if (!ptr->is_last_name) {
- if (ptr->domainname != domainname)
- continue;
- } else {
- /*
- * Use direct strcmp() since this is
- * unlikely used.
- */
- if (strcmp(ptr->domainname->name, last_name))
- continue;
- }
- }
- if (ptr->program && tomoyo_pathcmp(ptr->program, program))
- continue;
- return true;
- }
- return false;
-}
-
-/**
- * tomoyo_transition_type - Get domain transition type.
- *
- * @ns: Pointer to "struct tomoyo_policy_namespace".
- * @domainname: The name of current domain.
- * @program: The name of requested program.
- *
- * Returns TOMOYO_TRANSITION_CONTROL_TRANSIT if executing @program causes
- * domain transition across namespaces, TOMOYO_TRANSITION_CONTROL_INITIALIZE if
- * executing @program reinitializes domain transition within that namespace,
- * TOMOYO_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
- * others otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static enum tomoyo_transition_type tomoyo_transition_type
-(const struct tomoyo_policy_namespace *ns,
- const struct tomoyo_path_info *domainname,
- const struct tomoyo_path_info *program)
-{
- const char *last_name = tomoyo_last_word(domainname->name);
- enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET;
- while (type < TOMOYO_MAX_TRANSITION_TYPE) {
- const struct list_head * const list =
- &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
- if (!tomoyo_scan_transition(list, domainname, program,
- last_name, type)) {
- type++;
- continue;
- }
- if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET &&
- type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE)
- break;
- /*
- * Do not check for reset_domain if no_reset_domain matched.
- * Do not check for initialize_domain if no_initialize_domain
- * matched.
- */
- type++;
- type++;
- }
- return type;
-}
-
-/**
- * tomoyo_same_aggregator - Check for duplicated "struct tomoyo_aggregator" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_head".
- * @b: Pointer to "struct tomoyo_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a,
- const struct tomoyo_acl_head *b)
-{
- const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1),
- head);
- const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2),
- head);
- return p1->original_name == p2->original_name &&
- p1->aggregated_name == p2->aggregated_name;
-}
-
-/**
- * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_write_aggregator(struct tomoyo_acl_param *param)
-{
- struct tomoyo_aggregator e = { };
- int error = param->is_delete ? -ENOENT : -ENOMEM;
- const char *original_name = tomoyo_read_token(param);
- const char *aggregated_name = tomoyo_read_token(param);
- if (!tomoyo_correct_word(original_name) ||
- !tomoyo_correct_path(aggregated_name))
- return -EINVAL;
- e.original_name = tomoyo_get_name(original_name);
- e.aggregated_name = tomoyo_get_name(aggregated_name);
- if (!e.original_name || !e.aggregated_name ||
- e.aggregated_name->is_patterned) /* No patterns allowed. */
- goto out;
- param->list = &param->ns->policy_list[TOMOYO_ID_AGGREGATOR];
- error = tomoyo_update_policy(&e.head, sizeof(e), param,
- tomoyo_same_aggregator);
-out:
- tomoyo_put_name(e.original_name);
- tomoyo_put_name(e.aggregated_name);
- return error;
-}
-
-/**
- * tomoyo_find_namespace - Find specified namespace.
- *
- * @name: Name of namespace to find.
- * @len: Length of @name.
- *
- * Returns pointer to "struct tomoyo_policy_namespace" if found,
- * NULL otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static struct tomoyo_policy_namespace *tomoyo_find_namespace
-(const char *name, const unsigned int len)
-{
- struct tomoyo_policy_namespace *ns;
- list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
- if (strncmp(name, ns->name, len) ||
- (name[len] && name[len] != ' '))
- continue;
- return ns;
- }
- return NULL;
-}
-
-/**
- * tomoyo_assign_namespace - Create a new namespace.
- *
- * @domainname: Name of namespace to create.
- *
- * Returns pointer to "struct tomoyo_policy_namespace" on success,
- * NULL otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname)
-{
- struct tomoyo_policy_namespace *ptr;
- struct tomoyo_policy_namespace *entry;
- const char *cp = domainname;
- unsigned int len = 0;
- while (*cp && *cp++ != ' ')
- len++;
- ptr = tomoyo_find_namespace(domainname, len);
- if (ptr)
- return ptr;
- if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname))
- return NULL;
- entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS);
- if (!entry)
- return NULL;
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- goto out;
- ptr = tomoyo_find_namespace(domainname, len);
- if (!ptr && tomoyo_memory_ok(entry)) {
- char *name = (char *) (entry + 1);
- ptr = entry;
- memmove(name, domainname, len);
- name[len] = '\0';
- entry->name = name;
- tomoyo_init_policy_namespace(entry);
- entry = NULL;
- }
- mutex_unlock(&tomoyo_policy_lock);
-out:
- kfree(entry);
- return ptr;
-}
-
-/**
- * tomoyo_namespace_jump - Check for namespace jump.
- *
- * @domainname: Name of domain.
- *
- * Returns true if namespace differs, false otherwise.
- */
-static bool tomoyo_namespace_jump(const char *domainname)
-{
- const char *namespace = tomoyo_current_namespace()->name;
- const int len = strlen(namespace);
- return strncmp(domainname, namespace, len) ||
- (domainname[len] && domainname[len] != ' ');
-}
-
-/**
- * tomoyo_assign_domain - Create a domain or a namespace.
- *
- * @domainname: The name of domain.
- * @transit: True if transit to domain found or created.
- *
- * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
- const bool transit)
-{
- struct tomoyo_domain_info e = { };
- struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname);
- bool created = false;
- if (entry) {
- if (transit) {
- /*
- * Since namespace is created at runtime, profiles may
- * not be created by the moment the process transits to
- * that domain. Do not perform domain transition if
- * profile for that domain is not yet created.
- */
- if (tomoyo_policy_loaded &&
- !entry->ns->profile_ptr[entry->profile])
- return NULL;
- }
- return entry;
- }
- /* Requested domain does not exist. */
- /* Don't create requested domain if domainname is invalid. */
- if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 ||
- !tomoyo_correct_domain(domainname))
- return NULL;
- /*
- * Since definition of profiles and acl_groups may differ across
- * namespaces, do not inherit "use_profile" and "use_group" settings
- * by automatically creating requested domain upon domain transition.
- */
- if (transit && tomoyo_namespace_jump(domainname))
- return NULL;
- e.ns = tomoyo_assign_namespace(domainname);
- if (!e.ns)
- return NULL;
- /*
- * "use_profile" and "use_group" settings for automatically created
- * domains are inherited from current domain. These are 0 for manually
- * created domains.
- */
- if (transit) {
- const struct tomoyo_domain_info *domain = tomoyo_domain();
- e.profile = domain->profile;
- e.group = domain->group;
- }
- e.domainname = tomoyo_get_name(domainname);
- if (!e.domainname)
- return NULL;
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- goto out;
- entry = tomoyo_find_domain(domainname);
- if (!entry) {
- entry = tomoyo_commit_ok(&e, sizeof(e));
- if (entry) {
- INIT_LIST_HEAD(&entry->acl_info_list);
- list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
- created = true;
- }
- }
- mutex_unlock(&tomoyo_policy_lock);
-out:
- tomoyo_put_name(e.domainname);
- if (entry && transit) {
- if (created) {
- struct tomoyo_request_info r;
- tomoyo_init_request_info(&r, entry,
- TOMOYO_MAC_FILE_EXECUTE);
- r.granted = false;
- tomoyo_write_log(&r, "use_profile %u\n",
- entry->profile);
- tomoyo_write_log(&r, "use_group %u\n", entry->group);
- tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
- }
- }
- return entry;
-}
-
-/**
- * tomoyo_environ - Check permission for environment variable names.
- *
- * @ee: Pointer to "struct tomoyo_execve".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_environ(struct tomoyo_execve *ee)
-{
- struct tomoyo_request_info *r = &ee->r;
- struct linux_binprm *bprm = ee->bprm;
- /* env_page.data is allocated by tomoyo_dump_page(). */
- struct tomoyo_page_dump env_page = { };
- char *arg_ptr; /* Size is TOMOYO_EXEC_TMPSIZE bytes */
- int arg_len = 0;
- unsigned long pos = bprm->p;
- int offset = pos % PAGE_SIZE;
- int argv_count = bprm->argc;
- int envp_count = bprm->envc;
- int error = -ENOMEM;
-
- ee->r.type = TOMOYO_MAC_ENVIRON;
- ee->r.profile = r->domain->profile;
- ee->r.mode = tomoyo_get_mode(r->domain->ns, ee->r.profile,
- TOMOYO_MAC_ENVIRON);
- if (!r->mode || !envp_count)
- return 0;
- arg_ptr = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
- if (!arg_ptr)
- goto out;
- while (error == -ENOMEM) {
- if (!tomoyo_dump_page(bprm, pos, &env_page))
- goto out;
- pos += PAGE_SIZE - offset;
- /* Read. */
- while (argv_count && offset < PAGE_SIZE) {
- if (!env_page.data[offset++])
- argv_count--;
- }
- if (argv_count) {
- offset = 0;
- continue;
- }
- while (offset < PAGE_SIZE) {
- const unsigned char c = env_page.data[offset++];
-
- if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) {
- if (c == '=') {
- arg_ptr[arg_len++] = '\0';
- } else if (c == '\\') {
- arg_ptr[arg_len++] = '\\';
- arg_ptr[arg_len++] = '\\';
- } else if (c > ' ' && c < 127) {
- arg_ptr[arg_len++] = c;
- } else {
- arg_ptr[arg_len++] = '\\';
- arg_ptr[arg_len++] = (c >> 6) + '0';
- arg_ptr[arg_len++]
- = ((c >> 3) & 7) + '0';
- arg_ptr[arg_len++] = (c & 7) + '0';
- }
- } else {
- arg_ptr[arg_len] = '\0';
- }
- if (c)
- continue;
- if (tomoyo_env_perm(r, arg_ptr)) {
- error = -EPERM;
- break;
- }
- if (!--envp_count) {
- error = 0;
- break;
- }
- arg_len = 0;
- }
- offset = 0;
- }
-out:
- if (r->mode != TOMOYO_CONFIG_ENFORCING)
- error = 0;
- kfree(env_page.data);
- kfree(arg_ptr);
- return error;
-}
-
-/**
- * tomoyo_find_next_domain - Find a domain.
- *
- * @bprm: Pointer to "struct linux_binprm".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_find_next_domain(struct linux_binprm *bprm)
-{
- struct tomoyo_domain_info *old_domain = tomoyo_domain();
- struct tomoyo_domain_info *domain = NULL;
- const char *original_name = bprm->filename;
- int retval = -ENOMEM;
- bool reject_on_transition_failure = false;
- const struct tomoyo_path_info *candidate;
- struct tomoyo_path_info exename;
- struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS);
-
- if (!ee)
- return -ENOMEM;
- ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
- if (!ee->tmp) {
- kfree(ee);
- return -ENOMEM;
- }
- /* ee->dump->data is allocated by tomoyo_dump_page(). */
- tomoyo_init_request_info(&ee->r, NULL, TOMOYO_MAC_FILE_EXECUTE);
- ee->r.ee = ee;
- ee->bprm = bprm;
- ee->r.obj = &ee->obj;
- ee->obj.path1 = bprm->file->f_path;
- /* Get symlink's pathname of program. */
- retval = -ENOENT;
- exename.name = tomoyo_realpath_nofollow(original_name);
- if (!exename.name)
- goto out;
- tomoyo_fill_path_info(&exename);
-retry:
- /* Check 'aggregator' directive. */
- {
- struct tomoyo_aggregator *ptr;
- struct list_head *list =
- &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
- /* Check 'aggregator' directive. */
- candidate = &exename;
- list_for_each_entry_rcu(ptr, list, head.list) {
- if (ptr->head.is_deleted ||
- !tomoyo_path_matches_pattern(&exename,
- ptr->original_name))
- continue;
- candidate = ptr->aggregated_name;
- break;
- }
- }
-
- /* Check execute permission. */
- retval = tomoyo_execute_permission(&ee->r, candidate);
- if (retval == TOMOYO_RETRY_REQUEST)
- goto retry;
- if (retval < 0)
- goto out;
- /*
- * To be able to specify domainnames with wildcards, use the
- * pathname specified in the policy (which may contain
- * wildcard) rather than the pathname passed to execve()
- * (which never contains wildcard).
- */
- if (ee->r.param.path.matched_path)
- candidate = ee->r.param.path.matched_path;
-
- /*
- * Check for domain transition preference if "file execute" matched.
- * If preference is given, make do_execve() fail if domain transition
- * has failed, for domain transition preference should be used with
- * destination domain defined.
- */
- if (ee->transition) {
- const char *domainname = ee->transition->name;
- reject_on_transition_failure = true;
- if (!strcmp(domainname, "keep"))
- goto force_keep_domain;
- if (!strcmp(domainname, "child"))
- goto force_child_domain;
- if (!strcmp(domainname, "reset"))
- goto force_reset_domain;
- if (!strcmp(domainname, "initialize"))
- goto force_initialize_domain;
- if (!strcmp(domainname, "parent")) {
- char *cp;
- strncpy(ee->tmp, old_domain->domainname->name,
- TOMOYO_EXEC_TMPSIZE - 1);
- cp = strrchr(ee->tmp, ' ');
- if (cp)
- *cp = '\0';
- } else if (*domainname == '<')
- strncpy(ee->tmp, domainname, TOMOYO_EXEC_TMPSIZE - 1);
- else
- snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
- old_domain->domainname->name, domainname);
- goto force_jump_domain;
- }
- /*
- * No domain transition preference specified.
- * Calculate domain to transit to.
- */
- switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
- candidate)) {
- case TOMOYO_TRANSITION_CONTROL_RESET:
-force_reset_domain:
- /* Transit to the root of specified namespace. */
- snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>",
- candidate->name);
- /*
- * Make do_execve() fail if domain transition across namespaces
- * has failed.
- */
- reject_on_transition_failure = true;
- break;
- case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
-force_initialize_domain:
- /* Transit to the child of current namespace's root. */
- snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
- old_domain->ns->name, candidate->name);
- break;
- case TOMOYO_TRANSITION_CONTROL_KEEP:
-force_keep_domain:
- /* Keep current domain. */
- domain = old_domain;
- break;
- default:
- if (old_domain == &tomoyo_kernel_domain &&
- !tomoyo_policy_loaded) {
- /*
- * Needn't to transit from kernel domain before
- * starting /sbin/init. But transit from kernel domain
- * if executing initializers because they might start
- * before /sbin/init.
- */
- domain = old_domain;
- break;
- }
-force_child_domain:
- /* Normal domain transition. */
- snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
- old_domain->domainname->name, candidate->name);
- break;
- }
-force_jump_domain:
- if (!domain)
- domain = tomoyo_assign_domain(ee->tmp, true);
- if (domain)
- retval = 0;
- else if (reject_on_transition_failure) {
- printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n",
- ee->tmp);
- retval = -ENOMEM;
- } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING)
- retval = -ENOMEM;
- else {
- retval = 0;
- if (!old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED]) {
- old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED] = true;
- ee->r.granted = false;
- tomoyo_write_log(&ee->r, "%s", tomoyo_dif
- [TOMOYO_DIF_TRANSITION_FAILED]);
- printk(KERN_WARNING
- "ERROR: Domain '%s' not defined.\n", ee->tmp);
- }
- }
- out:
- if (!domain)
- domain = old_domain;
- /* Update reference count on "struct tomoyo_domain_info". */
- atomic_inc(&domain->users);
- bprm->cred->security = domain;
- kfree(exename.name);
- if (!retval) {
- ee->r.domain = domain;
- retval = tomoyo_environ(ee);
- }
- kfree(ee->tmp);
- kfree(ee->dump.data);
- kfree(ee);
- return retval;
-}
-
-/**
- * tomoyo_dump_page - Dump a page to buffer.
- *
- * @bprm: Pointer to "struct linux_binprm".
- * @pos: Location to dump.
- * @dump: Poiner to "struct tomoyo_page_dump".
- *
- * Returns true on success, false otherwise.
- */
-bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
- struct tomoyo_page_dump *dump)
-{
- struct page *page;
-
- /* dump->data is released by tomoyo_find_next_domain(). */
- if (!dump->data) {
- dump->data = kzalloc(PAGE_SIZE, GFP_NOFS);
- if (!dump->data)
- return false;
- }
- /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
-#ifdef CONFIG_MMU
- if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
- return false;
-#else
- page = bprm->page[pos / PAGE_SIZE];
-#endif
- if (page != dump->page) {
- const unsigned int offset = pos % PAGE_SIZE;
- /*
- * Maybe kmap()/kunmap() should be used here.
- * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
- * So do I.
- */
- char *kaddr = kmap_atomic(page);
-
- dump->page = page;
- memcpy(dump->data + offset, kaddr + offset,
- PAGE_SIZE - offset);
- kunmap_atomic(kaddr);
- }
- /* Same with put_arg_page(page) in fs/exec.c */
-#ifdef CONFIG_MMU
- put_page(page);
-#endif
- return true;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/environ.c b/ANDROID_3.4.5/security/tomoyo/environ.c
deleted file mode 100644
index ad4c6e18..00000000
--- a/ANDROID_3.4.5/security/tomoyo/environ.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * security/tomoyo/environ.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-
-/**
- * tomoyo_check_env_acl - Check permission for environment variable's name.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_env_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_env_acl *acl =
- container_of(ptr, typeof(*acl), head);
-
- return tomoyo_path_matches_pattern(r->param.environ.name, acl->env);
-}
-
-/**
- * tomoyo_audit_env_log - Audit environment variable name log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_env_log(struct tomoyo_request_info *r)
-{
- return tomoyo_supervisor(r, "misc env %s\n",
- r->param.environ.name->name);
-}
-
-/**
- * tomoyo_env_perm - Check permission for environment variable's name.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @env: The name of environment variable.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env)
-{
- struct tomoyo_path_info environ;
- int error;
-
- if (!env || !*env)
- return 0;
- environ.name = env;
- tomoyo_fill_path_info(&environ);
- r->param_type = TOMOYO_TYPE_ENV_ACL;
- r->param.environ.name = &environ;
- do {
- tomoyo_check_acl(r, tomoyo_check_env_acl);
- error = tomoyo_audit_env_log(r);
- } while (error == TOMOYO_RETRY_REQUEST);
- return error;
-}
-
-/**
- * tomoyo_same_env_acl - Check for duplicated "struct tomoyo_env_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_env_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_env_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_env_acl *p2 = container_of(b, typeof(*p2), head);
-
- return p1->env == p2->env;
-}
-
-/**
- * tomoyo_write_env - Write "struct tomoyo_env_acl" list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_write_env(struct tomoyo_acl_param *param)
-{
- struct tomoyo_env_acl e = { .head.type = TOMOYO_TYPE_ENV_ACL };
- int error = -ENOMEM;
- const char *data = tomoyo_read_token(param);
-
- if (!tomoyo_correct_word(data) || strchr(data, '='))
- return -EINVAL;
- e.env = tomoyo_get_name(data);
- if (!e.env)
- return error;
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_env_acl, NULL);
- tomoyo_put_name(e.env);
- return error;
-}
-
-/**
- * tomoyo_write_misc - Update environment variable list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_write_misc(struct tomoyo_acl_param *param)
-{
- if (tomoyo_str_starts(&param->data, "env "))
- return tomoyo_write_env(param);
- return -EINVAL;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/file.c b/ANDROID_3.4.5/security/tomoyo/file.c
deleted file mode 100644
index 40039079..00000000
--- a/ANDROID_3.4.5/security/tomoyo/file.c
+++ /dev/null
@@ -1,1026 +0,0 @@
-/*
- * security/tomoyo/file.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-#include <linux/slab.h>
-
-/*
- * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
- */
-static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
- [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
- [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
- [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
- [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN,
- [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
- [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR,
- [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
- [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
- [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
- [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
- [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
-};
-
-/*
- * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
- */
-const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
- [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
- [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
-};
-
-/*
- * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
- */
-const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
- [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
- [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
- [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
-};
-
-/*
- * Mapping table from "enum tomoyo_path_number_acl_index" to
- * "enum tomoyo_mac_index".
- */
-const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
- [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
- [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
- [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
- [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK,
- [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL,
- [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD,
- [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN,
- [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
-};
-
-/**
- * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
- *
- * @ptr: Pointer to "struct tomoyo_name_union".
- *
- * Returns nothing.
- */
-void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
-{
- tomoyo_put_group(ptr->group);
- tomoyo_put_name(ptr->filename);
-}
-
-/**
- * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
- *
- * @name: Pointer to "struct tomoyo_path_info".
- * @ptr: Pointer to "struct tomoyo_name_union".
- *
- * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
- */
-const struct tomoyo_path_info *
-tomoyo_compare_name_union(const struct tomoyo_path_info *name,
- const struct tomoyo_name_union *ptr)
-{
- if (ptr->group)
- return tomoyo_path_matches_group(name, ptr->group);
- if (tomoyo_path_matches_pattern(name, ptr->filename))
- return ptr->filename;
- return NULL;
-}
-
-/**
- * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
- *
- * @ptr: Pointer to "struct tomoyo_number_union".
- *
- * Returns nothing.
- */
-void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
-{
- tomoyo_put_group(ptr->group);
-}
-
-/**
- * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
- *
- * @value: Number to check.
- * @ptr: Pointer to "struct tomoyo_number_union".
- *
- * Returns true if @value matches @ptr, false otherwise.
- */
-bool tomoyo_compare_number_union(const unsigned long value,
- const struct tomoyo_number_union *ptr)
-{
- if (ptr->group)
- return tomoyo_number_matches_group(value, value, ptr->group);
- return value >= ptr->values[0] && value <= ptr->values[1];
-}
-
-/**
- * tomoyo_add_slash - Add trailing '/' if needed.
- *
- * @buf: Pointer to "struct tomoyo_path_info".
- *
- * Returns nothing.
- *
- * @buf must be generated by tomoyo_encode() because this function does not
- * allocate memory for adding '/'.
- */
-static void tomoyo_add_slash(struct tomoyo_path_info *buf)
-{
- if (buf->is_dir)
- return;
- /*
- * This is OK because tomoyo_encode() reserves space for appending "/".
- */
- strcat((char *) buf->name, "/");
- tomoyo_fill_path_info(buf);
-}
-
-/**
- * tomoyo_get_realpath - Get realpath.
- *
- * @buf: Pointer to "struct tomoyo_path_info".
- * @path: Pointer to "struct path".
- *
- * Returns true on success, false otherwise.
- */
-static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
-{
- buf->name = tomoyo_realpath_from_path(path);
- if (buf->name) {
- tomoyo_fill_path_info(buf);
- return true;
- }
- return false;
-}
-
-/**
- * tomoyo_audit_path_log - Audit path request log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
-{
- return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword
- [r->param.path.operation],
- r->param.path.filename->name);
-}
-
-/**
- * tomoyo_audit_path2_log - Audit path/path request log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
-{
- return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
- [tomoyo_pp2mac[r->param.path2.operation]],
- r->param.path2.filename1->name,
- r->param.path2.filename2->name);
-}
-
-/**
- * tomoyo_audit_mkdev_log - Audit path/number/number/number request log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
-{
- return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n",
- tomoyo_mac_keywords
- [tomoyo_pnnn2mac[r->param.mkdev.operation]],
- r->param.mkdev.filename->name,
- r->param.mkdev.mode, r->param.mkdev.major,
- r->param.mkdev.minor);
-}
-
-/**
- * tomoyo_audit_path_number_log - Audit path/number request log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
-{
- const u8 type = r->param.path_number.operation;
- u8 radix;
- char buffer[64];
- switch (type) {
- case TOMOYO_TYPE_CREATE:
- case TOMOYO_TYPE_MKDIR:
- case TOMOYO_TYPE_MKFIFO:
- case TOMOYO_TYPE_MKSOCK:
- case TOMOYO_TYPE_CHMOD:
- radix = TOMOYO_VALUE_TYPE_OCTAL;
- break;
- case TOMOYO_TYPE_IOCTL:
- radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
- break;
- default:
- radix = TOMOYO_VALUE_TYPE_DECIMAL;
- break;
- }
- tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
- radix);
- return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
- [tomoyo_pn2mac[type]],
- r->param.path_number.filename->name, buffer);
-}
-
-/**
- * tomoyo_check_path_acl - Check permission for path operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- *
- * To be able to use wildcard for domain transition, this function sets
- * matching entry on success. Since the caller holds tomoyo_read_lock(),
- * it is safe to set matching entry.
- */
-static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
- head);
- if (acl->perm & (1 << r->param.path.operation)) {
- r->param.path.matched_path =
- tomoyo_compare_name_union(r->param.path.filename,
- &acl->name);
- return r->param.path.matched_path != NULL;
- }
- return false;
-}
-
-/**
- * tomoyo_check_path_number_acl - Check permission for path number operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_path_number_acl *acl =
- container_of(ptr, typeof(*acl), head);
- return (acl->perm & (1 << r->param.path_number.operation)) &&
- tomoyo_compare_number_union(r->param.path_number.number,
- &acl->number) &&
- tomoyo_compare_name_union(r->param.path_number.filename,
- &acl->name);
-}
-
-/**
- * tomoyo_check_path2_acl - Check permission for path path operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_path2_acl *acl =
- container_of(ptr, typeof(*acl), head);
- return (acl->perm & (1 << r->param.path2.operation)) &&
- tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1)
- && tomoyo_compare_name_union(r->param.path2.filename2,
- &acl->name2);
-}
-
-/**
- * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_mkdev_acl *acl =
- container_of(ptr, typeof(*acl), head);
- return (acl->perm & (1 << r->param.mkdev.operation)) &&
- tomoyo_compare_number_union(r->param.mkdev.mode,
- &acl->mode) &&
- tomoyo_compare_number_union(r->param.mkdev.major,
- &acl->major) &&
- tomoyo_compare_number_union(r->param.mkdev.minor,
- &acl->minor) &&
- tomoyo_compare_name_union(r->param.mkdev.filename,
- &acl->name);
-}
-
-/**
- * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
- return tomoyo_same_name_union(&p1->name, &p2->name);
-}
-
-/**
- * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
- struct tomoyo_acl_info *b,
- const bool is_delete)
-{
- u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head)
- ->perm;
- u16 perm = *a_perm;
- const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
- if (is_delete)
- perm &= ~b_perm;
- else
- perm |= b_perm;
- *a_perm = perm;
- return !perm;
-}
-
-/**
- * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
- *
- * @perm: Permission.
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_update_path_acl(const u16 perm,
- struct tomoyo_acl_param *param)
-{
- struct tomoyo_path_acl e = {
- .head.type = TOMOYO_TYPE_PATH_ACL,
- .perm = perm
- };
- int error;
- if (!tomoyo_parse_name_union(param, &e.name))
- error = -EINVAL;
- else
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_path_acl,
- tomoyo_merge_path_acl);
- tomoyo_put_name_union(&e.name);
- return error;
-}
-
-/**
- * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
- return tomoyo_same_name_union(&p1->name, &p2->name) &&
- tomoyo_same_number_union(&p1->mode, &p2->mode) &&
- tomoyo_same_number_union(&p1->major, &p2->major) &&
- tomoyo_same_number_union(&p1->minor, &p2->minor);
-}
-
-/**
- * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
- struct tomoyo_acl_info *b,
- const bool is_delete)
-{
- u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
- head)->perm;
- u8 perm = *a_perm;
- const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head)
- ->perm;
- if (is_delete)
- perm &= ~b_perm;
- else
- perm |= b_perm;
- *a_perm = perm;
- return !perm;
-}
-
-/**
- * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list.
- *
- * @perm: Permission.
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_update_mkdev_acl(const u8 perm,
- struct tomoyo_acl_param *param)
-{
- struct tomoyo_mkdev_acl e = {
- .head.type = TOMOYO_TYPE_MKDEV_ACL,
- .perm = perm
- };
- int error;
- if (!tomoyo_parse_name_union(param, &e.name) ||
- !tomoyo_parse_number_union(param, &e.mode) ||
- !tomoyo_parse_number_union(param, &e.major) ||
- !tomoyo_parse_number_union(param, &e.minor))
- error = -EINVAL;
- else
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_mkdev_acl,
- tomoyo_merge_mkdev_acl);
- tomoyo_put_name_union(&e.name);
- tomoyo_put_number_union(&e.mode);
- tomoyo_put_number_union(&e.major);
- tomoyo_put_number_union(&e.minor);
- return error;
-}
-
-/**
- * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
- return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
- tomoyo_same_name_union(&p1->name2, &p2->name2);
-}
-
-/**
- * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
- struct tomoyo_acl_info *b,
- const bool is_delete)
-{
- u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head)
- ->perm;
- u8 perm = *a_perm;
- const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm;
- if (is_delete)
- perm &= ~b_perm;
- else
- perm |= b_perm;
- *a_perm = perm;
- return !perm;
-}
-
-/**
- * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
- *
- * @perm: Permission.
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_update_path2_acl(const u8 perm,
- struct tomoyo_acl_param *param)
-{
- struct tomoyo_path2_acl e = {
- .head.type = TOMOYO_TYPE_PATH2_ACL,
- .perm = perm
- };
- int error;
- if (!tomoyo_parse_name_union(param, &e.name1) ||
- !tomoyo_parse_name_union(param, &e.name2))
- error = -EINVAL;
- else
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_path2_acl,
- tomoyo_merge_path2_acl);
- tomoyo_put_name_union(&e.name1);
- tomoyo_put_name_union(&e.name2);
- return error;
-}
-
-/**
- * tomoyo_path_permission - Check permission for single path operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @operation: Type of operation.
- * @filename: Filename to check.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
- const struct tomoyo_path_info *filename)
-{
- int error;
-
- r->type = tomoyo_p2mac[operation];
- r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
- if (r->mode == TOMOYO_CONFIG_DISABLED)
- return 0;
- r->param_type = TOMOYO_TYPE_PATH_ACL;
- r->param.path.filename = filename;
- r->param.path.operation = operation;
- do {
- tomoyo_check_acl(r, tomoyo_check_path_acl);
- error = tomoyo_audit_path_log(r);
- } while (error == TOMOYO_RETRY_REQUEST);
- return error;
-}
-
-/**
- * tomoyo_execute_permission - Check permission for execute operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @filename: Filename to check.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_execute_permission(struct tomoyo_request_info *r,
- const struct tomoyo_path_info *filename)
-{
- /*
- * Unlike other permission checks, this check is done regardless of
- * profile mode settings in order to check for domain transition
- * preference.
- */
- r->type = TOMOYO_MAC_FILE_EXECUTE;
- r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
- r->param_type = TOMOYO_TYPE_PATH_ACL;
- r->param.path.filename = filename;
- r->param.path.operation = TOMOYO_TYPE_EXECUTE;
- tomoyo_check_acl(r, tomoyo_check_path_acl);
- r->ee->transition = r->matched_acl && r->matched_acl->cond ?
- r->matched_acl->cond->transit : NULL;
- if (r->mode != TOMOYO_CONFIG_DISABLED)
- return tomoyo_audit_path_log(r);
- return 0;
-}
-
-/**
- * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1),
- head);
- const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
- head);
- return tomoyo_same_name_union(&p1->name, &p2->name) &&
- tomoyo_same_number_union(&p1->number, &p2->number);
-}
-
-/**
- * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
- struct tomoyo_acl_info *b,
- const bool is_delete)
-{
- u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl,
- head)->perm;
- u8 perm = *a_perm;
- const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head)
- ->perm;
- if (is_delete)
- perm &= ~b_perm;
- else
- perm |= b_perm;
- *a_perm = perm;
- return !perm;
-}
-
-/**
- * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
- *
- * @perm: Permission.
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_update_path_number_acl(const u8 perm,
- struct tomoyo_acl_param *param)
-{
- struct tomoyo_path_number_acl e = {
- .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
- .perm = perm
- };
- int error;
- if (!tomoyo_parse_name_union(param, &e.name) ||
- !tomoyo_parse_number_union(param, &e.number))
- error = -EINVAL;
- else
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_path_number_acl,
- tomoyo_merge_path_number_acl);
- tomoyo_put_name_union(&e.name);
- tomoyo_put_number_union(&e.number);
- return error;
-}
-
-/**
- * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
- *
- * @type: Type of operation.
- * @path: Pointer to "struct path".
- * @number: Number.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_path_number_perm(const u8 type, struct path *path,
- unsigned long number)
-{
- struct tomoyo_request_info r;
- struct tomoyo_obj_info obj = {
- .path1 = *path,
- };
- int error = -ENOMEM;
- struct tomoyo_path_info buf;
- int idx;
-
- if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
- == TOMOYO_CONFIG_DISABLED || !path->dentry)
- return 0;
- idx = tomoyo_read_lock();
- if (!tomoyo_get_realpath(&buf, path))
- goto out;
- r.obj = &obj;
- if (type == TOMOYO_TYPE_MKDIR)
- tomoyo_add_slash(&buf);
- r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
- r.param.path_number.operation = type;
- r.param.path_number.filename = &buf;
- r.param.path_number.number = number;
- do {
- tomoyo_check_acl(&r, tomoyo_check_path_number_acl);
- error = tomoyo_audit_path_number_log(&r);
- } while (error == TOMOYO_RETRY_REQUEST);
- kfree(buf.name);
- out:
- tomoyo_read_unlock(idx);
- if (r.mode != TOMOYO_CONFIG_ENFORCING)
- error = 0;
- return error;
-}
-
-/**
- * tomoyo_check_open_permission - Check permission for "read" and "write".
- *
- * @domain: Pointer to "struct tomoyo_domain_info".
- * @path: Pointer to "struct path".
- * @flag: Flags for open().
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
- struct path *path, const int flag)
-{
- const u8 acc_mode = ACC_MODE(flag);
- int error = 0;
- struct tomoyo_path_info buf;
- struct tomoyo_request_info r;
- struct tomoyo_obj_info obj = {
- .path1 = *path,
- };
- int idx;
-
- buf.name = NULL;
- r.mode = TOMOYO_CONFIG_DISABLED;
- idx = tomoyo_read_lock();
- if (acc_mode &&
- tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
- != TOMOYO_CONFIG_DISABLED) {
- if (!tomoyo_get_realpath(&buf, path)) {
- error = -ENOMEM;
- goto out;
- }
- r.obj = &obj;
- if (acc_mode & MAY_READ)
- error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
- &buf);
- if (!error && (acc_mode & MAY_WRITE))
- error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
- TOMOYO_TYPE_APPEND :
- TOMOYO_TYPE_WRITE,
- &buf);
- }
- out:
- kfree(buf.name);
- tomoyo_read_unlock(idx);
- if (r.mode != TOMOYO_CONFIG_ENFORCING)
- error = 0;
- return error;
-}
-
-/**
- * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
- *
- * @operation: Type of operation.
- * @path: Pointer to "struct path".
- * @target: Symlink's target if @operation is TOMOYO_TYPE_SYMLINK,
- * NULL otherwise.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_path_perm(const u8 operation, struct path *path, const char *target)
-{
- struct tomoyo_request_info r;
- struct tomoyo_obj_info obj = {
- .path1 = *path,
- };
- int error;
- struct tomoyo_path_info buf;
- bool is_enforce;
- struct tomoyo_path_info symlink_target;
- int idx;
-
- if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
- == TOMOYO_CONFIG_DISABLED)
- return 0;
- is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
- error = -ENOMEM;
- buf.name = NULL;
- idx = tomoyo_read_lock();
- if (!tomoyo_get_realpath(&buf, path))
- goto out;
- r.obj = &obj;
- switch (operation) {
- case TOMOYO_TYPE_RMDIR:
- case TOMOYO_TYPE_CHROOT:
- tomoyo_add_slash(&buf);
- break;
- case TOMOYO_TYPE_SYMLINK:
- symlink_target.name = tomoyo_encode(target);
- if (!symlink_target.name)
- goto out;
- tomoyo_fill_path_info(&symlink_target);
- obj.symlink_target = &symlink_target;
- break;
- }
- error = tomoyo_path_permission(&r, operation, &buf);
- if (operation == TOMOYO_TYPE_SYMLINK)
- kfree(symlink_target.name);
- out:
- kfree(buf.name);
- tomoyo_read_unlock(idx);
- if (!is_enforce)
- error = 0;
- return error;
-}
-
-/**
- * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar".
- *
- * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
- * @path: Pointer to "struct path".
- * @mode: Create mode.
- * @dev: Device number.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_mkdev_perm(const u8 operation, struct path *path,
- const unsigned int mode, unsigned int dev)
-{
- struct tomoyo_request_info r;
- struct tomoyo_obj_info obj = {
- .path1 = *path,
- };
- int error = -ENOMEM;
- struct tomoyo_path_info buf;
- int idx;
-
- if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
- == TOMOYO_CONFIG_DISABLED)
- return 0;
- idx = tomoyo_read_lock();
- error = -ENOMEM;
- if (tomoyo_get_realpath(&buf, path)) {
- r.obj = &obj;
- dev = new_decode_dev(dev);
- r.param_type = TOMOYO_TYPE_MKDEV_ACL;
- r.param.mkdev.filename = &buf;
- r.param.mkdev.operation = operation;
- r.param.mkdev.mode = mode;
- r.param.mkdev.major = MAJOR(dev);
- r.param.mkdev.minor = MINOR(dev);
- tomoyo_check_acl(&r, tomoyo_check_mkdev_acl);
- error = tomoyo_audit_mkdev_log(&r);
- kfree(buf.name);
- }
- tomoyo_read_unlock(idx);
- if (r.mode != TOMOYO_CONFIG_ENFORCING)
- error = 0;
- return error;
-}
-
-/**
- * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
- *
- * @operation: Type of operation.
- * @path1: Pointer to "struct path".
- * @path2: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_path2_perm(const u8 operation, struct path *path1,
- struct path *path2)
-{
- int error = -ENOMEM;
- struct tomoyo_path_info buf1;
- struct tomoyo_path_info buf2;
- struct tomoyo_request_info r;
- struct tomoyo_obj_info obj = {
- .path1 = *path1,
- .path2 = *path2,
- };
- int idx;
-
- if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
- == TOMOYO_CONFIG_DISABLED)
- return 0;
- buf1.name = NULL;
- buf2.name = NULL;
- idx = tomoyo_read_lock();
- if (!tomoyo_get_realpath(&buf1, path1) ||
- !tomoyo_get_realpath(&buf2, path2))
- goto out;
- switch (operation) {
- struct dentry *dentry;
- case TOMOYO_TYPE_RENAME:
- case TOMOYO_TYPE_LINK:
- dentry = path1->dentry;
- if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
- break;
- /* fall through */
- case TOMOYO_TYPE_PIVOT_ROOT:
- tomoyo_add_slash(&buf1);
- tomoyo_add_slash(&buf2);
- break;
- }
- r.obj = &obj;
- r.param_type = TOMOYO_TYPE_PATH2_ACL;
- r.param.path2.operation = operation;
- r.param.path2.filename1 = &buf1;
- r.param.path2.filename2 = &buf2;
- do {
- tomoyo_check_acl(&r, tomoyo_check_path2_acl);
- error = tomoyo_audit_path2_log(&r);
- } while (error == TOMOYO_RETRY_REQUEST);
- out:
- kfree(buf1.name);
- kfree(buf2.name);
- tomoyo_read_unlock(idx);
- if (r.mode != TOMOYO_CONFIG_ENFORCING)
- error = 0;
- return error;
-}
-
-/**
- * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
- return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
- tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
- tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
- tomoyo_same_number_union(&p1->flags, &p2->flags);
-}
-
-/**
- * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param)
-{
- struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
- int error;
- if (!tomoyo_parse_name_union(param, &e.dev_name) ||
- !tomoyo_parse_name_union(param, &e.dir_name) ||
- !tomoyo_parse_name_union(param, &e.fs_type) ||
- !tomoyo_parse_number_union(param, &e.flags))
- error = -EINVAL;
- else
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_mount_acl, NULL);
- tomoyo_put_name_union(&e.dev_name);
- tomoyo_put_name_union(&e.dir_name);
- tomoyo_put_name_union(&e.fs_type);
- tomoyo_put_number_union(&e.flags);
- return error;
-}
-
-/**
- * tomoyo_write_file - Update file related list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_write_file(struct tomoyo_acl_param *param)
-{
- u16 perm = 0;
- u8 type;
- const char *operation = tomoyo_read_token(param);
- for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++)
- if (tomoyo_permstr(operation, tomoyo_path_keyword[type]))
- perm |= 1 << type;
- if (perm)
- return tomoyo_update_path_acl(perm, param);
- for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++)
- if (tomoyo_permstr(operation,
- tomoyo_mac_keywords[tomoyo_pp2mac[type]]))
- perm |= 1 << type;
- if (perm)
- return tomoyo_update_path2_acl(perm, param);
- for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++)
- if (tomoyo_permstr(operation,
- tomoyo_mac_keywords[tomoyo_pn2mac[type]]))
- perm |= 1 << type;
- if (perm)
- return tomoyo_update_path_number_acl(perm, param);
- for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++)
- if (tomoyo_permstr(operation,
- tomoyo_mac_keywords[tomoyo_pnnn2mac[type]]))
- perm |= 1 << type;
- if (perm)
- return tomoyo_update_mkdev_acl(perm, param);
- if (tomoyo_permstr(operation,
- tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT]))
- return tomoyo_update_mount_acl(param);
- return -EINVAL;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/gc.c b/ANDROID_3.4.5/security/tomoyo/gc.c
deleted file mode 100644
index 986a6a75..00000000
--- a/ANDROID_3.4.5/security/tomoyo/gc.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * security/tomoyo/gc.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-#include <linux/kthread.h>
-#include <linux/slab.h>
-
-/**
- * tomoyo_memory_free - Free memory for elements.
- *
- * @ptr: Pointer to allocated memory.
- *
- * Returns nothing.
- *
- * Caller holds tomoyo_policy_lock mutex.
- */
-static inline void tomoyo_memory_free(void *ptr)
-{
- tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr);
- kfree(ptr);
-}
-
-/* The list for "struct tomoyo_io_buffer". */
-static LIST_HEAD(tomoyo_io_buffer_list);
-/* Lock for protecting tomoyo_io_buffer_list. */
-static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
-
-/**
- * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
- * false otherwise.
- */
-static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
-{
- struct tomoyo_io_buffer *head;
- bool in_use = false;
-
- spin_lock(&tomoyo_io_buffer_list_lock);
- list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
- head->users++;
- spin_unlock(&tomoyo_io_buffer_list_lock);
- mutex_lock(&head->io_sem);
- if (head->r.domain == element || head->r.group == element ||
- head->r.acl == element || &head->w.domain->list == element)
- in_use = true;
- mutex_unlock(&head->io_sem);
- spin_lock(&tomoyo_io_buffer_list_lock);
- head->users--;
- if (in_use)
- break;
- }
- spin_unlock(&tomoyo_io_buffer_list_lock);
- return in_use;
-}
-
-/**
- * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
- *
- * @string: String to check.
- *
- * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
- * false otherwise.
- */
-static bool tomoyo_name_used_by_io_buffer(const char *string)
-{
- struct tomoyo_io_buffer *head;
- const size_t size = strlen(string) + 1;
- bool in_use = false;
-
- spin_lock(&tomoyo_io_buffer_list_lock);
- list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
- int i;
- head->users++;
- spin_unlock(&tomoyo_io_buffer_list_lock);
- mutex_lock(&head->io_sem);
- for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
- const char *w = head->r.w[i];
- if (w < string || w > string + size)
- continue;
- in_use = true;
- break;
- }
- mutex_unlock(&head->io_sem);
- spin_lock(&tomoyo_io_buffer_list_lock);
- head->users--;
- if (in_use)
- break;
- }
- spin_unlock(&tomoyo_io_buffer_list_lock);
- return in_use;
-}
-
-/**
- * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_transition_control(struct list_head *element)
-{
- struct tomoyo_transition_control *ptr =
- container_of(element, typeof(*ptr), head.list);
- tomoyo_put_name(ptr->domainname);
- tomoyo_put_name(ptr->program);
-}
-
-/**
- * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_aggregator(struct list_head *element)
-{
- struct tomoyo_aggregator *ptr =
- container_of(element, typeof(*ptr), head.list);
- tomoyo_put_name(ptr->original_name);
- tomoyo_put_name(ptr->aggregated_name);
-}
-
-/**
- * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_manager(struct list_head *element)
-{
- struct tomoyo_manager *ptr =
- container_of(element, typeof(*ptr), head.list);
- tomoyo_put_name(ptr->manager);
-}
-
-/**
- * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static void tomoyo_del_acl(struct list_head *element)
-{
- struct tomoyo_acl_info *acl =
- container_of(element, typeof(*acl), list);
- tomoyo_put_condition(acl->cond);
- switch (acl->type) {
- case TOMOYO_TYPE_PATH_ACL:
- {
- struct tomoyo_path_acl *entry
- = container_of(acl, typeof(*entry), head);
- tomoyo_put_name_union(&entry->name);
- }
- break;
- case TOMOYO_TYPE_PATH2_ACL:
- {
- struct tomoyo_path2_acl *entry
- = container_of(acl, typeof(*entry), head);
- tomoyo_put_name_union(&entry->name1);
- tomoyo_put_name_union(&entry->name2);
- }
- break;
- case TOMOYO_TYPE_PATH_NUMBER_ACL:
- {
- struct tomoyo_path_number_acl *entry
- = container_of(acl, typeof(*entry), head);
- tomoyo_put_name_union(&entry->name);
- tomoyo_put_number_union(&entry->number);
- }
- break;
- case TOMOYO_TYPE_MKDEV_ACL:
- {
- struct tomoyo_mkdev_acl *entry
- = container_of(acl, typeof(*entry), head);
- tomoyo_put_name_union(&entry->name);
- tomoyo_put_number_union(&entry->mode);
- tomoyo_put_number_union(&entry->major);
- tomoyo_put_number_union(&entry->minor);
- }
- break;
- case TOMOYO_TYPE_MOUNT_ACL:
- {
- struct tomoyo_mount_acl *entry
- = container_of(acl, typeof(*entry), head);
- tomoyo_put_name_union(&entry->dev_name);
- tomoyo_put_name_union(&entry->dir_name);
- tomoyo_put_name_union(&entry->fs_type);
- tomoyo_put_number_union(&entry->flags);
- }
- break;
- case TOMOYO_TYPE_ENV_ACL:
- {
- struct tomoyo_env_acl *entry =
- container_of(acl, typeof(*entry), head);
-
- tomoyo_put_name(entry->env);
- }
- break;
- case TOMOYO_TYPE_INET_ACL:
- {
- struct tomoyo_inet_acl *entry =
- container_of(acl, typeof(*entry), head);
-
- tomoyo_put_group(entry->address.group);
- tomoyo_put_number_union(&entry->port);
- }
- break;
- case TOMOYO_TYPE_UNIX_ACL:
- {
- struct tomoyo_unix_acl *entry =
- container_of(acl, typeof(*entry), head);
-
- tomoyo_put_name_union(&entry->name);
- }
- break;
- case TOMOYO_TYPE_MANUAL_TASK_ACL:
- {
- struct tomoyo_task_acl *entry =
- container_of(acl, typeof(*entry), head);
- tomoyo_put_name(entry->domainname);
- }
- break;
- }
-}
-
-/**
- * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- *
- * Caller holds tomoyo_policy_lock mutex.
- */
-static inline void tomoyo_del_domain(struct list_head *element)
-{
- struct tomoyo_domain_info *domain =
- container_of(element, typeof(*domain), list);
- struct tomoyo_acl_info *acl;
- struct tomoyo_acl_info *tmp;
- /*
- * Since this domain is referenced from neither
- * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete
- * elements without checking for is_deleted flag.
- */
- list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
- tomoyo_del_acl(&acl->list);
- tomoyo_memory_free(acl);
- }
- tomoyo_put_name(domain->domainname);
-}
-
-/**
- * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-void tomoyo_del_condition(struct list_head *element)
-{
- struct tomoyo_condition *cond = container_of(element, typeof(*cond),
- head.list);
- const u16 condc = cond->condc;
- const u16 numbers_count = cond->numbers_count;
- const u16 names_count = cond->names_count;
- const u16 argc = cond->argc;
- const u16 envc = cond->envc;
- unsigned int i;
- const struct tomoyo_condition_element *condp
- = (const struct tomoyo_condition_element *) (cond + 1);
- struct tomoyo_number_union *numbers_p
- = (struct tomoyo_number_union *) (condp + condc);
- struct tomoyo_name_union *names_p
- = (struct tomoyo_name_union *) (numbers_p + numbers_count);
- const struct tomoyo_argv *argv
- = (const struct tomoyo_argv *) (names_p + names_count);
- const struct tomoyo_envp *envp
- = (const struct tomoyo_envp *) (argv + argc);
- for (i = 0; i < numbers_count; i++)
- tomoyo_put_number_union(numbers_p++);
- for (i = 0; i < names_count; i++)
- tomoyo_put_name_union(names_p++);
- for (i = 0; i < argc; argv++, i++)
- tomoyo_put_name(argv->value);
- for (i = 0; i < envc; envp++, i++) {
- tomoyo_put_name(envp->name);
- tomoyo_put_name(envp->value);
- }
-}
-
-/**
- * tomoyo_del_name - Delete members in "struct tomoyo_name".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_name(struct list_head *element)
-{
- /* Nothing to do. */
-}
-
-/**
- * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_path_group(struct list_head *element)
-{
- struct tomoyo_path_group *member =
- container_of(element, typeof(*member), head.list);
- tomoyo_put_name(member->member_name);
-}
-
-/**
- * tomoyo_del_group - Delete "struct tomoyo_group".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_group(struct list_head *element)
-{
- struct tomoyo_group *group =
- container_of(element, typeof(*group), head.list);
- tomoyo_put_name(group->group_name);
-}
-
-/**
- * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_address_group(struct list_head *element)
-{
- /* Nothing to do. */
-}
-
-/**
- * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void tomoyo_del_number_group(struct list_head *element)
-{
- /* Nothing to do. */
-}
-
-/**
- * tomoyo_try_to_gc - Try to kfree() an entry.
- *
- * @type: One of values in "enum tomoyo_policy_id".
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- *
- * Caller holds tomoyo_policy_lock mutex.
- */
-static void tomoyo_try_to_gc(const enum tomoyo_policy_id type,
- struct list_head *element)
-{
- /*
- * __list_del_entry() guarantees that the list element became no longer
- * reachable from the list which the element was originally on (e.g.
- * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the
- * list element became no longer referenced by syscall users.
- */
- __list_del_entry(element);
- mutex_unlock(&tomoyo_policy_lock);
- synchronize_srcu(&tomoyo_ss);
- /*
- * However, there are two users which may still be using the list
- * element. We need to defer until both users forget this element.
- *
- * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl}
- * and "struct tomoyo_io_buffer"->w.domain forget this element.
- */
- if (tomoyo_struct_used_by_io_buffer(element))
- goto reinject;
- switch (type) {
- case TOMOYO_ID_TRANSITION_CONTROL:
- tomoyo_del_transition_control(element);
- break;
- case TOMOYO_ID_MANAGER:
- tomoyo_del_manager(element);
- break;
- case TOMOYO_ID_AGGREGATOR:
- tomoyo_del_aggregator(element);
- break;
- case TOMOYO_ID_GROUP:
- tomoyo_del_group(element);
- break;
- case TOMOYO_ID_PATH_GROUP:
- tomoyo_del_path_group(element);
- break;
- case TOMOYO_ID_ADDRESS_GROUP:
- tomoyo_del_address_group(element);
- break;
- case TOMOYO_ID_NUMBER_GROUP:
- tomoyo_del_number_group(element);
- break;
- case TOMOYO_ID_CONDITION:
- tomoyo_del_condition(element);
- break;
- case TOMOYO_ID_NAME:
- /*
- * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[]
- * forget this element.
- */
- if (tomoyo_name_used_by_io_buffer
- (container_of(element, typeof(struct tomoyo_name),
- head.list)->entry.name))
- goto reinject;
- tomoyo_del_name(element);
- break;
- case TOMOYO_ID_ACL:
- tomoyo_del_acl(element);
- break;
- case TOMOYO_ID_DOMAIN:
- /*
- * Don't kfree() until all "struct cred"->security forget this
- * element.
- */
- if (atomic_read(&container_of
- (element, typeof(struct tomoyo_domain_info),
- list)->users))
- goto reinject;
- break;
- case TOMOYO_MAX_POLICY:
- break;
- }
- mutex_lock(&tomoyo_policy_lock);
- if (type == TOMOYO_ID_DOMAIN)
- tomoyo_del_domain(element);
- tomoyo_memory_free(element);
- return;
-reinject:
- /*
- * We can safely reinject this element here bacause
- * (1) Appending list elements and removing list elements are protected
- * by tomoyo_policy_lock mutex.
- * (2) Only this function removes list elements and this function is
- * exclusively executed by tomoyo_gc_mutex mutex.
- * are true.
- */
- mutex_lock(&tomoyo_policy_lock);
- list_add_rcu(element, element->prev);
-}
-
-/**
- * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
- *
- * @id: One of values in "enum tomoyo_policy_id".
- * @member_list: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static void tomoyo_collect_member(const enum tomoyo_policy_id id,
- struct list_head *member_list)
-{
- struct tomoyo_acl_head *member;
- struct tomoyo_acl_head *tmp;
- list_for_each_entry_safe(member, tmp, member_list, list) {
- if (!member->is_deleted)
- continue;
- member->is_deleted = TOMOYO_GC_IN_PROGRESS;
- tomoyo_try_to_gc(id, &member->list);
- }
-}
-
-/**
- * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
- *
- * @list: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static void tomoyo_collect_acl(struct list_head *list)
-{
- struct tomoyo_acl_info *acl;
- struct tomoyo_acl_info *tmp;
- list_for_each_entry_safe(acl, tmp, list, list) {
- if (!acl->is_deleted)
- continue;
- acl->is_deleted = TOMOYO_GC_IN_PROGRESS;
- tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list);
- }
-}
-
-/**
- * tomoyo_collect_entry - Try to kfree() deleted elements.
- *
- * Returns nothing.
- */
-static void tomoyo_collect_entry(void)
-{
- int i;
- enum tomoyo_policy_id id;
- struct tomoyo_policy_namespace *ns;
- mutex_lock(&tomoyo_policy_lock);
- {
- struct tomoyo_domain_info *domain;
- struct tomoyo_domain_info *tmp;
- list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list,
- list) {
- tomoyo_collect_acl(&domain->acl_info_list);
- if (!domain->is_deleted || atomic_read(&domain->users))
- continue;
- tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list);
- }
- }
- list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
- for (id = 0; id < TOMOYO_MAX_POLICY; id++)
- tomoyo_collect_member(id, &ns->policy_list[id]);
- for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
- tomoyo_collect_acl(&ns->acl_group[i]);
- }
- {
- struct tomoyo_shared_acl_head *ptr;
- struct tomoyo_shared_acl_head *tmp;
- list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list,
- list) {
- if (atomic_read(&ptr->users) > 0)
- continue;
- atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
- tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list);
- }
- }
- list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
- for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
- struct list_head *list = &ns->group_list[i];
- struct tomoyo_group *group;
- struct tomoyo_group *tmp;
- switch (i) {
- case 0:
- id = TOMOYO_ID_PATH_GROUP;
- break;
- case 1:
- id = TOMOYO_ID_NUMBER_GROUP;
- break;
- default:
- id = TOMOYO_ID_ADDRESS_GROUP;
- break;
- }
- list_for_each_entry_safe(group, tmp, list, head.list) {
- tomoyo_collect_member(id, &group->member_list);
- if (!list_empty(&group->member_list) ||
- atomic_read(&group->head.users) > 0)
- continue;
- atomic_set(&group->head.users,
- TOMOYO_GC_IN_PROGRESS);
- tomoyo_try_to_gc(TOMOYO_ID_GROUP,
- &group->head.list);
- }
- }
- }
- for (i = 0; i < TOMOYO_MAX_HASH; i++) {
- struct list_head *list = &tomoyo_name_list[i];
- struct tomoyo_shared_acl_head *ptr;
- struct tomoyo_shared_acl_head *tmp;
- list_for_each_entry_safe(ptr, tmp, list, list) {
- if (atomic_read(&ptr->users) > 0)
- continue;
- atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
- tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list);
- }
- }
- mutex_unlock(&tomoyo_policy_lock);
-}
-
-/**
- * tomoyo_gc_thread - Garbage collector thread function.
- *
- * @unused: Unused.
- *
- * Returns 0.
- */
-static int tomoyo_gc_thread(void *unused)
-{
- /* Garbage collector thread is exclusive. */
- static DEFINE_MUTEX(tomoyo_gc_mutex);
- if (!mutex_trylock(&tomoyo_gc_mutex))
- goto out;
- tomoyo_collect_entry();
- {
- struct tomoyo_io_buffer *head;
- struct tomoyo_io_buffer *tmp;
-
- spin_lock(&tomoyo_io_buffer_list_lock);
- list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
- list) {
- if (head->users)
- continue;
- list_del(&head->list);
- kfree(head->read_buf);
- kfree(head->write_buf);
- kfree(head);
- }
- spin_unlock(&tomoyo_io_buffer_list_lock);
- }
- mutex_unlock(&tomoyo_gc_mutex);
-out:
- /* This acts as do_exit(0). */
- return 0;
-}
-
-/**
- * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
- *
- * @head: Pointer to "struct tomoyo_io_buffer".
- * @is_register: True if register, false if unregister.
- *
- * Returns nothing.
- */
-void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
-{
- bool is_write = false;
-
- spin_lock(&tomoyo_io_buffer_list_lock);
- if (is_register) {
- head->users = 1;
- list_add(&head->list, &tomoyo_io_buffer_list);
- } else {
- is_write = head->write_buf != NULL;
- if (!--head->users) {
- list_del(&head->list);
- kfree(head->read_buf);
- kfree(head->write_buf);
- kfree(head);
- }
- }
- spin_unlock(&tomoyo_io_buffer_list_lock);
- if (is_write) {
- struct task_struct *task = kthread_create(tomoyo_gc_thread,
- NULL,
- "GC for TOMOYO");
- if (!IS_ERR(task))
- wake_up_process(task);
- }
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/group.c b/ANDROID_3.4.5/security/tomoyo/group.c
deleted file mode 100644
index 50092534..00000000
--- a/ANDROID_3.4.5/security/tomoyo/group.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * security/tomoyo/group.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include <linux/slab.h>
-#include "common.h"
-
-/**
- * tomoyo_same_path_group - Check for duplicated "struct tomoyo_path_group" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_head".
- * @b: Pointer to "struct tomoyo_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a,
- const struct tomoyo_acl_head *b)
-{
- return container_of(a, struct tomoyo_path_group, head)->member_name ==
- container_of(b, struct tomoyo_path_group, head)->member_name;
-}
-
-/**
- * tomoyo_same_number_group - Check for duplicated "struct tomoyo_number_group" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_head".
- * @b: Pointer to "struct tomoyo_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
- const struct tomoyo_acl_head *b)
-{
- return !memcmp(&container_of(a, struct tomoyo_number_group, head)
- ->number,
- &container_of(b, struct tomoyo_number_group, head)
- ->number,
- sizeof(container_of(a, struct tomoyo_number_group, head)
- ->number));
-}
-
-/**
- * tomoyo_same_address_group - Check for duplicated "struct tomoyo_address_group" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_head".
- * @b: Pointer to "struct tomoyo_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool tomoyo_same_address_group(const struct tomoyo_acl_head *a,
- const struct tomoyo_acl_head *b)
-{
- const struct tomoyo_address_group *p1 = container_of(a, typeof(*p1),
- head);
- const struct tomoyo_address_group *p2 = container_of(b, typeof(*p2),
- head);
-
- return tomoyo_same_ipaddr_union(&p1->address, &p2->address);
-}
-
-/**
- * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @type: Type of this group.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type)
-{
- struct tomoyo_group *group = tomoyo_get_group(param, type);
- int error = -EINVAL;
- if (!group)
- return -ENOMEM;
- param->list = &group->member_list;
- if (type == TOMOYO_PATH_GROUP) {
- struct tomoyo_path_group e = { };
- e.member_name = tomoyo_get_name(tomoyo_read_token(param));
- if (!e.member_name) {
- error = -ENOMEM;
- goto out;
- }
- error = tomoyo_update_policy(&e.head, sizeof(e), param,
- tomoyo_same_path_group);
- tomoyo_put_name(e.member_name);
- } else if (type == TOMOYO_NUMBER_GROUP) {
- struct tomoyo_number_group e = { };
- if (param->data[0] == '@' ||
- !tomoyo_parse_number_union(param, &e.number))
- goto out;
- error = tomoyo_update_policy(&e.head, sizeof(e), param,
- tomoyo_same_number_group);
- /*
- * tomoyo_put_number_union() is not needed because
- * param->data[0] != '@'.
- */
- } else {
- struct tomoyo_address_group e = { };
-
- if (param->data[0] == '@' ||
- !tomoyo_parse_ipaddr_union(param, &e.address))
- goto out;
- error = tomoyo_update_policy(&e.head, sizeof(e), param,
- tomoyo_same_address_group);
- }
-out:
- tomoyo_put_group(group);
- return error;
-}
-
-/**
- * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group.
- *
- * @pathname: The name of pathname.
- * @group: Pointer to "struct tomoyo_path_group".
- *
- * Returns matched member's pathname if @pathname matches pathnames in @group,
- * NULL otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-const struct tomoyo_path_info *
-tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
- const struct tomoyo_group *group)
-{
- struct tomoyo_path_group *member;
- list_for_each_entry_rcu(member, &group->member_list, head.list) {
- if (member->head.is_deleted)
- continue;
- if (!tomoyo_path_matches_pattern(pathname, member->member_name))
- continue;
- return member->member_name;
- }
- return NULL;
-}
-
-/**
- * tomoyo_number_matches_group - Check whether the given number matches members of the given number group.
- *
- * @min: Min number.
- * @max: Max number.
- * @group: Pointer to "struct tomoyo_number_group".
- *
- * Returns true if @min and @max partially overlaps @group, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-bool tomoyo_number_matches_group(const unsigned long min,
- const unsigned long max,
- const struct tomoyo_group *group)
-{
- struct tomoyo_number_group *member;
- bool matched = false;
- list_for_each_entry_rcu(member, &group->member_list, head.list) {
- if (member->head.is_deleted)
- continue;
- if (min > member->number.values[1] ||
- max < member->number.values[0])
- continue;
- matched = true;
- break;
- }
- return matched;
-}
-
-/**
- * tomoyo_address_matches_group - Check whether the given address matches members of the given address group.
- *
- * @is_ipv6: True if @address is an IPv6 address.
- * @address: An IPv4 or IPv6 address.
- * @group: Pointer to "struct tomoyo_address_group".
- *
- * Returns true if @address matches addresses in @group group, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
- const struct tomoyo_group *group)
-{
- struct tomoyo_address_group *member;
- bool matched = false;
- const u8 size = is_ipv6 ? 16 : 4;
-
- list_for_each_entry_rcu(member, &group->member_list, head.list) {
- if (member->head.is_deleted)
- continue;
- if (member->address.is_ipv6 != is_ipv6)
- continue;
- if (memcmp(&member->address.ip[0], address, size) > 0 ||
- memcmp(address, &member->address.ip[1], size) > 0)
- continue;
- matched = true;
- break;
- }
- return matched;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/load_policy.c b/ANDROID_3.4.5/security/tomoyo/load_policy.c
deleted file mode 100644
index 078fac0b..00000000
--- a/ANDROID_3.4.5/security/tomoyo/load_policy.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * security/tomoyo/load_policy.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-
-#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
-
-/*
- * Path to the policy loader. (default = CONFIG_SECURITY_TOMOYO_POLICY_LOADER)
- */
-static const char *tomoyo_loader;
-
-/**
- * tomoyo_loader_setup - Set policy loader.
- *
- * @str: Program to use as a policy loader (e.g. /sbin/tomoyo-init ).
- *
- * Returns 0.
- */
-static int __init tomoyo_loader_setup(char *str)
-{
- tomoyo_loader = str;
- return 0;
-}
-
-__setup("TOMOYO_loader=", tomoyo_loader_setup);
-
-/**
- * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
- *
- * Returns true if /sbin/tomoyo-init exists, false otherwise.
- */
-static bool tomoyo_policy_loader_exists(void)
-{
- struct path path;
- if (!tomoyo_loader)
- tomoyo_loader = CONFIG_SECURITY_TOMOYO_POLICY_LOADER;
- if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
- printk(KERN_INFO "Not activating Mandatory Access Control "
- "as %s does not exist.\n", tomoyo_loader);
- return false;
- }
- path_put(&path);
- return true;
-}
-
-/*
- * Path to the trigger. (default = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER)
- */
-static const char *tomoyo_trigger;
-
-/**
- * tomoyo_trigger_setup - Set trigger for activation.
- *
- * @str: Program to use as an activation trigger (e.g. /sbin/init ).
- *
- * Returns 0.
- */
-static int __init tomoyo_trigger_setup(char *str)
-{
- tomoyo_trigger = str;
- return 0;
-}
-
-__setup("TOMOYO_trigger=", tomoyo_trigger_setup);
-
-/**
- * tomoyo_load_policy - Run external policy loader to load policy.
- *
- * @filename: The program about to start.
- *
- * This function checks whether @filename is /sbin/init , and if so
- * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init
- * and then continues invocation of /sbin/init.
- * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and
- * writes to /sys/kernel/security/tomoyo/ interfaces.
- *
- * Returns nothing.
- */
-void tomoyo_load_policy(const char *filename)
-{
- static bool done;
- char *argv[2];
- char *envp[3];
-
- if (tomoyo_policy_loaded || done)
- return;
- if (!tomoyo_trigger)
- tomoyo_trigger = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER;
- if (strcmp(filename, tomoyo_trigger))
- return;
- if (!tomoyo_policy_loader_exists())
- return;
- done = true;
- printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
- tomoyo_loader);
- argv[0] = (char *) tomoyo_loader;
- argv[1] = NULL;
- envp[0] = "HOME=/";
- envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
- envp[2] = NULL;
- call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
- tomoyo_check_profile();
-}
-
-#endif
diff --git a/ANDROID_3.4.5/security/tomoyo/memory.c b/ANDROID_3.4.5/security/tomoyo/memory.c
deleted file mode 100644
index 0e995716..00000000
--- a/ANDROID_3.4.5/security/tomoyo/memory.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * security/tomoyo/memory.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include <linux/hash.h>
-#include <linux/slab.h>
-#include "common.h"
-
-/**
- * tomoyo_warn_oom - Print out of memory warning message.
- *
- * @function: Function's name.
- */
-void tomoyo_warn_oom(const char *function)
-{
- /* Reduce error messages. */
- static pid_t tomoyo_last_pid;
- const pid_t pid = current->pid;
- if (tomoyo_last_pid != pid) {
- printk(KERN_WARNING "ERROR: Out of memory at %s.\n",
- function);
- tomoyo_last_pid = pid;
- }
- if (!tomoyo_policy_loaded)
- panic("MAC Initialization failed.\n");
-}
-
-/* Memoy currently used by policy/audit log/query. */
-unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
-/* Memory quota for "policy"/"audit log"/"query". */
-unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
-
-/**
- * tomoyo_memory_ok - Check memory quota.
- *
- * @ptr: Pointer to allocated memory.
- *
- * Returns true on success, false otherwise.
- *
- * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
- *
- * Caller holds tomoyo_policy_lock mutex.
- */
-bool tomoyo_memory_ok(void *ptr)
-{
- if (ptr) {
- const size_t s = ksize(ptr);
- tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
- if (!tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
- tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
- tomoyo_memory_quota[TOMOYO_MEMORY_POLICY])
- return true;
- tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
- }
- tomoyo_warn_oom(__func__);
- return false;
-}
-
-/**
- * tomoyo_commit_ok - Check memory quota.
- *
- * @data: Data to copy from.
- * @size: Size in byte.
- *
- * Returns pointer to allocated memory on success, NULL otherwise.
- * @data is zero-cleared on success.
- *
- * Caller holds tomoyo_policy_lock mutex.
- */
-void *tomoyo_commit_ok(void *data, const unsigned int size)
-{
- void *ptr = kzalloc(size, GFP_NOFS);
- if (tomoyo_memory_ok(ptr)) {
- memmove(ptr, data, size);
- memset(data, 0, size);
- return ptr;
- }
- kfree(ptr);
- return NULL;
-}
-
-/**
- * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @idx: Index number.
- *
- * Returns pointer to "struct tomoyo_group" on success, NULL otherwise.
- */
-struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
- const u8 idx)
-{
- struct tomoyo_group e = { };
- struct tomoyo_group *group = NULL;
- struct list_head *list;
- const char *group_name = tomoyo_read_token(param);
- bool found = false;
- if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP)
- return NULL;
- e.group_name = tomoyo_get_name(group_name);
- if (!e.group_name)
- return NULL;
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- goto out;
- list = &param->ns->group_list[idx];
- list_for_each_entry(group, list, head.list) {
- if (e.group_name != group->group_name ||
- atomic_read(&group->head.users) == TOMOYO_GC_IN_PROGRESS)
- continue;
- atomic_inc(&group->head.users);
- found = true;
- break;
- }
- if (!found) {
- struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e));
- if (entry) {
- INIT_LIST_HEAD(&entry->member_list);
- atomic_set(&entry->head.users, 1);
- list_add_tail_rcu(&entry->head.list, list);
- group = entry;
- found = true;
- }
- }
- mutex_unlock(&tomoyo_policy_lock);
-out:
- tomoyo_put_name(e.group_name);
- return found ? group : NULL;
-}
-
-/*
- * tomoyo_name_list is used for holding string data used by TOMOYO.
- * Since same string data is likely used for multiple times (e.g.
- * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
- * "const struct tomoyo_path_info *".
- */
-struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
-
-/**
- * tomoyo_get_name - Allocate permanent memory for string data.
- *
- * @name: The string to store into the permernent memory.
- *
- * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
- */
-const struct tomoyo_path_info *tomoyo_get_name(const char *name)
-{
- struct tomoyo_name *ptr;
- unsigned int hash;
- int len;
- struct list_head *head;
-
- if (!name)
- return NULL;
- len = strlen(name) + 1;
- hash = full_name_hash((const unsigned char *) name, len - 1);
- head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- return NULL;
- list_for_each_entry(ptr, head, head.list) {
- if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name) ||
- atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
- continue;
- atomic_inc(&ptr->head.users);
- goto out;
- }
- ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
- if (tomoyo_memory_ok(ptr)) {
- ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
- memmove((char *) ptr->entry.name, name, len);
- atomic_set(&ptr->head.users, 1);
- tomoyo_fill_path_info(&ptr->entry);
- list_add_tail(&ptr->head.list, head);
- } else {
- kfree(ptr);
- ptr = NULL;
- }
-out:
- mutex_unlock(&tomoyo_policy_lock);
- return ptr ? &ptr->entry : NULL;
-}
-
-/* Initial namespace.*/
-struct tomoyo_policy_namespace tomoyo_kernel_namespace;
-
-/**
- * tomoyo_mm_init - Initialize mm related code.
- */
-void __init tomoyo_mm_init(void)
-{
- int idx;
- for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
- INIT_LIST_HEAD(&tomoyo_name_list[idx]);
- tomoyo_kernel_namespace.name = "<kernel>";
- tomoyo_init_policy_namespace(&tomoyo_kernel_namespace);
- tomoyo_kernel_domain.ns = &tomoyo_kernel_namespace;
- INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
- tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>");
- list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/mount.c b/ANDROID_3.4.5/security/tomoyo/mount.c
deleted file mode 100644
index fe00cdfd..00000000
--- a/ANDROID_3.4.5/security/tomoyo/mount.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * security/tomoyo/mount.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include <linux/slab.h>
-#include "common.h"
-
-/* String table for special mount operations. */
-static const char * const tomoyo_mounts[TOMOYO_MAX_SPECIAL_MOUNT] = {
- [TOMOYO_MOUNT_BIND] = "--bind",
- [TOMOYO_MOUNT_MOVE] = "--move",
- [TOMOYO_MOUNT_REMOUNT] = "--remount",
- [TOMOYO_MOUNT_MAKE_UNBINDABLE] = "--make-unbindable",
- [TOMOYO_MOUNT_MAKE_PRIVATE] = "--make-private",
- [TOMOYO_MOUNT_MAKE_SLAVE] = "--make-slave",
- [TOMOYO_MOUNT_MAKE_SHARED] = "--make-shared",
-};
-
-/**
- * tomoyo_audit_mount_log - Audit mount log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
-{
- return tomoyo_supervisor(r, "file mount %s %s %s 0x%lX\n",
- r->param.mount.dev->name,
- r->param.mount.dir->name,
- r->param.mount.type->name,
- r->param.mount.flags);
-}
-
-/**
- * tomoyo_check_mount_acl - Check permission for path path path number operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_mount_acl *acl =
- container_of(ptr, typeof(*acl), head);
- return tomoyo_compare_number_union(r->param.mount.flags,
- &acl->flags) &&
- tomoyo_compare_name_union(r->param.mount.type,
- &acl->fs_type) &&
- tomoyo_compare_name_union(r->param.mount.dir,
- &acl->dir_name) &&
- (!r->param.mount.need_dev ||
- tomoyo_compare_name_union(r->param.mount.dev,
- &acl->dev_name));
-}
-
-/**
- * tomoyo_mount_acl - Check permission for mount() operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @dev_name: Name of device file. Maybe NULL.
- * @dir: Pointer to "struct path".
- * @type: Name of filesystem type.
- * @flags: Mount options.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
- struct path *dir, const char *type,
- unsigned long flags)
-{
- struct tomoyo_obj_info obj = { };
- struct path path;
- struct file_system_type *fstype = NULL;
- const char *requested_type = NULL;
- const char *requested_dir_name = NULL;
- const char *requested_dev_name = NULL;
- struct tomoyo_path_info rtype;
- struct tomoyo_path_info rdev;
- struct tomoyo_path_info rdir;
- int need_dev = 0;
- int error = -ENOMEM;
- r->obj = &obj;
-
- /* Get fstype. */
- requested_type = tomoyo_encode(type);
- if (!requested_type)
- goto out;
- rtype.name = requested_type;
- tomoyo_fill_path_info(&rtype);
-
- /* Get mount point. */
- obj.path2 = *dir;
- requested_dir_name = tomoyo_realpath_from_path(dir);
- if (!requested_dir_name) {
- error = -ENOMEM;
- goto out;
- }
- rdir.name = requested_dir_name;
- tomoyo_fill_path_info(&rdir);
-
- /* Compare fs name. */
- if (type == tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]) {
- /* dev_name is ignored. */
- } else if (type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE] ||
- type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE] ||
- type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE] ||
- type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]) {
- /* dev_name is ignored. */
- } else if (type == tomoyo_mounts[TOMOYO_MOUNT_BIND] ||
- type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) {
- need_dev = -1; /* dev_name is a directory */
- } else {
- fstype = get_fs_type(type);
- if (!fstype) {
- error = -ENODEV;
- goto out;
- }
- if (fstype->fs_flags & FS_REQUIRES_DEV)
- /* dev_name is a block device file. */
- need_dev = 1;
- }
- if (need_dev) {
- /* Get mount point or device file. */
- if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
- error = -ENOENT;
- goto out;
- }
- obj.path1 = path;
- requested_dev_name = tomoyo_realpath_from_path(&path);
- if (!requested_dev_name) {
- error = -ENOENT;
- goto out;
- }
- } else {
- /* Map dev_name to "<NULL>" if no dev_name given. */
- if (!dev_name)
- dev_name = "<NULL>";
- requested_dev_name = tomoyo_encode(dev_name);
- if (!requested_dev_name) {
- error = -ENOMEM;
- goto out;
- }
- }
- rdev.name = requested_dev_name;
- tomoyo_fill_path_info(&rdev);
- r->param_type = TOMOYO_TYPE_MOUNT_ACL;
- r->param.mount.need_dev = need_dev;
- r->param.mount.dev = &rdev;
- r->param.mount.dir = &rdir;
- r->param.mount.type = &rtype;
- r->param.mount.flags = flags;
- do {
- tomoyo_check_acl(r, tomoyo_check_mount_acl);
- error = tomoyo_audit_mount_log(r);
- } while (error == TOMOYO_RETRY_REQUEST);
- out:
- kfree(requested_dev_name);
- kfree(requested_dir_name);
- if (fstype)
- put_filesystem(fstype);
- kfree(requested_type);
- /* Drop refcount obtained by kern_path(). */
- if (obj.path1.dentry)
- path_put(&obj.path1);
- return error;
-}
-
-/**
- * tomoyo_mount_permission - Check permission for mount() operation.
- *
- * @dev_name: Name of device file. Maybe NULL.
- * @path: Pointer to "struct path".
- * @type: Name of filesystem type. Maybe NULL.
- * @flags: Mount options.
- * @data_page: Optional data. Maybe NULL.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_mount_permission(char *dev_name, struct path *path,
- const char *type, unsigned long flags,
- void *data_page)
-{
- struct tomoyo_request_info r;
- int error;
- int idx;
-
- if (tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_MOUNT)
- == TOMOYO_CONFIG_DISABLED)
- return 0;
- if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
- flags &= ~MS_MGC_MSK;
- if (flags & MS_REMOUNT) {
- type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT];
- flags &= ~MS_REMOUNT;
- } else if (flags & MS_BIND) {
- type = tomoyo_mounts[TOMOYO_MOUNT_BIND];
- flags &= ~MS_BIND;
- } else if (flags & MS_SHARED) {
- if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
- return -EINVAL;
- type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED];
- flags &= ~MS_SHARED;
- } else if (flags & MS_PRIVATE) {
- if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE))
- return -EINVAL;
- type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE];
- flags &= ~MS_PRIVATE;
- } else if (flags & MS_SLAVE) {
- if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE))
- return -EINVAL;
- type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE];
- flags &= ~MS_SLAVE;
- } else if (flags & MS_UNBINDABLE) {
- if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE))
- return -EINVAL;
- type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE];
- flags &= ~MS_UNBINDABLE;
- } else if (flags & MS_MOVE) {
- type = tomoyo_mounts[TOMOYO_MOUNT_MOVE];
- flags &= ~MS_MOVE;
- }
- if (!type)
- type = "<NULL>";
- idx = tomoyo_read_lock();
- error = tomoyo_mount_acl(&r, dev_name, path, type, flags);
- tomoyo_read_unlock(idx);
- return error;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/network.c b/ANDROID_3.4.5/security/tomoyo/network.c
deleted file mode 100644
index 97527710..00000000
--- a/ANDROID_3.4.5/security/tomoyo/network.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- * security/tomoyo/network.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-#include <linux/slab.h>
-
-/* Structure for holding inet domain socket's address. */
-struct tomoyo_inet_addr_info {
- __be16 port; /* In network byte order. */
- const __be32 *address; /* In network byte order. */
- bool is_ipv6;
-};
-
-/* Structure for holding unix domain socket's address. */
-struct tomoyo_unix_addr_info {
- u8 *addr; /* This may not be '\0' terminated string. */
- unsigned int addr_len;
-};
-
-/* Structure for holding socket address. */
-struct tomoyo_addr_info {
- u8 protocol;
- u8 operation;
- struct tomoyo_inet_addr_info inet;
- struct tomoyo_unix_addr_info unix0;
-};
-
-/* String table for socket's protocols. */
-const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX] = {
- [SOCK_STREAM] = "stream",
- [SOCK_DGRAM] = "dgram",
- [SOCK_RAW] = "raw",
- [SOCK_SEQPACKET] = "seqpacket",
- [0] = " ", /* Dummy for avoiding NULL pointer dereference. */
- [4] = " ", /* Dummy for avoiding NULL pointer dereference. */
-};
-
-/**
- * tomoyo_parse_ipaddr_union - Parse an IP address.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @ptr: Pointer to "struct tomoyo_ipaddr_union".
- *
- * Returns true on success, false otherwise.
- */
-bool tomoyo_parse_ipaddr_union(struct tomoyo_acl_param *param,
- struct tomoyo_ipaddr_union *ptr)
-{
- u8 * const min = ptr->ip[0].in6_u.u6_addr8;
- u8 * const max = ptr->ip[1].in6_u.u6_addr8;
- char *address = tomoyo_read_token(param);
- const char *end;
-
- if (!strchr(address, ':') &&
- in4_pton(address, -1, min, '-', &end) > 0) {
- ptr->is_ipv6 = false;
- if (!*end)
- ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
- else if (*end++ != '-' ||
- in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
- return false;
- return true;
- }
- if (in6_pton(address, -1, min, '-', &end) > 0) {
- ptr->is_ipv6 = true;
- if (!*end)
- memmove(max, min, sizeof(u16) * 8);
- else if (*end++ != '-' ||
- in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
- return false;
- return true;
- }
- return false;
-}
-
-/**
- * tomoyo_print_ipv4 - Print an IPv4 address.
- *
- * @buffer: Buffer to write to.
- * @buffer_len: Size of @buffer.
- * @min_ip: Pointer to __be32.
- * @max_ip: Pointer to __be32.
- *
- * Returns nothing.
- */
-static void tomoyo_print_ipv4(char *buffer, const unsigned int buffer_len,
- const __be32 *min_ip, const __be32 *max_ip)
-{
- snprintf(buffer, buffer_len, "%pI4%c%pI4", min_ip,
- *min_ip == *max_ip ? '\0' : '-', max_ip);
-}
-
-/**
- * tomoyo_print_ipv6 - Print an IPv6 address.
- *
- * @buffer: Buffer to write to.
- * @buffer_len: Size of @buffer.
- * @min_ip: Pointer to "struct in6_addr".
- * @max_ip: Pointer to "struct in6_addr".
- *
- * Returns nothing.
- */
-static void tomoyo_print_ipv6(char *buffer, const unsigned int buffer_len,
- const struct in6_addr *min_ip,
- const struct in6_addr *max_ip)
-{
- snprintf(buffer, buffer_len, "%pI6c%c%pI6c", min_ip,
- !memcmp(min_ip, max_ip, 16) ? '\0' : '-', max_ip);
-}
-
-/**
- * tomoyo_print_ip - Print an IP address.
- *
- * @buf: Buffer to write to.
- * @size: Size of @buf.
- * @ptr: Pointer to "struct ipaddr_union".
- *
- * Returns nothing.
- */
-void tomoyo_print_ip(char *buf, const unsigned int size,
- const struct tomoyo_ipaddr_union *ptr)
-{
- if (ptr->is_ipv6)
- tomoyo_print_ipv6(buf, size, &ptr->ip[0], &ptr->ip[1]);
- else
- tomoyo_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0],
- &ptr->ip[1].s6_addr32[0]);
-}
-
-/*
- * Mapping table from "enum tomoyo_network_acl_index" to
- * "enum tomoyo_mac_index" for inet domain socket.
- */
-static const u8 tomoyo_inet2mac
-[TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
- [SOCK_STREAM] = {
- [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_STREAM_BIND,
- [TOMOYO_NETWORK_LISTEN] =
- TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN,
- [TOMOYO_NETWORK_CONNECT] =
- TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT,
- },
- [SOCK_DGRAM] = {
- [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_DGRAM_BIND,
- [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_DGRAM_SEND,
- },
- [SOCK_RAW] = {
- [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_RAW_BIND,
- [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_RAW_SEND,
- },
-};
-
-/*
- * Mapping table from "enum tomoyo_network_acl_index" to
- * "enum tomoyo_mac_index" for unix domain socket.
- */
-static const u8 tomoyo_unix2mac
-[TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
- [SOCK_STREAM] = {
- [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND,
- [TOMOYO_NETWORK_LISTEN] =
- TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN,
- [TOMOYO_NETWORK_CONNECT] =
- TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT,
- },
- [SOCK_DGRAM] = {
- [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND,
- [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND,
- },
- [SOCK_SEQPACKET] = {
- [TOMOYO_NETWORK_BIND] =
- TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND,
- [TOMOYO_NETWORK_LISTEN] =
- TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
- [TOMOYO_NETWORK_CONNECT] =
- TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
- },
-};
-
-/**
- * tomoyo_same_inet_acl - Check for duplicated "struct tomoyo_inet_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool tomoyo_same_inet_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_inet_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_inet_acl *p2 = container_of(b, typeof(*p2), head);
-
- return p1->protocol == p2->protocol &&
- tomoyo_same_ipaddr_union(&p1->address, &p2->address) &&
- tomoyo_same_number_union(&p1->port, &p2->port);
-}
-
-/**
- * tomoyo_same_unix_acl - Check for duplicated "struct tomoyo_unix_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool tomoyo_same_unix_acl(const struct tomoyo_acl_info *a,
- const struct tomoyo_acl_info *b)
-{
- const struct tomoyo_unix_acl *p1 = container_of(a, typeof(*p1), head);
- const struct tomoyo_unix_acl *p2 = container_of(b, typeof(*p2), head);
-
- return p1->protocol == p2->protocol &&
- tomoyo_same_name_union(&p1->name, &p2->name);
-}
-
-/**
- * tomoyo_merge_inet_acl - Merge duplicated "struct tomoyo_inet_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool tomoyo_merge_inet_acl(struct tomoyo_acl_info *a,
- struct tomoyo_acl_info *b,
- const bool is_delete)
-{
- u8 * const a_perm =
- &container_of(a, struct tomoyo_inet_acl, head)->perm;
- u8 perm = *a_perm;
- const u8 b_perm = container_of(b, struct tomoyo_inet_acl, head)->perm;
-
- if (is_delete)
- perm &= ~b_perm;
- else
- perm |= b_perm;
- *a_perm = perm;
- return !perm;
-}
-
-/**
- * tomoyo_merge_unix_acl - Merge duplicated "struct tomoyo_unix_acl" entry.
- *
- * @a: Pointer to "struct tomoyo_acl_info".
- * @b: Pointer to "struct tomoyo_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool tomoyo_merge_unix_acl(struct tomoyo_acl_info *a,
- struct tomoyo_acl_info *b,
- const bool is_delete)
-{
- u8 * const a_perm =
- &container_of(a, struct tomoyo_unix_acl, head)->perm;
- u8 perm = *a_perm;
- const u8 b_perm = container_of(b, struct tomoyo_unix_acl, head)->perm;
-
- if (is_delete)
- perm &= ~b_perm;
- else
- perm |= b_perm;
- *a_perm = perm;
- return !perm;
-}
-
-/**
- * tomoyo_write_inet_network - Write "struct tomoyo_inet_acl" list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-int tomoyo_write_inet_network(struct tomoyo_acl_param *param)
-{
- struct tomoyo_inet_acl e = { .head.type = TOMOYO_TYPE_INET_ACL };
- int error = -EINVAL;
- u8 type;
- const char *protocol = tomoyo_read_token(param);
- const char *operation = tomoyo_read_token(param);
-
- for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
- if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
- break;
- for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
- if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
- e.perm |= 1 << type;
- if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
- return -EINVAL;
- if (param->data[0] == '@') {
- param->data++;
- e.address.group =
- tomoyo_get_group(param, TOMOYO_ADDRESS_GROUP);
- if (!e.address.group)
- return -ENOMEM;
- } else {
- if (!tomoyo_parse_ipaddr_union(param, &e.address))
- goto out;
- }
- if (!tomoyo_parse_number_union(param, &e.port) ||
- e.port.values[1] > 65535)
- goto out;
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_inet_acl,
- tomoyo_merge_inet_acl);
-out:
- tomoyo_put_group(e.address.group);
- tomoyo_put_number_union(&e.port);
- return error;
-}
-
-/**
- * tomoyo_write_unix_network - Write "struct tomoyo_unix_acl" list.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_write_unix_network(struct tomoyo_acl_param *param)
-{
- struct tomoyo_unix_acl e = { .head.type = TOMOYO_TYPE_UNIX_ACL };
- int error;
- u8 type;
- const char *protocol = tomoyo_read_token(param);
- const char *operation = tomoyo_read_token(param);
-
- for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
- if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
- break;
- for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
- if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
- e.perm |= 1 << type;
- if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
- return -EINVAL;
- if (!tomoyo_parse_name_union(param, &e.name))
- return -EINVAL;
- error = tomoyo_update_domain(&e.head, sizeof(e), param,
- tomoyo_same_unix_acl,
- tomoyo_merge_unix_acl);
- tomoyo_put_name_union(&e.name);
- return error;
-}
-
-/**
- * tomoyo_audit_net_log - Audit network log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @family: Name of socket family ("inet" or "unix").
- * @protocol: Name of protocol in @family.
- * @operation: Name of socket operation.
- * @address: Name of address.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_net_log(struct tomoyo_request_info *r,
- const char *family, const u8 protocol,
- const u8 operation, const char *address)
-{
- return tomoyo_supervisor(r, "network %s %s %s %s\n", family,
- tomoyo_proto_keyword[protocol],
- tomoyo_socket_keyword[operation], address);
-}
-
-/**
- * tomoyo_audit_inet_log - Audit INET network log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_inet_log(struct tomoyo_request_info *r)
-{
- char buf[128];
- int len;
- const __be32 *address = r->param.inet_network.address;
-
- if (r->param.inet_network.is_ipv6)
- tomoyo_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)
- address, (const struct in6_addr *) address);
- else
- tomoyo_print_ipv4(buf, sizeof(buf), address, address);
- len = strlen(buf);
- snprintf(buf + len, sizeof(buf) - len, " %u",
- r->param.inet_network.port);
- return tomoyo_audit_net_log(r, "inet", r->param.inet_network.protocol,
- r->param.inet_network.operation, buf);
-}
-
-/**
- * tomoyo_audit_unix_log - Audit UNIX network log.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_audit_unix_log(struct tomoyo_request_info *r)
-{
- return tomoyo_audit_net_log(r, "unix", r->param.unix_network.protocol,
- r->param.unix_network.operation,
- r->param.unix_network.address->name);
-}
-
-/**
- * tomoyo_check_inet_acl - Check permission for inet domain socket operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_inet_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_inet_acl *acl =
- container_of(ptr, typeof(*acl), head);
- const u8 size = r->param.inet_network.is_ipv6 ? 16 : 4;
-
- if (!(acl->perm & (1 << r->param.inet_network.operation)) ||
- !tomoyo_compare_number_union(r->param.inet_network.port,
- &acl->port))
- return false;
- if (acl->address.group)
- return tomoyo_address_matches_group
- (r->param.inet_network.is_ipv6,
- r->param.inet_network.address, acl->address.group);
- return acl->address.is_ipv6 == r->param.inet_network.is_ipv6 &&
- memcmp(&acl->address.ip[0],
- r->param.inet_network.address, size) <= 0 &&
- memcmp(r->param.inet_network.address,
- &acl->address.ip[1], size) <= 0;
-}
-
-/**
- * tomoyo_check_unix_acl - Check permission for unix domain socket operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_unix_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_unix_acl *acl =
- container_of(ptr, typeof(*acl), head);
-
- return (acl->perm & (1 << r->param.unix_network.operation)) &&
- tomoyo_compare_name_union(r->param.unix_network.address,
- &acl->name);
-}
-
-/**
- * tomoyo_inet_entry - Check permission for INET network operation.
- *
- * @address: Pointer to "struct tomoyo_addr_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_inet_entry(const struct tomoyo_addr_info *address)
-{
- const int idx = tomoyo_read_lock();
- struct tomoyo_request_info r;
- int error = 0;
- const u8 type = tomoyo_inet2mac[address->protocol][address->operation];
-
- if (type && tomoyo_init_request_info(&r, NULL, type)
- != TOMOYO_CONFIG_DISABLED) {
- r.param_type = TOMOYO_TYPE_INET_ACL;
- r.param.inet_network.protocol = address->protocol;
- r.param.inet_network.operation = address->operation;
- r.param.inet_network.is_ipv6 = address->inet.is_ipv6;
- r.param.inet_network.address = address->inet.address;
- r.param.inet_network.port = ntohs(address->inet.port);
- do {
- tomoyo_check_acl(&r, tomoyo_check_inet_acl);
- error = tomoyo_audit_inet_log(&r);
- } while (error == TOMOYO_RETRY_REQUEST);
- }
- tomoyo_read_unlock(idx);
- return error;
-}
-
-/**
- * tomoyo_check_inet_address - Check permission for inet domain socket's operation.
- *
- * @addr: Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- * @port: Port number.
- * @address: Pointer to "struct tomoyo_addr_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_check_inet_address(const struct sockaddr *addr,
- const unsigned int addr_len,
- const u16 port,
- struct tomoyo_addr_info *address)
-{
- struct tomoyo_inet_addr_info *i = &address->inet;
-
- switch (addr->sa_family) {
- case AF_INET6:
- if (addr_len < SIN6_LEN_RFC2133)
- goto skip;
- i->is_ipv6 = true;
- i->address = (__be32 *)
- ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
- i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
- break;
- case AF_INET:
- if (addr_len < sizeof(struct sockaddr_in))
- goto skip;
- i->is_ipv6 = false;
- i->address = (__be32 *)
- &((struct sockaddr_in *) addr)->sin_addr;
- i->port = ((struct sockaddr_in *) addr)->sin_port;
- break;
- default:
- goto skip;
- }
- if (address->protocol == SOCK_RAW)
- i->port = htons(port);
- return tomoyo_inet_entry(address);
-skip:
- return 0;
-}
-
-/**
- * tomoyo_unix_entry - Check permission for UNIX network operation.
- *
- * @address: Pointer to "struct tomoyo_addr_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_unix_entry(const struct tomoyo_addr_info *address)
-{
- const int idx = tomoyo_read_lock();
- struct tomoyo_request_info r;
- int error = 0;
- const u8 type = tomoyo_unix2mac[address->protocol][address->operation];
-
- if (type && tomoyo_init_request_info(&r, NULL, type)
- != TOMOYO_CONFIG_DISABLED) {
- char *buf = address->unix0.addr;
- int len = address->unix0.addr_len - sizeof(sa_family_t);
-
- if (len <= 0) {
- buf = "anonymous";
- len = 9;
- } else if (buf[0]) {
- len = strnlen(buf, len);
- }
- buf = tomoyo_encode2(buf, len);
- if (buf) {
- struct tomoyo_path_info addr;
-
- addr.name = buf;
- tomoyo_fill_path_info(&addr);
- r.param_type = TOMOYO_TYPE_UNIX_ACL;
- r.param.unix_network.protocol = address->protocol;
- r.param.unix_network.operation = address->operation;
- r.param.unix_network.address = &addr;
- do {
- tomoyo_check_acl(&r, tomoyo_check_unix_acl);
- error = tomoyo_audit_unix_log(&r);
- } while (error == TOMOYO_RETRY_REQUEST);
- kfree(buf);
- } else
- error = -ENOMEM;
- }
- tomoyo_read_unlock(idx);
- return error;
-}
-
-/**
- * tomoyo_check_unix_address - Check permission for unix domain socket's operation.
- *
- * @addr: Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- * @address: Pointer to "struct tomoyo_addr_info".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_check_unix_address(struct sockaddr *addr,
- const unsigned int addr_len,
- struct tomoyo_addr_info *address)
-{
- struct tomoyo_unix_addr_info *u = &address->unix0;
-
- if (addr->sa_family != AF_UNIX)
- return 0;
- u->addr = ((struct sockaddr_un *) addr)->sun_path;
- u->addr_len = addr_len;
- return tomoyo_unix_entry(address);
-}
-
-/**
- * tomoyo_kernel_service - Check whether I'm kernel service or not.
- *
- * Returns true if I'm kernel service, false otherwise.
- */
-static bool tomoyo_kernel_service(void)
-{
- /* Nothing to do if I am a kernel service. */
- return segment_eq(get_fs(), KERNEL_DS);
-}
-
-/**
- * tomoyo_sock_family - Get socket's family.
- *
- * @sk: Pointer to "struct sock".
- *
- * Returns one of PF_INET, PF_INET6, PF_UNIX or 0.
- */
-static u8 tomoyo_sock_family(struct sock *sk)
-{
- u8 family;
-
- if (tomoyo_kernel_service())
- return 0;
- family = sk->sk_family;
- switch (family) {
- case PF_INET:
- case PF_INET6:
- case PF_UNIX:
- return family;
- default:
- return 0;
- }
-}
-
-/**
- * tomoyo_socket_listen_permission - Check permission for listening a socket.
- *
- * @sock: Pointer to "struct socket".
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_socket_listen_permission(struct socket *sock)
-{
- struct tomoyo_addr_info address;
- const u8 family = tomoyo_sock_family(sock->sk);
- const unsigned int type = sock->type;
- struct sockaddr_storage addr;
- int addr_len;
-
- if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))
- return 0;
- {
- const int error = sock->ops->getname(sock, (struct sockaddr *)
- &addr, &addr_len, 0);
-
- if (error)
- return error;
- }
- address.protocol = type;
- address.operation = TOMOYO_NETWORK_LISTEN;
- if (family == PF_UNIX)
- return tomoyo_check_unix_address((struct sockaddr *) &addr,
- addr_len, &address);
- return tomoyo_check_inet_address((struct sockaddr *) &addr, addr_len,
- 0, &address);
-}
-
-/**
- * tomoyo_socket_connect_permission - Check permission for setting the remote address of a socket.
- *
- * @sock: Pointer to "struct socket".
- * @addr: Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_socket_connect_permission(struct socket *sock,
- struct sockaddr *addr, int addr_len)
-{
- struct tomoyo_addr_info address;
- const u8 family = tomoyo_sock_family(sock->sk);
- const unsigned int type = sock->type;
-
- if (!family)
- return 0;
- address.protocol = type;
- switch (type) {
- case SOCK_DGRAM:
- case SOCK_RAW:
- address.operation = TOMOYO_NETWORK_SEND;
- break;
- case SOCK_STREAM:
- case SOCK_SEQPACKET:
- address.operation = TOMOYO_NETWORK_CONNECT;
- break;
- default:
- return 0;
- }
- if (family == PF_UNIX)
- return tomoyo_check_unix_address(addr, addr_len, &address);
- return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
- &address);
-}
-
-/**
- * tomoyo_socket_bind_permission - Check permission for setting the local address of a socket.
- *
- * @sock: Pointer to "struct socket".
- * @addr: Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
- int addr_len)
-{
- struct tomoyo_addr_info address;
- const u8 family = tomoyo_sock_family(sock->sk);
- const unsigned int type = sock->type;
-
- if (!family)
- return 0;
- switch (type) {
- case SOCK_STREAM:
- case SOCK_DGRAM:
- case SOCK_RAW:
- case SOCK_SEQPACKET:
- address.protocol = type;
- address.operation = TOMOYO_NETWORK_BIND;
- break;
- default:
- return 0;
- }
- if (family == PF_UNIX)
- return tomoyo_check_unix_address(addr, addr_len, &address);
- return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
- &address);
-}
-
-/**
- * tomoyo_socket_sendmsg_permission - Check permission for sending a datagram.
- *
- * @sock: Pointer to "struct socket".
- * @msg: Pointer to "struct msghdr".
- * @size: Unused.
- *
- * Returns 0 on success, negative value otherwise.
- */
-int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg,
- int size)
-{
- struct tomoyo_addr_info address;
- const u8 family = tomoyo_sock_family(sock->sk);
- const unsigned int type = sock->type;
-
- if (!msg->msg_name || !family ||
- (type != SOCK_DGRAM && type != SOCK_RAW))
- return 0;
- address.protocol = type;
- address.operation = TOMOYO_NETWORK_SEND;
- if (family == PF_UNIX)
- return tomoyo_check_unix_address((struct sockaddr *)
- msg->msg_name,
- msg->msg_namelen, &address);
- return tomoyo_check_inet_address((struct sockaddr *) msg->msg_name,
- msg->msg_namelen,
- sock->sk->sk_protocol, &address);
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/realpath.c b/ANDROID_3.4.5/security/tomoyo/realpath.c
deleted file mode 100644
index 80a09c37..00000000
--- a/ANDROID_3.4.5/security/tomoyo/realpath.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * security/tomoyo/realpath.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include "common.h"
-#include <linux/magic.h>
-
-/**
- * tomoyo_encode2 - Encode binary string to ascii string.
- *
- * @str: String in binary format.
- * @str_len: Size of @str in byte.
- *
- * Returns pointer to @str in ascii format on success, NULL otherwise.
- *
- * This function uses kzalloc(), so caller must kfree() if this function
- * didn't return NULL.
- */
-char *tomoyo_encode2(const char *str, int str_len)
-{
- int i;
- int len = 0;
- const char *p = str;
- char *cp;
- char *cp0;
-
- if (!p)
- return NULL;
- for (i = 0; i < str_len; i++) {
- const unsigned char c = p[i];
-
- if (c == '\\')
- len += 2;
- else if (c > ' ' && c < 127)
- len++;
- else
- len += 4;
- }
- len++;
- /* Reserve space for appending "/". */
- cp = kzalloc(len + 10, GFP_NOFS);
- if (!cp)
- return NULL;
- cp0 = cp;
- p = str;
- for (i = 0; i < str_len; i++) {
- const unsigned char c = p[i];
-
- if (c == '\\') {
- *cp++ = '\\';
- *cp++ = '\\';
- } else if (c > ' ' && c < 127) {
- *cp++ = c;
- } else {
- *cp++ = '\\';
- *cp++ = (c >> 6) + '0';
- *cp++ = ((c >> 3) & 7) + '0';
- *cp++ = (c & 7) + '0';
- }
- }
- return cp0;
-}
-
-/**
- * tomoyo_encode - Encode binary string to ascii string.
- *
- * @str: String in binary format.
- *
- * Returns pointer to @str in ascii format on success, NULL otherwise.
- *
- * This function uses kzalloc(), so caller must kfree() if this function
- * didn't return NULL.
- */
-char *tomoyo_encode(const char *str)
-{
- return str ? tomoyo_encode2(str, strlen(str)) : NULL;
-}
-
-/**
- * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
- *
- * @path: Pointer to "struct path".
- * @buffer: Pointer to buffer to return value in.
- * @buflen: Sizeof @buffer.
- *
- * Returns the buffer on success, an error code otherwise.
- *
- * If dentry is a directory, trailing '/' is appended.
- */
-static char *tomoyo_get_absolute_path(struct path *path, char * const buffer,
- const int buflen)
-{
- char *pos = ERR_PTR(-ENOMEM);
- if (buflen >= 256) {
- /* go to whatever namespace root we are under */
- pos = d_absolute_path(path, buffer, buflen - 1);
- if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
- struct inode *inode = path->dentry->d_inode;
- if (inode && S_ISDIR(inode->i_mode)) {
- buffer[buflen - 2] = '/';
- buffer[buflen - 1] = '\0';
- }
- }
- }
- return pos;
-}
-
-/**
- * tomoyo_get_dentry_path - Get the path of a dentry.
- *
- * @dentry: Pointer to "struct dentry".
- * @buffer: Pointer to buffer to return value in.
- * @buflen: Sizeof @buffer.
- *
- * Returns the buffer on success, an error code otherwise.
- *
- * If dentry is a directory, trailing '/' is appended.
- */
-static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer,
- const int buflen)
-{
- char *pos = ERR_PTR(-ENOMEM);
- if (buflen >= 256) {
- pos = dentry_path_raw(dentry, buffer, buflen - 1);
- if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
- struct inode *inode = dentry->d_inode;
- if (inode && S_ISDIR(inode->i_mode)) {
- buffer[buflen - 2] = '/';
- buffer[buflen - 1] = '\0';
- }
- }
- }
- return pos;
-}
-
-/**
- * tomoyo_get_local_path - Get the path of a dentry.
- *
- * @dentry: Pointer to "struct dentry".
- * @buffer: Pointer to buffer to return value in.
- * @buflen: Sizeof @buffer.
- *
- * Returns the buffer on success, an error code otherwise.
- */
-static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer,
- const int buflen)
-{
- struct super_block *sb = dentry->d_sb;
- char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen);
- if (IS_ERR(pos))
- return pos;
- /* Convert from $PID to self if $PID is current thread. */
- if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {
- char *ep;
- const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10);
- if (*ep == '/' && pid && pid ==
- task_tgid_nr_ns(current, sb->s_fs_info)) {
- pos = ep - 5;
- if (pos < buffer)
- goto out;
- memmove(pos, "/self", 5);
- }
- goto prepend_filesystem_name;
- }
- /* Use filesystem name for unnamed devices. */
- if (!MAJOR(sb->s_dev))
- goto prepend_filesystem_name;
- {
- struct inode *inode = sb->s_root->d_inode;
- /*
- * Use filesystem name if filesystem does not support rename()
- * operation.
- */
- if (inode->i_op && !inode->i_op->rename)
- goto prepend_filesystem_name;
- }
- /* Prepend device name. */
- {
- char name[64];
- int name_len;
- const dev_t dev = sb->s_dev;
- name[sizeof(name) - 1] = '\0';
- snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev),
- MINOR(dev));
- name_len = strlen(name);
- pos -= name_len;
- if (pos < buffer)
- goto out;
- memmove(pos, name, name_len);
- return pos;
- }
- /* Prepend filesystem name. */
-prepend_filesystem_name:
- {
- const char *name = sb->s_type->name;
- const int name_len = strlen(name);
- pos -= name_len + 1;
- if (pos < buffer)
- goto out;
- memmove(pos, name, name_len);
- pos[name_len] = ':';
- }
- return pos;
-out:
- return ERR_PTR(-ENOMEM);
-}
-
-/**
- * tomoyo_get_socket_name - Get the name of a socket.
- *
- * @path: Pointer to "struct path".
- * @buffer: Pointer to buffer to return value in.
- * @buflen: Sizeof @buffer.
- *
- * Returns the buffer.
- */
-static char *tomoyo_get_socket_name(struct path *path, char * const buffer,
- const int buflen)
-{
- struct inode *inode = path->dentry->d_inode;
- struct socket *sock = inode ? SOCKET_I(inode) : NULL;
- struct sock *sk = sock ? sock->sk : NULL;
- if (sk) {
- snprintf(buffer, buflen, "socket:[family=%u:type=%u:"
- "protocol=%u]", sk->sk_family, sk->sk_type,
- sk->sk_protocol);
- } else {
- snprintf(buffer, buflen, "socket:[unknown]");
- }
- return buffer;
-}
-
-/**
- * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
- *
- * @path: Pointer to "struct path".
- *
- * Returns the realpath of the given @path on success, NULL otherwise.
- *
- * If dentry is a directory, trailing '/' is appended.
- * Characters out of 0x20 < c < 0x7F range are converted to
- * \ooo style octal string.
- * Character \ is converted to \\ string.
- *
- * These functions use kzalloc(), so the caller must call kfree()
- * if these functions didn't return NULL.
- */
-char *tomoyo_realpath_from_path(struct path *path)
-{
- char *buf = NULL;
- char *name = NULL;
- unsigned int buf_len = PAGE_SIZE / 2;
- struct dentry *dentry = path->dentry;
- struct super_block *sb;
- if (!dentry)
- return NULL;
- sb = dentry->d_sb;
- while (1) {
- char *pos;
- struct inode *inode;
- buf_len <<= 1;
- kfree(buf);
- buf = kmalloc(buf_len, GFP_NOFS);
- if (!buf)
- break;
- /* To make sure that pos is '\0' terminated. */
- buf[buf_len - 1] = '\0';
- /* Get better name for socket. */
- if (sb->s_magic == SOCKFS_MAGIC) {
- pos = tomoyo_get_socket_name(path, buf, buf_len - 1);
- goto encode;
- }
- /* For "pipe:[\$]". */
- if (dentry->d_op && dentry->d_op->d_dname) {
- pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1);
- goto encode;
- }
- inode = sb->s_root->d_inode;
- /*
- * Get local name for filesystems without rename() operation
- * or dentry without vfsmount.
- */
- if (!path->mnt || (inode->i_op && !inode->i_op->rename))
- pos = tomoyo_get_local_path(path->dentry, buf,
- buf_len - 1);
- /* Get absolute name for the rest. */
- else {
- pos = tomoyo_get_absolute_path(path, buf, buf_len - 1);
- /*
- * Fall back to local name if absolute name is not
- * available.
- */
- if (pos == ERR_PTR(-EINVAL))
- pos = tomoyo_get_local_path(path->dentry, buf,
- buf_len - 1);
- }
-encode:
- if (IS_ERR(pos))
- continue;
- name = tomoyo_encode(pos);
- break;
- }
- kfree(buf);
- if (!name)
- tomoyo_warn_oom(__func__);
- return name;
-}
-
-/**
- * tomoyo_realpath_nofollow - Get realpath of a pathname.
- *
- * @pathname: The pathname to solve.
- *
- * Returns the realpath of @pathname on success, NULL otherwise.
- */
-char *tomoyo_realpath_nofollow(const char *pathname)
-{
- struct path path;
-
- if (pathname && kern_path(pathname, 0, &path) == 0) {
- char *buf = tomoyo_realpath_from_path(&path);
- path_put(&path);
- return buf;
- }
- return NULL;
-}
diff --git a/ANDROID_3.4.5/security/tomoyo/securityfs_if.c b/ANDROID_3.4.5/security/tomoyo/securityfs_if.c
deleted file mode 100644
index 8592f2fc..00000000
--- a/ANDROID_3.4.5/security/tomoyo/securityfs_if.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * security/tomoyo/securityfs_if.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include <linux/security.h>
-#include "common.h"
-
-/**
- * tomoyo_check_task_acl - Check permission for task operation.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- * @ptr: Pointer to "struct tomoyo_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool tomoyo_check_task_acl(struct tomoyo_request_info *r,
- const struct tomoyo_acl_info *ptr)
-{
- const struct tomoyo_task_acl *acl = container_of(ptr, typeof(*acl),
- head);
- return !tomoyo_pathcmp(r->param.task.domainname, acl->domainname);
-}
-
-/**
- * tomoyo_write_self - write() for /sys/kernel/security/tomoyo/self_domain interface.
- *
- * @file: Pointer to "struct file".
- * @buf: Domainname to transit to.
- * @count: Size of @buf.
- * @ppos: Unused.
- *
- * Returns @count on success, negative value otherwise.
- *
- * If domain transition was permitted but the domain transition failed, this
- * function returns error rather than terminating current thread with SIGKILL.
- */
-static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- char *data;
- int error;
- if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10)
- return -ENOMEM;
- data = kzalloc(count + 1, GFP_NOFS);
- if (!data)
- return -ENOMEM;
- if (copy_from_user(data, buf, count)) {
- error = -EFAULT;
- goto out;
- }
- tomoyo_normalize_line(data);
- if (tomoyo_correct_domain(data)) {
- const int idx = tomoyo_read_lock();
- struct tomoyo_path_info name;
- struct tomoyo_request_info r;
- name.name = data;
- tomoyo_fill_path_info(&name);
- /* Check "task manual_domain_transition" permission. */
- tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE);
- r.param_type = TOMOYO_TYPE_MANUAL_TASK_ACL;
- r.param.task.domainname = &name;
- tomoyo_check_acl(&r, tomoyo_check_task_acl);
- if (!r.granted)
- error = -EPERM;
- else {
- struct tomoyo_domain_info *new_domain =
- tomoyo_assign_domain(data, true);
- if (!new_domain) {
- error = -ENOENT;
- } else {
- struct cred *cred = prepare_creds();
- if (!cred) {
- error = -ENOMEM;
- } else {
- struct tomoyo_domain_info *old_domain =
- cred->security;
- cred->security = new_domain;
- atomic_inc(&new_domain->users);
- atomic_dec(&old_domain->users);
- commit_creds(cred);
- error = 0;
- }
- }
- }
- tomoyo_read_unlock(idx);
- } else
- error = -EINVAL;
-out:
- kfree(data);
- return error ? error : count;
-}
-
-/**
- * tomoyo_read_self - read() for /sys/kernel/security/tomoyo/self_domain interface.
- *
- * @file: Pointer to "struct file".
- * @buf: Domainname which current thread belongs to.
- * @count: Size of @buf.
- * @ppos: Bytes read by now.
- *
- * Returns read size on success, negative value otherwise.
- */
-static ssize_t tomoyo_read_self(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- const char *domain = tomoyo_domain()->domainname->name;
- loff_t len = strlen(domain);
- loff_t pos = *ppos;
- if (pos >= len || !count)
- return 0;
- len -= pos;
- if (count < len)
- len = count;
- if (copy_to_user(buf, domain + pos, len))
- return -EFAULT;
- *ppos += len;
- return len;
-}
-
-/* Operations for /sys/kernel/security/tomoyo/self_domain interface. */
-static const struct file_operations tomoyo_self_operations = {
- .write = tomoyo_write_self,
- .read = tomoyo_read_self,
-};
-
-/**
- * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
- *
- * @inode: Pointer to "struct inode".
- * @file: Pointer to "struct file".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_open(struct inode *inode, struct file *file)
-{
- const int key = ((u8 *) file->f_path.dentry->d_inode->i_private)
- - ((u8 *) NULL);
- return tomoyo_open_control(key, file);
-}
-
-/**
- * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface.
- *
- * @inode: Pointer to "struct inode".
- * @file: Pointer to "struct file".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_release(struct inode *inode, struct file *file)
-{
- return tomoyo_close_control(file->private_data);
-}
-
-/**
- * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface.
- *
- * @file: Pointer to "struct file".
- * @wait: Pointer to "poll_table". Maybe NULL.
- *
- * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write,
- * POLLOUT | POLLWRNORM otherwise.
- */
-static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
-{
- return tomoyo_poll_control(file, wait);
-}
-
-/**
- * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface.
- *
- * @file: Pointer to "struct file".
- * @buf: Pointer to buffer.
- * @count: Size of @buf.
- * @ppos: Unused.
- *
- * Returns bytes read on success, negative value otherwise.
- */
-static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
-{
- return tomoyo_read_control(file->private_data, buf, count);
-}
-
-/**
- * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface.
- *
- * @file: Pointer to "struct file".
- * @buf: Pointer to buffer.
- * @count: Size of @buf.
- * @ppos: Unused.
- *
- * Returns @count on success, negative value otherwise.
- */
-static ssize_t tomoyo_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- return tomoyo_write_control(file->private_data, buf, count);
-}
-
-/*
- * tomoyo_operations is a "struct file_operations" which is used for handling
- * /sys/kernel/security/tomoyo/ interface.
- *
- * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR).
- * See tomoyo_io_buffer for internals.
- */
-static const struct file_operations tomoyo_operations = {
- .open = tomoyo_open,
- .release = tomoyo_release,
- .poll = tomoyo_poll,
- .read = tomoyo_read,
- .write = tomoyo_write,
- .llseek = noop_llseek,
-};
-
-/**
- * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory.
- *
- * @name: The name of the interface file.
- * @mode: The permission of the interface file.
- * @parent: The parent directory.
- * @key: Type of interface.
- *
- * Returns nothing.
- */
-static void __init tomoyo_create_entry(const char *name, const umode_t mode,
- struct dentry *parent, const u8 key)
-{
- securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key,
- &tomoyo_operations);
-}
-
-/**
- * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface.
- *
- * Returns 0.
- */
-static int __init tomoyo_initerface_init(void)
-{
- struct dentry *tomoyo_dir;
-
- /* Don't create securityfs entries unless registered. */
- if (current_cred()->security != &tomoyo_kernel_domain)
- return 0;
-
- tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
- tomoyo_create_entry("query", 0600, tomoyo_dir,
- TOMOYO_QUERY);
- tomoyo_create_entry("domain_policy", 0600, tomoyo_dir,
- TOMOYO_DOMAINPOLICY);
- tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
- TOMOYO_EXCEPTIONPOLICY);
- tomoyo_create_entry("audit", 0400, tomoyo_dir,
- TOMOYO_AUDIT);
- tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
- TOMOYO_PROCESS_STATUS);
- tomoyo_create_entry("stat", 0644, tomoyo_dir,
- TOMOYO_STAT);
- tomoyo_create_entry("profile", 0600, tomoyo_dir,
- TOMOYO_PROFILE);
- tomoyo_create_entry("manager", 0600, tomoyo_dir,
- TOMOYO_MANAGER);
- tomoyo_create_entry("version", 0400, tomoyo_dir,
- TOMOYO_VERSION);
- securityfs_create_file("self_domain", 0666, tomoyo_dir, NULL,
- &tomoyo_self_operations);
- tomoyo_load_builtin_policy();
- return 0;
-}
-
-fs_initcall(tomoyo_initerface_init);
diff --git a/ANDROID_3.4.5/security/tomoyo/tomoyo.c b/ANDROID_3.4.5/security/tomoyo/tomoyo.c
deleted file mode 100644
index 620d37c1..00000000
--- a/ANDROID_3.4.5/security/tomoyo/tomoyo.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * security/tomoyo/tomoyo.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include <linux/security.h>
-#include "common.h"
-
-/**
- * tomoyo_cred_alloc_blank - Target for security_cred_alloc_blank().
- *
- * @new: Pointer to "struct cred".
- * @gfp: Memory allocation flags.
- *
- * Returns 0.
- */
-static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
-{
- new->security = NULL;
- return 0;
-}
-
-/**
- * tomoyo_cred_prepare - Target for security_prepare_creds().
- *
- * @new: Pointer to "struct cred".
- * @old: Pointer to "struct cred".
- * @gfp: Memory allocation flags.
- *
- * Returns 0.
- */
-static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
- gfp_t gfp)
-{
- struct tomoyo_domain_info *domain = old->security;
- new->security = domain;
- if (domain)
- atomic_inc(&domain->users);
- return 0;
-}
-
-/**
- * tomoyo_cred_transfer - Target for security_transfer_creds().
- *
- * @new: Pointer to "struct cred".
- * @old: Pointer to "struct cred".
- */
-static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
-{
- tomoyo_cred_prepare(new, old, 0);
-}
-
-/**
- * tomoyo_cred_free - Target for security_cred_free().
- *
- * @cred: Pointer to "struct cred".
- */
-static void tomoyo_cred_free(struct cred *cred)
-{
- struct tomoyo_domain_info *domain = cred->security;
- if (domain)
- atomic_dec(&domain->users);
-}
-
-/**
- * tomoyo_bprm_set_creds - Target for security_bprm_set_creds().
- *
- * @bprm: Pointer to "struct linux_binprm".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
-{
- int rc;
-
- rc = cap_bprm_set_creds(bprm);
- if (rc)
- return rc;
-
- /*
- * Do only if this function is called for the first time of an execve
- * operation.
- */
- if (bprm->cred_prepared)
- return 0;
-#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
- /*
- * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
- * for the first time.
- */
- if (!tomoyo_policy_loaded)
- tomoyo_load_policy(bprm->filename);
-#endif
- /*
- * Release reference to "struct tomoyo_domain_info" stored inside
- * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
- * stored inside "bprm->cred->security" will be acquired later inside
- * tomoyo_find_next_domain().
- */
- atomic_dec(&((struct tomoyo_domain_info *)
- bprm->cred->security)->users);
- /*
- * Tell tomoyo_bprm_check_security() is called for the first time of an
- * execve operation.
- */
- bprm->cred->security = NULL;
- return 0;
-}
-
-/**
- * tomoyo_bprm_check_security - Target for security_bprm_check().
- *
- * @bprm: Pointer to "struct linux_binprm".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
-{
- struct tomoyo_domain_info *domain = bprm->cred->security;
-
- /*
- * Execute permission is checked against pathname passed to do_execve()
- * using current domain.
- */
- if (!domain) {
- const int idx = tomoyo_read_lock();
- const int err = tomoyo_find_next_domain(bprm);
- tomoyo_read_unlock(idx);
- return err;
- }
- /*
- * Read permission is checked against interpreters using next domain.
- */
- return tomoyo_check_open_permission(domain, &bprm->file->f_path,
- O_RDONLY);
-}
-
-/**
- * tomoyo_inode_getattr - Target for security_inode_getattr().
- *
- * @mnt: Pointer to "struct vfsmount".
- * @dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
-{
- struct path path = { mnt, dentry };
- return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL);
-}
-
-/**
- * tomoyo_path_truncate - Target for security_path_truncate().
- *
- * @path: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_truncate(struct path *path)
-{
- return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
-}
-
-/**
- * tomoyo_path_unlink - Target for security_path_unlink().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
-{
- struct path path = { parent->mnt, dentry };
- return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
-}
-
-/**
- * tomoyo_path_mkdir - Target for security_path_mkdir().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- * @mode: DAC permission mode.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
- umode_t mode)
-{
- struct path path = { parent->mnt, dentry };
- return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
- mode & S_IALLUGO);
-}
-
-/**
- * tomoyo_path_rmdir - Target for security_path_rmdir().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
-{
- struct path path = { parent->mnt, dentry };
- return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
-}
-
-/**
- * tomoyo_path_symlink - Target for security_path_symlink().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- * @old_name: Symlink's content.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
- const char *old_name)
-{
- struct path path = { parent->mnt, dentry };
- return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
-}
-
-/**
- * tomoyo_path_mknod - Target for security_path_mknod().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- * @mode: DAC permission mode.
- * @dev: Device attributes.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
- umode_t mode, unsigned int dev)
-{
- struct path path = { parent->mnt, dentry };
- int type = TOMOYO_TYPE_CREATE;
- const unsigned int perm = mode & S_IALLUGO;
-
- switch (mode & S_IFMT) {
- case S_IFCHR:
- type = TOMOYO_TYPE_MKCHAR;
- break;
- case S_IFBLK:
- type = TOMOYO_TYPE_MKBLOCK;
- break;
- default:
- goto no_dev;
- }
- return tomoyo_mkdev_perm(type, &path, perm, dev);
- no_dev:
- switch (mode & S_IFMT) {
- case S_IFIFO:
- type = TOMOYO_TYPE_MKFIFO;
- break;
- case S_IFSOCK:
- type = TOMOYO_TYPE_MKSOCK;
- break;
- }
- return tomoyo_path_number_perm(type, &path, perm);
-}
-
-/**
- * tomoyo_path_link - Target for security_path_link().
- *
- * @old_dentry: Pointer to "struct dentry".
- * @new_dir: Pointer to "struct path".
- * @new_dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
- struct dentry *new_dentry)
-{
- struct path path1 = { new_dir->mnt, old_dentry };
- struct path path2 = { new_dir->mnt, new_dentry };
- return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
-}
-
-/**
- * tomoyo_path_rename - Target for security_path_rename().
- *
- * @old_parent: Pointer to "struct path".
- * @old_dentry: Pointer to "struct dentry".
- * @new_parent: Pointer to "struct path".
- * @new_dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_rename(struct path *old_parent,
- struct dentry *old_dentry,
- struct path *new_parent,
- struct dentry *new_dentry)
-{
- struct path path1 = { old_parent->mnt, old_dentry };
- struct path path2 = { new_parent->mnt, new_dentry };
- return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
-}
-
-/**
- * tomoyo_file_fcntl - Target for security_file_fcntl().
- *
- * @file: Pointer to "struct file".
- * @cmd: Command for fcntl().
- * @arg: Argument for @cmd.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
- return 0;
- return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
- O_WRONLY | (arg & O_APPEND));
-}
-
-/**
- * tomoyo_dentry_open - Target for security_dentry_open().
- *
- * @f: Pointer to "struct file".
- * @cred: Pointer to "struct cred".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
-{
- int flags = f->f_flags;
- /* Don't check read permission here if called from do_execve(). */
- if (current->in_execve)
- return 0;
- return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
-}
-
-/**
- * tomoyo_file_ioctl - Target for security_file_ioctl().
- *
- * @file: Pointer to "struct file".
- * @cmd: Command for ioctl().
- * @arg: Argument for @cmd.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
-}
-
-/**
- * tomoyo_path_chmod - Target for security_path_chmod().
- *
- * @path: Pointer to "struct path".
- * @mode: DAC permission mode.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_chmod(struct path *path, umode_t mode)
-{
- return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, path,
- mode & S_IALLUGO);
-}
-
-/**
- * tomoyo_path_chown - Target for security_path_chown().
- *
- * @path: Pointer to "struct path".
- * @uid: Owner ID.
- * @gid: Group ID.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
-{
- int error = 0;
- if (uid != (uid_t) -1)
- error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, uid);
- if (!error && gid != (gid_t) -1)
- error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, gid);
- return error;
-}
-
-/**
- * tomoyo_path_chroot - Target for security_path_chroot().
- *
- * @path: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_chroot(struct path *path)
-{
- return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
-}
-
-/**
- * tomoyo_sb_mount - Target for security_sb_mount().
- *
- * @dev_name: Name of device file. Maybe NULL.
- * @path: Pointer to "struct path".
- * @type: Name of filesystem type. Maybe NULL.
- * @flags: Mount options.
- * @data: Optional data. Maybe NULL.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_sb_mount(char *dev_name, struct path *path,
- char *type, unsigned long flags, void *data)
-{
- return tomoyo_mount_permission(dev_name, path, type, flags, data);
-}
-
-/**
- * tomoyo_sb_umount - Target for security_sb_umount().
- *
- * @mnt: Pointer to "struct vfsmount".
- * @flags: Unmount options.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
-{
- struct path path = { mnt, mnt->mnt_root };
- return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
-}
-
-/**
- * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
- *
- * @old_path: Pointer to "struct path".
- * @new_path: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
-{
- return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
-}
-
-/**
- * tomoyo_socket_listen - Check permission for listen().
- *
- * @sock: Pointer to "struct socket".
- * @backlog: Backlog parameter.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_listen(struct socket *sock, int backlog)
-{
- return tomoyo_socket_listen_permission(sock);
-}
-
-/**
- * tomoyo_socket_connect - Check permission for connect().
- *
- * @sock: Pointer to "struct socket".
- * @addr: Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
- int addr_len)
-{
- return tomoyo_socket_connect_permission(sock, addr, addr_len);
-}
-
-/**
- * tomoyo_socket_bind - Check permission for bind().
- *
- * @sock: Pointer to "struct socket".
- * @addr: Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
- int addr_len)
-{
- return tomoyo_socket_bind_permission(sock, addr, addr_len);
-}
-
-/**
- * tomoyo_socket_sendmsg - Check permission for sendmsg().
- *
- * @sock: Pointer to "struct socket".
- * @msg: Pointer to "struct msghdr".
- * @size: Size of message.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
- int size)
-{
- return tomoyo_socket_sendmsg_permission(sock, msg, size);
-}
-
-/*
- * tomoyo_security_ops is a "struct security_operations" which is used for
- * registering TOMOYO.
- */
-static struct security_operations tomoyo_security_ops = {
- .name = "tomoyo",
- .cred_alloc_blank = tomoyo_cred_alloc_blank,
- .cred_prepare = tomoyo_cred_prepare,
- .cred_transfer = tomoyo_cred_transfer,
- .cred_free = tomoyo_cred_free,
- .bprm_set_creds = tomoyo_bprm_set_creds,
- .bprm_check_security = tomoyo_bprm_check_security,
- .file_fcntl = tomoyo_file_fcntl,
- .dentry_open = tomoyo_dentry_open,
- .path_truncate = tomoyo_path_truncate,
- .path_unlink = tomoyo_path_unlink,
- .path_mkdir = tomoyo_path_mkdir,
- .path_rmdir = tomoyo_path_rmdir,
- .path_symlink = tomoyo_path_symlink,
- .path_mknod = tomoyo_path_mknod,
- .path_link = tomoyo_path_link,
- .path_rename = tomoyo_path_rename,
- .inode_getattr = tomoyo_inode_getattr,
- .file_ioctl = tomoyo_file_ioctl,
- .path_chmod = tomoyo_path_chmod,
- .path_chown = tomoyo_path_chown,
- .path_chroot = tomoyo_path_chroot,
- .sb_mount = tomoyo_sb_mount,
- .sb_umount = tomoyo_sb_umount,
- .sb_pivotroot = tomoyo_sb_pivotroot,
- .socket_bind = tomoyo_socket_bind,
- .socket_connect = tomoyo_socket_connect,
- .socket_listen = tomoyo_socket_listen,
- .socket_sendmsg = tomoyo_socket_sendmsg,
-};
-
-/* Lock for GC. */
-struct srcu_struct tomoyo_ss;
-
-/**
- * tomoyo_init - Register TOMOYO Linux as a LSM module.
- *
- * Returns 0.
- */
-static int __init tomoyo_init(void)
-{
- struct cred *cred = (struct cred *) current_cred();
-
- if (!security_module_enable(&tomoyo_security_ops))
- return 0;
- /* register ourselves with the security framework */
- if (register_security(&tomoyo_security_ops) ||
- init_srcu_struct(&tomoyo_ss))
- panic("Failure registering TOMOYO Linux");
- printk(KERN_INFO "TOMOYO Linux initialized\n");
- cred->security = &tomoyo_kernel_domain;
- tomoyo_mm_init();
- return 0;
-}
-
-security_initcall(tomoyo_init);
diff --git a/ANDROID_3.4.5/security/tomoyo/util.c b/ANDROID_3.4.5/security/tomoyo/util.c
deleted file mode 100644
index 867558c9..00000000
--- a/ANDROID_3.4.5/security/tomoyo/util.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * security/tomoyo/util.c
- *
- * Copyright (C) 2005-2011 NTT DATA CORPORATION
- */
-
-#include <linux/slab.h>
-#include "common.h"
-
-/* Lock for protecting policy. */
-DEFINE_MUTEX(tomoyo_policy_lock);
-
-/* Has /sbin/init started? */
-bool tomoyo_policy_loaded;
-
-/*
- * Mapping table from "enum tomoyo_mac_index" to
- * "enum tomoyo_mac_category_index".
- */
-const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
- /* CONFIG::file group */
- [TOMOYO_MAC_FILE_EXECUTE] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_OPEN] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_CREATE] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_UNLINK] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_GETATTR] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_MKDIR] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_RMDIR] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_MKFIFO] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_MKSOCK] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_TRUNCATE] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_SYMLINK] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_MKBLOCK] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_MKCHAR] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_LINK] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_RENAME] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_CHMOD] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_CHOWN] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_CHGRP] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_IOCTL] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_CHROOT] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE,
- [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
- /* CONFIG::network group */
- [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_INET_RAW_BIND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_INET_RAW_SEND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] =
- TOMOYO_MAC_CATEGORY_NETWORK,
- /* CONFIG::misc group */
- [TOMOYO_MAC_ENVIRON] = TOMOYO_MAC_CATEGORY_MISC,
-};
-
-/**
- * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
- *
- * @time: Seconds since 1970/01/01 00:00:00.
- * @stamp: Pointer to "struct tomoyo_time".
- *
- * Returns nothing.
- *
- * This function does not handle Y2038 problem.
- */
-void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp)
-{
- static const u16 tomoyo_eom[2][12] = {
- { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
- { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
- };
- u16 y;
- u8 m;
- bool r;
- stamp->sec = time % 60;
- time /= 60;
- stamp->min = time % 60;
- time /= 60;
- stamp->hour = time % 24;
- time /= 24;
- for (y = 1970; ; y++) {
- const unsigned short days = (y & 3) ? 365 : 366;
- if (time < days)
- break;
- time -= days;
- }
- r = (y & 3) == 0;
- for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++)
- ;
- if (m)
- time -= tomoyo_eom[r][m - 1];
- stamp->year = y;
- stamp->month = ++m;
- stamp->day = ++time;
-}
-
-/**
- * tomoyo_permstr - Find permission keywords.
- *
- * @string: String representation for permissions in foo/bar/buz format.
- * @keyword: Keyword to find from @string/
- *
- * Returns ture if @keyword was found in @string, false otherwise.
- *
- * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
- */
-bool tomoyo_permstr(const char *string, const char *keyword)
-{
- const char *cp = strstr(string, keyword);
- if (cp)
- return cp == string || *(cp - 1) == '/';
- return false;
-}
-
-/**
- * tomoyo_read_token - Read a word from a line.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns a word on success, "" otherwise.
- *
- * To allow the caller to skip NULL check, this function returns "" rather than
- * NULL if there is no more words to read.
- */
-char *tomoyo_read_token(struct tomoyo_acl_param *param)
-{
- char *pos = param->data;
- char *del = strchr(pos, ' ');
- if (del)
- *del++ = '\0';
- else
- del = pos + strlen(pos);
- param->data = del;
- return pos;
-}
-
-/**
- * tomoyo_get_domainname - Read a domainname from a line.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- *
- * Returns a domainname on success, NULL otherwise.
- */
-const struct tomoyo_path_info *tomoyo_get_domainname
-(struct tomoyo_acl_param *param)
-{
- char *start = param->data;
- char *pos = start;
- while (*pos) {
- if (*pos++ != ' ' || *pos++ == '/')
- continue;
- pos -= 2;
- *pos++ = '\0';
- break;
- }
- param->data = pos;
- if (tomoyo_correct_domain(start))
- return tomoyo_get_name(start);
- return NULL;
-}
-
-/**
- * tomoyo_parse_ulong - Parse an "unsigned long" value.
- *
- * @result: Pointer to "unsigned long".
- * @str: Pointer to string to parse.
- *
- * Returns one of values in "enum tomoyo_value_type".
- *
- * The @src is updated to point the first character after the value
- * on success.
- */
-u8 tomoyo_parse_ulong(unsigned long *result, char **str)
-{
- const char *cp = *str;
- char *ep;
- int base = 10;
- if (*cp == '0') {
- char c = *(cp + 1);
- if (c == 'x' || c == 'X') {
- base = 16;
- cp += 2;
- } else if (c >= '0' && c <= '7') {
- base = 8;
- cp++;
- }
- }
- *result = simple_strtoul(cp, &ep, base);
- if (cp == ep)
- return TOMOYO_VALUE_TYPE_INVALID;
- *str = ep;
- switch (base) {
- case 16:
- return TOMOYO_VALUE_TYPE_HEXADECIMAL;
- case 8:
- return TOMOYO_VALUE_TYPE_OCTAL;
- default:
- return TOMOYO_VALUE_TYPE_DECIMAL;
- }
-}
-
-/**
- * tomoyo_print_ulong - Print an "unsigned long" value.
- *
- * @buffer: Pointer to buffer.
- * @buffer_len: Size of @buffer.
- * @value: An "unsigned long" value.
- * @type: Type of @value.
- *
- * Returns nothing.
- */
-void tomoyo_print_ulong(char *buffer, const int buffer_len,
- const unsigned long value, const u8 type)
-{
- if (type == TOMOYO_VALUE_TYPE_DECIMAL)
- snprintf(buffer, buffer_len, "%lu", value);
- else if (type == TOMOYO_VALUE_TYPE_OCTAL)
- snprintf(buffer, buffer_len, "0%lo", value);
- else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL)
- snprintf(buffer, buffer_len, "0x%lX", value);
- else
- snprintf(buffer, buffer_len, "type(%u)", type);
-}
-
-/**
- * tomoyo_parse_name_union - Parse a tomoyo_name_union.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @ptr: Pointer to "struct tomoyo_name_union".
- *
- * Returns true on success, false otherwise.
- */
-bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
- struct tomoyo_name_union *ptr)
-{
- char *filename;
- if (param->data[0] == '@') {
- param->data++;
- ptr->group = tomoyo_get_group(param, TOMOYO_PATH_GROUP);
- return ptr->group != NULL;
- }
- filename = tomoyo_read_token(param);
- if (!tomoyo_correct_word(filename))
- return false;
- ptr->filename = tomoyo_get_name(filename);
- return ptr->filename != NULL;
-}
-
-/**
- * tomoyo_parse_number_union - Parse a tomoyo_number_union.
- *
- * @param: Pointer to "struct tomoyo_acl_param".
- * @ptr: Pointer to "struct tomoyo_number_union".
- *
- * Returns true on success, false otherwise.
- */
-bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
- struct tomoyo_number_union *ptr)
-{
- char *data;
- u8 type;
- unsigned long v;
- memset(ptr, 0, sizeof(*ptr));
- if (param->data[0] == '@') {
- param->data++;
- ptr->group = tomoyo_get_group(param, TOMOYO_NUMBER_GROUP);
- return ptr->group != NULL;
- }
- data = tomoyo_read_token(param);
- type = tomoyo_parse_ulong(&v, &data);
- if (type == TOMOYO_VALUE_TYPE_INVALID)
- return false;
- ptr->values[0] = v;
- ptr->value_type[0] = type;
- if (!*data) {
- ptr->values[1] = v;
- ptr->value_type[1] = type;
- return true;
- }
- if (*data++ != '-')
- return false;
- type = tomoyo_parse_ulong(&v, &data);
- if (type == TOMOYO_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
- return false;
- ptr->values[1] = v;
- ptr->value_type[1] = type;
- return true;
-}
-
-/**
- * tomoyo_byte_range - Check whether the string is a \ooo style octal value.
- *
- * @str: Pointer to the string.
- *
- * Returns true if @str is a \ooo style octal value, false otherwise.
- *
- * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF.
- * This function verifies that \ooo is in valid range.
- */
-static inline bool tomoyo_byte_range(const char *str)
-{
- return *str >= '0' && *str++ <= '3' &&
- *str >= '0' && *str++ <= '7' &&
- *str >= '0' && *str <= '7';
-}
-
-/**
- * tomoyo_alphabet_char - Check whether the character is an alphabet.
- *
- * @c: The character to check.
- *
- * Returns true if @c is an alphabet character, false otherwise.
- */
-static inline bool tomoyo_alphabet_char(const char c)
-{
- return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
-}
-
-/**
- * tomoyo_make_byte - Make byte value from three octal characters.
- *
- * @c1: The first character.
- * @c2: The second character.
- * @c3: The third character.
- *
- * Returns byte value.
- */
-static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
-{
- return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
-}
-
-/**
- * tomoyo_valid - Check whether the character is a valid char.
- *
- * @c: The character to check.
- *
- * Returns true if @c is a valid character, false otherwise.
- */
-static inline bool tomoyo_valid(const unsigned char c)
-{
- return c > ' ' && c < 127;
-}
-
-/**
- * tomoyo_invalid - Check whether the character is an invalid char.
- *
- * @c: The character to check.
- *
- * Returns true if @c is an invalid character, false otherwise.
- */
-static inline bool tomoyo_invalid(const unsigned char c)
-{
- return c && (c <= ' ' || c >= 127);
-}
-
-/**
- * tomoyo_str_starts - Check whether the given string starts with the given keyword.
- *
- * @src: Pointer to pointer to the string.
- * @find: Pointer to the keyword.
- *
- * Returns true if @src starts with @find, false otherwise.
- *
- * The @src is updated to point the first character after the @find
- * if @src starts with @find.
- */
-bool tomoyo_str_starts(char **src, const char *find)
-{
- const int len = strlen(find);
- char *tmp = *src;
-
- if (strncmp(tmp, find, len))
- return false;
- tmp += len;
- *src = tmp;
- return true;
-}
-
-/**
- * tomoyo_normalize_line - Format string.
- *
- * @buffer: The line to normalize.
- *
- * Leading and trailing whitespaces are removed.
- * Multiple whitespaces are packed into single space.
- *
- * Returns nothing.
- */
-void tomoyo_normalize_line(unsigned char *buffer)
-{
- unsigned char *sp = buffer;
- unsigned char *dp = buffer;
- bool first = true;
-
- while (tomoyo_invalid(*sp))
- sp++;
- while (*sp) {
- if (!first)
- *dp++ = ' ';
- first = false;
- while (tomoyo_valid(*sp))
- *dp++ = *sp++;
- while (tomoyo_invalid(*sp))
- sp++;
- }
- *dp = '\0';
-}
-
-/**
- * tomoyo_correct_word2 - Validate a string.
- *
- * @string: The string to check. Maybe non-'\0'-terminated.
- * @len: Length of @string.
- *
- * Check whether the given string follows the naming rules.
- * Returns true if @string follows the naming rules, false otherwise.
- */
-static bool tomoyo_correct_word2(const char *string, size_t len)
-{
- const char *const start = string;
- bool in_repetition = false;
- unsigned char c;
- unsigned char d;
- unsigned char e;
- if (!len)
- goto out;
- while (len--) {
- c = *string++;
- if (c == '\\') {
- if (!len--)
- goto out;
- c = *string++;
- switch (c) {
- case '\\': /* "\\" */
- continue;
- case '$': /* "\$" */
- case '+': /* "\+" */
- case '?': /* "\?" */
- case '*': /* "\*" */
- case '@': /* "\@" */
- case 'x': /* "\x" */
- case 'X': /* "\X" */
- case 'a': /* "\a" */
- case 'A': /* "\A" */
- case '-': /* "\-" */
- continue;
- case '{': /* "/\{" */
- if (string - 3 < start || *(string - 3) != '/')
- break;
- in_repetition = true;
- continue;
- case '}': /* "\}/" */
- if (*string != '/')
- break;
- if (!in_repetition)
- break;
- in_repetition = false;
- continue;
- case '0': /* "\ooo" */
- case '1':
- case '2':
- case '3':
- if (!len-- || !len--)
- break;
- d = *string++;
- e = *string++;
- if (d < '0' || d > '7' || e < '0' || e > '7')
- break;
- c = tomoyo_make_byte(c, d, e);
- if (c <= ' ' || c >= 127)
- continue;
- }
- goto out;
- } else if (in_repetition && c == '/') {
- goto out;
- } else if (c <= ' ' || c >= 127) {
- goto out;
- }
- }
- if (in_repetition)
- goto out;
- return true;
- out:
- return false;
-}
-
-/**
- * tomoyo_correct_word - Validate a string.
- *
- * @string: The string to check.
- *
- * Check whether the given string follows the naming rules.
- * Returns true if @string follows the naming rules, false otherwise.
- */
-bool tomoyo_correct_word(const char *string)
-{
- return tomoyo_correct_word2(string, strlen(string));
-}
-
-/**
- * tomoyo_correct_path - Validate a pathname.
- *
- * @filename: The pathname to check.
- *
- * Check whether the given pathname follows the naming rules.
- * Returns true if @filename follows the naming rules, false otherwise.
- */
-bool tomoyo_correct_path(const char *filename)
-{
- return *filename == '/' && tomoyo_correct_word(filename);
-}
-
-/**
- * tomoyo_correct_domain - Check whether the given domainname follows the naming rules.
- *
- * @domainname: The domainname to check.
- *
- * Returns true if @domainname follows the naming rules, false otherwise.
- */
-bool tomoyo_correct_domain(const unsigned char *domainname)
-{
- if (!domainname || !tomoyo_domain_def(domainname))
- return false;
- domainname = strchr(domainname, ' ');
- if (!domainname++)
- return true;
- while (1) {
- const unsigned char *cp = strchr(domainname, ' ');
- if (!cp)
- break;
- if (*domainname != '/' ||
- !tomoyo_correct_word2(domainname, cp - domainname))
- return false;
- domainname = cp + 1;
- }
- return tomoyo_correct_path(domainname);
-}
-
-/**
- * tomoyo_domain_def - Check whether the given token can be a domainname.
- *
- * @buffer: The token to check.
- *
- * Returns true if @buffer possibly be a domainname, false otherwise.
- */
-bool tomoyo_domain_def(const unsigned char *buffer)
-{
- const unsigned char *cp;
- int len;
- if (*buffer != '<')
- return false;
- cp = strchr(buffer, ' ');
- if (!cp)
- len = strlen(buffer);
- else
- len = cp - buffer;
- if (buffer[len - 1] != '>' ||
- !tomoyo_correct_word2(buffer + 1, len - 2))
- return false;
- return true;
-}
-
-/**
- * tomoyo_find_domain - Find a domain by the given name.
- *
- * @domainname: The domainname to find.
- *
- * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
-{
- struct tomoyo_domain_info *domain;
- struct tomoyo_path_info name;
-
- name.name = domainname;
- tomoyo_fill_path_info(&name);
- list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
- if (!domain->is_deleted &&
- !tomoyo_pathcmp(&name, domain->domainname))
- return domain;
- }
- return NULL;
-}
-
-/**
- * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
- *
- * @filename: The string to evaluate.
- *
- * Returns the initial length without a pattern in @filename.
- */
-static int tomoyo_const_part_length(const char *filename)
-{
- char c;
- int len = 0;
-
- if (!filename)
- return 0;
- while ((c = *filename++) != '\0') {
- if (c != '\\') {
- len++;
- continue;
- }
- c = *filename++;
- switch (c) {
- case '\\': /* "\\" */
- len += 2;
- continue;
- case '0': /* "\ooo" */
- case '1':
- case '2':
- case '3':
- c = *filename++;
- if (c < '0' || c > '7')
- break;
- c = *filename++;
- if (c < '0' || c > '7')
- break;
- len += 4;
- continue;
- }
- break;
- }
- return len;
-}
-
-/**
- * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members.
- *
- * @ptr: Pointer to "struct tomoyo_path_info" to fill in.
- *
- * The caller sets "struct tomoyo_path_info"->name.
- */
-void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
-{
- const char *name = ptr->name;
- const int len = strlen(name);
-
- ptr->const_len = tomoyo_const_part_length(name);
- ptr->is_dir = len && (name[len - 1] == '/');
- ptr->is_patterned = (ptr->const_len < len);
- ptr->hash = full_name_hash(name, len);
-}
-
-/**
- * tomoyo_file_matches_pattern2 - Pattern matching without '/' character and "\-" pattern.
- *
- * @filename: The start of string to check.
- * @filename_end: The end of string to check.
- * @pattern: The start of pattern to compare.
- * @pattern_end: The end of pattern to compare.
- *
- * Returns true if @filename matches @pattern, false otherwise.
- */
-static bool tomoyo_file_matches_pattern2(const char *filename,
- const char *filename_end,
- const char *pattern,
- const char *pattern_end)
-{
- while (filename < filename_end && pattern < pattern_end) {
- char c;
- if (*pattern != '\\') {
- if (*filename++ != *pattern++)
- return false;
- continue;
- }
- c = *filename;
- pattern++;
- switch (*pattern) {
- int i;
- int j;
- case '?':
- if (c == '/') {
- return false;
- } else if (c == '\\') {
- if (filename[1] == '\\')
- filename++;
- else if (tomoyo_byte_range(filename + 1))
- filename += 3;
- else
- return false;
- }
- break;
- case '\\':
- if (c != '\\')
- return false;
- if (*++filename != '\\')
- return false;
- break;
- case '+':
- if (!isdigit(c))
- return false;
- break;
- case 'x':
- if (!isxdigit(c))
- return false;
- break;
- case 'a':
- if (!tomoyo_alphabet_char(c))
- return false;
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- if (c == '\\' && tomoyo_byte_range(filename + 1)
- && strncmp(filename + 1, pattern, 3) == 0) {
- filename += 3;
- pattern += 2;
- break;
- }
- return false; /* Not matched. */
- case '*':
- case '@':
- for (i = 0; i <= filename_end - filename; i++) {
- if (tomoyo_file_matches_pattern2(
- filename + i, filename_end,
- pattern + 1, pattern_end))
- return true;
- c = filename[i];
- if (c == '.' && *pattern == '@')
- break;
- if (c != '\\')
- continue;
- if (filename[i + 1] == '\\')
- i++;
- else if (tomoyo_byte_range(filename + i + 1))
- i += 3;
- else
- break; /* Bad pattern. */
- }
- return false; /* Not matched. */
- default:
- j = 0;
- c = *pattern;
- if (c == '$') {
- while (isdigit(filename[j]))
- j++;
- } else if (c == 'X') {
- while (isxdigit(filename[j]))
- j++;
- } else if (c == 'A') {
- while (tomoyo_alphabet_char(filename[j]))
- j++;
- }
- for (i = 1; i <= j; i++) {
- if (tomoyo_file_matches_pattern2(
- filename + i, filename_end,
- pattern + 1, pattern_end))
- return true;
- }
- return false; /* Not matched or bad pattern. */
- }
- filename++;
- pattern++;
- }
- while (*pattern == '\\' &&
- (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
- pattern += 2;
- return filename == filename_end && pattern == pattern_end;
-}
-
-/**
- * tomoyo_file_matches_pattern - Pattern matching without '/' character.
- *
- * @filename: The start of string to check.
- * @filename_end: The end of string to check.
- * @pattern: The start of pattern to compare.
- * @pattern_end: The end of pattern to compare.
- *
- * Returns true if @filename matches @pattern, false otherwise.
- */
-static bool tomoyo_file_matches_pattern(const char *filename,
- const char *filename_end,
- const char *pattern,
- const char *pattern_end)
-{
- const char *pattern_start = pattern;
- bool first = true;
- bool result;
-
- while (pattern < pattern_end - 1) {
- /* Split at "\-" pattern. */
- if (*pattern++ != '\\' || *pattern++ != '-')
- continue;
- result = tomoyo_file_matches_pattern2(filename,
- filename_end,
- pattern_start,
- pattern - 2);
- if (first)
- result = !result;
- if (result)
- return false;
- first = false;
- pattern_start = pattern;
- }
- result = tomoyo_file_matches_pattern2(filename, filename_end,
- pattern_start, pattern_end);
- return first ? result : !result;
-}
-
-/**
- * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
- *
- * @f: The start of string to check.
- * @p: The start of pattern to compare.
- *
- * Returns true if @f matches @p, false otherwise.
- */
-static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
-{
- const char *f_delimiter;
- const char *p_delimiter;
-
- while (*f && *p) {
- f_delimiter = strchr(f, '/');
- if (!f_delimiter)
- f_delimiter = f + strlen(f);
- p_delimiter = strchr(p, '/');
- if (!p_delimiter)
- p_delimiter = p + strlen(p);
- if (*p == '\\' && *(p + 1) == '{')
- goto recursive;
- if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
- p_delimiter))
- return false;
- f = f_delimiter;
- if (*f)
- f++;
- p = p_delimiter;
- if (*p)
- p++;
- }
- /* Ignore trailing "\*" and "\@" in @pattern. */
- while (*p == '\\' &&
- (*(p + 1) == '*' || *(p + 1) == '@'))
- p += 2;
- return !*f && !*p;
- recursive:
- /*
- * The "\{" pattern is permitted only after '/' character.
- * This guarantees that below "*(p - 1)" is safe.
- * Also, the "\}" pattern is permitted only before '/' character
- * so that "\{" + "\}" pair will not break the "\-" operator.
- */
- if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
- *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
- return false; /* Bad pattern. */
- do {
- /* Compare current component with pattern. */
- if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
- p_delimiter - 2))
- break;
- /* Proceed to next component. */
- f = f_delimiter;
- if (!*f)
- break;
- f++;
- /* Continue comparison. */
- if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
- return true;
- f_delimiter = strchr(f, '/');
- } while (f_delimiter);
- return false; /* Not matched. */
-}
-
-/**
- * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
- *
- * @filename: The filename to check.
- * @pattern: The pattern to compare.
- *
- * Returns true if matches, false otherwise.
- *
- * The following patterns are available.
- * \\ \ itself.
- * \ooo Octal representation of a byte.
- * \* Zero or more repetitions of characters other than '/'.
- * \@ Zero or more repetitions of characters other than '/' or '.'.
- * \? 1 byte character other than '/'.
- * \$ One or more repetitions of decimal digits.
- * \+ 1 decimal digit.
- * \X One or more repetitions of hexadecimal digits.
- * \x 1 hexadecimal digit.
- * \A One or more repetitions of alphabet characters.
- * \a 1 alphabet character.
- *
- * \- Subtraction operator.
- *
- * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
- * /dir/dir/dir/ ).
- */
-bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
- const struct tomoyo_path_info *pattern)
-{
- const char *f = filename->name;
- const char *p = pattern->name;
- const int len = pattern->const_len;
-
- /* If @pattern doesn't contain pattern, I can use strcmp(). */
- if (!pattern->is_patterned)
- return !tomoyo_pathcmp(filename, pattern);
- /* Don't compare directory and non-directory. */
- if (filename->is_dir != pattern->is_dir)
- return false;
- /* Compare the initial length without patterns. */
- if (strncmp(f, p, len))
- return false;
- f += len;
- p += len;
- return tomoyo_path_matches_pattern2(f, p);
-}
-
-/**
- * tomoyo_get_exe - Get tomoyo_realpath() of current process.
- *
- * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
- *
- * This function uses kzalloc(), so the caller must call kfree()
- * if this function didn't return NULL.
- */
-const char *tomoyo_get_exe(void)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- const char *cp = NULL;
-
- if (!mm)
- return NULL;
- down_read(&mm->mmap_sem);
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
- cp = tomoyo_realpath_from_path(&vma->vm_file->f_path);
- break;
- }
- }
- up_read(&mm->mmap_sem);
- return cp;
-}
-
-/**
- * tomoyo_get_mode - Get MAC mode.
- *
- * @ns: Pointer to "struct tomoyo_policy_namespace".
- * @profile: Profile number.
- * @index: Index number of functionality.
- *
- * Returns mode.
- */
-int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
- const u8 index)
-{
- u8 mode;
- struct tomoyo_profile *p;
-
- if (!tomoyo_policy_loaded)
- return TOMOYO_CONFIG_DISABLED;
- p = tomoyo_profile(ns, profile);
- mode = p->config[index];
- if (mode == TOMOYO_CONFIG_USE_DEFAULT)
- mode = p->config[tomoyo_index2category[index]
- + TOMOYO_MAX_MAC_INDEX];
- if (mode == TOMOYO_CONFIG_USE_DEFAULT)
- mode = p->default_config;
- return mode & 3;
-}
-
-/**
- * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members.
- *
- * @r: Pointer to "struct tomoyo_request_info" to initialize.
- * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain().
- * @index: Index number of functionality.
- *
- * Returns mode.
- */
-int tomoyo_init_request_info(struct tomoyo_request_info *r,
- struct tomoyo_domain_info *domain, const u8 index)
-{
- u8 profile;
- memset(r, 0, sizeof(*r));
- if (!domain)
- domain = tomoyo_domain();
- r->domain = domain;
- profile = domain->profile;
- r->profile = profile;
- r->type = index;
- r->mode = tomoyo_get_mode(domain->ns, profile, index);
- return r->mode;
-}
-
-/**
- * tomoyo_domain_quota_is_ok - Check for domain's quota.
- *
- * @r: Pointer to "struct tomoyo_request_info".
- *
- * Returns true if the domain is not exceeded quota, false otherwise.
- *
- * Caller holds tomoyo_read_lock().
- */
-bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
-{
- unsigned int count = 0;
- struct tomoyo_domain_info *domain = r->domain;
- struct tomoyo_acl_info *ptr;
-
- if (r->mode != TOMOYO_CONFIG_LEARNING)
- return false;
- if (!domain)
- return true;
- list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
- u16 perm;
- u8 i;
- if (ptr->is_deleted)
- continue;
- switch (ptr->type) {
- case TOMOYO_TYPE_PATH_ACL:
- perm = container_of(ptr, struct tomoyo_path_acl, head)
- ->perm;
- break;
- case TOMOYO_TYPE_PATH2_ACL:
- perm = container_of(ptr, struct tomoyo_path2_acl, head)
- ->perm;
- break;
- case TOMOYO_TYPE_PATH_NUMBER_ACL:
- perm = container_of(ptr, struct tomoyo_path_number_acl,
- head)->perm;
- break;
- case TOMOYO_TYPE_MKDEV_ACL:
- perm = container_of(ptr, struct tomoyo_mkdev_acl,
- head)->perm;
- break;
- case TOMOYO_TYPE_INET_ACL:
- perm = container_of(ptr, struct tomoyo_inet_acl,
- head)->perm;
- break;
- case TOMOYO_TYPE_UNIX_ACL:
- perm = container_of(ptr, struct tomoyo_unix_acl,
- head)->perm;
- break;
- case TOMOYO_TYPE_MANUAL_TASK_ACL:
- perm = 0;
- break;
- default:
- perm = 1;
- }
- for (i = 0; i < 16; i++)
- if (perm & (1 << i))
- count++;
- }
- if (count < tomoyo_profile(domain->ns, domain->profile)->
- pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
- return true;
- if (!domain->flags[TOMOYO_DIF_QUOTA_WARNED]) {
- domain->flags[TOMOYO_DIF_QUOTA_WARNED] = true;
- /* r->granted = false; */
- tomoyo_write_log(r, "%s", tomoyo_dif[TOMOYO_DIF_QUOTA_WARNED]);
- printk(KERN_WARNING "WARNING: "
- "Domain '%s' has too many ACLs to hold. "
- "Stopped learning mode.\n", domain->domainname->name);
- }
- return false;
-}